假设我有一个名为 synopsis 的命令,它将命令的名称作为参数并打印出其语法。现在我想将概要绑定到按键序列。如何将当前命令行中的命令名称传递给概要?这是所需行为的示例:
1$ bind -x '"\C-h": synopsis !#:0'
2$ ls -F^H
<ls syntax print out from synopsis>
3$ ls -F
2 中调用了概要,但没有历史扩展。我得到字符串“!#:0”而不是“ls”。似乎没有什么作用:-/
答案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
without -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"
or"\eh"
代替"\C-h"
,它可能已经是擦除/退格/“向后删除字符”。)