在zsh(以及bash)中,您可以使用一些历史单词扩展来表示先前命令的参数。
此示例显示了!:#
扩展历史记录中从上一个命令获取第二个参数:
% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar
我经常会忘记一个特定参数是什么#参数!:#
,当我记住它是哪个arg时,键入并不总是那么快。我知道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
这是仅在我按以下位置的Tab键时完成foo的样子<TAB>
:
% echo bar baz qux
bar baz qux
% foo <TAB>
bar baz echo qux
这对于完成命令“ foo”非常有用,但是我希望这些可以作为我执行的任何zsh扩展的选项。我认为这与zstyle completer东西有关,但是经过数小时的黑客攻击后,我意识到我已经超出了深度。
如何从上一个命令中获取参数作为zsh中任何命令的建议完成?
如果有帮助,我已经在bitbucket上共享了完整的zshrc compinstall文件。许多原因都来自多种渠道,其中一些是我自己入侵的。
更新:
@朱利安·尼古洛(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
和的目录中file2.txt
,而我的最后一个命令是echo foo bar baz
,则得到此信息是为了自动完成,这正是我想要的:
% ls
bar baz echo foo
- files -
file1.txt file2.txt
^[ .
(insert-last-word
)的补充,我喜欢copy-earlier-word
在所到达的行的单词之间循环insert-last-word
。为您.zshrc
:autoload copy-earlier-word && zle -N copy-earlier-word && bindkey '^[,' copy-earlier-word