From 4f55555ca92290e699930dbd199e3042160a98c3 Mon Sep 17 00:00:00 2001 From: Joshua Minor Date: Fri, 19 Nov 2021 01:05:26 -0800 Subject: [PATCH] Selection expands by word or line on double or triple click followed by drag. --- data/core/commands/doc.lua | 10 +++++----- data/core/docview.lua | 24 +++++++++++++++++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index ba3d1f0c..fe1fa3b1 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -82,13 +82,13 @@ local function split_cursor(direction) core.blink_reset() end -local function set_cursor(x, y, type) +local function set_cursor(x, y, snap_type) local line, col = dv():resolve_screen_position(x, y) doc():set_selection(line, col, line, col) - if type == "word" or type == "lines" then - command.perform("doc:select-" .. type) + if snap_type == "word" or snap_type == "lines" then + command.perform("doc:select-" .. snap_type) end - dv().mouse_selecting = { line, col } + dv().mouse_selecting = { line, col, snap_type } core.blink_reset() end @@ -402,7 +402,7 @@ local commands = { ["doc:select-to-cursor"] = function(x, y, clicks) local line1, col1 = select(3, doc():get_selection()) local line2, col2 = dv():resolve_screen_position(x, y) - dv().mouse_selecting = { line1, col1 } + dv().mouse_selecting = { line1, col1, nil } doc():set_selection(line2, col2, line1, col1) end, diff --git a/data/core/docview.lua b/data/core/docview.lua index 07da1cef..60ef62bc 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -224,6 +224,7 @@ function DocView:scroll_to_make_visible(line, col) end end + function DocView:on_mouse_moved(x, y, ...) DocView.super.on_mouse_moved(self, x, y, ...) @@ -235,7 +236,7 @@ function DocView:on_mouse_moved(x, y, ...) if self.mouse_selecting then local l1, c1 = self:resolve_screen_position(x, y) - local l2, c2 = table.unpack(self.mouse_selecting) + local l2, c2, snap_type = table.unpack(self.mouse_selecting) if keymap.modkeys["ctrl"] then if l1 > l2 then l1, l2 = l2, l1 end self.doc.selections = { } @@ -243,12 +244,33 @@ function DocView:on_mouse_moved(x, y, ...) self.doc:set_selections(i - l1 + 1, i, math.min(c1, #self.doc.lines[i]), i, math.min(c2, #self.doc.lines[i])) end else + if snap_type then + l1, c1, l2, c2 = self:mouse_selection(self.doc, snap_type, l1, c1, l2, c2) + end self.doc:set_selection(l1, c1, l2, c2) end end end +function DocView:mouse_selection(doc, snap_type, line1, col1, line2, col2) + local swap = line2 < line1 or line2 == line1 and col2 <= col1 + if swap then + line1, col1, line2, col2 = line2, col2, line1, col1 + end + if snap_type == "word" then + line1, col1 = translate.start_of_word(doc, line1, col1) + line2, col2 = translate.end_of_word(doc, line2, col2) + elseif snap_type == "lines" then + col1, col2 = 1, math.huge + end + if swap then + return line2, col2, line1, col1 + end + return line1, col1, line2, col2 +end + + function DocView:on_mouse_released(button) DocView.super.on_mouse_released(self, button) self.mouse_selecting = nil