在 zsh(以及 bash)中,您可以使用一些历史词扩展来表示先前命令的参数。
此示例显示通过扩展从历史记录中的上一个命令获取第二个参数!:#
:
% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar
我经常忘记某个特定参数到底是什么 # 参数,并且!:#
当我记住它是什么参数时,输入并不总是那么快。我知道要meta-.
替换最后一个参数,但有时它不是我想要的最后一个参数。
我想添加上一个命令中的参数作为建议,以完成我在 zsh 中键入的任何命令。
我能够弄清楚如何创建一个 shell 函数,该函数可以从最后一个命令创建一个参数数组 (0..N) 并将其绑定到特定命令。
_last_command_args() {
last_command=$history[$[HISTCMD-1]]
last_command_array=("${(s/ /)last_command}")
_sep_parts last_command_array
}
# trying to get last_command_args to be suggested for any command, this just works for foo
compdef _last_command_args foo
这就是完成 foo 的样子,我点击了 tab 键<TAB>
:
% echo bar baz qux
bar baz qux
% foo <TAB>
bar baz echo qux
这对于完成命令“foo”非常有用,但我希望这些成为我所做的任何 zsh 扩展的选项。我认为这与 zstyle 完成者的东西有关,但经过几个小时的黑客攻击后,我意识到我已经超出了我的能力范围。
如何从上一个命令中获取参数作为 zsh 中任何命令的建议补全?
我已经满了zshrc 编译安装文件如果有帮助的话,请在 bitbucket 上分享。其中很多内容是从各种来源抄袭的,其中一些是我自己编写的。
更新:
@Julien Nicoulaud 的回答让我很接近,我将其标记为已接受,因为它让我到达了我需要到达的地方。
根据我的特定配置,使用建议的:
zstyle ':completion:*' completer _last_command_args _complete
对我来说不太有效,因为它导致制表符完成仅显示最后一个命令的参数列表(尽管它实际上也完成了文件名,只是不显示它们)。更改顺序即可_complete _last_command_args
实现相反的效果。它会显示正常的文件名,但不显示last_command_args
我猜这与完成器的工作方式有关。我认为它只显示第一个成功返回的方法的输出,但我在解析 zsh 源以完全理解发生了什么时遇到困难。我能够调整我的方法以包含对的调用,_complete
以便它显示最后一个参数命令以及常规自动完成内容。不太分开,但对我来说已经足够好了。
这是我使用的完整函数以及我拥有的其他 zstyle 东西:
# adds the arguments from the last commadn to the autocomplete list
# I wasn't able to get this to work standalone and still print out both regular
# completion plus the last args, but this works well enough.
_complete_plus_last_command_args() {
last_command=$history[$[HISTCMD-1]]
last_command_array=("${(s/ /)last_command}")
_sep_parts last_command_array
_complete
}
_force_rehash() {
(( CURRENT == 1 )) && rehash
return 1 # Because we didn't really complete anything
}
zstyle ':completion:::::' completer _force_rehash _complete_plus_last_command_args _approximate
我拥有的其他 zstyle 行,对于此功能来说不是必需的,但可能会影响为什么这对我有用:
zstyle -e ':completion:*:approximate:*' max-errors 'reply=( $(( ($#PREFIX + $#SUFFIX) / 3 )) )'
zstyle ':completion:*:descriptions' format "- %d -"
zstyle ':completion:*:corrections' format "- %d - (errors %e})"
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
zstyle ':completion:*' group-name ''
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*' menu select
zstyle ':completion:*' verbose yes
file1.txt
现在,如果我位于包含and的目录中file2.txt
,并且我的最后一个命令是echo foo bar baz
,我会得到这个自动完成功能,这正是我想要的:
% ls
bar baz echo foo
- files -
file1.txt file2.txt
答案1
您可以将完成者添加到默认使用的完成者列表中:
zstyle ':completion:*' completer _last_command_args _complete