Skip to content

Commit

Permalink
Bind keys and allow users to override the default ones
Browse files Browse the repository at this point in the history
This will save users from some common boilerplate code in their own
.zshrc file.

Fixes #107
  • Loading branch information
ericbn committed Aug 3, 2021
1 parent 4abed97 commit d8e51d8
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 46 deletions.
94 changes: 54 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,58 +44,27 @@ Usage

1. Load this script into your interactive ZSH session:

% source zsh-history-substring-search.zsh
source zsh-history-substring-search.zsh

If you want to use [zsh-syntax-highlighting][6] along with this script,
then make sure that you load it *before* you load this script:

% source zsh-syntax-highlighting.zsh
% source zsh-history-substring-search.zsh
source zsh-syntax-highlighting.zsh
source zsh-history-substring-search.zsh

2. Bind keyboard shortcuts to this script's functions.
2. Type any part of any previous command and then:

Users typically bind their UP and DOWN arrow keys to this script, thus:
* Run `cat -v` in your favorite terminal emulator to observe key codes.
     (**NOTE:** In some cases, `cat -v` shows the wrong key codes. If the
key codes shown by `cat -v` don't work for you, press `<C-v><UP>` and
`<C-v><DOWN>` at your ZSH command line prompt for correct key codes.)
* Press the UP arrow key and observe what is printed in your terminal.
* Press the DOWN arrow key and observe what is printed in your terminal.
* Press the Control and C keys simultaneously to terminate the `cat -v`.
* Use your observations from the previous steps to create key bindings.
For example, if you observed `^[[A` for UP and `^[[B` for DOWN, then:

bindkey '^[[A' history-substring-search-up
bindkey '^[[B' history-substring-search-down

However, if the observed values don't work, you can try using terminfo:

bindkey "$terminfo[kcuu1]" history-substring-search-up
bindkey "$terminfo[kcud1]" history-substring-search-down

You might also want to bind the Control-P/N keys for use in EMACS mode:

bindkey -M emacs '^P' history-substring-search-up
bindkey -M emacs '^N' history-substring-search-down

You might also want to bind the `k` and `j` keys for use in VI mode:

bindkey -M vicmd 'k' history-substring-search-up
bindkey -M vicmd 'j' history-substring-search-down

3. Type any part of any previous command and then:

* Press the `history-substring-search-up` key, which was configured in
step 2 above, to select the nearest command that (1) contains your query
* Press the `history-substring-search-up` key, which is the UP key by
default, to select the nearest command that (1) contains your query
and (2) is also older than the current command in your command history.

* Press the `history-substring-search-down` key, which was configured in
step 2 above, to select the nearest command that (1) contains your query
* Press the `history-substring-search-down` key, which is the DOWN key by
default, to select the nearest command that (1) contains your query
and (2) is also newer than the current command in your command history.

* Press `^U` the Control and U keys simultaneously to abort the search.

4. If a matching command spans more than one line of text, press the LEFT
3. If a matching command spans more than one line of text, press the LEFT
arrow key to move the cursor away from the end of the command, and then:

* Press the `history-substring-search-up` key, which was configured in
Expand Down Expand Up @@ -161,6 +130,51 @@ default values.
receive globally unique search results only once, then use this
configuration variable, or use `setopt HIST_IGNORE_ALL_DUPS`.

The following variables must be overridden before having loaded this script
into your ZSH session, and they define the `history-substring-search-up` and
`history-substring-search-down` key bindings.

* `HISTORY_SUBSTRING_SEARCH_MAIN_UP_KEYS` is a global array that defines the
main keymap keys to be bind to the `history-substring-search-up` command.
Its default value is `('^[[A' $terminfo[kcuu1])`, which are two common codes
for the UP key in most terminals.

* `HISTORY_SUBSTRING_SEARCH_MAIN_DOWN_KEYS` is a global array that defines the
main keymap keys to be bind to the `history-substring-search-down` command.
Its default value is `('^[[B' $terminfo[kcud1])`, which are two common codes
for the DOWN key in most terminals.

* `HISTORY_SUBSTRING_SEARCH_EMACS_UP_KEYS` is a global array that defines the
EMACS mode keys to be bind to the `history-substring-search-up` command.
Its default value is `('^P')`, which is the code for the Control-P key.

* `HISTORY_SUBSTRING_SEARCH_EMACS_DOWN_KEYS` is a global array that defines the
EMACS mode keys to be bind to the `history-substring-search-down` command.
Its default value is `('^N')`, which is the code for the Control-N key.

* `HISTORY_SUBSTRING_SEARCH_VICMD_UP_KEYS` is a global array that defines the
VI mode keys to be bind to the `history-substring-search-up` command.
Its default value is `('k')`, which is the code for the `k` key.

* `HISTORY_SUBSTRING_SEARCH_VICMD_DOWN_KEYS` is a global array that defines the
VI mode keys to be bind to the `history-substring-search-down` command.
Its default value is `('j')`, which is the code for the `j` key.

Users typically bind their UP and DOWN arrow keys to this script. If the
defaults provided above don't work for you, then:
* Run `cat -v` in your favorite terminal emulator to observe key codes.
(**NOTE:** In some cases, `cat -v` shows the wrong key codes. If the
key codes shown by `cat -v` don't work for you, press `<Control-v><UP>` and
`<Control-v><DOWN>` at your ZSH command line prompt for correct key codes.)
* Press the UP arrow key and observe what is printed in your terminal.
* Press the DOWN arrow key and observe what is printed in your terminal.
* Press the Control and C keys simultaneously to terminate the `cat -v`.
* Use your observations from the previous steps to create key bindings.
For example, if you observed `^[OA` for UP and `^[OB` for DOWN, then:

HISTORY_SUBSTRING_SEARCH_MAIN_UP_KEYS=('^[OA')
HISTORY_SUBSTRING_SEARCH_MAIN_DOWN_KEYS=('^[OB')
source zsh-history-substring-search.zsh

History
------------------------------------------------------------------------------
Expand Down
69 changes: 63 additions & 6 deletions zsh-history-substring-search.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,44 @@
# declare global configuration variables
#-----------------------------------------------------------------------------

: ${HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold'}
: ${HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold'}
: ${HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'}
: ${HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE=''}
: ${HISTORY_SUBSTRING_SEARCH_FUZZY=''}
: ${HISTORY_SUBSTRING_SEARCH_PREFIXED=''}
if (( ! $+HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND )); then
typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold'
fi
if (( ! $+HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND )); then
typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold'
fi
if (( ! $+HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS )); then
typeset -g HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'
fi
if (( ! $+HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE )); then
typeset -g HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE=''
fi
if (( ! $+HISTORY_SUBSTRING_SEARCH_FUZZY )); then
typeset -g HISTORY_SUBSTRING_SEARCH_FUZZY=''
fi
if (( ! $+HISTORY_SUBSTRING_SEARCH_PREFIXED )); then
typeset -g HISTORY_SUBSTRING_SEARCH_PREFIXED=''
fi

zmodload -F zsh/terminfo +p:terminfo
if (( ! $+HISTORY_SUBSTRING_SEARCH_MAIN_UP_KEYS )); then
typeset -ga HISTORY_SUBSTRING_SEARCH_MAIN_UP_KEYS=('^[[A' $terminfo[kcuu1])
fi
if (( ! $+HISTORY_SUBSTRING_SEARCH_MAIN_DOWN_KEYS )); then
typeset -ga HISTORY_SUBSTRING_SEARCH_MAIN_DOWN_KEYS=('^[[B' $terminfo[kcud1])
fi
if (( ! $+HISTORY_SUBSTRING_SEARCH_EMACS_UP_KEYS )); then
typeset -ga HISTORY_SUBSTRING_SEARCH_EMACS_UP_KEYS=('^P')
fi
if (( ! $+HISTORY_SUBSTRING_SEARCH_EMACS_DOWN_KEYS )); then
typeset -ga HISTORY_SUBSTRING_SEARCH_EMACS_DOWN_KEYS=('^N')
fi
if (( ! $+HISTORY_SUBSTRING_SEARCH_VICMD_UP_KEYS )); then
typeset -ga HISTORY_SUBSTRING_SEARCH_VICMD_UP_KEYS=('k')
fi
if (( ! $+HISTORY_SUBSTRING_SEARCH_VICMD_DOWN_KEYS )); then
typeset -ga HISTORY_SUBSTRING_SEARCH_VICMD_DOWN_KEYS=('j')
fi

#-----------------------------------------------------------------------------
# declare internal global variables
Expand Down Expand Up @@ -763,5 +795,30 @@ _history-substring-search-down-search() {
fi
}

#-----------------------------------------------------------------------------
# Set key bindings
#-----------------------------------------------------------------------------

local _history_substring_search_key
for _history_substring_search_key in $HISTORY_SUBSTRING_SEARCH_MAIN_UP_KEYS; do
bindkey $_history_substring_search_key history-substring-search-up
done
for _history_substring_search_key in $HISTORY_SUBSTRING_SEARCH_MAIN_DOWN_KEYS; do
bindkey $_history_substring_search_key history-substring-search-down
done
for _history_substring_search_key in $HISTORY_SUBSTRING_SEARCH_EMACS_UP_KEYS; do
bindkey -M emacs $_history_substring_search_key history-substring-search-up
done
for _history_substring_search_key in $HISTORY_SUBSTRING_SEARCH_EMACS_DOWN_KEYS; do
bindkey -M emacs $_history_substring_search_key history-substring-search-down
done
for _history_substring_search_key in $HISTORY_SUBSTRING_SEARCH_VICMD_UP_KEYS; do
bindkey -M vicmd $_history_substring_search_key history-substring-search-up
done
for _history_substring_search_key in $HISTORY_SUBSTRING_SEARCH_VICMD_DOWN_KEYS; do
bindkey -M vicmd $_history_substring_search_key history-substring-search-down
done
unset _history_substring_search_key

# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
# vim: ft=zsh sw=2 ts=2 et

0 comments on commit d8e51d8

Please sign in to comment.