mirror of
https://github.com/zsh-users/zsh-history-substring-search.git
synced 2026-11-11 03:41:47 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f80b8eb33 | ||
|
|
2c36e4dd3a | ||
|
|
79d3619704 | ||
|
|
19cb0eb8be | ||
|
|
36505c46c7 | ||
|
|
8d4a409c89 | ||
|
|
47a7d416c6 | ||
|
|
d44159b5e8 | ||
|
|
4594acaa4f | ||
|
|
c35b4d1e8c | ||
|
|
933733e867 | ||
|
|
be0fe1fca9 | ||
|
|
fd27842cad | ||
|
|
563c88c4ca | ||
|
|
c750a17757 | ||
|
|
07011f632b | ||
|
|
2b6451de03 | ||
|
|
21c025eb33 | ||
|
|
34fdd6b1b2 |
+2
-2
@@ -1,2 +1,2 @@
|
|||||||
# zsh word code files (zcompile)
|
# zsh word code files (zcompile and zrecompile)
|
||||||
*.zwc
|
*.zwc*
|
||||||
|
|||||||
@@ -17,6 +17,27 @@ Requirements
|
|||||||
|
|
||||||
* [ZSH](http://zsh.sourceforge.net) 4.3 or newer
|
* [ZSH](http://zsh.sourceforge.net) 4.3 or newer
|
||||||
|
|
||||||
|
Install
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Using the [Homebrew]( https://brew.sh ) package manager:
|
||||||
|
|
||||||
|
brew install zsh-history-substring-search
|
||||||
|
echo 'source /usr/local/share/zsh-history-substring-search/zsh-history-substring-search.zsh' >> ~/.zshrc
|
||||||
|
|
||||||
|
Using [Oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh):
|
||||||
|
|
||||||
|
1. Clone this repository in oh-my-zsh's plugins directory:
|
||||||
|
|
||||||
|
git clone https://github.com/zsh-users/zsh-history-substring-search ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-history-substring-search
|
||||||
|
|
||||||
|
2. Activate the plugin in `~/.zshrc`:
|
||||||
|
|
||||||
|
plugins=( [plugins...] history-substring-search)
|
||||||
|
|
||||||
|
3. Source `~/.zshrc` to take changes into account:
|
||||||
|
|
||||||
|
source ~/.zshrc
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
@@ -35,24 +56,32 @@ Usage
|
|||||||
|
|
||||||
Users typically bind their UP and DOWN arrow keys to this script, thus:
|
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.
|
* 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 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 DOWN arrow key and observe what is printed in your terminal.
|
||||||
* Press the Control and C keys simultaneously to terminate the `cat -v`.
|
* Press the Control and C keys simultaneously to terminate the `cat -v`.
|
||||||
* Use your observations from the previous steps to create key bindings.
|
* Use your observations from the previous steps to create key bindings.
|
||||||
For example, if you observed `^[[A` for UP and `^[[B` for DOWN, then:
|
For example, if you observed `^[[A` for UP and `^[[B` for DOWN, then:
|
||||||
|
|
||||||
bindkey '^[[A' history-substring-search-up
|
bindkey '^[[A' history-substring-search-up
|
||||||
bindkey '^[[B' history-substring-search-down
|
bindkey '^[[B' history-substring-search-down
|
||||||
|
|
||||||
You might also want to bind the Control-P/N keys for use in EMACS mode:
|
However, if the observed values don't work, you can try using terminfo:
|
||||||
|
|
||||||
bindkey -M emacs '^P' history-substring-search-up
|
bindkey "$terminfo[kcuu1]" history-substring-search-up
|
||||||
bindkey -M emacs '^N' history-substring-search-down
|
bindkey "$terminfo[kcud1]" history-substring-search-down
|
||||||
|
|
||||||
You might also want to bind the `k` and `j` keys for use in VI mode:
|
You might also want to bind the Control-P/N keys for use in EMACS mode:
|
||||||
|
|
||||||
bindkey -M vicmd 'k' history-substring-search-up
|
bindkey -M emacs '^P' history-substring-search-up
|
||||||
bindkey -M vicmd 'j' history-substring-search-down
|
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:
|
3. Type any part of any previous command and then:
|
||||||
|
|
||||||
@@ -107,6 +136,11 @@ default values only after having loaded this script into your ZSH session.
|
|||||||
Flags" section in the zshexpn(1) man page to learn about the kinds of
|
Flags" section in the zshexpn(1) man page to learn about the kinds of
|
||||||
values you may assign to this variable.
|
values you may assign to this variable.
|
||||||
|
|
||||||
|
* `HISTORY_SUBSTRING_SEARCH_FUZZY` is a global variable that defines
|
||||||
|
how the command history will be searched for your query. If set to a non-empty
|
||||||
|
value, causes this script to perform a fuzzy search by words, matching in
|
||||||
|
given order e.g. `ab c` will match `*ab*c*`
|
||||||
|
|
||||||
* `HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE` is a global variable that defines
|
* `HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE` is a global variable that defines
|
||||||
whether all search results returned are _unique_. If set to a non-empty
|
whether all search results returned are _unique_. If set to a non-empty
|
||||||
value, then only unique search results are presented. This behaviour is off
|
value, then only unique search results are presented. This behaviour is off
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
0=${(%):-%N}
|
||||||
|
source ${0:A:h}/zsh-history-substring-search.zsh
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
# Copyright (c) 2011 Sorin Ionescu
|
# Copyright (c) 2011 Sorin Ionescu
|
||||||
# Copyright (c) 2011 Vincent Guerci
|
# Copyright (c) 2011 Vincent Guerci
|
||||||
# Copyright (c) 2016 Geza Lore
|
# Copyright (c) 2016 Geza Lore
|
||||||
|
# Copyright (c) 2017 Bengt Brodersen
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@@ -39,34 +40,30 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# declare global variables
|
# declare global configuration variables
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
typeset -g BUFFER MATCH MBEGIN MEND CURSOR
|
|
||||||
typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND
|
|
||||||
typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND
|
|
||||||
typeset -g HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS
|
|
||||||
typeset -g HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE
|
|
||||||
typeset -g _history_substring_search_refresh_display
|
|
||||||
typeset -g _history_substring_search_query_highlight
|
|
||||||
typeset -g _history_substring_search_result
|
|
||||||
typeset -g _history_substring_search_query
|
|
||||||
typeset -g -A _history_substring_search_raw_matches
|
|
||||||
typeset -g _history_substring_search_raw_match_index
|
|
||||||
typeset -g -A _history_substring_search_matches
|
|
||||||
typeset -g -A _history_substring_search_unique_filter
|
|
||||||
typeset -g _history_substring_search_match_index
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
# configuration variables
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold'
|
typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold'
|
||||||
typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold'
|
typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold'
|
||||||
typeset -g HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'
|
typeset -g HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'
|
||||||
typeset -g HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE=''
|
typeset -g HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE=''
|
||||||
typeset -g _history_substring_search_{refresh_display,query_highlight,result,query,match_index,raw_match_index}
|
typeset -g HISTORY_SUBSTRING_SEARCH_FUZZY=''
|
||||||
typeset -ga _history_substring_search{,_raw}_matches
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
# declare internal global variables
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typeset -g BUFFER MATCH MBEGIN MEND CURSOR
|
||||||
|
typeset -g _history_substring_search_refresh_display
|
||||||
|
typeset -g _history_substring_search_query_highlight
|
||||||
|
typeset -g _history_substring_search_result
|
||||||
|
typeset -g _history_substring_search_query
|
||||||
|
typeset -g -a _history_substring_search_query_parts
|
||||||
|
typeset -g -a _history_substring_search_raw_matches
|
||||||
|
typeset -g -i _history_substring_search_raw_match_index
|
||||||
|
typeset -g -a _history_substring_search_matches
|
||||||
|
typeset -g -i _history_substring_search_match_index
|
||||||
|
typeset -g -A _history_substring_search_unique_filter
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# the main ZLE widgets
|
# the main ZLE widgets
|
||||||
@@ -223,6 +220,7 @@ _history-substring-search-begin() {
|
|||||||
# speed things up a little.
|
# speed things up a little.
|
||||||
#
|
#
|
||||||
_history_substring_search_query=
|
_history_substring_search_query=
|
||||||
|
_history_substring_search_query_parts=()
|
||||||
_history_substring_search_raw_matches=()
|
_history_substring_search_raw_matches=()
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -233,20 +231,31 @@ _history-substring-search-begin() {
|
|||||||
_history_substring_search_query=$BUFFER
|
_history_substring_search_query=$BUFFER
|
||||||
|
|
||||||
#
|
#
|
||||||
# $BUFFER contains the text that is in the command-line currently.
|
# compose search pattern
|
||||||
# we put an extra "\\" before meta characters such as "\(" and "\)",
|
|
||||||
# so that they become "\\\(" and "\\\)".
|
|
||||||
#
|
#
|
||||||
local escaped_query=${BUFFER//(#m)[\][()|\\*?#<>~^]/\\$MATCH}
|
if [[ -n $HISTORY_SUBSTRING_SEARCH_FUZZY ]]; then
|
||||||
|
#
|
||||||
|
# `=` split string in arguments
|
||||||
|
#
|
||||||
|
_history_substring_search_query_parts=(${=_history_substring_search_query})
|
||||||
|
else
|
||||||
|
_history_substring_search_query_parts=(${==_history_substring_search_query})
|
||||||
|
fi
|
||||||
|
|
||||||
#
|
#
|
||||||
# Find all occurrences of the search query in the history file.
|
# Escape and join query parts with wildcard character '*' as seperator
|
||||||
|
# `(j:CHAR:)` join array to string with CHAR as seperator
|
||||||
|
#
|
||||||
|
local search_pattern="*${(j:*:)_history_substring_search_query_parts[@]//(#m)[\][()|\\*?#<>~^]/\\$MATCH}*"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Find all occurrences of the search pattern in the history file.
|
||||||
#
|
#
|
||||||
# (k) returns the "keys" (history index numbers) instead of the values
|
# (k) returns the "keys" (history index numbers) instead of the values
|
||||||
# (R) returns values in reverse older, so the index of the youngest
|
# (R) returns values in reverse older, so the index of the youngest
|
||||||
# matching history entry is at the head of the list.
|
# matching history entry is at the head of the list.
|
||||||
#
|
#
|
||||||
_history_substring_search_raw_matches=(${(k)history[(R)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)*${escaped_query}*]})
|
_history_substring_search_raw_matches=(${(k)history[(R)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)${search_pattern}]})
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -265,8 +274,7 @@ _history-substring-search-begin() {
|
|||||||
#
|
#
|
||||||
_history_substring_search_raw_match_index=0
|
_history_substring_search_raw_match_index=0
|
||||||
_history_substring_search_matches=()
|
_history_substring_search_matches=()
|
||||||
unset _history_substring_search_unique_filter
|
_history_substring_search_unique_filter=()
|
||||||
typeset -A -g _history_substring_search_unique_filter
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# If $_history_substring_search_match_index is equal to
|
# If $_history_substring_search_match_index is equal to
|
||||||
@@ -309,16 +317,21 @@ _history-substring-search-end() {
|
|||||||
_zsh_highlight
|
_zsh_highlight
|
||||||
|
|
||||||
# highlight the search query inside the command line
|
# highlight the search query inside the command line
|
||||||
if [[ -n $_history_substring_search_query_highlight && -n $_history_substring_search_query ]]; then
|
if [[ -n $_history_substring_search_query_highlight ]]; then
|
||||||
#
|
# highlight first matching query parts
|
||||||
# The following expression yields a variable $MBEGIN, which
|
local highlight_start_index=0
|
||||||
# indicates the begin position + 1 of the first occurrence
|
local highlight_end_index=0
|
||||||
# of _history_substring_search_query in $BUFFER.
|
local query_part
|
||||||
#
|
for query_part in $_history_substring_search_query_parts; do
|
||||||
: ${(S)BUFFER##(#m$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)($_history_substring_search_query##)}
|
local escaped_query_part=${query_part//(#m)[\][()|\\*?#<>~^]/\\$MATCH}
|
||||||
local begin=$(( MBEGIN - 1 ))
|
# (i) get index of pattern
|
||||||
local end=$(( begin + $#_history_substring_search_query ))
|
local query_part_match_index="${${BUFFER:$highlight_start_index}[(i)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)${escaped_query_part}]}"
|
||||||
region_highlight+=("$begin $end $_history_substring_search_query_highlight")
|
if [[ $query_part_match_index -le ${#BUFFER:$highlight_start_index} ]]; then
|
||||||
|
highlight_start_index=$(( $highlight_start_index + $query_part_match_index ))
|
||||||
|
highlight_end_index=$(( $highlight_start_index + ${#query_part} ))
|
||||||
|
region_highlight+=("$(($highlight_start_index - 1)) $(($highlight_end_index - 1)) $_history_substring_search_query_highlight")
|
||||||
|
fi
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# For debugging purposes:
|
# For debugging purposes:
|
||||||
@@ -447,7 +460,7 @@ _history_substring_search_process_raw_matches() {
|
|||||||
#
|
#
|
||||||
# Move on to the next raw entry and get its history index.
|
# Move on to the next raw entry and get its history index.
|
||||||
#
|
#
|
||||||
(( _history_substring_search_raw_match_index++ ))
|
_history_substring_search_raw_match_index+=1
|
||||||
local index=${_history_substring_search_raw_matches[$_history_substring_search_raw_match_index]}
|
local index=${_history_substring_search_raw_matches[$_history_substring_search_raw_match_index]}
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -627,7 +640,7 @@ _history-substring-search-up-search() {
|
|||||||
# 1. Move index to point to the next match.
|
# 1. Move index to point to the next match.
|
||||||
# 2. Update display to indicate search found.
|
# 2. Update display to indicate search found.
|
||||||
#
|
#
|
||||||
(( _history_substring_search_match_index++ ))
|
_history_substring_search_match_index+=1
|
||||||
_history-substring-search-found
|
_history-substring-search-found
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -638,7 +651,7 @@ _history-substring-search-up-search() {
|
|||||||
# _history_substring_search_matches.
|
# _history_substring_search_matches.
|
||||||
# 2. Update display to indicate search not found.
|
# 2. Update display to indicate search not found.
|
||||||
#
|
#
|
||||||
(( _history_substring_search_match_index++ ))
|
_history_substring_search_match_index+=1
|
||||||
_history-substring-search-not-found
|
_history-substring-search-not-found
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -707,7 +720,7 @@ _history-substring-search-down-search() {
|
|||||||
# 1. Move index to point to the previous match.
|
# 1. Move index to point to the previous match.
|
||||||
# 2. Update display to indicate search found.
|
# 2. Update display to indicate search found.
|
||||||
#
|
#
|
||||||
(( _history_substring_search_match_index-- ))
|
_history_substring_search_match_index+=-1
|
||||||
_history-substring-search-found
|
_history-substring-search-found
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -718,7 +731,7 @@ _history-substring-search-down-search() {
|
|||||||
# _history_substring_search_matches.
|
# _history_substring_search_matches.
|
||||||
# 2. Update display to indicate search not found.
|
# 2. Update display to indicate search not found.
|
||||||
#
|
#
|
||||||
(( _history_substring_search_match_index-- ))
|
_history_substring_search_match_index+=-1
|
||||||
_history-substring-search-not-found
|
_history-substring-search-not-found
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user