public function complete_application() { $buf = new Buffer(); $buf->appendLines(array("# {$this->programName} zsh completion script generated by CLIFramework", "# Web: http://github.com/c9s/php-CLIFramework", "# THIS IS AN AUTO-GENERATED FILE, PLEASE DON'T MODIFY THIS FILE DIRECTLY.")); $metaName = '_' . $this->programName . 'meta'; $buf->append($this->commandmeta_function()); $buf->appendLines(array("{$this->compName}() {", "local curcontext=\$curcontext state line", "typeset -A opt_args", "local ret=1", $this->complete_with_subcommands($this->app), "return ret", "}", "compdef {$this->compName} {$this->bindName}")); return $buf->__toString(); }
public function complete_application() { $bindName = $this->bindName; $compName = $this->compName; $compPrefix = "__" . $compName; $buf = new Buffer(); $buf->appendLines(array("#!/bin/bash", "# bash completion script generated by CLIFramework", "# Web: http://github.com/c9s/php-CLIFramework", "# THIS IS AN AUTO-GENERATED FILE, PLEASE DON'T MODIFY THIS FILE DIRECTLY.")); $buf->append(' # This function can be used to access a tokenized list of words # on the command line: # # __demo_reassemble_comp_words_by_ref \'=:\' # if test "${words_[cword_-1]}" = -w # then # ... # fi # # The argument should be a collection of characters from the list of # word completion separators (COMP_WORDBREAKS) to treat as ordinary # characters. # # This is roughly equivalent to going back in time and setting # COMP_WORDBREAKS to exclude those characters. The intent is to # make option types like --date=<type> and <rev>:<path> easy to # recognize by treating each shell word as a single token. # # It is best not to set COMP_WORDBREAKS directly because the value is # shared with other completion scripts. By the time the completion # function gets called, COMP_WORDS has already been populated so local # changes to COMP_WORDBREAKS have no effect. # # Output: words_, cword_, cur_. __demo_reassemble_comp_words_by_ref() { local exclude i j first # Which word separators to exclude? exclude="${1//[^$COMP_WORDBREAKS]}" cword_=$COMP_CWORD if [ -z "$exclude" ]; then words_=("${COMP_WORDS[@]}") return fi # List of word completion separators has shrunk; # re-assemble words to complete. for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do # Append each nonempty word consisting of just # word separator characters to the current word. first=t while [ $i -gt 0 ] && [ -n "${COMP_WORDS[$i]}" ] && # word consists of excluded word separators [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] do # Attach to the previous token, # unless the previous token is the command name. if [ $j -ge 2 ] && [ -n "$first" ]; then ((j--)) fi first= words_[$j]=${words_[j]}${COMP_WORDS[i]} if [ $i = $COMP_CWORD ]; then cword_=$j fi if (($i < ${#COMP_WORDS[@]} - 1)); then ((i++)) else # Done. return fi done words_[$j]=${words_[j]}${COMP_WORDS[i]} if [ $i = $COMP_CWORD ]; then cword_=$j fi done } if ! type _get_comp_words_by_ref >/dev/null 2>&1; then _get_comp_words_by_ref () { local exclude cur_ words_ cword_ if [ "$1" = "-n" ]; then exclude=$2 shift 2 fi __demo_reassemble_comp_words_by_ref "$exclude" cur_=${words_[cword_]} while [ $# -gt 0 ]; do case "$1" in cur) cur=$cur_ ;; prev) prev=${words_[$cword_-1]} ;; words) words=("${words_[@]}") ;; cword) cword=$cword_ ;; esac shift done } fi # Generates completion reply, appending a space to possible completion words, # if necessary. # It accepts 1 to 4 arguments: # 1: List of possible completion words. # 2: A prefix to be added to each possible completion word (optional). # 3: Generate possible completion matches for this word (optional). # 4: A suffix to be appended to each possible completion word (optional). __mycomp () { local cur_="${3-$cur}" case "$cur_" in --*=) ;; *) local c i=0 IFS=$\' \\t\\n\' for c in $1; do c="$c${4-}" if [[ $c == "$cur_"* ]]; then case $c in --*=*|*.) ;; *) c="$c " ;; esac COMPREPLY[i++]="${2-}$c" fi done ;; esac } __mycompappend () { local i=${#COMPREPLY[@]} for x in $1; do if [[ "$x" == "$3"* ]]; then COMPREPLY[i++]="$2$x$4" fi done } '); $completeMeta = <<<BASH __complete_meta () { local app="{$this->programName}" local command_signature=\$1 local complete_for=\$2 local arg=\$3 # could be "--dir", 0 for argument index local complete_type=\$4 local IFS=\$' ' # When completing argument valid values, we need to eval lines=(\$(\$app meta --bash --flat \$command_signature \$complete_for \$arg \$complete_type)) # Get the first line to return the compreply # Complete the rest lines as words COMPREPLY=(\$(compgen -W "\${lines[*]:1}" -- \$cur)) } BASH; $buf->append($completeMeta); $this->generateCommandCompletionRecursively($buf, $this->app, $compPrefix); $funcSuffix = command_signature_suffix($this->app); $buf->append("\n{$compPrefix}_main_wrapper()\n{\n {$compPrefix}_complete_{$funcSuffix} \"app\" 0\n}\ncomplete -o bashdefault -o default -o nospace -F {$compPrefix}_main_wrapper {$bindName} 2>/dev/null\n"); return $buf->__toString(); }