Gibt es eine Möglichkeit, den Befehl open im Terminal automatisch zu vervollständigen?


16

Ich verwende häufig den open -a Befehl im Terminal, um Anwendungen über ssh zu öffnen. Wie kann ich den Namen einer Anwendung automatisch vervollständigen lassen?


Welche Shell benutzt du?
Daniel Beck

2
Ich denke, ein geringfügig schnellerer Weg wäre, den vollständigen Pfad zu tippen (geh einfach eine Weile mit mir hier hin !!), zB open -a /Applications/Textedit.app foo.txt(ich nehme an, das ist, was du versuchst zu tun). Wenn Sie Tab nach dem Drücken /Avon /Applicationsund dann wieder Tab nach dem /Tevon /Textedit.appdann sollte , dass beide Teile für Sie automatisch vervollständigt , wie Sie gehen. Nicht ideal, gebe ich zu, aber vielleicht doch besser. Dies benutzte Bash.
Binarybob

Sie können auch versuchen, die Anweisungen am Ende dieses Beitrags zu befolgen
Lri

@ DanielBeck Bash.
Daviesgeek

Antworten:


9
_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

Dritte Version, bei der jetzt die Groß- und Kleinschreibung nicht mehr beachtet werden muss und innerhalb von Anführungszeichen gearbeitet werden muss.


Ich konnte nicht damit arbeiten DVD Player. Irgendwelche Ideen, was ist los? Sieht aus wie ein Tab anstelle eines Leerzeichens ...
Daniel Beck

@ DanielBeck Es fehlte IFS=$'\n'. Wie auch immer, ich habe die Antwort erneut bearbeitet.
Lri

Sieht gut aus. Ein spätes +1 für die mdfindIdee. Gute Arbeit an der Optimierung und Korrekturen. CoreServicessind wahrscheinlich persönliche Vorlieben. Was ist der Grund dafür nospace? Wenn es nur 1 Programm gibt, möchte ich sofort mit dem Öffnen der Datei fortfahren. Nur persönliche Vorlieben? Haben Sie eine Idee zu dem verbleibenden Zitatproblem? AFAICT, das ist das einzige, was für eine richtige Lösung übrig bleibt.
Daniel Beck

@DanielBeck Ich setze immer die -aFlagge am Ende, also denke ich, -o nospaceist es nur eine persönliche Präferenz. Vielleicht sollten wir Brett Terpstra anpingen oder etwas, um dieses Nerdfest zu beenden ...
Lri

Ich danke dir sehr!! @ DanielBeck dich auch. Ich habe mich wegen der Geschwindigkeit für die Version von Lri entschieden. Leider war deins etwas langsam. Vielen Dank euch beiden! Sie haben mir sehr geholfen und meine Terminalgeschwindigkeit erhöht.
Daviesgeek

7

Fügen Sie Ihrem .bash_profileoder Folgendes hinzu .bashrcund starten Sie eine neue Sitzung:

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

Es muss nichts installiert werden. Dies funktioniert bashsofort.


Programmnamen werden nur dann automatisch -avervollständigt, wenn die vorherige Option aktiviert ist und ansonsten das Standardverhalten anzeigt, z. B. eine Liste aller Dateien im aktuellen Verzeichnis zurückgeben oder das aktuelle Pfadpräfix vervollständigen.

Die Ergebnisse werden aus generiert. Dies system_profiler SPApplicationsDataTypeist der einfachste Weg, um alle Anwendungen zu erhalten, die so auf Ihrem System gestartet werden können. Die Liste wird verarbeitet, um nur die Programmnamen zurückzugeben, die Leerzeichen enthalten und sich von den Paketnamen unterscheiden können (auch wenn das .appSuffix ignoriert wird ).

Verwendung: Geben Sie ein open -a, gefolgt von einem Leerzeichen, gefolgt von Taboder Esc(zweimal auf meinem System, nicht sicher, ob es überall ist).

Beispiel mit allen Hilfsanwendungen für meinen 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

Nachteile und Probleme dieser Lösung:

  • Es gibt Unmengen von Programmen auf Ihrem System, die Sie möglicherweise nicht kennen, wie alles in /System/Library/CoreServices. Möglicherweise möchten Sie nicht alle auflisten. OTOH, es ist wirklich einfach zu sehen und zB CharacterPaletteoder KeyboardViewerso zu starten . * Konfigurieren Sie die mdfindAufrufe entsprechend dem -onlyinArgument.

  • Es ist ein bisschen langsam, wegen system_profiler SPApplicationsDataType. Möglicherweise müssen Sie ein oder zwei Sekunden warten, bis der Abschluss angezeigt wird. Jetzt nutzt man mdfindum schnell die Programme zu bekommen. Vielen Dank @Lri

  • Es kann mit Leerzeichen in Anwendungsnamen und in Anführungszeichen eingeschlossenen Programmnamen umgehen, ist aber ziemlich verrückt. Das Anführungszeichen muss das erste Zeichen sein: Solange Scan" to "Pes in gültig ist bash, wird es von diesem Programm nicht erkannt. Die Vervollständigung funktioniert auch nach einem Leerzeichen nicht (z. B. Scan\ to). Verwenden Sie in solchen Fällen Anführungszeichen ( "Scan to). Unterstützung für entkam Räumen ist nur gut abgeschlossen DVDzu DVD\ Player.


Wäre nicht mdfind 'kMDItemKind==Application'schneller? Wenn completion-ignore-caseaktiviert, sollte grep wahrscheinlich auch Groß- und Kleinschreibung ignorieren.
Lri

@Lri Du hast recht. Es konnte kein Fall gefunden werden, in dem diese Ergebnisse einen Unterschied gemacht hätten.
Daniel Beck

3

Programmierbare Autovervollständigung zur Rettung! Habe allerdings viel von der Bash Completion Homepage kopiert , was sich für eine Menge Autovervollständigungszauber auf jeden Fall lohnt. In diesem Fall benötigen Sie nur die letzte Funktion ( _open) und den Initialisierungsbefehl von unten.

Fügen Sie Folgendes hinzu zu .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

Also habe ich die Installationsanweisungen befolgt und den Code hinzugefügt .bashrc. Wie kann ich es nun zur automatischen Vervollständigung bringen? Was muss ich tun, um es automatisch zu vervollständigen? (Sorry, ich kann den Code nicht lesen)
Daviesgeek

1
Behandelt keine Programmnamen mit Leerzeichen (wie DVD Player.app). Listet auch Verzeichnisse auf /Applications(wie iWork 09, als separate Einträge iWorkund 09), jedoch nicht die darin enthaltenen Programme.
Daniel Beck

1

Dies ist in der Zsh-Shell standardmäßig aktiviert , sofern Sie die Vervollständigung selbst aktiviert haben. Zsh ist in OS X enthalten.

Alles, was Sie tun müssen, ist, autoload -Uz compinit; compinitIhre ~ / .zshrc einzugeben oder die Vervollständigung über das Konfigurationsmenü für die erste Ausführung zu aktivieren.

Zsh ist eigentlich größtenteils eine Obermenge von Bash, daher sollten Sie nichts Neues lernen müssen. Sogar Ihre Skripte werden wahrscheinlich funktionieren!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.