about summary refs log tree commit diff
path: root/Functions
diff options
context:
space:
mode:
authorPaul Ackersviller <packersv@users.sourceforge.net>2007-11-11 23:11:38 +0000
committerPaul Ackersviller <packersv@users.sourceforge.net>2007-11-11 23:11:38 +0000
commitc68317f5ebd65552dd2c5450b6f45f99ed3ce75c (patch)
tree7b1043ac777c5b1456bbb62b50eb77d91c002abb /Functions
parentfc20475e595028fc77d2f395b9ae000ff1617d3a (diff)
downloadzsh-c68317f5ebd65552dd2c5450b6f45f99ed3ce75c.tar.gz
zsh-c68317f5ebd65552dd2c5450b6f45f99ed3ce75c.tar.xz
zsh-c68317f5ebd65552dd2c5450b6f45f99ed3ce75c.zip
Merge of unposted (based on users/10881,10884): add auto-previous zstyle, update
smart-insert-last-word to use auto-suffix-retain, "always" block, etc.
plus users/11424: don't embed a comment inside a math expression.
Diffstat (limited to 'Functions')
-rw-r--r--Functions/Zle/smart-insert-last-word119
1 files changed, 119 insertions, 0 deletions
diff --git a/Functions/Zle/smart-insert-last-word b/Functions/Zle/smart-insert-last-word
new file mode 100644
index 000000000..27b0849ee
--- /dev/null
+++ b/Functions/Zle/smart-insert-last-word
@@ -0,0 +1,119 @@
+# smart-insert-last-word
+# 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:
+#
+#   zle -N insert-last-word smart-insert-last-word
+#
+# 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 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:
+#
+#   zstyle :insert-last-word match '*[[:alpha:]/\\]*'
+#
+# For example, you might want to include words that contain spaces:
+#
+#   zstyle :insert-last-word match '*[[:alpha:][:space:]/\\]*'
+#
+# Or include numbers as long as the word is at least two characters long:
+#
+#   zstyle :insert-last-word match '*([[:digit:]]?|[[:alpha:]/\\])*'
+#
+# That causes redirections like "2>" to be included.
+#
+# Note also that the style is looked up based on the widget name, so you
+# can bind this function to different widgets to use different patterns:
+#
+#   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 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
+
+integer cursor=$CURSOR lcursor=$CURSOR
+local lastcmd pattern numeric=$NUMERIC
+
+# Save state for repeated calls
+if (( HISTNO == _ilw_hist && cursor == _ilw_cursor )); then
+    NUMERIC=$[_ilw_count+1]
+    lcursor=$_ilw_lcursor
+else
+    NUMERIC=1
+    _ilw_lcursor=$lcursor
+fi
+# Handle the up to three arguments of .insert-last-word
+if (( $+1 )); then
+    if (( $+3 )); then
+	((NUMERIC = -($1)))
+    else
+	((NUMERIC = _ilw_count - $1))
+    fi
+    (( NUMERIC )) || LBUFFER[lcursor+1,cursor+1]=''
+    numeric=$((-(${2:--numeric})))
+fi
+_ilw_hist=$HISTNO
+_ilw_count=$NUMERIC
+
+if [[ -z "$numeric" ]]
+then
+    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
+      # The following accounts for 1-based index
+      (( found-- > 0 && (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