about summary refs log tree commit diff
path: root/Completion/Commands/_next_tags
blob: 6d3389ff16ca085b1d4c5a52376bcdb3f8985bc6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#compdef -k complete-word \C-xn

# Main widget.

_next_tags() {
  local comp

  if [[ -z $compstate[old_list] ]]; then
    comp=()
  else
    comp=(_complete)
  fi

  (( $+_sort_tags )) || _next_tags_not=

  _sort_tags=_next_tags_sort
  _next_tags_pre="${LBUFFER%${PREFIX}}"
  _next_tags_not="$_next_tags_not $_lastcomp[tags]"

  _main_complete "$comp[@]"

  [[ $compstate[insert] = automenu ]] &&
     compstate[insert]=automenu-unambiguous

  compstate[insert]=''
  compstate[list]='list force'

  compprefuncs=( "$compprefuncs[@]" _next_tags_pre )
}

# Pre-completion function.

_next_tags_pre() {

  # 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.

  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 tmp tmp2

  if ! zstyle -a ":completion:${curcontext}:" tag-order order; then
    if (( $+_comp_default_tags )); then
      order=( "$_comp_default_tags[@]" )
    else
      order=( 'arguments values' options )
    fi
  fi

  # But we also remove the tags we've already tried...

  tags=( "${(@)order:#(${(j:|:)~${=_next_tags_not}})}" )

  # ... unless that would remove all offered tags.

  [[ $#tags -ne $#order && "$tags" != *(${(j:|:)~argv})* ]] &&
    tags=( $order ) _next_tags_not=

  for tag in $tags; do
    case $tag in
    -)     nodef=yes;;
    *\(\)) "${${tag%%[ 	]#\(\)}##[ 	]#}" "$@";;
    \!*)   comptry "${(@)argv:#(${(j:|:)~${=~tag[2,-1]}})}";;
    ?*)    tmp=( ${${(s: :)${tag//\\\\ /$'\0'}}//$'\0'/ } ) tmp2=() tmp3=()
           for tag in "$tmp[@]"; do
	     if [[ "$tag" = *:* ]]; then
	       tmp2=( "$tmp2[@]" "${(@M)^argv:#${~tag%%:*}}:${tag#*:}" )
	     else
	       for atag in "${(@M)argv:#${~tag}}"; do
	         if zstyle -a ":completion:${curcontext}:${atag}" tag-aliases als; then
		   tmp3=( "$tmp3[@]" "$als[@]" )
		   tmp=( "${(@)tmp:#${atag}}" )
                 else
	           tmp2=( "$tmp2[@]" "$atag" )
		 fi
	       done
	     fi
	   done

	   comptry "${(@)tmp2:#(${(j:|:)~${(q)tmp%%:*}})}" "$tmp3[@]" "$tmp[@]"
	   ;;
    esac
  done

  if [[ -z "$nodef" ]]; then
    if (( $+_comp_default_tags )); then
      for tag in "$_comp_default_tags[@]"; do
        if zstyle -a ":completion:${curcontext}:${tag}" tag-aliases als; then
          comptry "$als[@]"
        else
          comptry "$tag"
	fi
      done
    else
      tmp2=()
      for tag; do
	if zstyle -a ":completion:${curcontext}:${tag}" tag-aliases als; then
	  tmp2=( "$tmp2[@]" "$als[@]" )
        else
	  tmp2=( "$tmp2[@]" "$tag" )
	fi
      done
      comptry "$tmp2[@]"
    fi
  fi
}

[[ -o kshautoload ]] || _next_tags "$@"