Zakończenie pierwszego argumentu cd OLD NEW

22

W zshThe cdpolecenie ma postać dwóch argumentów: cd OLD NEWzmienia się ${PWD/OLD/NEW}. Z systemem uzupełniania w nowym stylu, zsh jest w stanie NEWwykonać: drugi argument jest uzupełniany na podstawie tego, co OLDmożna zastąpić, aby uzyskać istniejący katalog. Ale pierwszy argument został uzupełniony tylko do istniejących katalogów.

Jak mogę zmusić Zsh do oferowania uzupełnień o możliwych wartościach OLD, oprócz uzupełniania istniejących katalogów?

Na przykład, jeśli bieżący katalog jest /path/to/fooi tam są również katalogi /also/to/fooi /path/to/foo/prime, następnie cd pTabuzupełnia psię prime. Jeśli mam zamiar uruchomić cd path also, chciałbym, aby zsh również zaoferował pathjako uzupełnienie. W jaki sposób?

Używanie już wpisanych wartości drugiego argumentu w celu ograniczenia możliwości pierwszego argumentu byłoby plusem, ale uzupełnienie pierwszego argumentu niezależnie również byłoby dobrze.

Gilles „SO- przestań być zły”
źródło
Czy twoim przykładem 2-argumentowego uzupełnienia byłoby: cd p also <Tab>lub cd p also <left arrow x 5> <Tab>?
Jeff Schaller
@JeffSchaller Przykładem wrażliwym na drugi argument jest cd p also<Left*5><Tab>: jeśli nacisnę, <Tab>gdy kursor jest w środku also, oczekuję, alsoże zostanie zakończony, a nie p.
Gilles „SO- przestań być zły”
Jeśli wpiszesz cd t<tab>powinny oferować th/to/foo/primei to/foo/prime? A może powinien ograniczyć się do granic katalogu?
Barmar
@Barmar Myślę, że najbardziej wygodne byłoby ograniczenie do granic katalogów.
Gilles „SO- przestań być zły”
Interesujące pytanie ...
wogsland,

Odpowiedzi:

1

Sądzę, że możesz dodać składniki $PWDdo cdlisty ukończenia, choć wydaje się, że wymaga to manipulacji _cd; to znaczy dostosowana wersja _cdmusi pojawić się najpierw w $fpath.

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

Następnie u góry ~/zcomp/_cddodaj funkcję

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

a następnie tuż przed _alternativewierszem dodaj to, co zwraca do listy alternatyw

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

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

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

return ret
...

chociaż to zawsze doda pwdelementy do cduzupełnień:

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

z dodatkową logiką można dodawać $PWDkomponenty tylko wtedy, gdy jest już obecny drugi argument zamiast zawsze.

Jednak! To zawsze przeszkadza w cdukończeniu i wymaga, abyśmy małpowali łatanie _cdukończenia. Inną opcją byłoby utworzenie nowej nazwy dla funkcji udostępnianej przez argument dwuargumentowy cd, być może wywoływany cdsub, i PWDwyświetlanie w tym celu tylko uzupełnienia składników. Dodaj to do~/.zshrc

function cdsub { builtin cd "$@" }

A potem wypatroszone _cd zakończenie, które_cdsub ma być umieszczone gdzieś w $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
gałązka
źródło