Hoàn thành đối số đầu tiên của cd OLD MỚI


22

Trong zsh, cdlệnh có dạng hai đối số: cd OLD NEWthay đổi thành ${PWD/OLD/NEW}. Với hệ thống hoàn thành kiểu mới, zsh có khả năng hoàn thành NEW: đối số thứ hai được hoàn thành dựa trên những gì OLDcó thể được thay thế bằng để có được một thư mục hiện có. Nhưng đối số đầu tiên chỉ được hoàn thành cho các thư mục hiện có.

Làm cách nào tôi có thể nhận zsh để cung cấp các hoàn thành có giá trị có thể OLD, ngoài việc hoàn thành các thư mục hiện có?

Ví dụ, nếu thư mục hiện hành là /path/to/foovà cũng có những thư mục /also/to/foo/path/to/foo/prime, sau đó cd pTabhoàn thành pđể prime. Nếu tôi có ý định chạy cd path alsothì tôi muốn zsh cũng sẽ pathhoàn thành. Làm sao?

Sử dụng các giá trị đã gõ của đối số thứ hai để hạn chế các khả năng cho đối số thứ nhất sẽ là một điểm cộng, nhưng hoàn thành độc lập đối số thứ nhất cũng sẽ ổn.


Ví dụ hoàn thành 2 đối số của bạn sẽ là : cd p also <Tab>, hoặc cd p also <left arrow x 5> <Tab>?
Jeff Schaller

@JeffSchaller Ví dụ nhạy cảm với đối số thứ hai sẽ là cd p also<Left*5><Tab>: nếu tôi nhấn <Tab>trong khi con trỏ ở trong also, tôi hy vọng alsosẽ được hoàn thành, không p.
Gilles 'SO- ngừng trở nên xấu xa'

Nếu bạn gõ cd t<tab>nó nên cung cấp th/to/foo/primeto/foo/prime? Hoặc nó chỉ nên giới hạn bản thân đến ranh giới thư mục?
Barmar

@Barmar Tôi nghĩ rằng giới hạn ranh giới thư mục sẽ là thuận tiện nhất.
Gilles 'SO- ngừng trở nên xấu xa'

Câu hỏi lặp đi lặp lại ...
wogsland 19/03/2017

Câu trả lời:


1

Tôi đoán bạn có thể thêm các thành phần của $PWDvào cddanh sách hoàn thành, mặc dù điều này dường như đòi hỏi không quan trọng với _cd; đó là, một phiên bản tùy chỉnh _cdphải xuất hiện đầu tiên trong $fpath.

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

Sau đó lên trên cùng của ~/zcomp/_cdmột chức năng

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

và sau đó ngay trước _alternativedòng thêm những gì trả về danh sách thay thế

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

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

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

return ret
...

mặc dù điều này sẽ luôn thêm các pwdthành phần để cdhoàn thành:

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

với logic bổ sung, bạn chỉ có thể thêm các $PWDthành phần khi đã có đối số thứ hai thay vì luôn luôn.

Tuy nhiên! Điều này luôn làm rối tung việc cdhoàn thành và yêu cầu chúng tôi phải vá lỗi _cdhoàn thành ngược dòng . Một tùy chọn khác là tạo một tên mới cho hàm được cung cấp bởi hai-arg cd, có lẽ được gọi cdsubvà chỉ có các thành PWDphần hoàn thành xuất hiện cho điều đó. Thêm cái này vào~/.zshrc

function cdsub { builtin cd "$@" }

Và sau đó, một sự _cd hoàn thành_cdsub ruột được đặt ở đâu đó trong $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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.