diff --git a/cmd/tailscale/cli/ffcomplete/internal/complete.go b/cmd/tailscale/cli/ffcomplete/internal/complete.go index 1eb58337b..046a968eb 100644 --- a/cmd/tailscale/cli/ffcomplete/internal/complete.go +++ b/cmd/tailscale/cli/ffcomplete/internal/complete.go @@ -193,12 +193,26 @@ walk: } // Strip any descriptions if they were suppressed. - if !descs { - for i := range words { - words[i], _, _ = strings.Cut(words[i], "\t") + clean := words[:0] + for _, w := range words { + if !descs { + w, _, _ = strings.Cut(w, "\t") } + w = cutAny(w, "\n\r") + if w == "" || w[0] == '\t' { + continue + } + clean = append(clean, w) + } + return clean, dir, nil +} + +func cutAny(s, cutset string) string { + i := strings.IndexAny(s, cutset) + if i == -1 { + return s } - return words, dir, nil + return s[:i] } // splitFlagArgs separates a list of command-line arguments into arguments diff --git a/cmd/tailscale/cli/ffcomplete/internal/complete_test.go b/cmd/tailscale/cli/ffcomplete/internal/complete_test.go index f5be74741..7e36b1bcd 100644 --- a/cmd/tailscale/cli/ffcomplete/internal/complete_test.go +++ b/cmd/tailscale/cli/ffcomplete/internal/complete_test.go @@ -50,11 +50,17 @@ func TestComplete(t *testing.T) { cmd := &ffcli.Command{ Name: "ping", FlagSet: newFlagSet("prog ping", flag.ContinueOnError, func(fs *flag.FlagSet) { - fs.String("until", "", "when pinging should end") + fs.String("until", "", "when pinging should end\nline break!") ffcomplete.Flag(fs, "until", ffcomplete.Fixed("forever", "direct")) }), } - ffcomplete.Args(cmd, ffcomplete.Fixed("jupiter", "neptune", "venus")) + ffcomplete.Args(cmd, ffcomplete.Fixed( + "jupiter\t5th planet\nand largets", + "neptune\t8th planet", + "venus\t2nd planet", + "\tonly description", + "\nonly line break", + )) return cmd }(), }, @@ -170,9 +176,9 @@ func TestComplete(t *testing.T) { showDescs: true, wantComp: []string{ "--until\twhen pinging should end", - "jupiter", - "neptune", - "venus", + "jupiter\t5th planet", + "neptune\t8th planet", + "venus\t2nd planet", }, wantDir: ffcomplete.ShellCompDirectiveNoFileComp, },