Vervollständigung für das erste Argument von cd OLD NEW

22

In zshhat der cdBefehl eine aus zwei Argumenten bestehende Form: cd OLD NEWändert sich zu ${PWD/OLD/NEW}. Mit dem neuen Vervollständigungssystem kann zsh vervollständigen NEW: Das zweite Argument wird auf der Grundlage dessen vervollständigt, was ersetzt werden OLDkann, um ein vorhandenes Verzeichnis zu erhalten. Das erste Argument wird jedoch nur für vorhandene Verzeichnisse ausgeführt.

Wie kann ich zsh dazu bringen OLD, zusätzlich zum Vervollständigen vorhandener Verzeichnisse Vervollständigungen anzubieten, für die Werte möglich sind ?

Zum Beispiel, wenn das aktuelle Verzeichnis /path/to/foound es gibt auch Verzeichnisse /also/to/foound /path/to/foo/primedann cd pTabvervollständigt pzu prime. Wenn ich ausführen cd path alsomöchte, möchte ich, dass zsh auch pathals Abschluss angeboten wird. Wie?

Die Verwendung von bereits eingegebenen Werten des zweiten Arguments zur Einschränkung der Möglichkeiten für das erste Argument wäre ein Plus, aber auch das unabhängige Vervollständigen des ersten Arguments wäre in Ordnung.

Gilles 'SO - hör auf böse zu sein'
quelle
Wäre Ihr Beispiel für die Vervollständigung mit zwei Argumenten:, cd p also <Tab>oder cd p also <left arrow x 5> <Tab>?
Jeff Schaller
@JeffSchaller Das Beispiel mit dem zweiten Argument wäre cd p also<Left*5><Tab>: Wenn ich drücke, <Tab>während sich der Cursor in der Liste befindet also, erwarte ich, dass der Vorgang alsoabgeschlossen ist, nicht p.
Gilles 'SO - hör auf böse zu sein',
Wenn Sie eingeben, cd t<tab>sollte es anbieten th/to/foo/primeund to/foo/prime? Oder sollte es sich nur auf Verzeichnisgrenzen beschränken?
Barmar
@Barmar Ich denke, die Beschränkung auf Verzeichnisgrenzen wäre am bequemsten.
Gilles 'SO- hör auf böse zu sein'
Interessante Frage ...
Wogsland

Antworten:

1

Ich schätze, Sie könnten die Komponenten von $PWDzur cdVervollständigungsliste hinzufügen , obwohl dies ein Umgreifen erfordert _cd. Das heißt, eine angepasste Version von _cdmuss zuerst in angezeigt werden $fpath.

% cd && mkdir zcomp
% cp $fpath[-1]/_cd zcomp
% fpath=(~/zcomp $fapth)

Dann oben oben ~/zcomp/_cdeine Funktion hinzufügen

_our_pwd() {
  _values ourpwd ${(ps:/:)PWD}
}

und dann _alternativefügen Sie kurz vor der Zeile hinzu, was zur Liste der Alternativen zurückkehrt

  ...
  alt=("$service-options:$service option:_cd_options" "$alt[@]")
fi

alt=(ourpwd:pwd:_our_pwd "$alt[@]")

_alternative "$alt[@]" && ret=0

return ret
...

Dadurch werden die pwdKomponenten jedoch immer zu den cdVervollständigungen hinzugefügt :

% cd
Users    jdoe    Applications/  Desktop/  Documents/  Downloads/  Library/
...

Mit zusätzlicher Logik können Sie die $PWDKomponenten nur dann hinzufügen, wenn statt immer bereits ein zweites Argument vorhanden ist.

Jedoch! Dies bringt die cdFertigstellung immer durcheinander und erfordert, dass wir die Upstream- _cdFertigstellung patchen . Eine andere Möglichkeit wäre, einen neuen Namen für die Funktion zu erstellen, die von dem Zwei-Argument bereitgestellt wird cd, das möglicherweise aufgerufen wird cdsub, und dafür nur die Vervollständigung von PWDKomponenten anzuzeigen. Fügen Sie dies zu~/.zshrc

function cdsub { builtin cd "$@" }

Und dann eine entkernt _cd Vervollständigung_cdsub , um irgendwo platziert zu werden in $fpath:

#compdef cdsub
#
# Modified version of _cd from ZSH 5.3.1 with specific support for the
# `cd old new` form whereby PWD elements are provided for completion.

_cd_options() {
  _arguments -s \
  '-q[quiet, no output or use of hooks]' \
  '-s[refuse to use paths with symlinks]' \
  '(-P)-L[retain symbolic links ignoring CHASE_LINKS]' \
  '(-L)-P[resolve symbolic links as CHASE_LINKS]'
}

setopt localoptions nonomatch

local expl ret=1 curarg
integer argstart=2 noopts

if (( CURRENT > 1 )); then
  # if not in command position, may have options.
  # Careful: -<-> is not an option.
  while [[ $words[$argstart] = -* && argstart -lt CURRENT ]]; do
    curarg=$words[$argstart]
    [[ $curarg = -<-> ]] && break
    (( argstart++ ))
    [[ $curarg = -- ]] && noopts=1 && break
  done
fi

if [[ CURRENT -eq $((argstart+1)) ]]; then
  # cd old new: look for old in $PWD and see what can replace it
  local rep
  # Get possible completions using word in position 2
  rep=(${~PWD/$words[$argstart]/*}~$PWD(-/))
  # Now remove all the common parts of $PWD and the completions from this
  rep=(${${rep#${PWD%%$words[$argstart]*}}%${PWD#*$words[$argstart]}})
  (( $#rep )) && _wanted -C replacement strings expl replacement compadd -a rep
else
  _values ourpwd ${(ps:/:)PWD} && ret=0
  return ret
fi
Thrig
quelle