我知道预执行()zsh 的钩子以及在 bash 中实现此操作的方式。(关联)
但我可以获得电流输入还在打字吗?
这个问题背后的想法如下:
为了更快地学习命令、参数和快捷方式,我想在提供“帮助/有用/快捷方式”提示的“数据库”中搜索正在输入的命令,并在另一个会话中输入时使用 screen/tmux 显示这些提示。
是否可以检查当前正在输入的命令?如果它不能在每次击键时都起作用,则计时器循环也可能起作用。
答案1
我只能回答zsh
,在哪里可以做到这一点,是的。
首先,已经有一些小工具增量完成。第一个显然是 Y. Fujii 写的。尽管其网站是日语,您无需讲日语就可以轻松了解其工作原理和使用方法。 自动对焦是原有脚本的扩展。
到目前为止的参考文献。zsh
在zsh 行编辑器( zle
) 负责命令行的交互使用。除了提供给小部件的许多其他变量(请参阅man zshzle
),这些变量对您来说也很有趣,因为您想捕获当前命令行:
$缓冲区:编辑缓冲区的全部内容。
$LBUFFER:缓冲区中位于光标位置左侧的部分。
$RBUFFER:缓冲区中位于光标位置右侧的部分。
这些变量是可写的,将会改变当前的命令行!
self-insert
要捕获每个击键,您可以修改默认情况下对除LF
或之外的每个击键执行的小部件CR
。这里有一个例子,它没有什么用处,但为每个击键附加一个点$RBUFFER
——只是为了说明它是如何工作的:
function self-insert() {
RBUFFER+="."
# execute some other command, but ensure they don't produce any output.
zle .self-insert
}
zle -N self-insert
.self-insert
是内置小部件,因此我们不会陷入无限循环。
因此,您既可以从头开始,也可以从 Fujii 的脚本开始并进行修改。后者的一个好处是,它还可以处理一些删除击键的操作,而我在这里忽略了这一点。
答案2
对于 Bash,您可以创建以下test.sh
脚本:
#!/usr/bin/env bash
ARRAY=('1' '2' '3' '4' '5' '6' '7' '8' '9' '0' '-' '=' 'BACKSPACE' ''
'q' 'w' 'e' 'r' 't' 'y' 'u' 'i' 'o' 'p' '[' ']' 'NEWLINE' ''
'a' 's' 'd' 'f' 'g' 'h' 'j' 'k' 'l' ';' "'" '' '' '' 'z' 'x' 'c'
'v' 'b' 'n' 'm' '0' ',' '.' '/' '' '' 'SPACE')
while read row
do
if [[ "$row" == *press* ]]
then
index=$((${row/key press /}-10))
if [[ "${ARRAY[$index]}" == 'NEWLINE' ]]
then
printf "\n"
elif [[ "${ARRAY[$index]}" == 'BACKSPACE' ]]
then
echo -ne "\b \b"
elif [[ "${ARRAY[$index]}" == 'SPACE' ]]
then
printf " "
else
printf "%s" "${ARRAY[$index]}"
fi
fi
done
这是一个简单的脚本,用于接收一些键盘代码并将其打印在屏幕上。现在将键盘代码传递给它:
$ stdbuf -o0 xinput test 'AT Translated Set 2 keyboard' | bash test.sh
现在,如果您在另一个终端中输入,它应该会收到键值。我不知道是否有任何巧妙的方法可以将键代码映射到它们的 ASCII 值,所以我只是做了一个简单的映射。您可以改进此代码以对其他键做出反应。但请注意,该脚本将接收所有键盘输入,而不仅仅是传递给一个给定的终端。
至于任务本身(检查当前正在输入的命令),您可以compgen -c
根据传递的参数生成可能的完成列表:
$ compgen -c 'ls' | head -1
ls
$ compgen -c 'lsp' | head -1
lspci