From 29bde6c72cddf745214e2c56556a1b389228ac79 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 14 Nov 2022 08:51:02 +0530 Subject: [PATCH] Improve formatting of completion entries with descriptions --- tools/cli/zsh.go | 12 +++++++----- tools/tui/readline/actions.go | 3 +++ tools/tui/readline/completion.go | 15 +++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tools/cli/zsh.go b/tools/cli/zsh.go index 917d69d33..cbd003462 100644 --- a/tools/cli/zsh.go +++ b/tools/cli/zsh.go @@ -49,16 +49,18 @@ func zsh_input_parser(data []byte, shell_state map[string]string) ([][]string, e return shell_input_parser(data, shell_state) } -func fmt_desc(word, desc string, max_word_len int, f *markup.Context, screen_width int) string { +func (self *Match) FormatForCompletionList(max_word_len int, f *markup.Context, screen_width int) string { + word := self.Word + desc := self.Description if desc == "" { return word } + word_len := wcswidth.Stringwidth(word) line, _, _ := utils.Cut(strings.TrimSpace(desc), "\n") desc = f.Prettify(line) multiline := false max_desc_len := screen_width - 2 - word_len := wcswidth.Stringwidth(word) if word_len > max_word_len { multiline = true } else { @@ -66,10 +68,10 @@ func fmt_desc(word, desc string, max_word_len int, f *markup.Context, screen_wid max_desc_len = screen_width - max_word_len - 3 } if wcswidth.Stringwidth(desc) > max_desc_len { - desc = wcswidth.TruncateToVisualLength(desc, max_desc_len-2) + "…" + desc = wcswidth.TruncateToVisualLength(desc, max_desc_len-2) + "\x1b[m…" } if multiline { - return word + "\n " + desc + return word + "\n" + strings.Repeat(" ", max_word_len+2) + desc } return word + " " + desc } @@ -106,7 +108,7 @@ func serialize(completions *Completions, f *markup.Context, screen_width int) ([ fmt.Fprintln(&output, "compdescriptions=(") limit := mg.max_visual_word_length(16) for _, m := range mg.Matches { - fmt.Fprintln(&output, utils.QuoteStringForSH(fmt_desc(m.Word, m.Description, limit, f, screen_width))) + fmt.Fprintln(&output, utils.QuoteStringForSH(m.FormatForCompletionList(limit, f, screen_width))) } fmt.Fprintln(&output, ")") cmd.WriteString(" -l -d compdescriptions") diff --git a/tools/tui/readline/actions.go b/tools/tui/readline/actions.go index b06cc54f7..062a120a2 100644 --- a/tools/tui/readline/actions.go +++ b/tools/tui/readline/actions.go @@ -671,6 +671,9 @@ func (self *Readline) perform_action(ac Action, repeat_count uint) error { err, dont_set_last_action := self._perform_action(ac, repeat_count) if err == nil && !dont_set_last_action { self.last_action = ac + if self.completions.current.results != nil && ac != ActionCompleteForward && ac != ActionCompleteBackward { + self.completions.current = completion{} + } } return err } diff --git a/tools/tui/readline/completion.go b/tools/tui/readline/completion.go index 63c10ba46..9a71114dc 100644 --- a/tools/tui/readline/completion.go +++ b/tools/tui/readline/completion.go @@ -121,23 +121,18 @@ func (self *Readline) complete(forwards bool, repeat_count uint) bool { func (self *Readline) screen_lines_for_match_group_with_descriptions(g *cli.MatchGroup, lines []string) []string { maxw := 0 - lengths := make(map[string]int) for _, m := range g.Matches { l := wcswidth.Stringwidth(m.Word) - lengths[m.Word] = l + if l > 16 { + maxw = 16 + break + } if l > maxw { maxw = l } } for _, m := range g.Matches { - p := m.Word + strings.Repeat(" ", maxw-lengths[m.Word]) - line, _, _ := utils.Cut(strings.TrimSpace(m.Description), "\n") - line = p + " - " + self.fmt_ctx.Prettify(line) - truncated := wcswidth.TruncateToVisualLength(line, self.screen_width-1) + "\x1b[m" - if len(truncated) < len(line) { - line = truncated + "…" - } - lines = append(lines, line) + lines = append(lines, utils.Splitlines(m.FormatForCompletionList(maxw, self.fmt_ctx, self.screen_width))...) } return lines }