Skip to content

Commit 5b921a0

Browse files
Kenny Yorknatecook1000
Kenny York
authored andcommitted
Bash does not like '-' in function names
1 parent ac615d4 commit 5b921a0

File tree

2 files changed

+109
-19
lines changed

2 files changed

+109
-19
lines changed

Sources/ArgumentParser/Completions/BashCompletionsGenerator.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ struct BashCompletionsGenerator {
1313
/// Generates a Bash completion script for the given command.
1414
static func generateCompletionScript(_ type: ParsableCommand.Type) -> String {
1515
// TODO: Add a check to see if the command is installed where we expect?
16-
let initialFunctionName = [type].completionFunctionName()
16+
let initialFunctionName = [type].completionFunctionName().makeSafeFunctionName
1717
return """
1818
#!/bin/bash
1919
@@ -26,7 +26,7 @@ struct BashCompletionsGenerator {
2626
/// Generates a Bash completion function for the last command in the given list.
2727
fileprivate static func generateCompletionFunction(_ commands: [ParsableCommand.Type]) -> String {
2828
let type = commands.last!
29-
let functionName = commands.completionFunctionName()
29+
let functionName = commands.completionFunctionName().makeSafeFunctionName
3030

3131
// The root command gets a different treatment for the parsing index.
3232
let isRootCommand = commands.count == 1
@@ -240,3 +240,9 @@ extension ArgumentDefinition {
240240
}
241241
}
242242
}
243+
244+
extension String {
245+
var makeSafeFunctionName: String {
246+
self.replacingOccurrences(of: "-", with: "_")
247+
}
248+
}

Tests/ArgumentParserUnitTests/CompletionScriptTests.swift

Lines changed: 101 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ extension CompletionScriptTests {
3434
}
3535

3636
struct Base: ParsableCommand {
37+
static var configuration = CommandConfiguration(
38+
commandName: "base-test",
39+
subcommands: [SubCommand.self]
40+
)
41+
3742
@Option(help: "The user's name.") var name: String
3843
@Option() var kind: Kind
3944
@Option(completion: .list(["1", "2", "3"])) var otherKind: Kind
@@ -43,6 +48,12 @@ extension CompletionScriptTests {
4348
@Option(completion: .list(["a", "b", "c"])) var path3: Path
4449

4550
@Flag(help: .hidden) var verbose = false
51+
52+
struct SubCommand: ParsableCommand {
53+
static var configuration = CommandConfiguration(
54+
commandName: "sub-command"
55+
)
56+
}
4657
}
4758

4859
func testBase_Zsh() throws {
@@ -138,12 +149,12 @@ extension CompletionScriptTests {
138149
}
139150

140151
private let zshBaseCompletions = """
141-
#compdef base
152+
#compdef base-test
142153
local context state state_descr line
143-
_base_commandname=$words[1]
154+
_base_test_commandname=$words[1]
144155
typeset -A opt_args
145156
146-
_base() {
157+
_base-test() {
147158
integer ret=1
148159
local -a args
149160
args+=(
@@ -154,6 +165,50 @@ _base() {
154165
'--path2:path2:_files'
155166
'--path3:path3:(a b c)'
156167
'(-h --help)'{-h,--help}'[Show help information.]'
168+
'(-): :->command'
169+
'(-)*:: :->arg'
170+
)
171+
_arguments -w -s -S $args[@] && ret=0
172+
case $state in
173+
(command)
174+
local subcommands
175+
subcommands=(
176+
'sub-command:'
177+
'help:Show subcommand help information.'
178+
)
179+
_describe "subcommand" subcommands
180+
;;
181+
(arg)
182+
case ${words[1]} in
183+
(sub-command)
184+
_base-test_sub-command
185+
;;
186+
(help)
187+
_base-test_help
188+
;;
189+
esac
190+
;;
191+
esac
192+
193+
return ret
194+
}
195+
196+
_base-test_sub-command() {
197+
integer ret=1
198+
local -a args
199+
args+=(
200+
'(-h --help)'{-h,--help}'[Show help information.]'
201+
)
202+
_arguments -w -s -S $args[@] && ret=0
203+
204+
return ret
205+
}
206+
207+
_base-test_help() {
208+
integer ret=1
209+
local -a args
210+
args+=(
211+
':subcommands:'
157212
)
158213
_arguments -w -s -S $args[@] && ret=0
159214
@@ -166,17 +221,17 @@ _custom_completion() {
166221
_describe '' completions
167222
}
168223
169-
_base
224+
_base-test
170225
"""
171226

172227
private let bashBaseCompletions = """
173228
#!/bin/bash
174229
175-
_base() {
230+
_base_test() {
176231
cur="${COMP_WORDS[COMP_CWORD]}"
177232
prev="${COMP_WORDS[COMP_CWORD-1]}"
178233
COMPREPLY=()
179-
opts="--name --kind --other-kind --path1 --path2 --path3 -h --help"
234+
opts="--name --kind --other-kind --path1 --path2 --path3 -h --help sub-command help"
180235
if [[ $COMP_CWORD == "1" ]]; then
181236
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
182237
return
@@ -215,11 +270,37 @@ _base() {
215270
return
216271
;;
217272
esac
273+
case ${COMP_WORDS[1]} in
274+
(sub-command)
275+
_base_test_sub-command 2
276+
return
277+
;;
278+
(help)
279+
_base_test_help 2
280+
return
281+
;;
282+
esac
283+
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
284+
}
285+
_base_test_sub_command() {
286+
opts="-h --help"
287+
if [[ $COMP_CWORD == "$1" ]]; then
288+
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
289+
return
290+
fi
291+
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
292+
}
293+
_base_test_help() {
294+
opts=""
295+
if [[ $COMP_CWORD == "$1" ]]; then
296+
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
297+
return
298+
fi
218299
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
219300
}
220301
221302
222-
complete -F _base base
303+
complete -F _base_test base-test
223304
"""
224305

225306
private let zshEscapedCompletion = """
@@ -252,7 +333,7 @@ _escaped-command
252333

253334
private let fishBaseCompletions = """
254335
# A function which filters options which starts with "-" from $argv.
255-
function _swift_base_preprocessor
336+
function _swift_base-test_preprocessor
256337
set -l results
257338
for i in (seq (count $argv))
258339
switch (echo $argv[$i] | string sub -l 1)
@@ -263,8 +344,8 @@ function _swift_base_preprocessor
263344
end
264345
end
265346
266-
function _swift_base_using_command
267-
set -l currentCommands (_swift_base_preprocessor (commandline -opc))
347+
function _swift_base-test_using_command
348+
set -l currentCommands (_swift_base-test_preprocessor (commandline -opc))
268349
set -l expectedCommands (string split " " $argv[1])
269350
set -l subcommands (string split " " $argv[2])
270351
if [ (count $currentCommands) -ge (count $expectedCommands) ]
@@ -288,13 +369,16 @@ function _swift_base_using_command
288369
return 1
289370
end
290371
291-
complete -c base -n '_swift_base_using_command \"base\"' -l name -d 'The user\\\'s name.'
292-
complete -c base -n '_swift_base_using_command \"base\"' -l kind -r -f -k -a 'one two custom-three'
293-
complete -c base -n '_swift_base_using_command \"base\"' -l other-kind -r -f -k -a '1 2 3'
294-
complete -c base -n '_swift_base_using_command \"base\"' -l path1 -r -f -a '(for i in *.{}; echo $i;end)'
295-
complete -c base -n '_swift_base_using_command \"base\"' -l path2 -r -f -a '(for i in *.{}; echo $i;end)'
296-
complete -c base -n '_swift_base_using_command \"base\"' -l path3 -r -f -k -a 'a b c'
297-
complete -c base -n '_swift_base_using_command \"base\"' -s h -l help -d 'Show help information.'
372+
complete -c base-test -n '_swift_base-test_using_command "base-test sub-command"' -s h -l help -d 'Show help information.'
373+
complete -c base-test -n '_swift_base-test_using_command "base-test" "sub-command help"' -l name -d 'The user\'s name.'
374+
complete -c base-test -n '_swift_base-test_using_command "base-test" "sub-command help"' -l kind -r -f -k -a 'one two custom-three'
375+
complete -c base-test -n '_swift_base-test_using_command "base-test" "sub-command help"' -l other-kind -r -f -k -a '1 2 3'
376+
complete -c base-test -n '_swift_base-test_using_command "base-test" "sub-command help"' -l path1 -r -f -a '(for i in *.{}; echo $i;end)'
377+
complete -c base-test -n '_swift_base-test_using_command "base-test" "sub-command help"' -l path2 -r -f -a '(for i in *.{}; echo $i;end)'
378+
complete -c base-test -n '_swift_base-test_using_command "base-test" "sub-command help"' -l path3 -r -f -k -a 'a b c'
379+
complete -c base-test -n '_swift_base-test_using_command "base-test" "sub-command help"' -s h -l help -d 'Show help information.'
380+
complete -c base-test -n '_swift_base-test_using_command "base-test" "sub-command help"' -f -a 'sub-command' -d ''
381+
complete -c base-test -n '_swift_base-test_using_command "base-test" "sub-command help"' -f -a 'help' -d 'Show subcommand help information.'
298382
"""
299383

300384
// MARK: - Test Hidden Subcommand

0 commit comments

Comments
 (0)