about summary refs log tree commit diff
path: root/Completion/Commands
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Commands')
-rw-r--r--Completion/Commands/_complete_help73
-rw-r--r--Completion/Commands/_history_complete_word107
-rw-r--r--Completion/Commands/_next_tags86
3 files changed, 218 insertions, 48 deletions
diff --git a/Completion/Commands/_complete_help b/Completion/Commands/_complete_help
index cfefdcf90..cfc922df5 100644
--- a/Completion/Commands/_complete_help
+++ b/Completion/Commands/_complete_help
@@ -1,35 +1,80 @@
 #compdef -k complete-word \C-xh
 
 _complete_help() {
-  local _sort_tags=_help_sort_tags text i
-  typeset -A help_tags
-  typeset -U help_contexts
-
-  help_contexts=()
+  local _sort_tags=_help_sort_tags text i j k
+  typeset -A help_funcs help_tags help_sfuncs help_styles
 
   compadd() { return 1 }
+  zstyle() {
+    local _f="${${(@)${(@)funcstack[2,(i)_(main_complete|complete|approximate|normal)]}:#_(wanted|requested|loop|try)}% *}"
+
+    [[ -z "$_f" ]] && _f="${${(@)funcstack[2,(i)_(main_complete|complete|approximate|normal)]}:#_(wanted|requested|loop|try)}"
+
+    if [[ "$help_sfuncs[$2]" != *${_f}* ||
+          "$help_styles[${2}${_f}]" != *${3}* ]]; then
+      [[ "$help_sfuncs[$2]" != *${_f}* ]] &&
+          help_sfuncs[$2]="${help_sfuncs[$2]}:${_f}"
+      local _t
+
+      case "$1" in
+      -s) _t='[string] ';;
+      -a) _t='[array]  ';;
+      -h) _t='[assoc]  ';;
+      *)  _t='[boolean]';;
+      esac
+      help_styles[${2}${_f}]="${help_styles[${2}${_f}]},${_t} ${3}:${_f}"
+    fi
+    builtin zstyle "$@"
+  }
 
   _main_complete
 
-  unfunction compadd
+  unfunction compadd zstyle
 
-  for i in "$help_contexts[@]"; do
+  for i in "${(@ok)help_funcs}"; do
     text="${text}
-tags in context \`${i}': ${help_tags[$i]}"
+tags in context :completion:${i}:"
+    tmp=()
+    for j in "${(@s.:.)help_funcs[$i][2,-1]}"; do
+      tmp=( "$tmp[@]" "${(@s.,.)help_tags[${i}${j}][2,-1]}" )
+    done
+    zformat -a tmp '  (' "$tmp[@]"
+    tmp=( '
+    '${^tmp}')' )
+    text="${text}${tmp}"
   done
 
-  compstate[list]=list
-  compstate[force_list]=yes
+  text="$text
+"
+  for i in "${(@ok)help_sfuncs}"; do
+    text="${text}
+styles in context ${i}"
+    tmp=()
+    for j in "${(@s.:.)help_sfuncs[$i][2,-1]}"; do
+      tmp=( "$tmp[@]" "${(@s.,.)help_styles[${i}${j}][2,-1]}" )
+    done
+    zformat -a tmp '  (' "$tmp[@]"
+    tmp=( '
+    '${^tmp}')' )
+    text="${text}${tmp}"
+  done
+
+  compstate[list]='list force'
   compstate[insert]=''
 
   compadd -UX "$text[2,-1]" -n ''
 }
 
 _help_sort_tags() {
-  help_contexts=( "$help_contexts[@]" "$curcontext" )
-  help_tags[$curcontext]="${help_tags[$curcontext]}
-    ${argv}"
-  comptry "$@"
+  local f="${${(@)${(@)funcstack[3,(i)_(main_complete|complete|approximate|normal)]}:#_(wanted|requested|loop|try)}% *}"
+
+  if [[ "$help_funcs[$curcontext]" != *${f}* ||
+        "$help_tags[${curcontext}${f}]" != *(${(j:|:)~argv})* ]]; then
+    [[ "$help_funcs[$curcontext]" != *${f}* ]] &&
+        help_funcs[$curcontext]="${help_funcs[$curcontext]}:${f}"
+    help_tags[${curcontext}${f}]="${help_tags[${curcontext}${f}]},${argv}:${f}"
+    comptry "$@"
+  fi
 }
 
 _complete_help "$@"
diff --git a/Completion/Commands/_history_complete_word b/Completion/Commands/_history_complete_word
index fc67c0f14..d904e01f1 100644
--- a/Completion/Commands/_history_complete_word
+++ b/Completion/Commands/_history_complete_word
@@ -1,2 +1,105 @@
-#compdef -k complete-word \e/
-compgen -Q -H 0 ''
+#compdef -K _history-complete-older complete-word \e/ _history-complete-newer complete-word \e,
+#
+# Complete words from the history
+#
+# by Adam Spiers, with help gratefully received from
+# Sven Wischnowsky and Bart Schaefer
+#
+# Available styles:
+#
+#   :history-words:list -- display lists of available matches
+#   :history-words:stop -- prevent looping at beginning and end of matches
+#                          during menu-completion
+#   :history-words:sort -- sort matches lexically (default is to sort by age)
+#   :history-words:remove-all-dups --
+#                          remove /all/ duplicate matches rather than just
+#                          consecutives
+#
+
+_history_complete_word () {
+  local expl direction stop
+
+  if [[ $WIDGET = *newer ]]; then
+    direction=newer
+  else
+    direction=older
+  fi
+
+  zstyle -s ":completion:${curcontext}:history-words" stop stop
+
+  zstyle -t ":completion:${curcontext}:history-words" list || compstate[list]=''
+
+  if [[ -n "$compstate[old_list]" &&
+        ( -n "$stop" || "$compstate[insert]" = menu ) ]] ; then
+    # array of matches is newest -> oldest (reverse of history order)
+    if [[ "$direction" == 'older' ]]; then
+      if [[ compstate[old_insert] -eq $_hist_menu_length ||
+            "$_hist_stop" == 'oldest' ]]; then
+        _hist_stop='oldest'
+        [[ "$stop" = verbose ]] &&
+          _message 'beginning of history reached'
+      elif [[ "$_hist_stop" == 'newest' ]]; then
+        zle -Rc
+        _history_complete_word_gen_matches
+      else
+        compstate[old_list]=keep
+        (( compstate[insert] = compstate[old_insert] + 1 ))
+      fi
+    elif [[ "$direction" == 'newer' ]]; then
+      if [[ compstate[old_insert] -eq 1 || "$_hist_stop" == 'newest' ]]; then
+        _hist_stop='newest'
+        [[ "$stop" = verbose ]] && _message 'end of history reached'
+      elif [[ "$_hist_stop" == 'oldest' ]]; then
+        zle -Rc
+        _history_complete_word_gen_matches
+      else
+        compstate[old_list]=keep
+        (( compstate[insert] = compstate[old_insert] - 1 ))
+      fi
+    fi
+  else
+    _hist_stop=''
+    _hist_old_prefix="$PREFIX"
+    _history_complete_word_gen_matches
+  fi
+
+  [[ -n "$compstate[nmatches]" ]]
+}
+
+_history_complete_word_gen_matches () {
+  local opt
+
+  [[ -n "$_hist_stop" ]] && PREFIX="$_hist_old_prefix"
+
+  if zstyle -t ":completion:${curcontext}:history-words" remove-all-dups; then
+    opt=-
+  else
+    opt=-1
+  fi
+  if zstyle -t ":completion:${curcontext}:history-words" sort; then
+    opt="${opt}J"
+  else
+    opt="${opt}V"
+  fi
+
+  _wanted "$opt" history-words expl 'history word' \
+      compadd -Q - "$historywords[@]"
+
+  zstyle -t ":completion:${curcontext}:history-words" list ||
+      compstate[list]=
+
+  _hist_menu_length="$compstate[nmatches]"
+
+  case "$direction" in 
+    newer)  compstate[insert]=$_hist_menu_length
+	    [[ -n "$_hist_stop" ]] && (( compstate[insert]-- ))
+            ;;
+    older)  compstate[insert]=1
+	    [[ -n "$_hist_stop" ]] && (( compstate[insert]++ ))
+            ;;
+  esac
+
+  [[ -n "$_hist_stop" ]] && _hist_stop=''
+}
+
+_history_complete_word "$@"
diff --git a/Completion/Commands/_next_tags b/Completion/Commands/_next_tags
index 8bd3f5921..4861d1adf 100644
--- a/Completion/Commands/_next_tags
+++ b/Completion/Commands/_next_tags
@@ -1,70 +1,92 @@
 #compdef -k complete-word \C-xn
 
-# Main widget/completer.
+# Main widget.
 
 _next_tags() {
+  local comp
 
-  if [[ $#funcstack -gt 1 ]]; then
+  if [[ -z $compstate[old_list] ]]; then
+    comp=()
+  else
+    comp=(_complete)
+  fi
 
-    # Called as completer, probably `remove' our helper function. A better
-    # test would be nice, but I think one should still be able to edit the
-    # current word between attempts to complete it.
+  (( $+_sort_tags )) || _next_tags_not=
 
-    [[ $_next_tags_pre != ${LBUFFER%${PREFIX}} ]] && unset _sort_tags
+  _sort_tags=_next_tags_sort
+  _next_tags_pre="${LBUFFER%${PREFIX}}"
+  _next_tags_not="$_next_tags_not $_lastcomp[tags]"
 
-    return 1
-  else
-    local comp
+  _main_complete "$comp[@]"
 
-    if [[ -z $compstate[old_list] ]]; then
-      comp=()
-    else
-      comp=(_next_tags _complete)
-    fi
+  [[ $compstate[insert] = automenu ]] &&
+     compstate[insert]=automenu-unambiguous
+
+  compstate[insert]=''
+  compstate[list]='list force'
 
-    (( $+_sort_tags )) || _next_tags_not=
+  compprefuncs=( "$compprefuncs[@]" _next_tags_pre )
+}
 
-    _sort_tags=_next_tags_sort
-    _next_tags_pre="${LBUFFER%${PREFIX}}"
-    _next_tags_not="$_next_tags_not $_lastcomp[tags]"
+# Pre-completion function.
 
-    _main_complete "$comp[@]"
+_next_tags_pre() {
 
-    [[ $compstate[insert] = automenu ]] &&
-       compstate[insert]=automenu-unambiguous
+  # Probably `remove' our sort function. A better test would be nice, but
+  # I think one should still be able to edit the current word between
+  # attempts to complete it.
 
-    compstate[insert]=''
-    compstate[list]='list force'
+  if [[ $_next_tags_pre != ${LBUFFER%${PREFIX}} ]]; then
+    unset _sort_tags
+  else
+    compprefuncs=( "$compprefuncs[@]" _next_tags_pre )
   fi
 }
 
 # Helper function for sorting tags. Most of this is copied from _tags.
 
 _next_tags_sort() {
-  local order tags tag nodef
+  local order tags tag nodef tmp
 
   zstyle -a ":completion:${curcontext}:" tag-order order ||
-    order=( 'arguments values' options globbed-files directories all-files )
+      order=('arguments values' options)
 
   # But we also remove the tags we've already tried...
 
-  tags=( "${(@)order:#(${(j:|:)~${=_next_tags_not}})}" )
+  tags=( "${(@)order:#(${(j:|:)~${=_next_tags_not}})(|:*)}" )
 
   # ... unless that would remove all offered tags.
 
-  [[ $#tags -ne $#order && "$tags" != *(${(j:|:)~argv})* ]] &&
-    tags=( $order ) _next_tags_not=
-
+  if [[ $funcstack[4] = _files ]]; then
+    if zstyle -a ":completion:${curcontext}:" file-patterns tmp; then
+      [[ "$tags" = *${${tmp[-1]##[^\\]:}%:*}* ]] &&
+          tags=( $order ) _next_tags_not=
+    else
+      [[ "$tags" = *all-files* ]] && tags=( $order ) _next_tags_not=
+    fi
+  else
+     [[ $#tags -ne $#order && "$tags" != *(${(j:|:)~argv})* ]] &&
+        tags=( $order ) _next_tags_not=
+  fi
   for tag in $tags; do
     case $tag in
     -)     nodef=yes;;
     *\(\)) "${${tag%%[ 	]#\(\)}##[ 	]#}" "$@";;
-    \!*)   comptry "${(@)argv:#(${(j:|:)~${=tag[2,-1]}})}";;
-    ?*)    comptry ${=tag};;
+    \!*)   comptry "${(@)argv:#(${(j:|:)~${=~tag[2,-1]}})}";;
+    ?*)    comptry -m "$tag";;
     esac
   done
 
-  [[ -z "$nodef" ]] && comptry "$@"
+  if [[ -z "$nodef" ]]; then
+    if [[ $funcstack[4] = _files ]]; then
+      if zstyle -a ":completion:${curcontext}:" file-patterns tmp; then
+        [[ "$argv" = *${${tmp[-1]##[^\\]:}%:*}* ]] && _next_tags_not=
+      else
+        [[ "$argv" = *all-files* ]] && _next_tags_not=
+      fi
+    fi
+    comptry "${(@)argv:#(${(j:|:)~${=_next_tags_not}})(|:*)}"
+  fi
 }
 
 [[ -o kshautoload ]] || _next_tags "$@"