Skip to content

Commit 5b64990

Browse files
committed
Fix fish for ShellDirectiveNoSpace and file comp
For fish shell we achieve ShellDirectiveNoSpace by outputing a fake second completion with an extra character. However, this extra character was being added after the description string, instead of before. This commit fixes that. It also cleans up the script of useless code, now that fish completion details are better understood. Signed-off-by: Marc Khouzam <[email protected]>
1 parent b97b5ea commit 5b64990

File tree

1 file changed

+54
-49
lines changed

1 file changed

+54
-49
lines changed

fish_completions.go

Lines changed: 54 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ function __%[1]s_debug
2828
end
2929
3030
function __%[1]s_perform_completion
31-
__%[1]s_debug "Starting __%[1]s_perform_completion with: $argv"
31+
__%[1]s_debug "Starting __%[1]s_perform_completion"
3232
33-
set args (string split -- " " "$argv")
33+
set args (string split -- " " (commandline -c))
3434
set lastArg "$args[-1]"
3535
3636
__%[1]s_debug "args: $args"
@@ -71,31 +71,22 @@ function __%[1]s_perform_completion
7171
printf "%%s\n" "$directiveLine"
7272
end
7373
74-
# This function does three things:
75-
# 1- Obtain the completions and store them in the global __%[1]s_comp_results
76-
# 2- Set the __%[1]s_comp_do_file_comp flag if file completion should be performed
77-
# and unset it otherwise
78-
# 3- Return true if the completion results are not empty
74+
# This function does two things:
75+
# - Obtain the completions and store them in the global __%[1]s_comp_results
76+
# - Return false if file completion should be performed
7977
function __%[1]s_prepare_completions
78+
__%[1]s_debug ""
79+
__%[1]s_debug "========= starting completion logic =========="
80+
8081
# Start fresh
81-
set --erase __%[1]s_comp_do_file_comp
8282
set --erase __%[1]s_comp_results
8383
84-
# Check if the command-line is already provided. This is useful for testing.
85-
if not set --query __%[1]s_comp_commandLine
86-
# Use the -c flag to allow for completion in the middle of the line
87-
set __%[1]s_comp_commandLine (commandline -c)
88-
end
89-
__%[1]s_debug "commandLine is: $__%[1]s_comp_commandLine"
90-
91-
set results (__%[1]s_perform_completion "$__%[1]s_comp_commandLine")
92-
set --erase __%[1]s_comp_commandLine
84+
set results (__%[1]s_perform_completion)
9385
__%[1]s_debug "Completion results: $results"
9486
9587
if test -z "$results"
9688
__%[1]s_debug "No completion, probably due to a failure"
9789
# Might as well do file completion, in case it helps
98-
set --global __%[1]s_comp_do_file_comp 1
9990
return 1
10091
end
10192
@@ -119,7 +110,6 @@ function __%[1]s_prepare_completions
119110
if test $compErr -eq 1
120111
__%[1]s_debug "Received error directive: aborting."
121112
# Might as well do file completion, in case it helps
122-
set --global __%[1]s_comp_do_file_comp 1
123113
return 1
124114
end
125115
@@ -128,7 +118,6 @@ function __%[1]s_prepare_completions
128118
if test $filefilter -eq 1; or test $dirfilter -eq 1
129119
__%[1]s_debug "File extension filtering or directory filtering not supported"
130120
# Do full file completion instead
131-
set --global __%[1]s_comp_do_file_comp 1
132121
return 1
133122
end
134123
@@ -137,27 +126,51 @@ function __%[1]s_prepare_completions
137126
138127
__%[1]s_debug "nospace: $nospace, nofiles: $nofiles"
139128
140-
# Important not to quote the variable for count to work
141-
set numComps (count $__%[1]s_comp_results)
142-
__%[1]s_debug "numComps: $numComps"
143-
144-
if test $numComps -eq 1; and test $nospace -ne 0
145-
# To support the "nospace" directive we trick the shell
146-
# by outputting an extra, longer completion.
147-
__%[1]s_debug "Adding second completion to perform nospace directive"
148-
set --append __%[1]s_comp_results $__%[1]s_comp_results[1].
129+
# If we want to prevent a space, or if file completion is NOT disabled,
130+
# we need to count the number of valid completions.
131+
# To do so, we will filter on prefix as the completions we have received
132+
# may not already be filtered so as to allow fish to match on different
133+
# criteria than prefix.
134+
if test $nospace -ne 0; or test $nofiles -eq 0
135+
set prefix (commandline -t)
136+
__%[1]s_debug "prefix: $prefix"
137+
138+
set completions
139+
for comp in $__%[1]s_comp_results
140+
if test (string match -e -r "^$prefix" "$comp")
141+
set -a completions $comp
142+
end
143+
end
144+
set --global __%[1]s_comp_results $completions
145+
__%[1]s_debug "Filtered completions are: $__%[1]s_comp_results"
146+
147+
# Important not to quote the variable for count to work
148+
set numComps (count $__%[1]s_comp_results)
149+
__%[1]s_debug "numComps: $numComps"
150+
151+
if test $numComps -eq 1; and test $nospace -ne 0
152+
# To support the "nospace" directive we trick the shell
153+
# by outputting an extra, longer completion.
154+
# We must first split on \t to get rid of the descriptions because
155+
# the extra character we add to the fake second completion must be
156+
# before the description. We don't need descriptions anyway since
157+
# there is only a single real completion which the shell will expand
158+
# immediately.
159+
__%[1]s_debug "Adding second completion to perform nospace directive"
160+
set split (string split --max 1 \t $__%[1]s_comp_results[1])
161+
set --global __%[1]s_comp_results $split[1] $split[1].
162+
__%[1]s_debug "Completions are now: $__%[1]s_comp_results"
163+
end
164+
165+
if test $numComps -eq 0; and test $nofiles -eq 0
166+
# To be consistent with bash and zsh, we only trigger file
167+
# completion when there are no other completions
168+
__%[1]s_debug "Requesting file completion"
169+
return 1
170+
end
149171
end
150172
151-
if test $numComps -eq 0; and test $nofiles -eq 0
152-
__%[1]s_debug "Requesting file completion"
153-
set --global __%[1]s_comp_do_file_comp 1
154-
end
155-
156-
# If we don't want file completion, we must return true even if there
157-
# are no completions found. This is because fish will perform the last
158-
# completion command, even if its condition is false, if no other
159-
# completion command was triggered
160-
return (not set --query __%[1]s_comp_do_file_comp)
173+
return 0
161174
end
162175
163176
# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves
@@ -170,16 +183,8 @@ complete --do-complete "%[2]s " > /dev/null 2>&1
170183
# Remove any pre-existing completions for the program since we will be handling all of them.
171184
complete -c %[2]s -e
172185
173-
# The order in which the below two lines are defined is very important so that __%[1]s_prepare_completions
174-
# is called first. It is __%[1]s_prepare_completions that sets up the __%[1]s_comp_do_file_comp variable.
175-
#
176-
# This completion will be run second as complete commands are added FILO.
177-
# It triggers file completion choices when __%[1]s_comp_do_file_comp is set.
178-
complete -c %[2]s -n 'set --query __%[1]s_comp_do_file_comp'
179-
180-
# This completion will be run first as complete commands are added FILO.
181-
# The call to __%[1]s_prepare_completions will setup both __%[1]s_comp_results and __%[1]s_comp_do_file_comp.
182-
# It provides the program's completion choices.
186+
# The call to __%[1]s_prepare_completions will setup __%[1]s_comp_results
187+
# which provides the program's completion choices.
183188
complete -c %[2]s -n '__%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
184189
185190
`, nameForVar, name, compCmd,

0 commit comments

Comments
 (0)