在 中zsh
,组合键Alt+.绑定到insert-last-word
,它将在当前命令行上插入上一个命令的最后一个参数。
我正在寻找一个类似于Alt+ 的键绑定/快捷方式.,不同之处在于它会将上一个命令中的所有参数粘贴到命令行上。
我知道我可以输入!*
,zsh 会将其解释为“重用上一个命令中的所有参数”。但这并不完全是我想要的。另外,它实际上并没有粘贴参数以便我可以看到它们,zsh 仅!*
如此解释。我可以点击Tab将其展开,但这是另一个必要的命令。
我更愿意将其作为组合键,例如Alt+ something,而不是必须键入 '!*' 并按 Tab 键
我怎样才能做到这一点 ?
更新
广泛使用该小部件几年后,我发现了一些让我困扰的事情:(我将小部件绑定到Alt+ /)
- 它一次可以正常工作,但是当我再次重复时,它会从文件开头循环浏览我的 zsh 历史记录
.zsh_history
。
相反,我希望小部件能够向后移动,从最近的历史记录回到开头。
- 再次,当它从我的 zsh 历史记录的开头循环时,命令和要完成的参数之间的空格被删除。
IE:
输入一些带参数的命令:
echo 111 222 333
使用小部件来完成上一个命令的参数:
printf <WIDGET>
printf 111 222 333
以上按预期工作。但是当我再次按下 WIDGET 时,它突然表现如下:
printf <WIDGET>
printf111 222 333
即命令和参数之间的空格被删除
- 最后,我想绑定另一个键,例如Alt+\来执行相反的操作,这样当我按Alt+/太多次时,我可以后退一步。
答案1
插入除第一个以外的所有内容单词对于之前的历史条目,您可以定义一个自定义小部件,例如:
insert-last-words() {
emulate -L zsh
set -o extendedglob # for the # wildcard operator
local direction
case $WIDGET in
(*-reverse) direction=-1;;
(*) direction=1;;
esac
if [[ ${WIDGET%-reverse} = ${LASTWIDGET%-reverse} ]]; then
# subsequent invocations go further back in history like
# insert-last-word
(($+INSERT_LAST_WORDS_SKIP_UNDO)) ||
NUMERIC=1 zle undo # previous invocation
# we honour $NUMERIC for Alt+4 Alt+/ to go back 4 in history
((INSERT_LAST_WORDS_INDEX += ${NUMERIC-1} * direction))
else
# head of history upon first invocation
INSERT_LAST_WORDS_INDEX=0
fi
unset INSERT_LAST_WORDS_SKIP_UNDO
local lastwords
local cmd=${history:$INSERT_LAST_WORDS_INDEX:1}
# cmdline split according to zsh tokenisation rules
lastwords=(${(z)cmd})
if (($#lastwords <= 1)); then
# return failure (causing beep or visual indication) when the
# corresponding cmd had no arguments. We also need to remember
# not to undo next time.
INSERT_LAST_WORDS_SKIP_UNDO=1
return 1
fi
# remove first word (preserving spacing between the remaining
# words).
cmd=${cmd##[[:space:]]#$lastwords[1][[:space:]]#}
LBUFFER+=$cmd
}
zle -N insert-last-words
zle -N insert-last-words-reverse insert-last-words
bindkey '\e/' insert-last-words
bindkey '\e\\' insert-last-words-reverse