aboutsummaryrefslogtreecommitdiff
path: root/plugins/regexreplacepreview.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/regexreplacepreview.lua')
-rw-r--r--plugins/regexreplacepreview.lua222
1 files changed, 113 insertions, 109 deletions
diff --git a/plugins/regexreplacepreview.lua b/plugins/regexreplacepreview.lua
index 1c8b845..18d692b 100644
--- a/plugins/regexreplacepreview.lua
+++ b/plugins/regexreplacepreview.lua
@@ -1,4 +1,4 @@
--- mod-version:2 -- lite-xl 2.0
+-- mod-version:3
local core = require "core"
local keymap = require "core.keymap"
local command = require "core.command"
@@ -6,121 +6,125 @@ local command = require "core.command"
-- Takes the following pattern: /pattern/replace/
-- Capture groupings can be replaced using \1 through \9
local function regex_replace_file(view, pattern, old_lines, raw, start_line, end_line)
- local doc = view.doc
- local start_pattern, end_pattern, end_replacement, start_replacement = 2, 2;
- repeat
- end_pattern = string.find(pattern, "/", end_pattern)
- until end_pattern == nil or pattern[end_pattern-1] ~= "\\"
- if end_pattern == nil then
- end_pattern = #pattern + 1
- else
- end_pattern = end_pattern - 1
- start_replacement = end_pattern+2;
- end_replacement = end_pattern+2;
- repeat
- end_replacement = string.find(pattern, "/", end_replacement)
- until end_replacement == nil or pattern[end_replacement-1] ~= "\\"
- end
- end_replacement = end_replacement and (end_replacement - 1)
-
- local re = start_pattern ~= end_pattern and regex.compile(pattern:sub(start_pattern, end_pattern))
-
- local replacement = end_replacement and pattern:sub(start_replacement, end_replacement)
- local replace_line = raw and function(line, new_text)
- if line == #doc.lines then
- doc:raw_remove(line, 1, line, #doc.lines[line], { idx = 1 }, 0)
- else
- doc:raw_remove(line, 1, line+1, 1, { idx = 1 }, 0)
- end
- doc:raw_insert(line, 1, new_text, { idx = 1 }, 0)
- end or function(line, new_text)
- if line == #doc.lines then
- doc:remove(line, 1, line, #doc.lines[line])
- else
- doc:remove(line, 1, line+1, 1)
- end
- doc:insert(line, 1, new_text)
- end
-
- local line_scroll = nil
- if re then
- for i = (start_line or 1), (end_line or #doc.lines) do
- local new_text, matches, rmatches
- local old_text = old_lines[i] or doc.lines[i]
- local old_length = #old_text
- if replacement then
- new_text, matches, rmatches = regex.gsub(re, old_text, replacement)
- end
- if matches and #matches > 0 then
- old_lines[i] = old_text
- replace_line(i, new_text)
- if line_scroll == nil then
- line_scroll = i
- doc:set_selection(i, rmatches[1][1], i, rmatches[1][2])
- end
- elseif old_lines[i] then
- replace_line(i, old_lines[i])
- old_lines[i] = nil
- end
- if not replacement then
- local s,e = regex.match(re, old_text)
- if s then
- line_scroll = i
- doc:set_selection(i, s, i, e)
- break
- end
- end
+ local doc = view.doc
+ local start_pattern, end_pattern, end_replacement, start_replacement = 2, 2;
+ repeat
+ end_pattern = string.find(pattern, "/", end_pattern)
+ until end_pattern == nil or pattern[end_pattern-1] ~= "\\"
+ if end_pattern == nil then
+ end_pattern = #pattern + 1
+ else
+ end_pattern = end_pattern - 1
+ start_replacement = end_pattern+2;
+ end_replacement = end_pattern+2;
+ repeat
+ end_replacement = string.find(pattern, "/", end_replacement)
+ until end_replacement == nil or pattern[end_replacement-1] ~= "\\"
+ end
+ end_replacement = end_replacement and (end_replacement - 1)
+
+ local re = start_pattern ~= end_pattern
+ and regex.compile(pattern:sub(start_pattern, end_pattern))
+
+ local replacement = end_replacement and pattern:sub(
+ start_replacement, end_replacement
+ )
+ local replace_line = raw and function(line, new_text)
+ if line == #doc.lines then
+ doc:raw_remove(line, 1, line, #doc.lines[line], { idx = 1 }, 0)
+ else
+ doc:raw_remove(line, 1, line+1, 1, { idx = 1 }, 0)
+ end
+ doc:raw_insert(line, 1, new_text, { idx = 1 }, 0)
+ end or function(line, new_text)
+ if line == #doc.lines then
+ doc:remove(line, 1, line, #doc.lines[line])
+ else
+ doc:remove(line, 1, line+1, 1)
+ end
+ doc:insert(line, 1, new_text)
+ end
+
+ local line_scroll = nil
+ if re then
+ for i = (start_line or 1), (end_line or #doc.lines) do
+ local new_text, matches, rmatches
+ local old_text = old_lines[i] or doc.lines[i]
+ local old_length = #old_text
+ if replacement then
+ new_text, matches, rmatches = regex.gsub(re, old_text, replacement)
end
- if line_scroll then
- view:scroll_to_line(line_scroll, true)
+ if matches and #matches > 0 then
+ old_lines[i] = old_text
+ replace_line(i, new_text)
+ if line_scroll == nil then
+ line_scroll = i
+ doc:set_selection(i, rmatches[1][1], i, rmatches[1][2])
+ end
+ elseif old_lines[i] then
+ replace_line(i, old_lines[i])
+ old_lines[i] = nil
end
- end
- if replacement == nil then
- for k,v in pairs(old_lines) do
- replace_line(k, v)
+ if not replacement then
+ local s,e = regex.match(re, old_text)
+ if s then
+ line_scroll = i
+ doc:set_selection(i, s, i, e)
+ break
+ end
end
- old_lines = {}
- end
- return old_lines, line_scroll ~= nil
+ end
+ if line_scroll then
+ view:scroll_to_line(line_scroll, true)
+ end
+ end
+ if replacement == nil then
+ for k,v in pairs(old_lines) do
+ replace_line(k, v)
+ end
+ old_lines = {}
+ end
+ return old_lines, line_scroll ~= nil
end
command.add("core.docview", {
- ["regex-replace-preview:find-replace-regex"] = function()
- core.command_view:set_text("/")
- local old_lines = {}
- local view = core.active_view
- local doc = view.doc
- local original_selection = { doc:get_selection(true) }
- local selection = doc:has_selection() and { doc:get_selection(true) } or {}
- core.command_view:enter(
- "Regex Replace (enter pattern as /old/new/)",
- function(pattern)
- regex_replace_file(view, pattern, {}, false, selection[1], selection[3])
- end,
- function(pattern)
- local incremental, has_replacement = regex_replace_file(view, pattern, old_lines, true, selection[1], selection[3])
- if incremental then
- old_lines = incremental
- end
- if not has_replacement then
- doc:set_selection(unpack(original_selection))
+ ["regex-replace-preview:find-replace-regex"] = function()
+ local old_lines = {}
+ local view = core.active_view
+ local doc = view.doc
+ local original_selection = { doc:get_selection(true) }
+ local selection = doc:has_selection() and { doc:get_selection(true) } or {}
+ core.command_view:enter("Regex Replace (enter pattern as /old/new/)", {
+ text = "/",
+ submit = function(pattern)
+ regex_replace_file(view, pattern, {}, false, selection[1], selection[3])
+ end,
+ suggest = function(pattern)
+ local incremental, has_replacement = regex_replace_file(
+ view, pattern, old_lines, true, selection[1], selection[3]
+ )
+ if incremental then
+ old_lines = incremental
+ end
+ if not has_replacement then
+ doc:set_selection(table.unpack(original_selection))
+ end
+ end,
+ cancel = function(pattern)
+ for k,v in pairs(old_lines) do
+ if v then
+ if k == #doc.lines then
+ doc:raw_remove(k, 1, k, #doc.lines[k], { idx = 1 }, 0)
+ else
+ doc:raw_remove(k, 1, k+1, 1, { idx = 1 }, 0)
end
- end,
- function(pattern)
- for k,v in pairs(old_lines) do
- if v then
- if k == #doc.lines then
- doc:raw_remove(k, 1, k, #doc.lines[k], { idx = 1 }, 0)
- else
- doc:raw_remove(k, 1, k+1, 1, { idx = 1 }, 0)
- end
- doc:raw_insert(k, 1, v, { idx = 1 }, 0)
- end
- end
- doc:set_selection(unpack(original_selection))
- end
- )
- end
+ doc:raw_insert(k, 1, v, { idx = 1 }, 0)
+ end
+ end
+ doc:set_selection(table.unpack(original_selection))
+ end
+ })
+ end
})
keymap.add { ["ctrl+shift+r"] = "regex-replace-preview:find-replace-regex" }