about summary refs log tree commit diff
path: root/Completion/Core/_expand
blob: e611dc3e2a6f15a86a0bf314f20239f450d506e1 (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
132
133
134
135
136
137
#autoload

# This completer function is intended to be used as the first completer
# function and allows one to say more explicitly when and how the word
# from the line should be expanded than expand-or-complete.
# This function will allow other completer functions to be called if
# the expansions done produce no result or do not change the original
# word from the line.

local exp word="$PREFIX$SUFFIX" group=-V expl expl2 disp orig menu prompt
local curcontext="${curcontext}" expr descr

[[ "$curcontext" != :correct* ]] && curcontext="${curcontext}:correct"

# First, see if we should insert all *completions*.

if _style -s '' completions expr && [[ "${(e):-\$[$expr]}" -eq 1 ]]; then
  compstate[insert]=all
  return 1
fi

# Do this only for the first global matcher.

[[ "$compstate[matcher]" -le 1 ]] || return 1

# In exp we will collect the expansion.

exp=("$word")

# First try substitution. That weird thing spanning multiple lines
# changes quoted spaces, tabs, and newlines into spaces.

_style -s '' substitute expr && [[ "${(e):-\$[$expr]}" -eq 1 ]] &&
    exp=( "${(e)exp//\\[ 	
]/ }" )

# If the array is empty, store the original string again.

[[ -z "$exp" ]] && exp=("$word")

# Now try globbing.

_style -s '' glob expr && [[ "${(e):-\$[$expr]}" -eq 1 ]] &&
    exp=( ${~exp}(N) )

# If we don't have any expansions or only one and that is the same
# as the original string, we let other completers run.

[[ $#exp -eq 0 ||
   ( $#exp -eq 1 && "$exp[1]" = "$word"(|\(N\)) ) ]] && return 1

# Get the options for adding the original string and `all'-string.

_style -s '' original orig
_style -s '' menu menu
_style -s '' prompt prompt
_style -s descriptions format descr

if [[ "$orig" = *show* ]]; then
  if [[ -n "$descr" ]]; then
    expl=(-X "${descr//\\%d/original}")
  else
    expl=()
  fi
else
  expl=(-n)
fi

if [[ -n "$menu" && "$menu" != *only* && "$menu" = *show-all* ]]; then
  if [[ -n "$descr" ]]; then
    expl2=(-ld disp -X "${descr//\\%d/all words}")
  else
    expl2=(-ld disp )
  fi
  disp=( "$exp" )
  if [[ ${#disp[1]} -gt COLUMNS-5 ]]; then
    disp=( "${disp[1][1,COLUMNS-5]}..." )
  fi
else
  expl2=(-n)
fi

# Quote the results and remove unnecessary quotes before `='s.

    exp=( "${(@)${(@)${(@q)exp}//\\\\=/=}/#=/\\=}" )

# We have expansions, should we menucomplete them?

if [[ -z "$menu" ]]; then

  # No, so if the user only wants a list, we add the strings
  # separately. Otherwise we add the whole array as one string,
  # probably also adding the original string.

  if [[ -z "$compstate[insert]" ]]; then
    compadd -U -V _expand -Q - "$exp[@]"
  else
    [[ -n "$orig" && "$orig" != *last* ]] &&
        compadd "$expl[@]" -UQ -V _expand_original - "$word"

    compadd -UQ -V _expand - "$exp"

    [[ -n "$orig" && "$orig" = *last* ]] &&
        compadd "$expl[@]" -UQ -V _expand_original - "$word"

    compstate[insert]=menu
  fi
else
  # Sorting? We just use a different group type then.

  [[ "$menu" = *sort* ]] && group=-J

  # Now add the expansion string, probably also adding the original
  # and/or the string containing all expanded string.

  [[ -n "$orig" && "$orig" != *last* ]] &&
      compadd "$expl[@]" -UQ -V _expand_original - "$word"

  [[ $#exp -ne 1 && "$menu" = *last* && "$menu" != *only* ]] &&
      compadd "$expl2[@]" -UQ -V _expand_all - "$exp"

  if [[ -z "$prompt" ]]; then
    compadd -UQ $group _expand - "$exp[@]"
  else
    compadd -UQ -X "${prompt//\\%o/$word}" \
            $group _expand - "$exp[@]"
  fi
  [[ $#exp -ne 1 && "$menu" != *last* && "$menu" != *only* ]] &&
      compadd "$expl2[@]" -UQ -V _expand_all - "$exp"

  [[ -n "$orig" && "$orig" = *last* ]] &&
      compadd "$expl[@]" -UQ -V _expand_original - "$word"

  compstate[insert]=menu
fi

return 0