From d19f28f2b4e5950bb5ab287280274bae129b30d2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 27 Mar 2023 21:23:31 +0530 Subject: [PATCH] More work on mouse selection in the diff kitten --- kittens/diff/mouse.go | 62 ++++++++++++++++++++++++++++++++++++++++++- kittens/diff/ui.go | 4 +++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/kittens/diff/mouse.go b/kittens/diff/mouse.go index ae96b049c..81d334a8a 100644 --- a/kittens/diff/mouse.go +++ b/kittens/diff/mouse.go @@ -14,8 +14,15 @@ import ( var _ = fmt.Print +type SelectionBoundary struct { + line ScrollPos + x int +} + type MouseSelection struct { - start_line, end_line ScrollPos + start, end SelectionBoundary + is_active bool + min_x, max_x int } type KittyOpts struct { @@ -52,10 +59,63 @@ func (self *Handler) handle_wheel_event(up bool) { } func (self *Handler) start_mouse_selection(ev *loop.MouseEvent) { + self.mouse_selection = MouseSelection{} + ms := &self.mouse_selection + available_cols := self.logical_lines.columns / 2 + if ev.Cell.Y >= self.screen_size.num_lines || ev.Cell.X < self.logical_lines.margin_size || (ev.Cell.X >= available_cols && ev.Cell.X < available_cols+self.logical_lines.margin_size) { + return + } + pos := self.scroll_pos + self.logical_lines.IncrementScrollPosBy(&pos, ev.Cell.Y) + ll := self.logical_lines.At(pos.logical_line) + if ll.line_type == EMPTY_LINE || ll.line_type == IMAGE_LINE { + return + } + ms.start.line = pos + + ms.start.x = ev.Cell.X + ms.min_x = self.logical_lines.margin_size + ms.max_x = available_cols - 1 + if ms.start.x >= available_cols { + ms.min_x += available_cols + ms.max_x += available_cols + } + ms.start.x = utils.Max(ms.min_x, utils.Min(ms.start.x, ms.max_x)) + + ms.end = ms.start + ms.is_active = true } func (self *Handler) update_mouse_selection(ev *loop.MouseEvent) { + ms := &self.mouse_selection + if !self.mouse_selection.is_active { + return + } + pos := self.scroll_pos + y := ev.Cell.Y + y = utils.Max(0, utils.Min(y, self.screen_size.num_lines-1)) + self.logical_lines.IncrementScrollPosBy(&pos, y) + 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 +} + +func (self *Handler) clear_mouse_selection() { + self.mouse_selection = MouseSelection{} } func (self *Handler) finish_mouse_selection(ev *loop.MouseEvent) { + self.update_mouse_selection(ev) + ms := &self.mouse_selection + if !self.mouse_selection.is_active { + return + } + ms.is_active = false +} + +func (self *Handler) add_mouse_selection_to_line(line string, line_pos ScrollPos) { + ms := &self.mouse_selection + if !ms.is_active { + return + } } diff --git a/kittens/diff/ui.go b/kittens/diff/ui.go index 3f2b30ded..8bf57048c 100644 --- a/kittens/diff/ui.go +++ b/kittens/diff/ui.go @@ -249,6 +249,7 @@ func (self *Handler) handle_async_result(r AsyncResult) error { case DIFF: self.diff_map = r.diff_map self.calculate_statistics() + self.clear_mouse_selection() err := self.render_diff() if err != nil { return err @@ -272,6 +273,7 @@ func (self *Handler) handle_async_result(r AsyncResult) error { } func (self *Handler) on_resize(old_size, new_size loop.ScreenSize) error { + self.clear_mouse_selection() self.update_screen_size(new_size) if self.diff_map != nil && self.collection != nil { err := self.render_diff() @@ -352,6 +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) lp.QueueWriteString(sl) lp.MoveCursorVertically(1) lp.QueueWriteString("\x1b[m\r") @@ -543,6 +546,7 @@ func (self *Handler) change_context_count(val int) bool { self.current_context_count = val p := self.scroll_pos self.restore_position = &p + self.clear_mouse_selection() self.generate_diff() self.draw_screen() return true