summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Schaefer <barts@users.sourceforge.net>2007-02-26 07:43:39 +0000
committerBart Schaefer <barts@users.sourceforge.net>2007-02-26 07:43:39 +0000
commit236d910fb396c76ec351889261c29277af918a2b (patch)
tree9b7725752a9459edbe04c2d125bb788a36926388
parent3fc59a0f09c9ee9af2ed202c50397784bd16efc1 (diff)
downloadzsh-236d910fb396c76ec351889261c29277af918a2b.tar.gz
zsh-236d910fb396c76ec351889261c29277af918a2b.zip
unposted (based on users/10881,10884): add auto-previous zstyle, update
smart-insert-last-word to use auto-suffix-retain, "always" block, etc.
-rw-r--r--Doc/Zsh/contrib.yo5
-rw-r--r--Functions/Zle/smart-insert-last-word71
2 files changed, 55 insertions, 21 deletions
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index f2592c85e..8686e9430 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -1127,6 +1127,11 @@ different widgets to use different patterns:
example(zle -N insert-last-assignment smart-insert-last-word
zstyle :insert-last-assignment match '[[:alpha:]][][[:alnum:]]#=*'
bindkey '\e=' insert-last-assignment)
+
+If no interesting word is found and the tt(auto-previous) style is set to
+a true value, the search continues upward through the history. When
+tt(auto-previous) is unset or false (the default), the widget must be
+invoked repeatedly in order to search earlier history lines.
)
tindex(which-command)
item(tt(which-command))(
diff --git a/Functions/Zle/smart-insert-last-word b/Functions/Zle/smart-insert-last-word
index 380c19954..269bd2808 100644
--- a/Functions/Zle/smart-insert-last-word
+++ b/Functions/Zle/smart-insert-last-word
@@ -2,6 +2,7 @@
# Inspired by Christoph Lange <langec@gmx.de> from zsh-users/3265;
# rewritten to correct multiple-call behavior after zsh-users/3270;
# modified to work with copy-earlier-word after zsh-users/5832.
+# Edited further per zsh-users/10881 and zsh-users/10884.
#
# This function as a ZLE widget can replace insert-last-word, like so:
#
@@ -10,7 +11,7 @@
# With a numeric prefix, behaves like insert-last-word, except that words
# in comments are ignored when interactive_comments is set.
#
-# Otherwise, the rightmost "interesting" word from the previous command is
+# Otherwise, the rightmost "interesting" word from any previous command is
# found and inserted. The default definition of "interesting" is that the
# word contains at least one alphabetic character, slash, or backslash.
# This definition can be overridden by use of a style like so:
@@ -33,9 +34,17 @@
# zle -N insert-last-assignment smart-insert-last-word
# zstyle :insert-last-assignment match '[[:alpha:]][][[:alnum:]]#=*'
# bindkey '\e=' insert-last-assignment
+#
+# The "auto-previous" style, if set to a true value, causes the search to
+# proceed upward through the history until an interesting word is found.
+# If auto-previous is unset or false and there is no interesting word, the
+# last word is returned.
emulate -L zsh
-setopt extendedglob
+setopt extendedglob nohistignoredups
+
+# Begin by preserving completion suffix if any
+zle auto-suffix-retain
# Not strictly necessary:
# (($+_ilw_hist)) || integer -g _ilw_hist _ilw_count _ilw_cursor _ilw_lcursor
@@ -64,27 +73,47 @@ fi
_ilw_hist=$HISTNO
_ilw_count=$NUMERIC
-zle .up-history || return 1 # Retrieve previous command
-lastcmd=( ${${(z)BUFFER}:#\;} ) # Split into shell words
-zle .down-history # Return to current command
-CURSOR=$cursor # Restore cursor position
-NUMERIC=${numeric:-1} # In case of fall through
-
-(( NUMERIC > $#lastcmd )) && return 1
-
if [[ -z "$numeric" ]]
then
- integer i=1
- zstyle -s :$WIDGET match pattern ||
- pattern='*[[:alpha:]/\\]*'
- while ((i <= $#lastcmd)); do
- if [[ $lastcmd[-i] == $~pattern ]]; then
- NUMERIC=$i
- break
- else
- ((++i))
- fi
- done
+ zstyle -s :$WIDGET match pattern || pattern='*[[:alpha:]/\\]*'
fi
+
+# Note that we must use .up-history for navigation here because of
+# possible "holes" in the $history hash (the result of dup expiry).
+# We need $history because $BUFFER retains edits in progress as the
+# user moves around the history, but we search the unedited lines.
+
+{
+ zmodload -i zsh/parameter
+ zle .end-of-history # Start from final command
+ zle .up-history || return 1 # Retrieve previous command
+ local buffer=$history[$HISTNO] # Get unedited history line
+ lastcmd=( ${${(z)buffer}:#\;} ) # Split into shell words
+ if [[ -n "$pattern" ]]
+ then
+ # This is the "smart" part -- search right-to-left and
+ # latest-to-earliest through the history for a word.
+ integer n=0 found=$lastcmd[(I)$pattern]
+ if zstyle -t :$WIDGET auto-previous
+ then
+ while (( found == 0 && ++n ))
+ do
+ zle .up-history || return 1
+ buffer=$history[$HISTNO]
+ lastcmd=( ${${(z)buffer}:#\;} )
+ found=$lastcmd[(I)$pattern]
+ done
+ fi
+ (( found-- > 0 && # Account for 1-based index
+ (numeric = $#lastcmd - found) ))
+ fi
+} always {
+ HISTNO=$_ilw_hist # Return to current command
+ CURSOR=$cursor # Restore cursor position
+ NUMERIC=${numeric:-1} # In case of fall-through
+}
+
+(( NUMERIC > $#lastcmd )) && return 1
+
LBUFFER[lcursor+1,cursor+1]=$lastcmd[-NUMERIC]
_ilw_cursor=$CURSOR