zsh 완료에 이전 명령의 매개변수 추가

zsh 완료에 이전 명령의 매개변수 추가

zsh(및 bash)에서는 일부 기록 단어 확장을 사용하여 이전 명령에 대한 인수를 나타낼 수 있습니다.

이 예에서는 확장을 통해 기록의 이전 명령에서 두 번째 인수를 가져오는 방법을 보여줍니다 !:#.

% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar

나는 종종 특정 매개변수가 # 매개변수인지 정확히 잊어버리고, !:#그것이 어떤 매개변수인지 기억할 때 입력이 항상 빠르지는 않습니다. 마지막 매개변수를 바꾸는 방법을 알고 있지만 meta-.때로는 내가 원하는 마지막 매개변수가 아닐 때도 있습니다.

zsh에 입력하는 모든 명령을 완료하기 위한 제안으로 이전 명령의 매개변수를 추가하고 싶습니다.

마지막 명령에서 인수 배열(0..N)을 생성하고 이를 특정 명령에 바인딩하는 셸 함수를 생성하는 방법을 알아낼 수 있었습니다.

_last_command_args() {
    last_command=$history[$[HISTCMD-1]]
    last_command_array=("${(s/ /)last_command}") 
    _sep_parts last_command_array
}

# trying to get last_command_args to be suggested for any command, this just works for foo
compdef _last_command_args foo

Tab 키를 사용한 후 foo의 모습은 다음과 같습니다 <TAB>.

% echo bar baz qux
bar baz qux
% foo <TAB>
bar   baz   echo  qux 

이는 "foo" 명령을 완료하는 데 유용하지만, 제가 만드는 모든 zsh 확장에 대한 옵션으로 사용하고 싶습니다. 나는 그것이 zstyle Completer와 관련이 있다고 생각했지만 몇 시간의 해킹 후에 나는 내 능력을 넘어서는 것을 깨달았습니다.

zsh의 모든 명령에 대해 제안된 완성으로 이전 명령에서 매개변수를 가져오는 방법은 무엇입니까?

나는 전체 해요zshrc는 설치 파일을 컴파일합니다.도움이 되셨다면 bitbucket에 공유해주세요. 대부분은 다양한 출처에서 표절되었으며, 그 중 일부는 제가 직접 작성한 것입니다.

고쳐 쓰다:

@Julien Nicoulaud의 답변은 저를 가까워지게 만들었고 제가 있어야 할 곳으로 이동하게 해주기 때문에 승인된 것으로 표시했습니다.

내 특정 구성에 따라 권장 사항을 사용합니다.

zstyle ':completion:*' completer _last_command_args _complete

탭 완성이 마지막 명령의 인수 목록만 표시하기 때문에 나에게는 잘 작동하지 않습니다(비록 실제로는 파일 이름도 완성하지만 표시하지는 않습니다). 순서를 변경하면 _complete _last_command_args반대 효과가 나타납니다. 일반 파일 이름은 표시되지만 last_command_args는 표시되지 않습니다.

나는 이것이 완성자가 작동하는 방식과 관련이 있다고 생각합니다. 성공적으로 반환된 첫 번째 방법의 출력만 표시한다고 생각했지만 무슨 일이 일어나고 있는지 완전히 이해하기 위해 zsh 소스를 구문 분석하는 데 문제가 있습니다. 호출을 포함하여 _complete명령에 대한 마지막 인수와 일반 자동 완성 항목을 표시하도록 메서드를 조정할 수 있었습니다 . 너무 분리되지는 않지만 나에게는 충분합니다.

내가 가지고 있는 다른 zstyle 항목과 함께 사용하는 전체 기능은 다음과 같습니다.

# adds the arguments from the last commadn to the autocomplete list
# I wasn't able to get this to work standalone and still print out both regular
# completion plus the last args, but this works well enough.
_complete_plus_last_command_args() {
    last_command=$history[$[HISTCMD-1]]
    last_command_array=("${(s/ /)last_command}") 
    _sep_parts last_command_array
    _complete 
}


_force_rehash() {
  (( CURRENT == 1 )) && rehash
  return 1  # Because we didn't really complete anything
}

zstyle ':completion:::::' completer _force_rehash _complete_plus_last_command_args _approximate 

이 기능에는 필요하지 않지만 이것이 나에게 적합한 이유에 영향을 미칠 수 있는 추가 zstyle 행이 있습니다.

zstyle -e ':completion:*:approximate:*' max-errors 'reply=( $(( ($#PREFIX + $#SUFFIX) / 3 )) )'
zstyle ':completion:*:descriptions' format "- %d -"
zstyle ':completion:*:corrections' format "- %d - (errors %e})"
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
zstyle ':completion:*' group-name ''
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*' menu select
zstyle ':completion:*' verbose yes

file1.txt이제 and 가 포함된 디렉토리에 있고 file2.txt마지막 명령이 이면 echo foo bar baz정확히 내가 원하는 대로 자동 완성이 표시됩니다.

% ls
bar   baz   echo  foo 
- files -
file1.txt   file2.txt 

답변1

기본적으로 사용되는 완성자 목록에 완성자를 추가할 수 있습니다.

zstyle ':completion:*' completer _last_command_args _complete

관련 정보