diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2004-07-29 14:21:57 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2004-07-29 14:21:57 +0000 |
commit | efe2876d927b5d028031a6023b622be44c5d5b8a (patch) | |
tree | b2bf41f0a9d4d29850b748948d04706dbde8b566 /Functions/Zle/history-pattern-search | |
parent | e1d8ca1d70053e44c3e4950ceafe3f07e6e67d0d (diff) | |
download | zsh-efe2876d927b5d028031a6023b622be44c5d5b8a.tar.gz zsh-efe2876d927b5d028031a6023b622be44c5d5b8a.tar.xz zsh-efe2876d927b5d028031a6023b622be44c5d5b8a.zip |
20219: make zle parameter HISTNO writeable
add history-pattern-search widget
Diffstat (limited to 'Functions/Zle/history-pattern-search')
-rw-r--r-- | Functions/Zle/history-pattern-search | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/Functions/Zle/history-pattern-search b/Functions/Zle/history-pattern-search new file mode 100644 index 000000000..02f85a2fb --- /dev/null +++ b/Functions/Zle/history-pattern-search @@ -0,0 +1,81 @@ +# Prompt for an search in the history for a pattern. +# Patterns to search are standard zsh patterns, but may include +# ^ at the start or $ at the end to anchor the pattern to the +# start or end of the history entry respectively. +# +# To search backwards, create a widget history-pattern-search-backward: +# zle -N history-pattern-search-backward history-pattern-search +# and to search forwards, create history-pattern-search-forward +# zle -N history-pattern-search-forward history-pattern-search + +# Use extended globbing by default. +emulate -L zsh +setopt extendedglob + +# Load required features. +autoload -U read-from-minibuffer +zmodload -i zsh/parameter + +local REPLY dir new +integer i +local -a found match mbegin mend + +# Decide if we are searching backwards or forwards. +if [[ $WIDGET = *forward* ]]; then + dir="forw" +else + dir="rev" +fi + +# Read pattern. Prompt could be made customisable. +read-from-minibuffer "pat ($dir): " + +# Abort if bad status or nothing entered +[[ $? -ne 0 || -z $REPLY ]] && return 0 + +# Handle start-of-line anchor. +if [[ $REPLY = \^* ]]; then + REPLY=$REPLY[2,-1] +else + REPLY="*$REPLY" +fi + +# Handle end-of-line anchor. +if [[ $REPLY = *\$ ]]; then + REPLY=$REPLY[1,-2] +else + REPLY="$REPLY*" +fi + +# Search history for pattern. +# As $history is an associative array we can get all matches. +found=(${(kon)history[(R)$REPLY]}) + +if [[ $dir = forw ]]; then + # Searching forward. Look back through matches until we + # get back to the current history number. + for (( i = ${#found}; i >= 1; i-- )); do + (( $found[$i] <= HISTNO )) && break + new=$found[$i] + done +else + # Searching backward. Look forward through matches until we + # reach the current history number. + for (( i = 1; i <= ${#found}; i++ )); do + (( $found[$i] >= HISTNO )) && break + new=$found[$i] + done +fi + +if [[ -n $new ]]; then + # Match found. Move to line. + HISTNO=$new + if [[ $REPLY = *\* && $history[$new] = (#b)(${~REPLY[1,-2]})* ]]; then + # If not anchored to the end, move to the end of the pattern + # we were searching for. + CURSOR=$mend[1] + fi + return 0 +else + return 1 +fi |