summary refs log tree commit diff
path: root/Completion/Zsh/Context/_subscript
blob: 0c9a89ad5dc794721a906b3253ea1f10cc34536e (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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#compdef -subscript-

local expl ind osuf=']' flags sep

if [[ "$1" = -q ]]; then
  compquote osuf
  osuf+=' '
  shift
fi

compset -P '\(([^\(\)]|\(*\))##\)' # remove subscript flags

# Look for a dynamic name expansion.  Completion only gives us
# the stuff inside the square brackets; we need to find out what's
# outside.  We ought to check for quoting, really, but given we've
# got to the subscript code " ~[" is pretty likely to be a dynamic
# name expansion.  Also expand in anything that looks like an assignment
# or colon list.
integer pos=$((CURSOR+1))
while [[ pos -gt 1 && $BUFFER[pos-1] != '[' ]]; do (( pos-- )); done
if [[ $BUFFER[1,pos-1] = (|*[[:space:]:=]##)\~\[ ]]; then
  _dynamic_directory_name
elif [[ "$PREFIX" = :* ]]; then
  _wanted characters expl 'character class' \
      compadd -p: -S ':]' alnum alpha ascii blank cntrl digit graph \
      lower print punct space upper xdigit IFS IDENT IFSSPACE WORD
elif compset -P '\('; then
  local match
  compset -S '\)*'

  if [[ $PREFIX = (#b)*([bns])(?|)(*) ]]; then
    local f=$match[1] d=$match[2] e=$match[2] v=$match[3]
    [[ $f = s && ${(Pt)${compstate[parameter]}} != scalar* ]] && return 1
    if [[ -z $d ]]; then
      _message -e delimiters 'delimiter'
      return
    else
      case $d in
      (\() e=\);;
      (\[) e=\];;
      (\{) e=\};;
      esac
      if [[ $v != *$e* ]]; then
	case $f in
	(s) _message 'separator string';;
	(b|n) [[ $v = <-># ]] && _message 'number' || return 1;;
	esac
	[[ -n $v && $SUFFIX$ISUFFIX != *$e* ]] && _message 'delimiter'
	return 0
      fi
    fi
  fi

  case ${(Pt)${compstate[parameter]}} in
    assoc*) flags=(
      '(R k K i I)r[any one value matched by subscript as pattern]'
      '(r k K i I)R[all values matched by subscript as pattern]'
      '(r R K i I)k[any one value where subscript matched by key as pattern]'
      '(r R k i I)K[all values where subscript matched by key as pattern]'
      '(r R k K I)i[any one key matched by subscript as pattern]'
      '(r R k K i)I[all keys matched by subscript as pattern]'
      'e[interpret * or @ as a single key]'
    );;
    (|scalar*)) flags=(
      'f[make subscripting work on lines of scalar]'
      'w[make subscripting work on words of scalar]'
      's[specify word separator]'
      'p[recognise escape sequences in subsequent s flag]'
    );&
    array*) flags=($flags
      'e[interpret * or @ as a single key and use plain string matching]'
      'n[Nth lowest/highest index with i/I/r/R flag]'
      'b[begin with specified element]'
      '(r R k K i)I[highest index of value matched by subscript]'
      '(r R k K I)i[lowest index of value matched by subscript]'
      '(r k K i I)R[value matched by subscript at highest index]'
      '(R k K i I)r[value matched by subscript at lowest index]'
    );;
  esac

  _values -s '' 'subscript flags' $flags
elif [[ ${(Pt)${compstate[parameter]}} = assoc* ]]; then
  local suf MATCH MBEGIN MEND
  local -a keys
  keys=("${(@)${(@k)${(P)compstate[parameter]}}//(#m)[\$\\\[\]\(\)\{\}]/\\$MATCH}")
  keys=("${(@)keys//#%(#m)[*@]/(e)$MATCH}")
  [[ "$RBUFFER" != (|\\)\]* ]] && suf="$osuf"

  _wanted association-keys expl 'association key' \
      compadd -Q -S "$suf" -a keys
elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then
  local list i j ret=1 disp

  _tags indexes parameters

  while _tags; do
    if _requested indexes; then
      ind=( {1..${#${(P)${compstate[parameter]}}}} )
      if zstyle -T ":completion:${curcontext}:indexes" verbose; then
        list=()
        for i in "$ind[@]"; do
          if [[ "$i" = ${PREFIX}*${SUFFIX} ]]; then
              list+=( "${i}:$(print -D -- ${(P)${compstate[parameter]}[$i]})" )
	  else
	      list+=( '' )
	  fi
        done
        zstyle -s ":completion:${curcontext}:indexes" list-separator sep || sep=--
        zformat -a list " $sep " "$list[@]"
	disp=( -d list)
      else
        disp=()
      fi

      if [[ "$RBUFFER" = (|\\)\]* ]]; then
        _all_labels -V indexes expl 'array index' \
            compadd -S '' "$disp[@]" -a ind && ret=0
      else
        _all_labels -V indexes expl 'array index' \
            compadd -S "$osuf" "$disp[@]" -a ind && ret=0
      fi
    fi
    _requested parameters && _parameters && ret=0

    (( ret )) || return 0
  done

  return 1
else
  _dispatch -math- -math-
fi