git-bug

  1# fish completion for git-bug                              -*- shell-script -*-
  2
  3function __git_bug_debug
  4    set file "$BASH_COMP_DEBUG_FILE"
  5    if test -n "$file"
  6        echo "$argv" >> $file
  7    end
  8end
  9
 10function __git_bug_perform_completion
 11    __git_bug_debug "Starting __git_bug_perform_completion with: $argv"
 12
 13    set args (string split -- " " "$argv")
 14    set lastArg "$args[-1]"
 15
 16    __git_bug_debug "args: $args"
 17    __git_bug_debug "last arg: $lastArg"
 18
 19    set emptyArg ""
 20    if test -z "$lastArg"
 21        __git_bug_debug "Setting emptyArg"
 22        set emptyArg \"\"
 23    end
 24    __git_bug_debug "emptyArg: $emptyArg"
 25
 26    if not type -q "$args[1]"
 27        # This can happen when "complete --do-complete git-bug" is called when running this script.
 28        __git_bug_debug "Cannot find $args[1]. No completions."
 29        return
 30    end
 31
 32    set requestComp "$args[1] __complete $args[2..-1] $emptyArg"
 33    __git_bug_debug "Calling $requestComp"
 34
 35    set results (eval $requestComp 2> /dev/null)
 36    set comps $results[1..-2]
 37    set directiveLine $results[-1]
 38
 39    # For Fish, when completing a flag with an = (e.g., <program> -n=<TAB>)
 40    # completions must be prefixed with the flag
 41    set flagPrefix (string match -r -- '-.*=' "$lastArg")
 42
 43    __git_bug_debug "Comps: $comps"
 44    __git_bug_debug "DirectiveLine: $directiveLine"
 45    __git_bug_debug "flagPrefix: $flagPrefix"
 46
 47    for comp in $comps
 48        printf "%s%s\n" "$flagPrefix" "$comp"
 49    end
 50
 51    printf "%s\n" "$directiveLine"
 52end
 53
 54# This function does three things:
 55# 1- Obtain the completions and store them in the global __git_bug_comp_results
 56# 2- Set the __git_bug_comp_do_file_comp flag if file completion should be performed
 57#    and unset it otherwise
 58# 3- Return true if the completion results are not empty
 59function __git_bug_prepare_completions
 60    # Start fresh
 61    set --erase __git_bug_comp_do_file_comp
 62    set --erase __git_bug_comp_results
 63
 64    # Check if the command-line is already provided.  This is useful for testing.
 65    if not set --query __git_bug_comp_commandLine
 66        # Use the -c flag to allow for completion in the middle of the line
 67        set __git_bug_comp_commandLine (commandline -c)
 68    end
 69    __git_bug_debug "commandLine is: $__git_bug_comp_commandLine"
 70
 71    set results (__git_bug_perform_completion "$__git_bug_comp_commandLine")
 72    set --erase __git_bug_comp_commandLine
 73    __git_bug_debug "Completion results: $results"
 74
 75    if test -z "$results"
 76        __git_bug_debug "No completion, probably due to a failure"
 77        # Might as well do file completion, in case it helps
 78        set --global __git_bug_comp_do_file_comp 1
 79        return 1
 80    end
 81
 82    set directive (string sub --start 2 $results[-1])
 83    set --global __git_bug_comp_results $results[1..-2]
 84
 85    __git_bug_debug "Completions are: $__git_bug_comp_results"
 86    __git_bug_debug "Directive is: $directive"
 87
 88    set shellCompDirectiveError 1
 89    set shellCompDirectiveNoSpace 2
 90    set shellCompDirectiveNoFileComp 4
 91    set shellCompDirectiveFilterFileExt 8
 92    set shellCompDirectiveFilterDirs 16
 93
 94    if test -z "$directive"
 95        set directive 0
 96    end
 97
 98    set compErr (math (math --scale 0 $directive / $shellCompDirectiveError) % 2)
 99    if test $compErr -eq 1
100        __git_bug_debug "Received error directive: aborting."
101        # Might as well do file completion, in case it helps
102        set --global __git_bug_comp_do_file_comp 1
103        return 1
104    end
105
106    set filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) % 2)
107    set dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) % 2)
108    if test $filefilter -eq 1; or test $dirfilter -eq 1
109        __git_bug_debug "File extension filtering or directory filtering not supported"
110        # Do full file completion instead
111        set --global __git_bug_comp_do_file_comp 1
112        return 1
113    end
114
115    set nospace (math (math --scale 0 $directive / $shellCompDirectiveNoSpace) % 2)
116    set nofiles (math (math --scale 0 $directive / $shellCompDirectiveNoFileComp) % 2)
117
118    __git_bug_debug "nospace: $nospace, nofiles: $nofiles"
119
120    # Important not to quote the variable for count to work
121    set numComps (count $__git_bug_comp_results)
122    __git_bug_debug "numComps: $numComps"
123
124    if test $numComps -eq 1; and test $nospace -ne 0
125        # To support the "nospace" directive we trick the shell
126        # by outputting an extra, longer completion.
127        __git_bug_debug "Adding second completion to perform nospace directive"
128        set --append __git_bug_comp_results $__git_bug_comp_results[1].
129    end
130
131    if test $numComps -eq 0; and test $nofiles -eq 0
132        __git_bug_debug "Requesting file completion"
133        set --global __git_bug_comp_do_file_comp 1
134    end
135
136    # If we don't want file completion, we must return true even if there
137    # are no completions found.  This is because fish will perform the last
138    # completion command, even if its condition is false, if no other
139    # completion command was triggered
140    return (not set --query __git_bug_comp_do_file_comp)
141end
142
143# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves
144# so we can properly delete any completions provided by another script.
145# The space after the the program name is essential to trigger completion for the program
146# and not completion of the program name itself.
147complete --do-complete "git-bug " > /dev/null 2>&1
148# Using '> /dev/null 2>&1' since '&>' is not supported in older versions of fish.
149
150# Remove any pre-existing completions for the program since we will be handling all of them.
151complete -c git-bug -e
152
153# The order in which the below two lines are defined is very important so that __git_bug_prepare_completions
154# is called first.  It is __git_bug_prepare_completions that sets up the __git_bug_comp_do_file_comp variable.
155#
156# This completion will be run second as complete commands are added FILO.
157# It triggers file completion choices when __git_bug_comp_do_file_comp is set.
158complete -c git-bug -n 'set --query __git_bug_comp_do_file_comp'
159
160# This completion will be run first as complete commands are added FILO.
161# The call to __git_bug_prepare_completions will setup both __git_bug_comp_results and __git_bug_comp_do_file_comp.
162# It provides the program's completion choices.
163complete -c git-bug -n '__git_bug_prepare_completions' -f -a '$__git_bug_comp_results'
164