에서 zsh
의 cd
명령은 두 인수의 형식은 다음과 같습니다 cd OLD NEW
로 변경됩니다 ${PWD/OLD/NEW}
. 새로운 스타일의 완성 시스템을 통해 zsh는 완성 할 수 있습니다 NEW
. 두 번째 인수는 OLD
기존 디렉토리를 얻기 위해 대체 할 수있는 항목을 기반으로 완료 됩니다. 그러나 첫 번째 인수는 기존 디렉토리에만 완료됩니다.
zsh가 OLD
기존 디렉토리를 완성하는 것 외에도 가능한 값을 제공하도록하려면 어떻게 해야합니까?
예를 들어, 현재 디렉토리가 /path/to/foo
있고 디렉토리도 /also/to/foo
있고 /path/to/foo/prime
이면로 cd p
Tab완료 p
됩니다 prime
. 내가 달리기 cd path also
를 원한다면 zsh가 path
완료로 제공하고 싶습니다 . 방법?
첫 번째 인수의 가능성을 제한하기 위해 두 번째 인수의 이미 유형이 지정된 값을 사용하는 것이 더하기는하지만 첫 번째 인수를 독립적으로 완료하는 것도 좋습니다.
답변
난 당신의 구성 요소를 추가 할 수 있습니다 생각 $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
아마도 two 라고 불리는 two-arg가 제공하는 함수의 새로운 이름을 만들고 컴포넌트 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