16 votes

Existe-t-il un moyen de compléter automatiquement la commande d'ouverture dans le Terminal ?

J'utilise fréquemment le open -a dans le Terminal pour ouvrir des applications via ssh. Comment faire pour que le nom d'une application soit auto-complété ?

0 votes

Quel shell utilisez-vous ?

2 votes

Je pense qu'un moyen un peu plus rapide serait de taper le chemin complet (suivez-moi un peu ! !), par ex. open -a /Applications/Textedit.app foo.txt (Je suppose que c'est ce que vous essayez de faire). Si vous appuyez sur la touche Tab après le /A de /Applications puis Tab à nouveau après le /Te de /Textedit.app alors cela devrait remplir automatiquement les deux parties pour vous au fur et à mesure. Pas idéal, je l'admets, mais peut-être un peu mieux. C'était en utilisant Bash.

0 votes

Vous pouvez également essayer de suivre les instructions figurant à la fin de cet article : brettterpstra.com/grabbing-a-mac-apps-icon-advanced-bash-usage-2

9voto

Fuzzy Purple Monkey Points 702
_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

Troisième version, qui devrait maintenant être insensible à la casse et fonctionner entre guillemets.

0 votes

Je n'ai pas réussi à faire fonctionner ça avec DVD Player . Une idée de ce qui ne va pas ? On dirait une tabulation au lieu d'un espace...

0 votes

@DanielBeck Il manquait IFS=$'\n' . Quoi qu'il en soit, j'ai réédité la réponse.

0 votes

Ça a l'air bien. Un +1 tardif pour le mdfind idée. Bon travail sur l'optimisation et les corrections. CoreServices sont probablement des préférences personnelles. Quelle est la raison pour laquelle nospace Mais S'il n'y a qu'un seul programme, je veux continuer tout de suite avec le fichier à ouvrir. Juste une préférence personnelle ? Une idée sur le problème des citations restantes ? AFAICT, c'est la seule chose qui reste pour une solution appropriée.

7voto

Aidan Ryan Points 5056

Ajoutez les éléments suivants à votre .bash_profile o .bashrc et lancer une nouvelle session :

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

Il n'est pas nécessaire d'installer quoi que ce soit. Cela fonctionne avec bash hors de la boîte.


Il ne complétera automatiquement les noms des programmes que si l'option précédente est -a et autrement montrer le comportement par défaut, par exemple retourner une liste de tous les fichiers dans le répertoire courant ou compléter le préfixe du chemin courant.

Les résultats sont générés à partir de system_profiler SPApplicationsDataType qui est le moyen le plus facile d'obtenir toutes les applications qui peut être lancé de cette façon sur votre système comme ça. La liste est traitée pour ne retourner que les noms des programmes, qui peuvent contenir des espaces et peuvent être différents des noms des paquets (même en ignorant .app suffixe)

Utilisation : Type open -a suivi d'un espace, puis d'un appui sur Tab o Esc (deux fois sur mon système, je ne sais pas si c'est le cas partout).

Exemple montrant toutes les applications d'aide pour mon scanner :

$ 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

Inconvénients et problèmes de cette solution :

  • Il y a des tonnes de programmes sur votre système dont vous n'êtes peut-être pas conscient, comme tout ce qui est en /System/Library/CoreServices . Vous n'avez peut-être pas envie de les énumérer tous. Par contre, il est très facile de voir et de lancer par exemple CharacterPalette o KeyboardViewer de cette façon. *Configurer le mdfind l'appel ou les appels de manière appropriée avec le -onlyin argument.

  • C'est un peu lent, à cause de system_profiler SPApplicationsDataType . Il se peut que vous deviez attendre une seconde ou deux avant que l'achèvement n'apparaisse. Utilise maintenant mdfind pour obtenir rapidement les programmes. Merci @Lri

  • Il peut gérer les espaces dans les noms d'applications et les noms de programmes entre guillemets, mais c'est assez compliqué. Il faut que le guillemet soit le premier caractère : Alors que Scan" to "P est valable dans bash ce programme ne le détectera pas. La complétion ne fonctionne pas non plus après un espace échappé (ex. Scan\ to ), utilisez des guillemets dans ce cas ( "Scan to ). La prise en charge des espaces échappés est seulement bonne pour compléter DVD à DVD\ Player .

0 votes

N'est-ce pas ? mdfind 'kMDItemKind==Application' être plus rapide ? Si completion-ignore-case est activé, grep devrait probablement ignorer la casse également.

0 votes

@Lri Vous avez raison. Je n'ai pas pu trouver un cas où ces résultats auraient fait une différence.

3voto

nohillside Points 82672

L'autocomplétion programmable à la rescousse ! J'ai eu besoin de beaucoup de copies du Page d'accueil de l'achèvement de Bash qui vaut la peine d'être installé de toute façon pour une grande partie de la magie de l'autocomplétion. Si vous le faites, vous n'aurez besoin que de la dernière fonction ( _open ) et la commande d'initialisation du dessous.

Ajoutez ce qui suit à .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/
    # bash-completion-devel@lists.alioth.debian.org/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

0 votes

J'ai donc suivi les instructions d'installation et j'ai ajouté le code à .bashrc . Maintenant, comment faire pour qu'il s'autocomplète ? Qu'est-ce que je pousse à l'autocomplétion ? (Désolé, je ne peux pas lire le code)

1 votes

Ne traite pas les noms de programmes comportant des espaces (comme DVD Player.app ). Liste les répertoires dans /Applications également (comme iWork 09 en tant qu'entrées séparées iWork y 09 ), mais pas les programmes qui y sont contenus.

1voto

lamas Points 2252

Cela vient activé par défaut avec le shell Zsh pour autant que vous ayez activé l'achèvement lui-même, bien sûr. Zsh est inclus dans OS X.

Tout ce que vous avez à faire est de mettre autoload -Uz compinit; compinit dans votre ~/.zshrc, ou activez la complétion via le menu de configuration de la première exécution.

Zsh est en fait un sur-ensemble de Bash, donc vous ne devriez pas avoir à apprendre quelque chose de nouveau. Même vos scripts fonctionneront probablement !

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X