¿Hay alguna manera de completar automáticamente el comando de abrir en la Terminal?

12

Con frecuencia uso el comando open -a en Terminal para abrir aplicaciones a través de ssh. ¿Cómo hago que se complete automáticamente el nombre de una aplicación?

    
pregunta daviesgeek 04.02.2012 - 04:51

3 respuestas

7
_complete_open() {
        COMPREPLY=()
        local cur="${COMP_WORDS[$COMP_CWORD]}"
        local prev="${COMP_WORDS[COMP_CWORD-1]}"
        [[ "$cur" == -* || "$prev" != '-a' ]] && return
        apps="$(mdfind kMDItemKind==Application -onlyin /Applications -onlyin ~/Applications -onlyin /Developer -onlyin ~/Developer | grep -v '/.*/.*/.*/.*/' | sed -E 's|.*/||g;s|\.app$||g' | uniq)"$'Finder\nArchive Utility\nCharacterPalette\nKeyboardViewer'
        local IFS=$'\n'
        if [[ "${cur:0:1}" = '"' || "${cur:0:1}" = "'" ]]; then
            quote="${cur:0:1}"
            cur="${cur:1}"
        fi
        local found="$(grep -i "^$cur" <<< "$apps")"
        if [[ "$quote" == '"' ]]; then
            found="$(sed "s|^|\"|g;s|$|\"|g" <<< "$found")"
        elif [[ "$quote" == "'" ]]; then
            found="$(sed "s|^|'|g;s|$|'|g" <<< "$found")"
        else
            found="$(sed 's| |\ |g' <<< "$found")"
        fi
        COMPREPLY=($found)
}

complete -o default -F _complete_open open

Tercera versión, que ahora debería distinguir entre mayúsculas y minúsculas y trabajar entre comillas.

    
respondido por el user495470 09.02.2012 - 09:38
6

Agregue lo siguiente a su .bash_profile o .bashrc e inicie una nueva sesión:

function _complete_open {
    cur=$2
    COMPREPLY=( );

    [[ "$COMP_WORDS" = "open" ]] || return
    [[ "${COMP_WORDS[ $(( $COMP_CWORD - 1 )) ]}" = "-a" ]] || return

    OLDIFS="$IFS"
    IFS=$'\n'
    local _part="${COMP_WORDS[$COMP_CWORD]}"

    if [[ "${_part:0:1}" = '"' || "${_part:0:1}" = "'" ]] ; then
        COMPREPLY=( $( compgen -W "$( mdfind kMDItemKind==Application | sed -e 's|.*/||g' -e 's|.app$||' | sort -u )" -- $cur ) )
    else
        COMPREPLY=( $( compgen -W "$( mdfind kMDItemKind==Application | sed -e 's|.*/||g' -e 's|.app$||' -e 's| |\\ |g' | sort -u )" -- $cur ) )
    fi
    IFS="$OLDIFS"
}

complete -o default -F _complete_open open

No es necesario instalar nada. Esto funciona con bash fuera de la caja.

Solo autocompletará los nombres de los programas si la opción anterior es -a y, de lo contrario, mostrará el comportamiento predeterminado, por ejemplo. devuelva una lista de todos los archivos en el directorio actual o complete el prefijo de ruta actual.

Los resultados se generan a partir de system_profiler SPApplicationsDataType , que es la forma más fácil de obtener todas las aplicaciones que se pueden iniciar de esta manera en su sistema de esa manera. La lista se procesa para devolver solo los nombres de los programas, que pueden contener espacios y pueden ser diferentes de los nombres de los paquetes (incluso cuando se ignoran .app suffix)

Uso: Escriba open -a , seguido de un espacio, seguido de presionar Tab o Esc (dos veces en mi sistema, no estoy seguro de si está en todas partes).

Ejemplo que muestra todas las aplicaciones de ayuda para mi escáner:

$ open -a Scan
Scan to E-mail          Scan to Excel           Scan to Folder          Scan to Print           Scan to Searchable PDF  Scan to Word            ScanSnap Manager

Inconvenientes y problemas de esta solución:

  • Hay toneladas de programas en tu sistema que quizás no conozcas, como todo en /System/Library/CoreServices . Es posible que no desee enumerar todos ellos. OTOH, es muy fácil de ver y lanzar, por ejemplo. CharacterPalette o KeyboardViewer de esta manera. * Configure las llamadas mdfind adecuadamente con el argumento -onlyin .

  • Es un poco lento, debido a system_profiler SPApplicationsDataType . Es posible que deba esperar uno o dos segundos antes de que aparezca la finalización. Ahora usa mdfind para obtener los programas rápidamente. Gracias @Lri

  • Puede manejar espacios en los nombres de las aplicaciones y en los nombres de los programas incluidos entre comillas, pero es bastante intrépido. Requiere que la cita sea el primer carácter: mientras Scan" to "P es válido en bash , este programa no lo detectará. La finalización tampoco funciona después de un espacio de escape (por ejemplo, Scan\ to ), use comillas en tales casos ( "Scan to ). El soporte para espacios escapados solo es bueno para completar DVD a DVD\ Player .

respondido por el Daniel Beck 09.02.2012 - 05:53
3

Autocompletado programable al rescate! Sin embargo, se necesitaba una gran cantidad de copias de la página principal de finalización de Bash , que vale la pena instalar de todos modos por un montón de magia de autocompletado . Si lo hace, solo necesitará la última función ( _open ) y el comando de inicialización desde abajo.

Agregue lo siguiente a .bashrc :

# taken from http://bash-completion.alioth.debian.org/

_compopt_o_filenames()
{
    # We test for compopt availability first because directly invoking it on
    # bash < 4 at this point may cause terminal echo to be turned off for some
    # reason, see https://bugzilla.redhat.com/653669 for more info.
    type compopt &>/dev/null && compopt -o filenames 2>/dev/null || \
        compgen -f /non-existing-dir/ >/dev/null
}

_tilde() {
    local result=0
    # Does $1 start with tilde (~) and doesn't contain slash (/)?
    if [[ ${1:0:1} == "~" && $1 == ${1//\/} ]]; then
        _compopt_o_filenames
        # Try generate username completions
        COMPREPLY=( $( compgen -P '~' -u "${1#\~}" ) )
        result=${#COMPREPLY[@]}
    fi
    return $result
}

_quote_readline_by_ref()
{
    if [[ ${1:0:1} == "'" ]]; then
        if [[ ${BASH_VERSINFO[0]} -ge 4 ]]; then
            # Leave out first character
            printf -v $2 %s "${1:1}"
        else
            # Quote word, leaving out first character
            printf -v $2 %q "${1:1}"
            # Double-quote word (bash-3)
            printf -v $2 %q ${!2}
        fi
    elif [[ ${BASH_VERSINFO[0]} -le 3 && ${1:0:1} == '"' ]]; then
        printf -v $2 %q "${1:1}"
    else
        printf -v $2 %q "$1"
    fi

    # If result becomes quoted like this: $'string', re-evaluate in order to
    # drop the additional quoting.  See also: http://www.mail-archive.com/
    # [email protected]/msg01942.html
    [[ ${!2:0:1} == '$' ]] && eval $2=${!2}
} # _quote_readline_by_ref()

_filedir()
{
    local i IFS=$'\n' xspec

    _tilde "$cur" || return 0

    local -a toks
    local quoted tmp

    _quote_readline_by_ref "$cur" quoted
    toks=( ${toks[@]-} $(
        compgen -d -- "$quoted" | {
            while read -r tmp; do
                printf '%s\n' $tmp
            done
        }
    ))

    if [[ "$1" != -d ]]; then
        # Munge xspec to contain uppercase version too
        [[ ${BASH_VERSINFO[0]} -ge 4 ]] && \
            xspec=${1:+"!*.@($1|${1^^})"} || \
            xspec=${1:+"!*.@($1|$(printf %s $1 | tr '[:lower:]' '[:upper:]'))"}
        toks=( ${toks[@]-} $( compgen -f -X "$xspec" -- $quoted) )
    fi
    [ ${#toks[@]} -ne 0 ] && _compopt_o_filenames

    COMPREPLY=( "${COMPREPLY[@]}" "${toks[@]}" )
} # _filedir()

# only the following is needed if bash-autocompletion is already installed
_open ()
{
    local cur;

    cur=$2;

    COMPREPLY=();
    if [ $COMP_CWORD -eq 2 ]; then
        COMPREPLY=($(compgen -W "$(/bin/ls /Applications)" -- $cur ));
        return 0
    fi

    _filedir
}

complete -F _open open
    
respondido por el nohillside 04.02.2012 - 10:00

Lea otras preguntas en las etiquetas