File: builder_completion.inc.sh

package info (click to toggle)
keyman 18.0.246-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 21,316 kB
  • sloc: python: 52,784; cpp: 21,289; sh: 7,633; ansic: 4,823; xml: 3,617; perl: 959; makefile: 139; javascript: 138
file content (129 lines) | stat: -rwxr-xr-x 4,537 bytes parent folder | download | duplicates (2)
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
# As this script must be sourced by shells to be useful, no practical #shebang is possible.

# Note:  must 'source' this file again in the terminal after any edits!
_comp_builder() {
  # Does the file actually exist?  If not, abort.
  local CMD_PATH=`readlink -f "$1"`
  if [ -z "${CMD_PATH}" ]; then
    exit 0
  fi

  # Detect - is this a keyman repo?  If not, exit early; we don't expect repo-external compatibility.
  local CMD_DIR="$(dirname "${CMD_PATH}")"
  cd "${CMD_DIR}"
  # Works correctly even if the directory has no backing repository.
  git remote get-url origin | grep -q 'github.com/keymanapp' || exit 0

  # Some of the configuration differs when ZSH is the OS's primary terminal; this flag
  # may be used to tailor this function accordingly.
  local IS_ZSH=false
  if [ "${SHELL##*/}" = "zsh" ]; then
    IS_ZSH=true
  fi

  # Warning - zsh uses -A, not -a, for array-read operations!
  # This is 'sourced' by the shell profile script, so macOS zsh terminal
  # usage must be aware of this and adapt.
  local READ_ARRAY="-a"
  if [ $IS_ZSH = true ]; then
    READ_ARRAY="-A"
  fi

  # Is it actually a builder-script?  If not, abort.  If so, it defines
  # a special option used to provide us with completion-target data.
  local builder_params=`${CMD_PATH} --builder-completion-describe` || exit 0

  local BASE_NAME=$(basename "$CMD_PATH")
  local BUILDER_ARG_STR="${COMP_LINE##*${BASE_NAME} }"

  local builder_args
  # Does not actually preserve an empty token at the end.
  read -r $READ_ARRAY builder_args <<< "${BUILDER_ARG_STR}"

  # Determine the current token (given the caret position) and
  # all existing, already-completed actions, targets, and options
  # for the script before the current token.
  local current_token=
  # If the caret is adjacent to non-whitespace - thus is editing
  # a builder argument...
  if [ ! -z "${COMP_WORDS[COMP_CWORD]}" ]; then
    # Then note the last token as the token being edited...
    current_token="${builder_args[-1]}"
    # ... and thus not pre-completed.
    unset builder_args[-1]
  fi

  # Parse the builder-description for completion target data.
  local action_str target_str option_str
  IFS=";" read -r action_str target_str option_str <<< "$builder_params"
  local actions targets options
  IFS=" " read -r $READ_ARRAY actions <<< "$action_str"
  IFS=" " read -r $READ_ARRAY targets <<< "$target_str"
  IFS=" " read -r $READ_ARRAY options <<< "$option_str"

  local action target
  if [[ $current_token =~ : ]]; then
    IFS=: read -r action target <<< "$current_token"
    target=:$target
  else
    action="$current_token"
    target=
  fi

  local all=()
  # If there is no $action component, it's a standalone target.

  if [[ -z "$action" ]] && [[ -z "$target" ]]; then
    all+="${actions[@]}"
    all+=" ${targets[@]}"
    all+=" ${options[@]}"

    COMPREPLY=( $(compgen -W "${all[@]}" -- "${current_token}") )
  elif [[ -z "$action" ]]; then
    # It's an unpaired target.
    all="${targets[@]}"
    COMPREPLY=( $(compgen -W "${all[@]}" -- "${current_token}") )

    if [ $IS_ZSH == false ]; then
      # bash doesn't handle completion with colons well; we should remove the
      # colon prefix from each entry.  ZSH actually doesn't have this issue.
      local i
      for (( i=0; i<${#COMPREPLY[@]}; i++ )); do
        COMPREPLY[$i]="${COMPREPLY[$i]##*:}"
      done
    fi
  elif [[ -z "$target" ]]; then
    # It's an untargeted action or an option.
    all+="${actions[@]}"
    all+=" ${options[@]}"

    COMPREPLY=( $(compgen -W "${all[@]}" -- "${current_token}") )
  else
    # Ah, an action-target pair.  We have an existing action, so we only need to
    # complete the target part.

    # First, build up the list of legal paired tokens.
    local actiontargets=()
    for e in "${targets[@]}"; do
      actiontargets+=("${action}${e}")
    done

    # Now, complete from that.
    all+="${actiontargets[@]}"
    COMPREPLY=( $(compgen -W "${all[@]}" -- "${current_token}") )

    if [ $IS_ZSH == false ]; then
      # bash doesn't handle completion with colons well; we should remove the
      # colon prefix from each entry.  ZSH actually doesn't have this issue.
      local i
      for (( i=0; i<${#COMPREPLY[@]}; i++ )); do
        COMPREPLY[$i]="${COMPREPLY[$i]##*:}"
      done
    fi
  fi
}

# When this script is sourced by .bashrc or similar, this provides autocompletion for
# builder scripts named build.sh and test.sh.
complete  -o bashdefault -F _comp_builder build.sh
complete  -o bashdefault -F _comp_builder test.sh