From 45c1e36de967370bdbd1a7eaf4a9135ad717a351 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 28 Mar 2023 08:10:29 +0530 Subject: [PATCH] More work on mouse selection --- kittens/diff/mouse.go | 30 ++++++++++++++++++++++++++++-- kittens/diff/render.go | 14 +++++++++++--- kittens/diff/ui.go | 2 +- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/kittens/diff/mouse.go b/kittens/diff/mouse.go index 81d334a8a..31f212c32 100644 --- a/kittens/diff/mouse.go +++ b/kittens/diff/mouse.go @@ -98,6 +98,7 @@ func (self *Handler) update_mouse_selection(ev *loop.MouseEvent) { ms.end.x = ev.Cell.X ms.end.x = utils.Max(ms.min_x, utils.Min(ms.end.x, ms.max_x)) ms.end.line = pos + self.draw_screen() } func (self *Handler) clear_mouse_selection() { @@ -113,9 +114,34 @@ func (self *Handler) finish_mouse_selection(ev *loop.MouseEvent) { ms.is_active = false } -func (self *Handler) add_mouse_selection_to_line(line string, line_pos ScrollPos) { +func format_part_of_line(sgr string, start_x, end_x, y int) string { + // DECCARA used to set formatting in specified region using zero based indexing + return fmt.Sprintf("\x1b[%d;%d;%d;%d;%s$r", y+1, start_x+1, y+1, end_x+1, sgr) +} + +func (self *Handler) add_mouse_selection_to_line(line string, line_pos ScrollPos, y int) string { ms := &self.mouse_selection if !ms.is_active { - return + return line } + a, b := ms.start.line, ms.end.line + ax, bx := ms.start.x, ms.end.x + if b.Less(a) { + a, b = b, a + ax, bx = bx, ax + } + if a.Less(line_pos) { + if line_pos.Less(b) { + line += format_part_of_line(selection_sgr, 0, ms.max_x, y) + } else if b == line_pos { + line += format_part_of_line(selection_sgr, 0, bx, y) + } + } else if a == line_pos { + if line_pos.Less(b) { + line += format_part_of_line(selection_sgr, ax, ms.max_x, y) + } else if b == line_pos { + line += format_part_of_line(selection_sgr, ax, bx, y) + } + } + return line } diff --git a/kittens/diff/render.go b/kittens/diff/render.go index 7aa1cc82b..c88694f17 100644 --- a/kittens/diff/render.go +++ b/kittens/diff/render.go @@ -82,16 +82,17 @@ func place_in(text string, sz int) string { return fill_in(fit_in(text, sz), sz) } -var title_format, text_format, margin_format, added_format, removed_format, added_margin_format, removed_margin_format, filler_format, margin_filler_format, hunk_margin_format, hunk_format, statusline_format, added_count_format, removed_count_format, message_format func(...any) string +var title_format, text_format, margin_format, added_format, removed_format, added_margin_format, removed_margin_format, filler_format, margin_filler_format, hunk_margin_format, hunk_format, statusline_format, added_count_format, removed_count_format, message_format, selection_format func(...any) string +var selection_sgr string func create_formatters() { ctx := style.Context{AllowEscapeCodes: true} text_format = ctx.SprintFunc(fmt.Sprintf("bg=%s", conf.Background.AsRGBSharp())) filler_format = ctx.SprintFunc(fmt.Sprintf("bg=%s", conf.Filler_bg.AsRGBSharp())) if conf.Margin_filler_bg.IsSet { - margin_filler_format = ctx.SprintFunc(fmt.Sprintf("bg=%s", conf.Margin_filler_bg.Color.AsRGBSharp())) + margin_filler_format = ctx.SprintFunc("bg=" + conf.Margin_filler_bg.Color.AsRGBSharp()) } else { - margin_filler_format = ctx.SprintFunc(fmt.Sprintf("bg=%s", conf.Filler_bg.AsRGBSharp())) + margin_filler_format = ctx.SprintFunc("bg=" + conf.Filler_bg.AsRGBSharp()) } added_format = ctx.SprintFunc(fmt.Sprintf("bg=%s", conf.Added_bg.AsRGBSharp())) added_margin_format = ctx.SprintFunc(fmt.Sprintf("fg=%s bg=%s", conf.Margin_fg.AsRGBSharp(), conf.Added_margin_bg.AsRGBSharp())) @@ -105,6 +106,13 @@ func create_formatters() { hunk_format = ctx.SprintFunc(fmt.Sprintf("fg=%s bg=%s", conf.Margin_fg.AsRGBSharp(), conf.Hunk_bg.AsRGBSharp())) hunk_margin_format = ctx.SprintFunc(fmt.Sprintf("fg=%s bg=%s", conf.Margin_fg.AsRGBSharp(), conf.Hunk_margin_bg.AsRGBSharp())) message_format = ctx.SprintFunc("bold") + if conf.Select_fg.IsSet { + selection_format = ctx.SprintFunc(fmt.Sprintf("fg=%s bg=%s", conf.Select_fg.Color.AsRGBSharp(), conf.Select_bg.AsRGBSharp())) + } else { + selection_format = ctx.SprintFunc("bg=" + conf.Select_bg.AsRGBSharp()) + } + selection_sgr, _, _ = strings.Cut(selection_format("|"), "|") + selection_sgr = selection_sgr[2 : len(selection_sgr)-1] } func center_span(ltype string, offset, size int) *sgr.Span { diff --git a/kittens/diff/ui.go b/kittens/diff/ui.go index 8bf57048c..cd75654a8 100644 --- a/kittens/diff/ui.go +++ b/kittens/diff/ui.go @@ -354,7 +354,7 @@ func (self *Handler) draw_screen() { if self.current_search != nil { sl = self.current_search.markup_line(sl, pos) } - self.add_mouse_selection_to_line(sl, pos) + sl = self.add_mouse_selection_to_line(sl, pos, num_written) lp.QueueWriteString(sl) lp.MoveCursorVertically(1) lp.QueueWriteString("\x1b[m\r")