cdの最初の引数の完成OLD NEW


22

ではzshcdコマンドには2つの引数の形式cd OLD NEWがあり${PWD/OLD/NEW}ます。新しいスタイルの補完システムでは、zshは補完できますNEW。2番目の引数はOLD、既存のディレクトリを取得するために置き換えることができるものに基づいて補完されます。ただし、最初の引数は既存のディレクトリに対してのみ完了します。

OLD既存のディレクトリを補完するだけでなく、に可能な値である補完をzshに提供するにはどうすればよいですか?

たとえば、現在のディレクトリが/path/to/fooであり、ディレクトリ/also/to/fooおよびがある/path/to/foo/prime場合、にcd pTab完了pprimeます。実行する場合cd path alsoは、zshにpath補完としても提供したいと思います。どうやって?

2番目の引数の型指定済みの値を使用して最初の引数の可能性を制限することはプラスになりますが、最初の引数を個別に完了することも問題ありません。


2引数補完の例は次のようになりますcd p also <Tab>cd p also <left arrow x 5> <Tab>
ジェフシャラー

@JeffSchaller 2番目の引数の影響を受けやすい例はcd p also<Left*5><Tab>次のように<Tab>なります。カーソルが入っているalsoときにを押すalsoと、ではなく、完了することが期待されますp
ジル 'SO-悪であるのをやめる'

入力する場合cd t<tab>、提供する必要がth/to/foo/primeありto/foo/primeますか?それとも、ディレクトリ境界だけに制限する必要がありますか?
バーマー

@Barmarディレクトリの境界に制限するのが最も便利だと思います。
ジル「SO-悪であるのをやめる」

興味深い質問
...-wogsland

回答:


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では、常にではなく2番目の引数が既に存在する場合にのみコンポーネントを追加できます。

しかしながら!これは常にcd完了を台無しにし、上流の_cd完了にモンキーパッチを適用する必要があります。別のオプションはcd、おそらく呼び出されるtwo-argによって提供される関数の新しい名前を作成し、そのためcdsubPWDコンポーネントの補完のみを表示することです。これを追加~/.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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.