Indirekt dank JakeGould stolperte ich über eine Lösung: zsh-capture-completion
. Tatsächlich gibt es zwei weitere fast identische Fragen zu den Unix-Stack-Exchange-Sites, beide mit der Antwort, die ich hier gegeben habe.
Skript-Quellcode für zsh-capture-completion
finden Sie hier:
#!/bin/zsh zmodload zsh/zpty || { echo 'error: missing module zsh/zpty' >&2; exit 1 } # spawn shell zpty z zsh -f -i # line buffer for pty output local line setopt rcquotes () { zpty -w z source $1 repeat 4; do zpty -r z line [[ $line == ok* ]] && return done echo 'error initializing.' >&2 exit 2 } =( <<< ' # no prompt! PROMPT= # load completion system autoload compinit compinit -d ~/.zcompdump_capture # never run a command bindkey ''^M'' undefined bindkey ''^J'' undefined bindkey ''^I'' complete-word # send a line with null-byte at the end before and after completions are output null-line () { echo -E - $''\0'' } compprefuncs=( null-line ) comppostfuncs=( null-line exit ) # never group stuff! zstyle '':completion:*'' list-grouped false # don''t insert tab when attempting completion on empty line zstyle '':completion:*'' insert-tab false # no list separator, this saves some stripping later on zstyle '':completion:*'' list-separator '''' # we use zparseopts zmodload zsh/zutil # override compadd (this our hook) compadd () { # check if any of -O, -A or -D are given if [[ ${@[1,(i)(-|--)]} == *-(O|A|D)\ * ]]; then # if that is the case, just delegate and leave builtin compadd "$@" return $? fi # ok, this concerns us! # echo -E - got this: "$@" # be careful with namespacing here, we don''t want to mess with stuff that # should be passed to compadd! typeset -a __hits __dscr __tmp # do we have a description parameter? # note we don''t use zparseopts here because of combined option parameters # with arguments like -default- confuse it. if (( $@[(I)-d] )); then # kind of a hack, $+@[(r)-d] doesn''t work because of line noise overload # next param after -d __tmp=${@[$[${@[(i)-d]}+1]]} # description can be given as an array parameter name, or inline () array if [[ $__tmp == \(* ]]; then eval "__dscr=$__tmp" else __dscr=( "${(@P)__tmp}" ) fi fi # capture completions by injecting -A parameter into the compadd call. # this takes care of matching for us. builtin compadd -A __hits -D __dscr "$@" setopt localoptions norcexpandparam extendedglob # extract prefixes and suffixes from compadd call. we can''t do zsh''s cool # -r remove-func magic, but it''s better than nothing. typeset -A apre hpre hsuf asuf zparseopts -E P:=apre p:=hpre S:=asuf s:=hsuf # append / to directories? we are only emulating -f in a half-assed way # here, but it''s better than nothing. integer dirsuf=0 # don''t be fooled by -default- >.> if [[ -z $hsuf && "${${@//-default-/}% -# *}" == *-[[:alnum:]]#f* ]]; then dirsuf=1 fi # just drop [[ -n $__hits ]] || return # this is the point where we have all matches in $__hits and all # descriptions in $__dscr! # display all matches local dsuf dscr for i in ; do # add a dir suffix? (( dirsuf )) && [[ -d $__hits[$i] ]] && dsuf=/ || dsuf= # description to be displayed afterwards (( $#__dscr >= $i )) && dscr=" -- ${$##$__hits[$i] #}" || dscr= echo -E - $IPREFIX$apre$hpre$__hits[$i]$dsuf$hsuf$asuf$dscr done } # signal success! echo ok') zpty -w z "$*"$'\t' integer tog=0 # read from the pty, and parse linewise while zpty -r z; do :; done | while IFS= read -r line; do if [[ $line == *$'\0\r' ]]; then (( tog++ )) && return 0 || continue fi # display between toggles (( tog )) && echo -E - $line done return 2
Hier ist ein Beispiel für die Verwendung von Skripts:
══► % cd ~/.zsh_plugins ══► % zsh ./zsh-capture-completion/capture.zsh 'cd ' zaw/ zsh-capture-completion/ zsh-syntax-highlighting/ zsh-vimode-visual/
Beachten Sie das Leerzeichen im obigen Befehl. Mit dem Space stellt das Skript die Liste der Ordner bereit, in die Sie cd
aus dem aktuellen Verzeichnis gelangen können. Andernfalls würde das Skript alle Vervollständigungen für Befehle bereitstellen, die mit beginnen cd
.
Ich sollte auch beachten, dass selbst der Autor des bereitgestellten Skripts / Plugins seine Lösung als "hacky" betrachtet. Wenn jemand eine kürzere oder einfachere Lösung kennt, würde ich mich freuen, diese als Antwort zu akzeptieren.