From 5532b52ad8c743b64b6202e11fb49f3dd9c3f8b4 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 29 Nov 2023 16:40:47 +0100 Subject: [PATCH] Fix selecting newlines with `find-replace:select-add-{next,all}` (#1608) * Avoid adding existing selections in `select_add_next` * Use the first available selection as delimiter in `select_add_next` * Fix returning searches with newlines in `search.find` * Fix repeat search when the last result spanned multiple lines --- data/core/commands/findreplace.lua | 11 +++++++---- data/core/doc/search.lua | 13 ++++++++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/data/core/commands/findreplace.lua b/data/core/commands/findreplace.lua index a3151cb7..b77bbcf2 100644 --- a/data/core/commands/findreplace.lua +++ b/data/core/commands/findreplace.lua @@ -164,13 +164,16 @@ local function is_in_any_selection(line, col) end local function select_add_next(all) - local il1, ic1 = doc():get_selection(true) - for idx, l1, c1, l2, c2 in doc():get_selections(true, true) do + local il1, ic1 + for _, l1, c1, l2, c2 in doc():get_selections(true, true) do + if not il1 then + il1, ic1 = l1, c1 + end local text = doc():get_text(l1, c1, l2, c2) repeat l1, c1, l2, c2 = search.find(doc(), l2, c2, text, { wrap = true }) if l1 == il1 and c1 == ic1 then break end - if l2 and (all or not is_in_any_selection(l2, c2)) then + if l2 and not is_in_any_selection(l2, c2) then doc():add_selection(l2, c2, l1, c1) if not all then core.active_view:scroll_to_make_visible(l2, c2) @@ -266,7 +269,7 @@ command.add(valid_for_finding, { core.error("No find to continue from") else local sl1, sc1, sl2, sc2 = dv.doc:get_selection(true) - local line1, col1, line2, col2 = last_fn(dv.doc, sl1, sc2, last_text, case_sensitive, find_regex, false) + local line1, col1, line2, col2 = last_fn(dv.doc, sl2, sc2, last_text, case_sensitive, find_regex, false) if line1 then dv.doc:set_selection(line2, col2, line1, col1) dv:scroll_to_line(line2, true) diff --git a/data/core/doc/search.lua b/data/core/doc/search.lua index 8395769a..3cfe6a2d 100644 --- a/data/core/doc/search.lua +++ b/data/core/doc/search.lua @@ -66,7 +66,18 @@ function search.find(doc, line, col, text, opt) s, e = search_func(line_text, pattern, col, plain) end if s then - return line, s, line, e + 1 + local line2 = line + -- If we've matched the newline too, + -- return until the initial character of the next line. + if e >= #doc.lines[line] then + line2 = line + 1 + e = 0 + end + -- Avoid returning matches that go beyond the last line. + -- This is needed to avoid selecting the "last" newline. + if line2 <= #doc.lines then + return line, s, line2, e + 1 + end end col = opt.reverse and -1 or 1 end