Summary
rebuildColonSeparatedArgs documents that it rejoins shell-completion arguments when either the next token is ":" or the current token already ends with ":". The implementation enters the loop for the second case but immediately breaks instead of appending the following token.
As a result, a tokenization shape such as:
[]string{"config:", "get"}
remains two arguments instead of being reconstructed as:
This can make colon-named commands fail to resolve correctly when a shell presents the word-break boundary after the colon rather than returning the colon as its own token.
Reproduction
On current main (d082a010f7c6cacf407d8a1581446a7857f9f1bb):
got := rebuildColonSeparatedArgs([]string{"config:", "get"})
// current: []string{"config:", "get"}
// expected: []string{"config:get"}
The function's existing comment explicitly describes the intended rule:
Keep joining while the next element is ":" or the current element ends with ":"
but the current loop body contains:
if args[i+1] == ":" {
// append colon and possibly the following element
...
} else {
break
}
So the strings.HasSuffix(current, ":") half of the loop condition cannot actually join anything unless the next token is also a standalone colon.
Expected behavior
Both common shell tokenization shapes should reconstruct to the same logical command token:
[]string{"config", ":", "get"} -> []string{"config:get"}
[]string{"config:", "get"} -> []string{"config:get"}
Consecutive colon boundaries should also remain intact, e.g. {"a", ":", ":", "b"} -> {"a::b"}.
Suggested fix
While the next token is a standalone colon or the accumulated token ends in a colon, append the next token directly and advance. This removes the contradictory inner branch and handles both boundary shapes uniformly.
Add focused table-driven coverage for standalone-colon, trailing-colon, repeated-colon, and ordinary no-colon inputs.
Impact
This is shell-completion correctness. Depending on how the invoking shell splits a colon command at the cursor boundary, the completion helper can reconstruct a different argv shape and therefore miss the command or return irrelevant completions.
Summary
rebuildColonSeparatedArgsdocuments that it rejoins shell-completion arguments when either the next token is":"or the current token already ends with":". The implementation enters the loop for the second case but immediately breaks instead of appending the following token.As a result, a tokenization shape such as:
remains two arguments instead of being reconstructed as:
This can make colon-named commands fail to resolve correctly when a shell presents the word-break boundary after the colon rather than returning the colon as its own token.
Reproduction
On current
main(d082a010f7c6cacf407d8a1581446a7857f9f1bb):The function's existing comment explicitly describes the intended rule:
but the current loop body contains:
So the
strings.HasSuffix(current, ":")half of the loop condition cannot actually join anything unless the next token is also a standalone colon.Expected behavior
Both common shell tokenization shapes should reconstruct to the same logical command token:
Consecutive colon boundaries should also remain intact, e.g.
{"a", ":", ":", "b"}->{"a::b"}.Suggested fix
While the next token is a standalone colon or the accumulated token ends in a colon, append the next token directly and advance. This removes the contradictory inner branch and handles both boundary shapes uniformly.
Add focused table-driven coverage for standalone-colon, trailing-colon, repeated-colon, and ordinary no-colon inputs.
Impact
This is shell-completion correctness. Depending on how the invoking shell splits a colon command at the cursor boundary, the completion helper can reconstruct a different argv shape and therefore miss the command or return irrelevant completions.