From 688736c4cf04b6c46aecbe58cd608e94dfefd491 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 7 May 2024 10:24:14 +0530 Subject: [PATCH] ... --- kittens/choose_fonts/family_list.go | 16 ++++++++++++++++ kittens/choose_fonts/ui.go | 21 ++++++++++++++++++++- tools/tui/loop/api.go | 2 +- tools/tui/render_lines.go | 20 ++++++++++---------- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/kittens/choose_fonts/family_list.go b/kittens/choose_fonts/family_list.go index c39d133d8..6d52abd3e 100644 --- a/kittens/choose_fonts/family_list.go +++ b/kittens/choose_fonts/family_list.go @@ -2,6 +2,7 @@ package choose_fonts import ( "fmt" + "kitty/tools/tui" "kitty/tools/tui/subseq" "kitty/tools/utils" "kitty/tools/wcswidth" @@ -21,6 +22,16 @@ func (self *FamilyList) Len() int { return len(self.families) } +func (self *FamilyList) Select(family string) bool { + for idx, q := range self.families { + if q == family { + self.current_idx = idx + return true + } + } + return false +} + func (self *FamilyList) Next(delta int, allow_wrapping bool) bool { if len(self.display_strings) == 0 { return false @@ -84,6 +95,10 @@ func apply_search(families []string, expression string, marks ...string) (matche return } +func make_family_names_clickable(family string) string { + return tui.InternalHyperlink(family, "family-chosen:"+family) +} + func (self *FamilyList) UpdateFamilies(families []string) { self.families, self.all_families = families, families if self.current_search != "" { @@ -92,6 +107,7 @@ func (self *FamilyList) UpdateFamilies(families []string) { } else { self.display_strings = utils.Map(limit_lengths, families) } + self.display_strings = utils.Map(make_family_names_clickable, self.display_strings) self.widths = utils.Map(wcswidth.Stringwidth, self.display_strings) self.max_width = utils.Max(0, self.widths...) self.current_idx = 0 diff --git a/kittens/choose_fonts/ui.go b/kittens/choose_fonts/ui.go index 0fba97d47..d4b1ec477 100644 --- a/kittens/choose_fonts/ui.go +++ b/kittens/choose_fonts/ui.go @@ -137,7 +137,7 @@ func (h *handler) draw_listing_screen() (err error) { } lines = append(lines, line) } - _, _, str := h.render_lines.InRectangle(lines, 0, 0, 0, num_rows, &h.mouse_state) + _, _, str := h.render_lines.InRectangle(lines, 0, 0, 0, num_rows, &h.mouse_state, h.handle_click) h.lp.QueueWriteString(str) seps := strings.Repeat(SEPARATOR, num_rows) seps = strings.TrimSpace(seps) @@ -153,6 +153,25 @@ func (h *handler) draw_listing_screen() (err error) { return } +func (h *handler) handle_click(id string) error { + which, data, found := strings.Cut(id, ":") + if !found { + return fmt.Errorf("Not a valid click id: %s", id) + } + switch which { + case "family-chosen": + if h.state == LISTING_FAMILIES { + if h.family_list.Select(data) { + h.draw_screen() + } else { + h.lp.Beep() + } + + } + } + return nil +} + func (h *handler) update_family_search() { text := h.rl.AllText() if h.family_list.UpdateSearch(text) { diff --git a/tools/tui/loop/api.go b/tools/tui/loop/api.go index ff2d0a65c..2c083eb10 100644 --- a/tools/tui/loop/api.go +++ b/tools/tui/loop/api.go @@ -220,7 +220,7 @@ func (self *Loop) Println(args ...any) { func (self *Loop) style_region(style string, start_x, start_y, end_x, end_y int) string { sgr := self.SprintStyled(style, "|")[2:] sgr = sgr[:strings.IndexByte(sgr, 'm')] - return fmt.Sprintf("\x1b[%d;%d;%d;%d%s$r", start_y+1, start_x+1, end_y+1, end_x+1, sgr) + return fmt.Sprintf("\x1b[%d;%d;%d;%d;%s$r", start_y+1, start_x+1, end_y+1, end_x+1, sgr) } // Apply the specified style to the specified region of the screen (0-based diff --git a/tools/tui/render_lines.go b/tools/tui/render_lines.go index 839ede7d2..5450653c0 100644 --- a/tools/tui/render_lines.go +++ b/tools/tui/render_lines.go @@ -24,7 +24,7 @@ type RenderLines struct { } var hyperlink_pat = sync.OnceValue(func() *regexp.Regexp { - return regexp.MustCompile("\x1b]8;([^;]*);.*?(\x1b\\\\|\a)") + return regexp.MustCompile("\x1b]8;([^;]*);(.*?)(?:\x1b\\\\|\a)") }) // Render lines in the specified rectangle. If width > 0 then lines are wrapped @@ -32,7 +32,7 @@ var hyperlink_pat = sync.OnceValue(func() *regexp.Regexp { // move cursor is returned. Any internal hyperlinks are added to the // MouseState. func (r RenderLines) InRectangle( - lines []string, start_x, start_y, width, height int, mouse_state *MouseState, + lines []string, start_x, start_y, width, height int, mouse_state *MouseState, on_click ...func(id string) error, ) (all_rendered bool, y_after_last_line int, ans string) { end_y := start_y + height - 1 if end_y < start_y { @@ -59,23 +59,23 @@ func (r RenderLines) InRectangle( } } - commit_hyperlink := func() { - mouse_state.AddCellRegion(hyperlink_state.action, hyperlink_state.start_x, hyperlink_state.start_y, x, y) + commit_hyperlink := func() bool { + if hyperlink_state.action == "" { + return false + } + mouse_state.AddCellRegion(hyperlink_state.action, hyperlink_state.start_x, hyperlink_state.start_y, x, y, on_click...) hyperlink_state.action = `` + return true } add_hyperlink := func(id, url string) { is_closer := id == "" && url == "" if is_closer { - if hyperlink_state.action != "" { - commit_hyperlink() - } else { + if !commit_hyperlink() { buf.WriteString("\x1b]8;;\x1b\\") } } else { - if hyperlink_state.action != "" { - commit_hyperlink() - } + commit_hyperlink() if strings.HasPrefix(url, KittyInternalHyperlinkProtocol+":") { start_hyperlink(url[len(KittyInternalHyperlinkProtocol)+1:]) } else {