Skip to content

Commit 4a84b4f

Browse files
fix(autocomplete): zsh double space bug (#687)
1 parent 71baecf commit 4a84b4f

File tree

3 files changed

+11
-75
lines changed

3 files changed

+11
-75
lines changed

internal/core/autocomplete.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -431,18 +431,3 @@ func keySuggestion(key, keySchema string, completedArg map[string]struct{}) stri
431431
}
432432
return strings.ReplaceAll(key, "([0-9]+)", strconv.Itoa(i))
433433
}
434-
435-
func WordIndex(charIndex int, words []string) int {
436-
wordIndex := len(words)
437-
charCount := 0
438-
for i, word := range words {
439-
charCount += len(word)
440-
if charIndex <= charCount {
441-
wordIndex = i
442-
break
443-
}
444-
445-
charCount++ // space character
446-
}
447-
return wordIndex
448-
}

internal/core/autocomplete_test.go

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -143,33 +143,3 @@ func TestAutocomplete(t *testing.T) {
143143
t.Run("scw test --profile xxxx flower create name=p ", run(&testCase{Suggestions: AutocompleteSuggestions{"colours.0=", "leaves.0.size=", "size=", "species="}}))
144144
t.Run("scw test flower create name=p --profile xxxx", run(&testCase{Suggestions: nil}))
145145
}
146-
147-
func TestWordIndex(t *testing.T) {
148-
type testCase struct {
149-
CharIndex int
150-
Words []string
151-
WordIndex int
152-
}
153-
154-
run := func(tc *testCase) func(*testing.T) {
155-
return func(t *testing.T) {
156-
words := tc.Words
157-
if len(words) == 0 {
158-
name := strings.ReplaceAll(t.Name(), "TestWordIndex/", "")
159-
name = strings.ReplaceAll(name, " ", "_")
160-
words = strings.Split(name, "_")
161-
}
162-
163-
assert.Equal(t, tc.WordIndex, WordIndex(tc.CharIndex, words))
164-
}
165-
}
166-
167-
t.Run("scw", run(&testCase{CharIndex: 3, WordIndex: 0}))
168-
t.Run("scw ", run(&testCase{CharIndex: 3, WordIndex: 0}))
169-
t.Run("scw ", run(&testCase{CharIndex: 4, WordIndex: 1}))
170-
t.Run("scw plop", run(&testCase{CharIndex: 4, WordIndex: 1}))
171-
t.Run("scw plop", run(&testCase{CharIndex: 8, WordIndex: 1}))
172-
t.Run("scw in security-groups list", run(&testCase{CharIndex: 6, WordIndex: 1}))
173-
t.Run("scw in security-groups list", run(&testCase{CharIndex: 27, WordIndex: 3}))
174-
t.Run("scw in security-groups list ", run(&testCase{CharIndex: 28, WordIndex: 4}))
175-
}

internal/namespaces/autocomplete/autocomplete.go

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -98,22 +98,7 @@ var autocompleteScripts = map[string]autocompleteScript{
9898
CompleteFunc: `
9999
autoload -U compinit && compinit
100100
_scw () {
101-
# splits $BUFFER, i.e. the complete command line,
102-
# into shell words using shell parsing rules by Expansion Flag (z) and puts it into an array
103-
words=("${(z)BUFFER}")
104-
105-
# If the last char of the line is a space, a last empty word is not added to words.
106-
# We need to add it manually.
107-
lastChar="${BUFFER: -1}"
108-
if [[ $lastChar = *[!\ ]* ]]; then # if $lastChar contains something else than spaces
109-
: # do nothing
110-
else
111-
# words+=('') does not work
112-
# couldn't find a way to add an empty string to an array
113-
# we replace 'EMPTY_WORD' by '' later in go code
114-
words+=('EMPTY_WORD')
115-
fi
116-
output=($(scw autocomplete complete zsh -- $CURSOR $words))
101+
output=($(scw autocomplete complete zsh -- ${CURRENT} ${words}))
117102
opts=('-S' ' ')
118103
if [[ $output == *= ]]; then
119104
opts=('-S' '')
@@ -316,26 +301,22 @@ func autocompleteCompleteZshCommand() *core.Command {
316301
Run: func(ctx context.Context, argsI interface{}) (i interface{}, e error) {
317302
rawArgs := *argsI.(*args.RawArgs)
318303

319-
words := rawArgs[1:]
320-
charIndex, err := strconv.Atoi(rawArgs[0])
304+
// First arg is the word index.
305+
wordIndex, err := strconv.Atoi(rawArgs[0])
321306
if err != nil {
322307
return nil, err
323308
}
324-
wordIndex := core.WordIndex(charIndex, words)
325-
leftWords := words[:wordIndex]
326-
wordToComplete := words[wordIndex]
309+
wordIndex-- // In zsh word index starts at 1.
327310

328-
// In zsh, couldn't find a way to add an empty string to an array.
329-
// We added "EMPTY_WORD" instead.
330-
// "EMPTY_WORD" is replaced by "".
331-
// see the zsh script, line 106:
332-
// words+=('EMPTY_WORD')
333-
if wordToComplete == "EMPTY_WORD" {
334-
wordToComplete = ""
311+
// Other args are all the words.
312+
words := rawArgs[1:]
313+
if len(words) <= wordIndex {
314+
words = append(words, "") // Handle case when last word is empty.
335315
}
336316

337-
// TODO: compute rightWords once used by core.AutoComplete()
338-
rightWords := []string(nil)
317+
leftWords := words[:wordIndex]
318+
wordToComplete := words[wordIndex]
319+
rightWords := words[wordIndex+1:]
339320

340321
res := core.AutoComplete(ctx, leftWords, wordToComplete, rightWords)
341322
return strings.Join(res.Suggestions, " "), nil

0 commit comments

Comments
 (0)