cd OLD NEW 첫 번째 매개변수 완성

cd OLD NEW 첫 번째 매개변수 완성

에서 zsh명령 에는 다음 cd형식의 두 가지 인수가 있습니다 . 새로운 완성 시스템을 사용하여 zsh는 완료할 수 있습니다 . 두 번째 인수는 기존 디렉토리를 얻기 위해 대체할 수 있는 항목을 기반으로 완료됩니다. 그러나 첫 번째 매개변수는 기존 디렉터리에 대해서만 수행됩니다.cd OLD NEW${PWD/OLD/NEW}NEWOLD

OLD기존 디렉토리를 완성하는 것 외에도 zsh가 가능한 값의 완성을 제공하도록 하려면 어떻게 해야 합니까?

예를 들어, 현재 디렉터리가 /path/to/foo이고 디렉터리와 가 있는 /also/to/foo경우 /path/to/foo/prime완성 cd pTabp입니다 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

관련 정보