Reputation: 539
I frequently find myself wanting to repeat a command, and while !!
is useful, I'd like to bind that to ctrl-w or something like that. Is there a way to do that?
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.
I looked at this post about adding a shortcut to access the info
command and tried to extrapolate something out of it, but had no success. Zsh yelled at me about zle not being active or something.
I know this will rely on knowledge of how my shell is configured, so below I've pasted some relevant code, as well as a link to my entire .zshrc and dotfiles in general.
# 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
Full configs: https://github.com/yramagicman/dotfiles
Just the .zshrc: https://github.com/yramagicman/dotfiles/blob/master/.zshrc
custom plugins:
Upvotes: 1
Views: 4517
Reputation: 2131
EDIT: Alternative that doesn't break Esc/ search:
accept-line() { [ -z "$BUFFER" ] && zle up-history; zle ".$WIDGET"; }
zle -N zle-line-init
Redefine default Enter command so it inserts last command if the buffer is empty. Inspired by this answer.
ORIGINAL:
I have this in my .zshrc
:
last_if_empty() {
[ -z "$BUFFER" ] && zle up-history
zle accept-line
}
zle -N last_if_empty
bindkey -M viins '^M' last_if_empty
It remaps Enter to Run last command
if nothing has been typed on the screen.
Unfortunately it seems to break Esc/ search (Enter key doesn't work). I use Ctrl+R so it doesn't bother me, but might be a dealbreaker.
Upvotes: 0
Reputation: 18429
To get the last command from the history you can use the up-history
widget. This is by default bound to Ctrl+P in vicmd mode, so pressing Esc followed by Ctrl+P and then Enter (which invokes the widget accept-line
) would do the trick.
If you want to bind it to a single shortcut, you have to write your own widget. You can add this to your ~/.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
For the example I chose Ctrl+X as shortcut because by default it is unbound in vicmd mode and self-inserts in in viins mode, whereas Ctrl+W is already bound to vi-backward-kill-word
in viins. Of course you could overwrite the default binding if you do not use it anyway or bind the widget only in mode.
Upvotes: 5