명령 이름을 인수로 사용하고 해당 구문을 인쇄하는 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
사용 하는 것입니다 .-x
synopsis
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"
이미 삭제/백스페이스/"뒤로 문자 제거"를 사용할 수도 있습니다 .)