about summary refs log tree commit diff
path: root/Completion/Base/Completer/_approximate
blob: 6e094cd4553c0b5aa3d5a80af7ebf8a929ef8d60 (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
#autoload

# This code will try to correct the string on the line based on the
# strings generated for the context. These corrected strings will be
# shown in a list and one can cycle through them as in a menucompletion
# or get the corrected prefix.

# We don't try correction if the string is too short or we have tried it
# already.

[[ _matcher_num -gt 1 || "${#:-$PREFIX$SUFFIX}" -le 1 ]] && return 1

local _comp_correct _correct_expl comax cfgacc match
local oldcontext="${curcontext}" opm="$compstate[pattern_match]"

if [[ "$1" = -a* ]]; then
  cfgacc="${1[3,-1]}"
elif [[ "$1" = -a ]]; then
  cfgacc="$2"
else
  zstyle -s ":completion:${curcontext}:" max-errors cfgacc ||
      cfgacc='2 numeric'
fi

# Get the number of errors to accept.

if [[ "$cfgacc" = *numeric* && ${NUMERIC:-1} -ne 1 ]]; then
  # A numeric argument may mean that we should not try correction.

  [[ "$cfgacc" = *not-numeric* ]] && return 1

  # Prefer the numeric argument if that has a sensible value.

  comax="${NUMERIC:-1}"
else
  comax="${cfgacc//[^0-9]}"
fi

# If the number of errors to accept is too small, give up.

[[ "$comax" -lt 1 ]] && return 1

_tags corrections original

# Otherwise temporarily define a function to use instead of
# the builtin that adds matches. This is used to be able
# to stick the `(#a...)' in the right place (after an
# ignored prefix).

if (( ! $+functions[compadd] )); then
  compadd() {
    [[ ${argv[(I)-[a-zA-Z]#U[a-zA-Z]#]} -eq 0 &&
       "${#:-$PREFIX$SUFFIX}" -le _comp_correct ]] && return

    ### This distinction doesn't seem to be needed anymore
    # if [[ "$PREFIX" = \~*/* ]]; then
    #   PREFIX="${PREFIX%%/*}/(#a${_comp_correct})${PREFIX#*/}"
    # else
      PREFIX="(#a${_comp_correct})$PREFIX"
    # fi
    builtin compadd "$_correct_expl[@]" "$@"
  }
  trap 'unfunction compadd' EXIT INT
fi

_comp_correct=1

[[ -z "$compstate[pattern_match]" ]] && compstate[pattern_match]='*'

while [[ _comp_correct -le comax ]]; do
  curcontext="${oldcontext/(#b)([^:]#:[^:]#:)/${match[1][1,-2]}-${_comp_correct}:}"

  _description corrections _correct_expl corrections \
               "e:$_comp_correct" "o:$PREFIX$SUFFIX"

  if _complete; then
    if zstyle -t ":completion:${curcontext}:" insert-unambiguous &&
       [[ "${#compstate[unambiguous]}" -ge "${#:-$PREFIX$SUFFIX}" ]]; then
      compstate[pattern_insert]=unambiguous
    elif _requested original &&
         { [[ compstate[nmatches] -gt 1 ]] ||
           zstyle -t ":completion:${curcontext}:" original }; then
      local expl

      _description -V original expl original

      builtin compadd "$expl[@]" -U -Q - "$PREFIX$SUFFIX"

      # If you always want to see the list of possible corrections,
      # set `compstate[list]=list force' here.

      [[ "$compstate[list]" != list* ]] &&
          compstate[list]="$compstate[list] force"
    fi
    compstate[pattern_match]="$opm"

    return 0
  fi

  [[ "${#:-$PREFIX$SUFFIX}" -le _comp_correct+1 ]] && break
  (( _comp_correct++ ))
done

compstate[pattern_match]="$opm"

return 1