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-word187
1 files changed, 111 insertions, 76 deletions
diff --git a/Functions/Zle/incremental-complete-word b/Functions/Zle/incremental-complete-word
index 2a9c1aff2..e021bf6f7 100644
--- a/Functions/Zle/incremental-complete-word
+++ b/Functions/Zle/incremental-complete-word
@@ -1,89 +1,124 @@
-# 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 is shown after every character you
-# type, which you can delete with ^h or DEL.  RET will accept the
-# completion so far.  You can hit TAB to do normal completion and ^g to
-# abort back to the state when you started.
+# 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
+# completion so far.  You can hit TAB to do normal completion, ^g to
+# abort back to the state when you started, and ^d to list the matches.
 #
-# Completion keys:
-#   incremental_prompt   Prompt to show in status line during icompletion;
-#                        the sequence `%u' is replaced by the unambiguous
-#                        part of all matches if there is any and it is
-#                        different from the word on the line
-# incremental_stop       Pattern matching keys which will cause icompletion
-#                         to stop and the key to be re-executed
-# incremental_break      Pattern matching keys which will cause icompletion
-#                         to stop and the key to be discarded
-# incremental_completer  Set of completers, like the `completer' key
-#   incremental_list     If set to a non-empty string, the matches will be
-#                        listed on every key-press
-
-emulate -L zsh
-unsetopt autolist menucomplete automenu # doesn't work well
-
-local key lbuf="$LBUFFER" rbuf="$RBUFFER" pmpt word lastl lastr wid twid
-
-[[ -n "$compconfig[incremental_completer]" ]] &&
-set ${(s.:.)compconfig[incremental_completer]}
-pmpt="${compconfig[incremental_prompt]-incremental completion...}"
-
-if [[ -n "$compconfig[incremental_list]" ]]; then
-  wid=list-choices
-else
-  wid=complete-word
-fi
-
-zle $wid "$@"
-LBUFFER="$lbuf"
-RBUFFER="$rbuf"
-if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
-  word=''
-else
-  word="${_lastcomp[unambiguous]}"
-fi
-zle -R "${pmpt//\\%u/$word}"
-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
+# This works only with the new function based completion system.
+
+# 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 pstr word
+  local lastl lastr wid twid num post toolong
+  local curcontext="${curcontext}" stop brk
+
+  [[ -z "$curcontext" ]] && curcontext=:::
+  curcontext="incremental:${curcontext#*:}"
+
+  zstyle -s ":completion:${curcontext}" prompt pmpt ||
+    pmpt='incremental (%c): %u%s  %l'
+  zstyle -s ":completion:${curcontext}" stop stop
+  zstyle -s ":completion:${curcontext}" break brk
+
+  if zstyle -t ":completion:${curcontext}" list; then
+    wid=list-choices
+    post=( icw-list-helper )
   else
-    LBUFFER="$LBUFFER$key"
+    wid=complete-word
+    post=()
   fi
-  lastl="$LBUFFER"
-  lastr="$RBUFFER"
-  zle $twid "$@"
-  LBUFFER="$lastl"
-  RBUFFER="$lastr"
-  if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
+
+  comppostfuncs=( "$post[@]" )
+  zle $wid "$@"
+  LBUFFER="$lbuf"
+  RBUFFER="$rbuf"
+  num=$_lastcomp[nmatches]
+  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}"
+  zformat -f pstr "$pmpt" "u:${word}" "s:$state" "n:$num" \
+                          "l:$toolong" "c:${_lastcomp[completer][2,-1]}"
+  zle -R "$pstr"
   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" = ${~stop} ]]; then
+      zle -U "$key"
+      return
+    elif [[ "$key" = ${~brk} ]]; 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
+      word=''
+      state='-no match-'
+    elif [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
+      word=''
+      state='-no prefix-'
+    else
+      word="${_lastcomp[unambiguous]}"
+      state=''
+    fi
+    zformat -f pstr "$pmpt" "u:${word}" "s:$state" "n:$num" \
+                            "l:$toolong" "c:${_lastcomp[completer][2,-1]}"
+    zle -R "$pstr"
+    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'
+    [[ compstate[list_lines]+BUFFERLINES+1 -gt LINES ]] && compstate[list]=''
+
+    toolong='...'
+  fi
+}
+
+incremental-complete-word "$@"