在 zsh 中,如何将键盘快捷键绑定到 运行 最后一个命令?

In zsh how do I bind a keyboard shortcut to run the last command?

我经常发现自己想要重复一个命令,虽然 !! 很有用,但我想将它绑定到 ctrl-w 或类似的东西。有办法吗?

EDIT: I'm aware that the up arrow does what I want, however I would rather not have to leave the home row. Being an avid Vim user has taught me the value of staying on the home keys.

我查看了 this post 关于添加访问 info 命令的快捷方式的信息,并试图从中推断出一些东西,但没有成功。 zsh 冲我大喊 zle 不活跃什么的。

我知道这将依赖于我的 shell 配置方式的知识,所以在下面我粘贴了一些相关代码,以及 link 到我的整个 .zshrc 和点文件一般。

# oh-my-zsh plugins. zsh-aliases and drush are custom plugins.
plugins=( git z tmux web-search colored-man zsh-aliases drush)
ZSH_TMUX_AUTOSTART=true
#... $PATH, start background process (clipboard integration for tmux, 
# glances system monitor), history options, editor, all truncated for brevity.
# use vim mode
bindkey -v
#show insert/normal mode in prompt
function zle-line-init zle-keymap-select {
    RPS1="${${KEYMAP/vicmd/NORMAL}/(main|viins)/INSERT}"
    RPS2=$RPS1
zle reset-prompt
}
zle -N zle-line-init
zle -N zle-keymap-select
# rebind ctrl-r
bindkey -M vicmd '^R' history-incremental-search-backward
bindkey -M viins '^R' history-incremental-search-backward

完整配置:https://github.com/yramagicman/dotfiles

只是 .zshrc:https://github.com/yramagicman/dotfiles/blob/master/.zshrc

自定义插件:

要从历史记录中获取最后一个命令,您可以使用 up-history 小部件。在 vicmd 模式下默认绑定到 Ctrl+P,所以按 Esc 后跟 Ctrl+P 然后是 Enter (调用小部件 accept-line) 就可以了。

如果要将其绑定到单个快捷方式,则必须编写自己的小部件。您可以将此添加到您的 ~/.zshrc:

# define function that retrieves and runs last command
function run-again {
    # get previous history item
    zle up-history
    # confirm command
    zle accept-line
}

# define run-again widget from function of the same name
zle -N run-again

# bind widget to Ctrl+X in viins mode
bindkey -M viins '^X' run-again 
# bind widget to Ctrl+X in vicmd mode
bindkey -M vicmd '^X' run-again

示例中我选择了Ctrl+X作为快捷方式,因为默认情况下它在vicmd[=中是未绑定的37=] 模式和自插入 viins 模式,而 Ctrl+W 已经绑定在 viinsvi-backward-kill-word。当然,如果您不使用默认绑定或者仅在模式下绑定小部件,您可以覆盖默认绑定。

编辑: 不会中断的替代方案 Esc/ 搜索:

accept-line() { [ -z "$BUFFER" ] && zle up-history; zle ".$WIDGET"; }
zle -N zle-line-init

重新定义默认 Enter 命令,以便在缓冲区为空时插入最后一个命令。灵感来自 this answer.


原文:

我的.zshrc里有这个:

last_if_empty() {
  [ -z "$BUFFER" ] && zle up-history
  zle accept-line
}
zle -N last_if_empty
bindkey -M viins '^M' last_if_empty

如果屏幕上没有输入任何内容,它会将 Enter 重新映射到 Run last command

不幸的是,它似乎中断了 Esc/ 搜索(Enter 键不起作用)。我使用 Ctrl+R 所以它不会打扰我,但可能会破坏交易。