"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/dashdash/etc/dashdash.bash_completion.in" (8 Mar 2017, 14407 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Bash source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 #!/bin/bash
    2 #
    3 # Bash completion generated for '{{name}}' at {{date}}.
    4 #
    5 # The original template lives here:
    6 # https://github.com/trentm/node-dashdash/blob/master/etc/dashdash.bash_completion.in
    7 #
    8 
    9 #
   10 # Copyright 2016 Trent Mick
   11 # Copyright 2016 Joyent, Inc.
   12 #
   13 #
   14 # A generic Bash completion driver script.
   15 #
   16 # This is meant to provide a re-usable chunk of Bash to use for
   17 # "etc/bash_completion.d/" files for individual tools. Only the "Configuration"
   18 # section with tool-specific info need differ. Features:
   19 #
   20 # - support for short and long opts
   21 # - support for knowing which options take arguments
   22 # - support for subcommands (e.g. 'git log <TAB>' to show just options for the
   23 #   log subcommand)
   24 # - does the right thing with "--" to stop options
   25 # - custom optarg and arg types for custom completions
   26 # - (TODO) support for shells other than Bash (tcsh, zsh, fish?, etc.)
   27 #
   28 #
   29 # Examples/design:
   30 #
   31 # 1. Bash "default" completion. By default Bash's 'complete -o default' is
   32 #    enabled. That means when there are no completions (e.g. if no opts match
   33 #    the current word), then you'll get Bash's default completion. Most notably
   34 #    that means you get filename completion. E.g.:
   35 #       $ tool ./<TAB>
   36 #       $ tool READ<TAB>
   37 #
   38 # 2. all opts and subcmds:
   39 #       $ tool <TAB>
   40 #       $ tool -v <TAB>     # assuming '-v' doesn't take an arg
   41 #       $ tool -<TAB>       # matching opts
   42 #       $ git lo<TAB>       # matching subcmds
   43 #
   44 #    Long opt completions are given *without* the '=', i.e. we prefer space
   45 #    separated because that's easier for good completions.
   46 #
   47 # 3. long opt arg with '='
   48 #       $ tool --file=<TAB>
   49 #       $ tool --file=./d<TAB>
   50 #    We maintain the "--file=" prefix. Limitation: With the attached prefix
   51 #    the 'complete -o filenames' doesn't know to do dirname '/' suffixing. Meh.
   52 #
   53 # 4. envvars:
   54 #       $ tool $<TAB>
   55 #       $ tool $P<TAB>
   56 #    Limitation: Currently only getting exported vars, so we miss "PS1" and
   57 #    others.
   58 #
   59 # 5. Defer to other completion in a subshell:
   60 #       $ tool --file $(cat ./<TAB>
   61 #    We get this from 'complete -o default ...'.
   62 #
   63 # 6. Custom completion types from a provided bash function.
   64 #       $ tool --profile <TAB>        # complete available "profiles"
   65 #
   66 #
   67 # Dev Notes:
   68 # - compgen notes, from http://unix.stackexchange.com/questions/151118/understand-compgen-builtin-command
   69 # - https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html
   70 #
   71 
   72 
   73 # Debugging this completion:
   74 #   1. Uncomment the "_{{name}}_log_file=..." line.
   75 #   2. 'tail -f /var/tmp/dashdash-completion.log' in one terminal.
   76 #   3. Re-source this bash completion file.
   77 #_{{name}}_log=/var/tmp/dashdash-completion.log
   78 
   79 function _{{name}}_completer {
   80 
   81     # ---- cmd definition
   82 
   83     {{spec}}
   84 
   85 
   86     # ---- locals
   87 
   88     declare -a argv
   89 
   90 
   91     # ---- support functions
   92 
   93     function trace {
   94         [[ -n "$_{{name}}_log" ]] && echo "$*" >&2
   95     }
   96 
   97     function _dashdash_complete {
   98         local idx context
   99         idx=$1
  100         context=$2
  101 
  102         local shortopts longopts optargs subcmds allsubcmds argtypes
  103         shortopts="$(eval "echo \${cmd${context}_shortopts}")"
  104         longopts="$(eval "echo \${cmd${context}_longopts}")"
  105         optargs="$(eval "echo \${cmd${context}_optargs}")"
  106         subcmds="$(eval "echo \${cmd${context}_subcmds}")"
  107         allsubcmds="$(eval "echo \${cmd${context}_allsubcmds}")"
  108         IFS=', ' read -r -a argtypes <<< "$(eval "echo \${cmd${context}_argtypes}")"
  109 
  110         trace ""
  111         trace "_dashdash_complete(idx=$idx, context=$context)"
  112         trace "  shortopts: $shortopts"
  113         trace "  longopts: $longopts"
  114         trace "  optargs: $optargs"
  115         trace "  subcmds: $subcmds"
  116         trace "  allsubcmds: $allsubcmds"
  117 
  118         # Get 'state' of option parsing at this COMP_POINT.
  119         # Copying "dashdash.js#parse()" behaviour here.
  120         local state=
  121         local nargs=0
  122         local i=$idx
  123         local argtype
  124         local optname
  125         local prefix
  126         local word
  127         local dashdashseen=
  128         while [[ $i -lt $len && $i -le $COMP_CWORD ]]; do
  129             argtype=
  130             optname=
  131             prefix=
  132             word=
  133 
  134             arg=${argv[$i]}
  135             trace "  consider argv[$i]: '$arg'"
  136 
  137             if [[ "$arg" == "--" && $i -lt $COMP_CWORD ]]; then
  138                 trace "    dashdash seen"
  139                 dashdashseen=yes
  140                 state=arg
  141                 word=$arg
  142             elif [[ -z "$dashdashseen" && "${arg:0:2}" == "--" ]]; then
  143                 arg=${arg:2}
  144                 if [[ "$arg" == *"="* ]]; then
  145                     optname=${arg%%=*}
  146                     val=${arg##*=}
  147                     trace "    long opt: optname='$optname' val='$val'"
  148                     state=arg
  149                     argtype=$(echo "$optargs" | awk -F "-$optname=" '{print $2}' | cut -d' ' -f1)
  150                     word=$val
  151                     prefix="--$optname="
  152                 else
  153                     optname=$arg
  154                     val=
  155                     trace "    long opt: optname='$optname'"
  156                     state=longopt
  157                     word=--$optname
  158 
  159                     if [[ "$optargs" == *"-$optname="* && $i -lt $COMP_CWORD ]]; then
  160                         i=$(( $i + 1 ))
  161                         state=arg
  162                         argtype=$(echo "$optargs" | awk -F "-$optname=" '{print $2}' | cut -d' ' -f1)
  163                         word=${argv[$i]}
  164                         trace "    takes arg (consume argv[$i], word='$word')"
  165                     fi
  166                 fi
  167             elif [[ -z "$dashdashseen" && "${arg:0:1}" == "-" ]]; then
  168                 trace "    short opt group"
  169                 state=shortopt
  170                 word=$arg
  171 
  172                 local j=1
  173                 while [[ $j -lt ${#arg} ]]; do
  174                     optname=${arg:$j:1}
  175                     trace "    consider index $j: optname '$optname'"
  176 
  177                     if [[ "$optargs" == *"-$optname="* ]]; then
  178                         argtype=$(echo "$optargs" | awk -F "-$optname=" '{print $2}' | cut -d' ' -f1)
  179                         if [[ $(( $j + 1 )) -lt ${#arg} ]]; then
  180                             state=arg
  181                             word=${arg:$(( $j + 1 ))}
  182                             trace "      takes arg (rest of this arg, word='$word', argtype='$argtype')"
  183                         elif [[ $i -lt $COMP_CWORD ]]; then
  184                             state=arg
  185                             i=$(( $i + 1 ))
  186                             word=${argv[$i]}
  187                             trace "    takes arg (word='$word', argtype='$argtype')"
  188                         fi
  189                         break
  190                     fi
  191 
  192                     j=$(( $j + 1 ))
  193                 done
  194             elif [[ $i -lt $COMP_CWORD && -n "$arg" ]] && $(echo "$allsubcmds" | grep -w "$arg" >/dev/null); then
  195                 trace "    complete subcmd: recurse _dashdash_complete"
  196                 _dashdash_complete $(( $i + 1 )) "${context}__${arg/-/_}"
  197                 return
  198             else
  199                 trace "    not an opt or a complete subcmd"
  200                 state=arg
  201                 word=$arg
  202                 nargs=$(( $nargs + 1 ))
  203                 if [[ ${#argtypes[@]} -gt 0 ]]; then
  204                     argtype="${argtypes[$(( $nargs - 1 ))]}"
  205                     if [[ -z "$argtype" ]]; then
  206                         # If we have more args than argtypes, we use the
  207                         # last type.
  208                         argtype="${argtypes[@]: -1:1}"
  209                     fi
  210                 fi
  211             fi
  212 
  213             trace "    state=$state prefix='$prefix' word='$word'"
  214             i=$(( $i + 1 ))
  215         done
  216 
  217         trace "  parsed: state=$state optname='$optname' argtype='$argtype' prefix='$prefix' word='$word' dashdashseen=$dashdashseen"
  218         local compgen_opts=
  219         if [[ -n "$prefix" ]]; then
  220             compgen_opts="$compgen_opts -P $prefix"
  221         fi
  222 
  223         case $state in
  224         shortopt)
  225             compgen $compgen_opts -W "$shortopts $longopts" -- "$word"
  226             ;;
  227         longopt)
  228             compgen $compgen_opts -W "$longopts" -- "$word"
  229             ;;
  230         arg)
  231             # If we don't know what completion to do, then emit nothing. We
  232             # expect that we are running with:
  233             #       complete -o default ...
  234             # where "default" means: "Use Readline's default completion if
  235             # the compspec generates no matches." This gives us the good filename
  236             # completion, completion in subshells/backticks.
  237             #
  238             # We cannot support an argtype="directory" because
  239             #       compgen -S '/' -A directory -- "$word"
  240             # doesn't give a satisfying result. It doesn't stop at the trailing '/'
  241             # so you cannot descend into dirs.
  242             if [[ "${word:0:1}" == '$' ]]; then
  243                 # By default, Bash will complete '$<TAB>' to all envvars. Apparently
  244                 # 'complete -o default' does *not* give us that. The following
  245                 # gets *close* to the same completions: '-A export' misses envvars
  246                 # like "PS1".
  247                 trace "  completing envvars"
  248                 compgen $compgen_opts -P '$' -A export -- "${word:1}"
  249             elif [[ -z "$argtype" ]]; then
  250                 # Only include opts in completions if $word is not empty.
  251                 # This is to avoid completing the leading '-', which foils
  252                 # using 'default' completion.
  253                 if [[ -n "$dashdashseen" ]]; then
  254                     trace "  completing subcmds, if any (no argtype, dashdash seen)"
  255                     compgen $compgen_opts -W "$subcmds" -- "$word"
  256                 elif [[ -z "$word" ]]; then
  257                     trace "  completing subcmds, if any (no argtype, empty word)"
  258                     compgen $compgen_opts -W "$subcmds" -- "$word"
  259                 else
  260                     trace "  completing opts & subcmds (no argtype)"
  261                     compgen $compgen_opts -W "$shortopts $longopts $subcmds" -- "$word"
  262                 fi
  263             elif [[ $argtype == "none" ]]; then
  264                 # We want *no* completions, i.e. some way to get the active
  265                 # 'complete -o default' to not do filename completion.
  266                 trace "  completing 'none' (hack to imply no completions)"
  267                 echo "##-no-completion- -results-##"
  268             elif [[ $argtype == "file" ]]; then
  269                 # 'complete -o default' gives the best filename completion, at least
  270                 # on Mac.
  271                 trace "  completing 'file' (let 'complete -o default' handle it)"
  272                 echo ""
  273             elif ! type complete_$argtype 2>/dev/null >/dev/null; then
  274                 trace "  completing '$argtype' (fallback to default b/c complete_$argtype is unknown)"
  275                 echo ""
  276             else
  277                 trace "  completing custom '$argtype'"
  278                 completions=$(complete_$argtype "$word")
  279                 if [[ -z "$completions" ]]; then
  280                     trace "  no custom '$argtype' completions"
  281                     # These are in ascii and "dictionary" order so they sort
  282                     # correctly.
  283                     echo "##-no-completion- -results-##"
  284                 else
  285                     echo $completions
  286                 fi
  287             fi
  288             ;;
  289         *)
  290             trace "  unknown state: $state"
  291             ;;
  292         esac
  293     }
  294 
  295 
  296     trace ""
  297     trace "-- $(date)"
  298     #trace "\$IFS: '$IFS'"
  299     #trace "\$@: '$@'"
  300     #trace "COMP_WORDBREAKS: '$COMP_WORDBREAKS'"
  301     trace "COMP_CWORD: '$COMP_CWORD'"
  302     trace "COMP_LINE: '$COMP_LINE'"
  303     trace "COMP_POINT: $COMP_POINT"
  304 
  305     # Guard against negative COMP_CWORD. This is a Bash bug at least on
  306     # Mac 10.10.4's bash. See
  307     # <https://lists.gnu.org/archive/html/bug-bash/2009-07/msg00125.html>.
  308     if [[ $COMP_CWORD -lt 0 ]]; then
  309         trace "abort on negative COMP_CWORD"
  310         exit 1;
  311     fi
  312 
  313     # I don't know how to do array manip on argv vars,
  314     # so copy over to argv array to work on them.
  315     shift   # the leading '--'
  316     i=0
  317     len=$#
  318     while [[ $# -gt 0 ]]; do
  319         argv[$i]=$1
  320         shift;
  321         i=$(( $i + 1 ))
  322     done
  323     trace "argv: '${argv[@]}'"
  324     trace "argv[COMP_CWORD-1]: '${argv[$(( $COMP_CWORD - 1 ))]}'"
  325     trace "argv[COMP_CWORD]: '${argv[$COMP_CWORD]}'"
  326     trace "argv len: '$len'"
  327 
  328     _dashdash_complete 1 ""
  329 }
  330 
  331 
  332 # ---- mainline
  333 
  334 # Note: This if-block to help work with 'compdef' and 'compctl' is
  335 # adapted from 'npm completion'.
  336 if type complete &>/dev/null; then
  337     function _{{name}}_completion {
  338         local _log_file=/dev/null
  339         [[ -z "$_{{name}}_log" ]] || _log_file="$_{{name}}_log"
  340         COMPREPLY=($(COMP_CWORD="$COMP_CWORD" \
  341             COMP_LINE="$COMP_LINE" \
  342             COMP_POINT="$COMP_POINT" \
  343             _{{name}}_completer -- "${COMP_WORDS[@]}" \
  344             2>$_log_file)) || return $?
  345     }
  346     complete -o default -F _{{name}}_completion {{name}}
  347 elif type compdef &>/dev/null; then
  348     function _{{name}}_completion {
  349         local _log_file=/dev/null
  350         [[ -z "$_{{name}}_log" ]] || _log_file="$_{{name}}_log"
  351         compadd -- $(COMP_CWORD=$((CURRENT-1)) \
  352             COMP_LINE=$BUFFER \
  353             COMP_POINT=0 \
  354             _{{name}}_completer -- "${words[@]}" \
  355             2>$_log_file)
  356     }
  357     compdef _{{name}}_completion {{name}}
  358 elif type compctl &>/dev/null; then
  359     function _{{name}}_completion {
  360         local cword line point words si
  361         read -Ac words
  362         read -cn cword
  363         let cword-=1
  364         read -l line
  365         read -ln point
  366         local _log_file=/dev/null
  367         [[ -z "$_{{name}}_log" ]] || _log_file="$_{{name}}_log"
  368         reply=($(COMP_CWORD="$cword" \
  369             COMP_LINE="$line" \
  370             COMP_POINT="$point" \
  371             _{{name}}_completer -- "${words[@]}" \
  372             2>$_log_file)) || return $?
  373     }
  374     compctl -K _{{name}}_completion {{name}}
  375 fi
  376 
  377 
  378 ##
  379 ## This is a Bash completion file for the '{{name}}' command. You can install
  380 ## with either:
  381 ##
  382 ##     cp FILE /usr/local/etc/bash_completion.d/{{name}}   # Mac
  383 ##     cp FILE /etc/bash_completion.d/{{name}}             # Linux
  384 ##
  385 ## or:
  386 ##
  387 ##     cp FILE > ~/.{{name}}.completion
  388 ##     echo "source ~/.{{name}}.completion" >> ~/.bashrc
  389 ##