기록을 기반으로 바인드 -x에 대한 명령 매개변수를 지정하는 방법은 무엇입니까?

기록을 기반으로 바인드 -x에 대한 명령 매개변수를 지정하는 방법은 무엇입니까?

명령 이름을 인수로 사용하고 해당 구문을 인쇄하는 synopsis라는 명령이 있다고 가정합니다. 이제 요약을 키 시퀀스에 바인딩하고 싶습니다. 현재 명령줄에서 개요로 명령 이름을 어떻게 전달할 수 있나요? 다음은 원하는 동작의 예입니다.

1$ bind -x '"\C-h": synopsis !#:0'
2$ ls -F^H 
<ls syntax print out from synopsis> 
3$ ls -F

2에서 시놉시스가 호출되지만, 역사적 확장은 없다. "ls" 대신 "!#:0" 문자열이 표시됩니다. 아무것도 작동하지 않는 것 같습니다 :-/

답변1

키 입력에 바인딩된 함수에서는 변수를 통해 명령줄의 현재 내용에 액세스하고 수정할 수 있습니다.READLINE_LINE그리고READLINE_POINT. 개념 증명(테스트되지 않은 코드):

synopsis () (
  set -f
  IFS=$'\t\n\r ;&|'
  words=($READLINE_LINE)
  while [[ "${words[1]}" == @([<>]*|[A-Za-z0-9_]##=) ]]; do
    shift words
  done
  command=${words[1]}
  "$command" --help
)
bind -x '"\C-h": synopsis'

시도한 기록 확장 방법이 작동하지 않습니다. 명령줄을 실행할 때 기록 확장이 수행됩니다. 바인딩이 호출될 때 확장 가능한 기록이 없습니다.

하지만 당신의 근본적인 질문은당신의 껍질은 충분히 멋지지 않습니다. 이 기능은 이미 zsh에 존재하며 이름은 다음과 같습니다.run-help.

bash$ echo '실행 중인 도움말 자동 로드' >~/.zshrc
bash$ zsh
암흑별 %ls -FAlt+h

답변2

한 가지 가능성은 줄 시작 부분에 삽입하여 없이 bind사용 하는 것입니다 .-xsynopsis

bind "'\C-h": "\C-asynopsis \C-j"

논쟁을 벌이세요. 더 복잡한 버전은 다음과 같습니다.

bind '"\C-h": "\C-e !#:0\e^\e\C-] \C-usynopsis\C-j"'

그것을 파괴:

'\C-e '    end-of-line
' !#:0'    insert space and 1st argument of current line
'\e^'      history-expand-line
'\e\C-] '  character-search-backward (to last space)
'\C-u'     unix-line-discard (delete to beginning of line)
'synopsis' insert 'synopsis' in front of the first argument
'\C-j'     accept-line

이는 synopsis첫 번째 인수로만 실행되는 여러 인수가 있는 행을 처리합니다. ( "\C-xh"또는 "\eh"대신에 "\C-h"이미 삭제/백스페이스/"뒤로 문자 제거"를 사용할 수도 있습니다 .)

관련 정보