From efe2876d927b5d028031a6023b622be44c5d5b8a Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 29 Jul 2004 14:21:57 +0000 Subject: 20219: make zle parameter HISTNO writeable add history-pattern-search widget --- ChangeLog | 5 +++ Doc/Zsh/contrib.yo | 19 +++++++++ Doc/Zsh/zle.yo | 5 ++- Functions/Zle/.distfiles | 2 +- Functions/Zle/history-pattern-search | 81 ++++++++++++++++++++++++++++++++++++ Src/Zle/zle_hist.c | 2 + Src/Zle/zle_params.c | 13 +++++- 7 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 Functions/Zle/history-pattern-search diff --git a/ChangeLog b/ChangeLog index b9dfe083c..26fa66509 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2004-07-29 Peter Stephenson + * 20219: Doc/Zsh/contrib.yo, Doc/Zsh/zle.yo, + Functions/Zle/.distfiles, Functions/Zle/history-pattern-search, + Src/Zle/zle_hist.c, Src/Zle/zle_params.c: make zle parameter + HISTNO writeable, add history-pattern-search sample to use it. + * 20208: Src/prompt.c, Doc/Zsh/prompt.yo: ternary code character C etc. treat / as path with zero elements. diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index d205cce93..71867be2e 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -591,6 +591,25 @@ zle -N history-beginning-search-forward-end \ bindkey '\e^P' history-beginning-search-backward-end bindkey '\e^N' history-beginning-search-forward-end) ) +tindex(history-pattern-search) +tindex(history-pattern-search-backward) +tindex(history-pattern-search-forward) +item(tt(history-pattern-search))( +The function tt(history-pattern-search) implements widgets which prompt +for a pattern with which to search the history backwards or forwards. The +pattern is in the usual zsh format, however the first character may be +tt(^) to anchor the search to the start of the line, and the last character +may be tt($) to anchor the search to the end of the line. If the +search was not anchored to the end of the line the cursor is positioned +just after the pattern found. + +The commands to create bindable widgets are similar to those in the +example immediately above: + +example(autoload -U history-pattern-search +zle -N history-pattern-search-backward history-pattern-search +zle -N history-pattern-search-forward history-pattern-search) +) tindex(up-line-or-beginning-search) tindex(down-line-or-beginning-search) item(tt(up-line-or-beginning-search), tt(down-line-or-beginning-search))( diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index f2067d14f..fe6ef04a6 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -634,7 +634,10 @@ string which the next yank would insert in the line. ) vindex(HISTNO) item(tt(HISTNO) (integer))( -The current history number; read-only. +The current history number. Setting this has the same effect as +moving up or down in the history to the corresponding history line. +An attempt to set it is ignored if the line is not stored in the +history. ) vindex(KEYMAP) item(tt(KEYMAP) (scalar))( diff --git a/Functions/Zle/.distfiles b/Functions/Zle/.distfiles index 4b2da07a1..b00da2f41 100644 --- a/Functions/Zle/.distfiles +++ b/Functions/Zle/.distfiles @@ -13,5 +13,5 @@ down-case-word-match forward-word-match kill-word-match match-words-by-style select-word-style transpose-words-match up-case-word-match delete-whole-word-match quote-and-complete-word url-quote-magic -zed-set-file-name +zed-set-file-name history-pattern-search ' 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 diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c index 70d8699c0..c6fb7acdb 100644 --- a/Src/Zle/zle_hist.c +++ b/Src/Zle/zle_hist.c @@ -715,6 +715,8 @@ void free_isrch_spots(void) { zfree(isrch_spots, max_spot * sizeof(*isrch_spots)); + max_spot = 0; + isrch_spots = NULL; } /**/ diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c index f2eaea723..f0f1cde95 100644 --- a/Src/Zle/zle_params.c +++ b/Src/Zle/zle_params.c @@ -75,7 +75,7 @@ static struct zleparam { zleunsetfn, NULL }, { "NUMERIC", PM_INTEGER | PM_UNSET, FN(set_numeric), FN(get_numeric), unset_numeric, NULL }, - { "HISTNO", PM_INTEGER | PM_READONLY, NULL, FN(get_histno), + { "HISTNO", PM_INTEGER, FN(set_histno), FN(get_histno), zleunsetfn, NULL }, { "BUFFERLINES", PM_INTEGER | PM_READONLY, NULL, FN(get_bufferlines), zleunsetfn, NULL }, @@ -325,6 +325,17 @@ unset_numeric(Param pm, int exp) } } +/**/ +static void +set_histno(UNUSED(Param pm), zlong x) +{ + Histent he; + + if (!(he = quietgethist((int)x))) + return; + zle_setline(he); +} + /**/ static zlong get_histno(UNUSED(Param pm)) -- cgit 1.4.1