Separate up arrow lookback for local and global ZSH history
Copy & Paste this to your .zshrc
:
Cursors are using local history:
bindkey "${key[Up]}" up-line-or-local-history
bindkey "${key[Down]}" down-line-or-local-history
up-line-or-local-history() {
zle set-local-history 1
zle up-line-or-history
zle set-local-history 0
}
zle -N up-line-or-local-history
down-line-or-local-history() {
zle set-local-history 1
zle down-line-or-history
zle set-local-history 0
}
zle -N down-line-or-local-history
If you need also key bindings (CTRL + cursors) to step through the global history add also this to your .zshrc
:
bindkey "^[[1;5A" up-line-or-history # [CTRL] + Cursor up
bindkey "^[[1;5B" down-line-or-history # [CTRL] + Cursor down
To make this work the option SHARE_HISTORY (see 16.2.4 History) needs to be enabled. Run setopt
and check if "sharehistory" is listed. If not add setopt sharehistory
to your .zshrc
. Then one can use set-local-history as we did above. The documenation says:
By default, history movement commands visit the imported lines as well as the local lines, but you can toggle this on and off with the set-local-history zle binding. It is also possible to create a zle widget that will make some commands ignore imported commands, and some include them.
Note that by default global history is used (and all functions end with "zle set-local-history 0", i.e. local history is disabled). So pressing CTRL + R will search the global history by default (which makes sense in most cases).
This is quite similar to the solution by @mpy, but ready for copy & paste. It overwrites the cursor keys up and down. I used this mail list entry.
See also:
- http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html
- https://stackoverflow.com/questions/9502274/last-command-in-same-terminal/9518734?noredirect=1#comment15415094_9518734
You can setup a special zle widget to show only local history items:
function only-local-history () {
zle set-local-history 1
zle up-history
zle set-local-history 0
}
zle -N only-local-history
Assuming, that ↑ is bound to up-line-or-history
(I think that is default), you can bind this widget to another key stroke, like CTRL+↑:
bindkey "^[Oa" only-local-history
If this works is probably dependent of your terminal. Above line works in URxvt/Screen
. With xterm
you'll need
bindkey "^[[1;5A" only-local-history
for CTRL+↑.
Another variant could be
function peek-history () {
zle set-local-history
zle up-history
zle set-local-history
}
zle -N peek-history
so, if you have local history enabled, you can peek into the global one or vice versa.
@lumbic's answer worked for me only with a few changes:
setopt share_history
up-line-or-local-history() {
zle set-local-history 1
zle up-line-or-history
zle set-local-history 0
}
zle -N up-line-or-local-history
down-line-or-local-history() {
zle set-local-history 1
zle down-line-or-history
zle set-local-history 0
}
zle -N down-line-or-local-history
bindkey '^[OA' up-line-or-history # Cursor up
bindkey '^[OB' down-line-or-history # Cursor down
bindkey '^[[1;5A' up-line-or-local-history # [CTRL] + Cursor up
bindkey '^[[1;5B' down-line-or-local-history # [CTRL] + Cursor down
This code makes the global history the default, and uses CTRL-arrow for local history.
Note: I use zsh 5.0.2 together with oh-my-zsh.
I’ve been trying the options listed in other answers here but I was not happy with them. The widgets1up-history
or up-line-or-history
do not include beginning search and the widget1up-line-or-beginning-search
seems to not work well when altering local history preference while using it.2
So I came to the following settings. It enables Ctrl+arrows to browse the global history, Alt+arrows to browse the local history only (similar to Bash) and standalone arrows to use the smart beginning search (default in Oh My Zsh).
up-line-or-local-history() {
zle set-local-history 1
zle up-line-or-search
zle set-local-history 0
}
zle -N up-line-or-local-history
down-line-or-local-history() {
zle set-local-history 1
zle down-line-or-search
zle set-local-history 0
}
zle -N down-line-or-local-history
bindkey "${key[Up]}" up-line-or-beginning-search
bindkey "${key[Down]}" down-line-or-beginning-search
bindkey "^[[1;5A" up-line-or-search # [CTRL] + Cursor up
bindkey "^[[1;5B" down-line-or-search # [CTRL] + Cursor down
bindkey "^[[1;3A" up-line-or-local-history # [ALT] + Cursor up
bindkey "^[[1;3B" down-line-or-local-history # [ALT] + Cursor up
1 Their down
counterparts are meant implicitly, too.
2 The beginning used to search is redefined after altering local history preference, so the whole first found command is used as the beginning to be searched for in the second search.
Based on the various answers here, I was able to make a condenced version:
function up-line-or-history() {
zle set-local-history 1
zle .up-line-or-history
zle set-local-history 0
}
function down-line-or-history() {
zle set-local-history 1
zle .down-line-or-history
zle set-local-history 0
}
# Overwrite existing {up,down}-line-or-history widgets with the functions above.
zle -N up-line-or-history
zle -N down-line-or-history
This version will overwrite the existing up-line-or-history
and down-line-or-history
widgets with new user-defined widgets. This widget enables the local history and will then call the original widgets, which are available under the .
-prefixed names. See the zle widget documentation for details.
This means that you get to keep any existing keybindings. You can therefore avoid having to figure out what the escape sequence is for typing an up-arrow in your current terminal.