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
This commit is contained in:
Guldoman 2023-11-29 16:40:47 +01:00 committed by takase1121
parent 19cef97bcd
commit 8eacca7ae1
No known key found for this signature in database
GPG Key ID: 60EEFFC68EB3031B
2 changed files with 19 additions and 5 deletions

View File

@ -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)
@ -253,7 +256,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)

View File

@ -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