Penyelesaian untuk argumen pertama dari cd OLD NEW

22

Di zsh, cdperintah memiliki bentuk dua argumen: cd OLD NEWperubahan ke ${PWD/OLD/NEW}. Dengan sistem penyelesaian gaya baru, zsh mampu menyelesaikan NEW: argumen kedua diselesaikan berdasarkan apa yang OLDbisa diganti dengan untuk mendapatkan direktori yang ada. Tetapi argumen pertama hanya selesai untuk direktori yang ada.

Bagaimana saya bisa meminta zsh untuk menawarkan penyelesaian yang merupakan nilai yang mungkin untuk OLD, selain menyelesaikan direktori yang ada?

Sebagai contoh, jika direktori saat ini /path/to/foodan ada juga direktori /also/to/foodan /path/to/foo/prime, kemudian cd pTabmelengkapi puntuk prime. Jika saya bermaksud untuk menjalankan cd path alsomaka saya ingin zsh juga menawarkan pathsebagai penyelesaian. Bagaimana?

Menggunakan nilai-nilai yang sudah diketik dari argumen kedua untuk membatasi kemungkinan untuk argumen pertama akan menjadi nilai tambah, tetapi melengkapi argumen pertama secara mandiri juga akan baik-baik saja.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Apakah contoh penyelesaian 2-argumen Anda menjadi:, cd p also <Tab>atau cd p also <left arrow x 5> <Tab>?
Jeff Schaller
@JeffSchaller Contoh argumen-sensitif kedua adalah cd p also<Left*5><Tab>: jika saya menekan <Tab>saat kursor masuk also, saya berharap alsoakan selesai, tidak p.
Gilles 'SO- stop being evil'
Jika Anda mengetik, cd t<tab>apakah itu harus menawarkan th/to/foo/primedan to/foo/prime? Atau haruskah itu hanya membatasi diri ke batas direktori?
Barmar
@Barmar Saya pikir membatasi batas direktori akan menjadi yang paling nyaman.
Gilles 'SANGAT berhenti menjadi jahat'
Pertanyaan yang menarik ...
wogsland

Jawaban:

1

Saya kira Anda dapat menambahkan komponen $PWDke cddaftar penyelesaian, meskipun ini tampaknya membutuhkan mengutak-atik _cd; yaitu, versi khusus _cdharus muncul pertama kali di $fpath.

% cd && mkdir zcomp
% cp $fpath[-1]/_cd zcomp
% fpath=(~/zcomp $fapth)

Kemudian di bagian atas ~/zcomp/_cdtambahkan fungsi

_our_pwd() {
  _values ourpwd ${(ps:/:)PWD}
}

dan kemudian tepat sebelum _alternativebaris tambahkan apa yang kembali ke daftar alternatif

  ...
  alt=("$service-options:$service option:_cd_options" "$alt[@]")
fi

alt=(ourpwd:pwd:_our_pwd "$alt[@]")

_alternative "$alt[@]" && ret=0

return ret
...

meskipun ini akan selalu menambahkan pwdkomponen ke cdpenyelesaian:

% cd
Users    jdoe    Applications/  Desktop/  Documents/  Downloads/  Library/
...

dengan logika tambahan Anda hanya bisa menambahkan $PWDkomponen ketika sudah ada argumen kedua bukan selalu.

Namun! Ini selalu mengacaukan cdpenyelesaian dan mengharuskan kami menambal _cdpenyelesaian hulu . Pilihan lain adalah membuat nama baru untuk fungsi yang disediakan oleh dua-arg cd, mungkin disebut cdsub, dan hanya memiliki penyelesaian PWDkomponen yang muncul untuk itu. Tambahkan ini ke~/.zshrc

function cdsub { builtin cd "$@" }

Dan kemudian _cd penyelesaian_cdsub patah hati untuk ditempatkan di suatu tempat di $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
thrig
sumber