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:
parent
2571e17d1b
commit
9301220d26
|
@ -164,13 +164,16 @@ local function is_in_any_selection(line, col)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function select_add_next(all)
|
local function select_add_next(all)
|
||||||
local il1, ic1 = doc():get_selection(true)
|
local il1, ic1
|
||||||
for idx, l1, c1, l2, c2 in doc():get_selections(true, true) do
|
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)
|
local text = doc():get_text(l1, c1, l2, c2)
|
||||||
repeat
|
repeat
|
||||||
l1, c1, l2, c2 = search.find(doc(), l2, c2, text, { wrap = true })
|
l1, c1, l2, c2 = search.find(doc(), l2, c2, text, { wrap = true })
|
||||||
if l1 == il1 and c1 == ic1 then break end
|
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)
|
doc():add_selection(l2, c2, l1, c1)
|
||||||
if not all then
|
if not all then
|
||||||
core.active_view:scroll_to_make_visible(l2, c2)
|
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")
|
core.error("No find to continue from")
|
||||||
else
|
else
|
||||||
local sl1, sc1, sl2, sc2 = dv.doc:get_selection(true)
|
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
|
if line1 then
|
||||||
dv.doc:set_selection(line2, col2, line1, col1)
|
dv.doc:set_selection(line2, col2, line1, col1)
|
||||||
dv:scroll_to_line(line2, true)
|
dv:scroll_to_line(line2, true)
|
||||||
|
|
|
@ -66,7 +66,18 @@ function search.find(doc, line, col, text, opt)
|
||||||
s, e = search_func(line_text, pattern, col, plain)
|
s, e = search_func(line_text, pattern, col, plain)
|
||||||
end
|
end
|
||||||
if s then
|
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
|
end
|
||||||
col = opt.reverse and -1 or 1
|
col = opt.reverse and -1 or 1
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue