Skip to content
z-shellPublic

Latest commit

 

History

48 Commits

Folders and files

ZI logo ❮ Zi ❯ - H-S-MW (History Search Multi Word)

Binds Ctrl-R to search for multiple keywords.
History entries that match all keywords will be found and syntax highlighted.

ASCIInema Colored Zsh History – context of command demo

License (GPL version 3) Zsh 5.8 or newer


Usage

Press Ctrl-R and type one or more words. Entries that contain every word, in any order, are listed below the command line with syntax highlighting; the newest match comes first. A query in lower case ignores case, and any upper-case letter makes it exact. A leading ^ anchors the first word to the start of the entry and a trailing $ anchors the last word to its end.

Key Action
Up, Down, Ctrl-P, Ctrl-N Move to the previous or next match
Page Up, Page Down Move by a page
Enter Put the selected entry on the command line
Ctrl-K Show the entry in context, and again to go back
Ctrl-J Copy the selected entry to the end of history
Ctrl-V, Esc, Ctrl-C Cancel and keep the query (see clear-on-cancel)

Configuration

Every setting is a style in the :history-search-multi-word context, read when a search starts, so a change takes effect on the next Ctrl-R.

zstyle :history-search-multi-word page-size 8
zstyle :history-search-multi-word highlight-color "fg=yellow,bold"
Style Type Default Effect
page-size integer LINES / 3 Entries shown per page; an arithmetic expression such as LINES/4 works
highlight-color string bg=17 on 256-colour terminals, else fg=yellow,bold How the searched words are marked in the list
active string underline How the selected entry is marked, e.g. standout, bold, bg=blue
synhl boolean yes Syntax-highlight the list
check-paths boolean yes Test whether words are existing paths and mark them as paths
skip-paths array empty Patterns of paths never tested, e.g. slow network mounts
clear-on-cancel boolean no Clear the query when the search is cancelled
reset-prompt-protect boolean no Keep the search running when something calls zle reset-prompt
zstyle :history-search-multi-word skip-paths '/mnt/nfs/*' '/media/*'

Syntax highlighting styles

The colours of the highlighted list are styles in the :history-search-multi-word:highlight context, one per token type:

zstyle :history-search-multi-word:highlight path "bg=magenta,fg=white,bold"
zstyle :history-search-multi-word:highlight commandseparator "fg=241,bg=17"

Token types and their defaults: default (none), unknown-token (fg=red,bold), reserved-word (fg=yellow), alias, suffix-alias, builtin, function, command, precommand, hashed-command (all fg=green), commandseparator (none), path (fg=magenta), path_pathseparator (empty), globbing and history-expansion (fg=blue,bold), single-hyphen-option and double-hyphen-option (fg=cyan), back-quoted-argument (none), single-quoted-argument, double-quoted-argument and dollar-quoted-argument (fg=yellow), back-or-dollar-double-quoted-argument and back-dollar-quoted-argument (fg=cyan), assign and redirection (none), comment and newline (fg=black,bold), variable (none).

reset-prompt

A prompt that refreshes itself, for example a clock redrawn from sched, calls zle reset-prompt while the search may be open. With reset-prompt-protect set, the search redraws itself after such a call instead of being disturbed:

zstyle :history-search-multi-word reset-prompt-protect yes

PROMPT=%B%F{yellow}%D{%H:%M:%S}%B%b%f
schedprompt() {
  zle && zle reset-prompt
  sched +1 schedprompt
}

zmodload -i zsh/sched
schedprompt

Alternatively, call zle .reset-prompt (with the dot) to run the built-in widget rather than a copy other plugins may have wrapped.

Upgrading from earlier versions

This version follows version 2 of the Zsh Plugin Standard and reads only the styles above. Move older settings as follows:

Earlier setting Now
zstyle :plugin:history-search-multi-word STYLE VALUE zstyle :history-search-multi-word STYLE VALUE
HSMW_HIGHLIGHT_STYLES[TOKEN]=VALUE zstyle :history-search-multi-word:highlight TOKEN VALUE
FAST_BLIST_PATTERNS[PATTERN]=1 zstyle :history-search-multi-word skip-paths PATTERN ...

Public shell surface

The project identifier is history-search-multi-word. Loading the plugin in an interactive shell creates exactly these public names; everything else it creates is private and named _history_search_multi_word_*.

  • Function: history-search-multi-word, autoloaded; it implements the widgets.
  • Widgets: history-search-multi-word, history-search-multi-word-backwards, history-search-multi-word-pforwards, history-search-multi-word-pbackwards.
  • Key binding: Ctrl-R in the keymap main names when the plugin loads, usually emacs or viins.
  • Style contexts: :history-search-multi-word and :history-search-multi-word:highlight.
  • Unload function: history-search-multi-word_plugin_unload, and H-S-MW_plugin_unload, the name Zi calls.
  • fpath: the plugin's functions/ directory, added when it is not already there.

A search also creates the history-search-multi-word keymap and loads zsh/terminfo and zsh/termcap when they are not loaded yet. A non-interactive shell gets only the fpath entry, the autoload definitions, the two unload functions and one private state parameter, _history_search_multi_word_state.

Unloading

history-search-multi-word_plugin_unload removes everything the plugin created: its widgets, keymap, functions, parameters, the fpath entry it added and the terminal modules a search loaded. Ctrl-R gets back the widget or string it had before loading, in the keymap it was bound in, unless you have bound it to something else since; if it was unbound, it is unbound again. With Zi, zi unload z-shell/H-S-MW calls it.

Installation

The plugin is "standalone", which means that only sourcing it is needed. So to install, unpack H-S-MW somewhere and add to ~/.zshrc:

source {where-H-S-MW-is}/H-S-MW.plugin.zsh

If using a plugin manager, then Zi is recommended, but you can use others if you prefer:

Add zi load z-shell/H-S-MW to your ~/.zshrc file. Zi will handle cloning the plugin for you automatically the next time you start zsh.

Oh My Zsh (OMZ)

  1. Run this command to clone and mv to the ~/.oh-my-zsh/custom/plugins directory

    git clone https://github.com/z-shell/H-S-MW.git \
     ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/H-S-MW
  2. Add H-S-MW to your plugin list in the ~/.zshrc file

    plugins=(... H-S-MW)

Add antigen bundle z-shell/H-S-MW to your .zshrc file. Antigen will handle cloning the plugin for you automatically the next time you start zsh. You can also add the plugin to a running zsh with antigen bundle z-shell/H-S-MW for testing before adding it to your .zshrc.

  1. Add zgen load z-shell/H-S-MW to your .zshrc file in the same place you're doing your other zgen load calls in.
  2. Start a new terminal session

Supported Zsh versions

Zsh 5.8 or newer. The test workflow runs on Zsh 5.8.1 and 5.9.2.

Development

The tests drive the widget in an interactive shell through zsh/zpty; each file runs on its own and prints ok: or FAIL: lines:

for test in tests/test-*.zsh; do zsh -f "$test"; done

Set TEST_ZSH to run the shells under test with another Zsh binary. Loading costs about 2 ms in an interactive shell, measured with zsh/zprof and EPOCHREALTIME on Zsh 5.9.2; half of it is the subshell that records the earlier Ctrl-R binding so that unloading can restore it.

Releases

Used by

Contributors

Languages