about summary refs log tree commit diff
path: root/Functions/Zle/incremental-complete-word
diff options
context:
space:
mode:
Diffstat (limited to 'Functions/Zle/incremental-complete-word')
-rw-r--r--Functions/Zle/incremental-complete-word186
1 files changed, 107 insertions, 79 deletions
diff --git a/Functions/Zle/incremental-complete-word b/Functions/Zle/incremental-complete-word
index 3831ecaa6..3eaed1a9b 100644
--- a/Functions/Zle/incremental-complete-word
+++ b/Functions/Zle/incremental-complete-word
@@ -1,8 +1,7 @@
-# incremental-complete-word() {
-
 # Autoload this function, run `zle -N <func-name>' and bind <func-name>
 # to a key.
 
+
 # This allows incremental completion of a word.  After starting this
 # command, a list of completion choices can be shown after every character
 # you type, which you can delete with ^h or DEL.  RET will accept the
@@ -23,10 +22,12 @@
 #    such a common prefix, respectively. The sequence `%c' is replaced
 #    by the name of the completer function that generated the matches
 #    (without the leading underscore). Finally, `%n' is replaced by the
-#    number of matches generated and `%a' is replaced by an empty string
+#    number of matches generated, `%a' is replaced by an empty string
 #    if the matches are in the normal set (i.e. the one without file names
 #    with one of the suffixes from `fignore') and with ` -alt-' if the
-#    matches are in the alternate set.
+#    matches are in the alternate set, and if the `incremental_list' key
+#    (see below) is set, `%l' is replaced by `...' if the list of matches
+#    is too long to fit on the screen and with an empty string otherwise.
 #
 #  incremental_stop
 #    Pattern matching keys which will cause icompletion to stop and the
@@ -44,68 +45,37 @@
 #    key-press.
 
 
-emulate -L zsh
-unsetopt autolist menucomplete automenu # doesn't work well
-
-local key lbuf="$LBUFFER" rbuf="$RBUFFER" pmpt word
-local lastl lastr wid twid num alt
-
-[[ -n "$compconfig[incremental_completer]" ]] &&
-    set ${(s.:.)compconfig[incremental_completer]}
-pmpt="${compconfig[incremental_prompt]-incremental (%c): %u%s}"
-
-if [[ -n "$compconfig[incremental_list]" ]]; then
-  wid=list-choices
-else
-  wid=complete-word
-fi
-
-zle $wid "$@"
-LBUFFER="$lbuf"
-RBUFFER="$rbuf"
-if (( ! _lastcomp[nmatches] )); then
-  word=''
-  state='-no match-'
-elif [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
-  word=''
-  state='-no prefix-'
-else
-  word="${_lastcomp[unambiguous]}"
-  state=''
-fi
-num=$_lastcomp[normal_nmatches]
-if (( ! num )); then
-  num="${_lastcomp[nmatches]}"
-  alt=' -alt-'
-fi
-zle -R "${${${${${pmpt//\\%u/$word}//\\%s/$state}//\\%c/${_lastcomp[completer][2,-1]}}//\\%n/$num}//\\%a/$alt}"
-read -k key
-
-while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' &&
-         '#key' -ne '#\\C-g' ]]; do
-  twid=$wid
-  if [[ "$key" = ${~compconfig[incremental_stop]} ]]; then
-    zle -U "$key"
-    return
-  elif [[ "$key" = ${~compconfig[incremental_break]} ]]; then
-    return
-  elif [[ '#key' -eq '#\\C-h' || '#key' -eq '#\\C-?' ]]; then
-    [[ $#LBUFFER -gt $#l ]] && LBUFFER="$LBUFFER[1,-2]"
-  elif [[ '#key' -eq '#\\t' ]]; then
-    zle complete-word "$@"
-    lbuf="$LBUFFER"
-    rbuf="$RBUFFER"
-  elif [[ '#key' -eq '#\\C-d' ]]; then
-    twid=list-choices
+# The main widget function.
+
+incremental-complete-word() {
+  emulate -L zsh
+  unsetopt autolist menucomplete automenu # doesn't work well
+
+  local key lbuf="$LBUFFER" rbuf="$RBUFFER" pmpt word
+  local lastl lastr wid twid num alt post toolong
+
+  [[ -n "$compconfig[incremental_completer]" ]] &&
+      set ${(s.:.)compconfig[incremental_completer]}
+  pmpt="${compconfig[incremental_prompt]-incremental (%c): %u%s  %l}"
+
+  if [[ -n "$compconfig[incremental_list]" ]]; then
+    wid=list-choices
+    post=( icw-list-helper )
   else
-    LBUFFER="$LBUFFER$key"
+    wid=complete-word
+    post=()
+  fi
+
+  comppostfuncs=( "$post[@]" )
+  zle $wid "$@"
+  LBUFFER="$lbuf"
+  RBUFFER="$rbuf"
+  num=$_lastcomp[nmatches]
+  if (( ! num )); then
+    num="${_lastcomp[alternate_nmatches]}"
+    alt=' -alt-'
   fi
-  lastl="$LBUFFER"
-  lastr="$RBUFFER"
-  zle $twid "$@"
-  LBUFFER="$lastl"
-  RBUFFER="$lastr"
-  if (( ! _lastcomp[nmatches] )); then
+  if (( ! num )); then
     word=''
     state='-no match-'
   elif [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
@@ -115,20 +85,78 @@ while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' &&
     word="${_lastcomp[unambiguous]}"
     state=''
   fi
-  num=$_lastcomp[normal_nmatches]
-  if (( ! num )); then
-    num="${_lastcomp[nmatches]}"
-    alt=' -alt-'
-  else
-    alt=''
-  fi
-  zle -R "${${${${${pmpt//\\%u/$word}//\\%s/$state}//\\%c/${_lastcomp[completer][2,-1]}}//\\%n/$num}//\\%a/$alt}"
+  zle -R "${${${${${${pmpt//\\%u/$word}//\\%s/$state}//\\%c/${_lastcomp[completer][2,-1]}}//\\%n/$num}//\\%a/$alt}//\\%l/$toolong}"
   read -k key
-done
 
-if [[ '#key' -eq '#\\C-g' ]]; then
-  LBUFFER="$lbuf"
-  RBUFFER="$rbuf"
-fi
-zle -Rc
-# }
+  while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' &&
+           '#key' -ne '#\\C-g' ]]; do
+    twid=$wid
+    if [[ "$key" = ${~compconfig[incremental_stop]} ]]; then
+      zle -U "$key"
+      return
+    elif [[ "$key" = ${~compconfig[incremental_break]} ]]; then
+      return
+    elif [[ '#key' -eq '#\\C-h' || '#key' -eq '#\\C-?' ]]; then
+      [[ $#LBUFFER -gt $#l ]] && LBUFFER="$LBUFFER[1,-2]"
+    elif [[ '#key' -eq '#\\t' ]]; then
+      zle complete-word "$@"
+      lbuf="$LBUFFER"
+      rbuf="$RBUFFER"
+    elif [[ '#key' -eq '#\\C-d' ]]; then
+      twid=list-choices
+    else
+      LBUFFER="$LBUFFER$key"
+    fi
+    lastl="$LBUFFER"
+    lastr="$RBUFFER"
+    [[ "$twid" = "$wid" ]] && comppostfuncs=( "$post[@]" )
+    toolong=''
+    zle $twid "$@"
+    LBUFFER="$lastl"
+    RBUFFER="$lastr"
+    num=$_lastcomp[nmatches]
+    if (( ! num )); then
+      num="${_lastcomp[alternate_nmatches]}"
+      alt=' -alt-'
+    else
+      alt=''
+    fi
+    if (( ! num )); then
+      word=''
+      state='-no match-'
+    elif [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
+      word=''
+      state='-no prefix-'
+    else
+      word="${_lastcomp[unambiguous]}"
+      state=''
+    fi
+    zle -R "${${${${${${pmpt//\\%u/$word}//\\%s/$state}//\\%c/${_lastcomp[completer][2,-1]}}//\\%n/$num}//\\%a/$alt}//\\%l/$toolong}"
+    read -k key
+  done
+
+  if [[ '#key' -eq '#\\C-g' ]]; then
+    LBUFFER="$lbuf"
+    RBUFFER="$rbuf"
+  fi
+  zle -Rc
+}
+
+# Helper function used as a completion post-function used to make sure that
+# the list of matches in only shown if it fits on the screen.
+
+icw-list-helper() {
+
+  # +1 for the status line we will add...
+
+  if [[ compstate[list_lines]+BUFFERLINES+1 -gt LINES ]]; then
+    compstate[list]='list explanations'
+    if [[ compstate[list_lines]+BUFFERLINES+1 -gt LINES ]]; then
+      compstate[list]=''
+      compstate[force_list]=yes
+    fi
+    toolong='...'
+  fi
+}
+
+incremental-complete-word "$@"