에서 zsh
명령 에는 다음 cd
형식의 두 가지 인수가 있습니다 . 새로운 완성 시스템을 사용하여 zsh는 완료할 수 있습니다 . 두 번째 인수는 기존 디렉토리를 얻기 위해 대체할 수 있는 항목을 기반으로 완료됩니다. 그러나 첫 번째 매개변수는 기존 디렉터리에 대해서만 수행됩니다.cd OLD NEW
${PWD/OLD/NEW}
NEW
OLD
OLD
기존 디렉토리를 완성하는 것 외에도 zsh가 가능한 값의 완성을 제공하도록 하려면 어떻게 해야 합니까?
예를 들어, 현재 디렉터리가 /path/to/foo
이고 디렉터리와 가 있는 /also/to/foo
경우 /path/to/foo/prime
완성 cd p
Tab은 p
입니다 prime
. 를 실행하려면 zsh 도 완성본으로 cd path also
사용할 수 있기를 바랍니다 . path
어떻게?
두 번째 매개변수에 입력된 값을 사용하여 첫 번째 매개변수의 가능성을 제한하는 것이 유리할 수 있지만 첫 번째 매개변수를 독립적으로 수행하는 것도 가능합니다.
답변1
의 구성요소를 완성 목록 $PWD
에 추가할 수 있다고 가정합니다 . 하지만 그러려면 약간 의 조작 이 필요한 것 같습니다. 즉, .cd
_cd
_cd
$fpath
% cd && mkdir zcomp
% cp $fpath[-1]/_cd zcomp
% fpath=(~/zcomp $fapth)
그런 다음 상단에 ~/zcomp/_cd
기능을 추가하십시오 .
_our_pwd() {
_values ourpwd ${(ps:/:)PWD}
}
그런 다음 해당 줄 앞에 _alternative
대체 목록에 무언가를 다시 추가하세요.
...
alt=("$service-options:$service option:_cd_options" "$alt[@]")
fi
alt=(ourpwd:pwd:_our_pwd "$alt[@]")
_alternative "$alt[@]" && ret=0
return ret
...
이렇게 하면 항상 pwd
구성요소가 cd
완료됩니다.
% cd
Users jdoe Applications/ Desktop/ Documents/ Downloads/ Library/
...
추가 로직을 사용하면 $PWD
구성요소를 항상 추가하는 대신 두 번째 매개변수가 이미 있는 경우에만 구성요소를 추가할 수 있습니다.
하지만! 이로 인해 항상 cd
완료가 엉망이 되고 _cd
업스트림 완료를 원숭이 패치해야 합니다. 또 다른 옵션은 두 개의 매개변수 cd
(아마도 ) 가 제공되는 함수에 대한 새 이름을 만들고 cdsub
구성 요소의 완성을 표시하는 것입니다. PWD
에 추가하세요~/.zshrc
function cdsub { builtin cd "$@" }
그럼 속이 빈 하나_cd
다음과 같이 완료됨_cdsub
어딘가에 배치하십시오 $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