cd OLD NEW 第一个参数的完成

cd OLD NEW 第一个参数的完成

在 中zsh,该cd命令有两个参数形式:cd OLD NEW更改为${PWD/OLD/NEW}。使用新型补全系统,zsh 能够补全NEW:第二个参数是根据OLD可以替换的内容来补全的,以获得现有目录。但第一个参数仅对现有目录完成。

OLD除了完成现有目录之外,如何让 zsh 提供可能值的完成?

例如,如果当前目录是/path/to/foo且还有目录/also/to/foo/path/to/foo/prime,则cd pTab补全pprime。如果我打算运行cd path also,那么我希望 zsh 也提供path作为完成。如何?

使用第二个参数的已输入值来限制第一个参数的可能性将是一个优点,但独立完成第一个参数也可以。

答案1

我想您可以将 的组件添加$PWDcd完成列表中,尽管这似乎需要摆弄_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

相关内容