mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-10-09 12:02:08 +00:00
Completion: Do not emit multi line candidates for fish
fish splits the output of the completion function on newlines to build the candidate list, so an option whose help text spans paragraphs added its continuation lines as candidates of their own. Build the candidate with the newline replacement the fish2 branch already used, so both paths agree.
This commit is contained in:
parent
becd8ed74c
commit
bd3eb4c267
2 changed files with 32 additions and 2 deletions
|
|
@ -52,10 +52,15 @@ func fish_output_serializer(completions []*Completions, shell_state map[string]s
|
|||
n := completions[0].Delegate.NumToRemove
|
||||
fm := markup.New(false) // fish freaks out if there are escape codes in the description strings
|
||||
legacy_completion := shell_state["_legacy_completion"]
|
||||
// fish splits the output of the completion function on newlines, so a description
|
||||
// spanning multiple lines adds its continuation lines as spurious candidates.
|
||||
candidate := func(m *Match) string {
|
||||
return strings.ReplaceAll(m.Word+"\t"+fm.Prettify(m.Description), "\n", " ")
|
||||
}
|
||||
if legacy_completion == "fish2" {
|
||||
for _, mg := range completions[0].Groups {
|
||||
for _, m := range mg.Matches {
|
||||
f("%s", strings.ReplaceAll(m.Word+"\t"+fm.Prettify(m.Description), "\n", " "))
|
||||
f("%s", candidate(m))
|
||||
}
|
||||
}
|
||||
} else if n > 0 {
|
||||
|
|
@ -72,7 +77,7 @@ func fish_output_serializer(completions []*Completions, shell_state map[string]s
|
|||
} else {
|
||||
for _, mg := range completions[0].Groups {
|
||||
for _, m := range mg.Matches {
|
||||
f("echo -- %s", utils.QuoteStringForFish(m.Word+"\t"+fm.Prettify(m.Description)))
|
||||
f("echo -- %s", utils.QuoteStringForFish(candidate(m)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
25
tools/cli/fish_test.go
Normal file
25
tools/cli/fish_test.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// License: GPLv3 Copyright: 2026, Kovid Goyal, <kovid at kovidgoyal.net>
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFishCompletionMultilineDescription(t *testing.T) {
|
||||
completions := []*Completions{{Groups: []*MatchGroup{{Title: "Options", Matches: []*Match{
|
||||
{Word: "--config", Description: "Specify a path to the configuration file.\n\nIf it is not specified, config files are searched for."},
|
||||
}}}}}
|
||||
for _, shell_state := range []map[string]string{{}, {"_legacy_completion": "fish2"}} {
|
||||
data, err := fish_output_serializer(completions, shell_state)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// each candidate must be a single line, since fish splits the output of the
|
||||
// completion function on newlines to get the candidate list
|
||||
if q := strings.TrimRight(string(data), "\n"); strings.Contains(q, "\n") {
|
||||
t.Fatalf("A multi line description produced more than one candidate with shell state %#v:\n%s", shell_state, q)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue