From bbe4e21f52ea47057ee11991c4ad9fedb48c5520 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Sun, 29 Aug 2021 17:54:57 -0400 Subject: [PATCH] Fixed cursors moving around with removal and inserts with cursors. Also fixed drawing line highlights with multicursors. --- data/core/doc/init.lua | 19 +++++++++++++++++++ data/core/docview.lua | 10 +++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index d05d9d45..2165ed83 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -309,6 +309,7 @@ end function Doc:raw_insert(line, col, text, undo_stack, time) -- split text into lines and merge with line at insertion point local lines = split_lines(text) + local len = #lines[#lines] local before = self.lines[line]:sub(1, col - 1) local after = self.lines[line]:sub(col) for i = 1, #lines - 1 do @@ -325,6 +326,15 @@ function Doc:raw_insert(line, col, text, undo_stack, time) push_undo(undo_stack, time, "selection", unpack(self.selections)) push_undo(undo_stack, time, "remove", line, col, line2, col2) + -- keep cursors where they should be + for idx, cline1, ccol1, cline2, ccol2 in self:get_selections(true) do + if cline1 >= line then + local line_addition = line > cline1 or ccol1 > col and #lines - 1 or 0 + local column_addition = line == cline1 and ccol1 > col and len or 0 + self:set_selections(idx, cline1 + line_addition, ccol1 + column_addition, cline2 + line_addition, ccol2 + column_addition) + end + end + -- update highlighter and assure selection is in bounds self.highlighter:invalidate(line) self:sanitize_selection() @@ -343,6 +353,15 @@ function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time) -- splice line into line array common.splice(self.lines, line1, line2 - line1 + 1, { before .. after }) + + -- move all cursors back if they share a line with the removed text + for idx, cline1, ccol1, cline2, ccol2 in self:get_selections(true) do + if cline1 >= line2 then + local line_removal = line2 - line1 + local column_removal = line2 == cline2 and col2 < ccol1 and (line2 == line1 and col2 - col1 or col2) or 0 + self:set_selections(idx, cline1 - line_removal, ccol1 - column_removal, cline2 - line_removal, ccol2 - column_removal) + end + end -- update highlighter and assure selection is in bounds self.highlighter:invalidate(line1) diff --git a/data/core/docview.lua b/data/core/docview.lua index 89da8190..54eec575 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -366,16 +366,20 @@ function DocView:draw_line_body(idx, x, y) local x1 = x + self:get_col_x_offset(idx, col1) local x2 = x + self:get_col_x_offset(idx, col2) local lh = self:get_line_height() - renderer.draw_rect(x1, y, x2 - x1, lh, style.selection) + if x1 ~= x2 then + renderer.draw_rect(x1, y, x2 - x1, lh, style.selection) + end end end + local draw_highlight = nil for lidx, line1, col1, line2, col2 in self.doc:get_selections(true) do -- draw line highlight if caret is on this line - if config.highlight_current_line and (line1 == line2 and col1 == col2) + if draw_highlight ~= false and config.highlight_current_line and line1 == idx and core.active_view == self then - self:draw_line_highlight(x + self.scroll.x, y) + draw_highlight = (line1 == line2 and col1 == col2) end end + if draw_highlight then self:draw_line_highlight(x + self.scroll.x, y) end -- draw line's text self:draw_line_text(idx, x, y)