aboutsummaryrefslogtreecommitdiffhomepage
path: root/modules
diff options
context:
space:
mode:
authorGravatar mitchell <70453897+orbitalquark@users.noreply.github.com>2021-06-11 14:33:53 -0400
committerGravatar mitchell <70453897+orbitalquark@users.noreply.github.com>2021-06-11 14:33:53 -0400
commitc8d40c1af58d8b21bb99e850aa6e7ded61dd7275 (patch)
tree813784d50ae96ff8850c0ae2972b128e91e07b17 /modules
parent48134170e780091b753d11dd945547a719719dd3 (diff)
Support "Replace All" in multiple and rectangular selection.
Diffstat (limited to 'modules')
-rw-r--r--modules/textadept/find.lua53
1 files changed, 28 insertions, 25 deletions
diff --git a/modules/textadept/find.lua b/modules/textadept/find.lua
index c8a77d86..262c1574 100644
--- a/modules/textadept/find.lua
+++ b/modules/textadept/find.lua
@@ -398,35 +398,38 @@ local INDIC_REPLACE = _SCINTILLA.next_indic_number()
-- is replaced.
events.connect(events.REPLACE_ALL, function(ftext, rtext)
if ftext == '' then return end
- local count = 0
- local s, e = buffer.selection_start, buffer.selection_end
- local replace_in_sel = s ~= e and (ftext ~= find_text or buffer:get_sel_text() ~= found_text)
- if replace_in_sel then
- buffer.indicator_current = INDIC_REPLACE
- buffer:indicator_fill_range(e, 1)
- end
- local EOF = replace_in_sel and e == buffer.length + 1 -- no indicator at EOF
repl_text = rtext -- save for ui.find.focus()
+ local count = 0
+ local replace_in_sel = not buffer.selection_empty and
+ (ftext ~= find_text or buffer:get_sel_text() ~= found_text)
+ if replace_in_sel then buffer.indicator_current = INDIC_REPLACE end
+
+ for i = 1, buffer.selections do
+ local s, e = buffer.selection_n_start[i], buffer.selection_n_end[i]
+ if replace_in_sel then buffer:indicator_fill_range(e, 1) end
+ local EOF = replace_in_sel and e == buffer.length + 1 -- no indicator at EOF
+
+ -- Perform the search and replace.
+ buffer:begin_undo_action()
+ buffer.search_flags = get_flags()
+ buffer:set_target_range(not replace_in_sel and 1 or s, buffer.length + 1)
+ while buffer:search_in_target(ftext) ~= -1 and
+ (not replace_in_sel or buffer.target_end <= buffer:indicator_end(INDIC_REPLACE, s) or EOF) do
+ local offset = buffer.target_start ~= buffer.target_end and 0 or 1 -- for preventing loops
+ buffer:replace_target(not M.regex and rtext or unescape(rtext))
+ count = count + 1
+ buffer:set_target_range(buffer.target_end + offset, buffer.length + 1)
+ end
+ buffer:end_undo_action()
- -- Perform the search and replace.
- buffer:begin_undo_action()
- buffer.search_flags = get_flags()
- buffer:set_target_range(not replace_in_sel and 1 or s, buffer.length + 1)
- while buffer:search_in_target(ftext) ~= -1 and
- (not replace_in_sel or buffer.target_end <= buffer:indicator_end(INDIC_REPLACE, s) or EOF) do
- local offset = buffer.target_start ~= buffer.target_end and 0 or 1 -- for preventing loops
- buffer:replace_target(not M.regex and rtext or unescape(rtext))
- count = count + 1
- buffer:set_target_range(buffer.target_end + offset, buffer.length + 1)
+ -- Restore any original selection.
+ if replace_in_sel then
+ e = buffer:indicator_end(INDIC_REPLACE, s)
+ buffer.selection_n_start[i], buffer.selection_n_end[i] = s, e > 1 and e or buffer.length + 1
+ if e > 1 then buffer:indicator_clear_range(e, 1) end
+ end
end
- buffer:end_undo_action()
- -- Restore any original selection and report the number of replacements made.
- if replace_in_sel then
- e = buffer:indicator_end(INDIC_REPLACE, s)
- buffer:set_sel(s, e > 1 and e or buffer.length + 1)
- if e > 1 then buffer:indicator_clear_range(e, 1) end
- end
ui.statusbar_text = string.format('%d %s', count, _L['replacement(s) made'])
end)