20219: make zle parameter HISTNO writeable

add history-pattern-search widget
This commit is contained in:
Peter Stephenson 2004-07-29 14:21:57 +00:00
parent e1d8ca1d70
commit efe2876d92
7 changed files with 124 additions and 3 deletions

View file

@ -1,5 +1,10 @@
2004-07-29 Peter Stephenson <pws@csr.com>
* 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.

View file

@ -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))(

View file

@ -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))(

View file

@ -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
'

View file

@ -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

View file

@ -715,6 +715,8 @@ void
free_isrch_spots(void)
{
zfree(isrch_spots, max_spot * sizeof(*isrch_spots));
max_spot = 0;
isrch_spots = NULL;
}
/**/

View file

@ -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))