diff options
author | Guldoman <giulio.lettieri@gmail.com> | 2023-05-27 20:38:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-27 14:38:38 -0400 |
commit | 05370606bc2aafe4f2501522f0eacbd12b6e0637 (patch) | |
tree | 41925b1f7fea802dce1b1d96e64c97383ec4f4eb /plugins | |
parent | f139863fdee4f1c54468ff9be856de006cbcb099 (diff) | |
download | lite-xl-plugins-05370606bc2aafe4f2501522f0eacbd12b6e0637.tar.gz lite-xl-plugins-05370606bc2aafe4f2501522f0eacbd12b6e0637.zip |
Fix indentation in `lfautoinsert` and add support for multiple carets (#256)
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/lfautoinsert.lua | 70 |
1 files changed, 49 insertions, 21 deletions
diff --git a/plugins/lfautoinsert.lua b/plugins/lfautoinsert.lua index 492f323..3e5302f 100644 --- a/plugins/lfautoinsert.lua +++ b/plugins/lfautoinsert.lua @@ -66,31 +66,59 @@ end command.add("core.docview!", { ["autoinsert:newline"] = function(dv) - command.perform("doc:newline") - + local not_applied = { } + local fallback = true local doc = dv.doc - local line, col = doc:get_selection() - local text = doc.lines[line - 1] + local indent_type, soft_size = doc:get_indent_info() + local indent_string = indent_type == "hard" and "\t" or string.rep(" ", soft_size) + + for idx, line, col, line2, col2 in doc:get_selections(true, true) do + -- We need to add `\n` to keep compatibility with the patterns + -- that expected a newline to be placed where the caret is. + local text = doc.lines[line]:sub(1, col - 1) .. '\n' + local remainder = doc.lines[line]:sub(col, -1) + local current_indent = text:match("^[\t ]*") - for ptn, close in pairs(get_autoinsert_map(doc.filename)) do - local s, _, str = text:find(ptn) - if s then - if close - and col == #doc.lines[line] - and indent_size(doc, line + 1) <= indent_size(doc, line - 1) - then - close = str and close:gsub("$TEXT", str) or close - command.perform("doc:newline") - core.active_view:on_text_input(close) - command.perform("doc:move-to-previous-line") - if doc.lines[line+1] == doc.lines[line+2] then - doc:remove(line+1, 1, line+2, 1) + local pre, post + for ptn, close in pairs(get_autoinsert_map(doc.filename)) do + local s, _, str = text:find(ptn) + if s then + pre = string.format("\n%s%s", current_indent, indent_string) + if close + and col == #doc.lines[line] + and indent_size(doc, line + 1) <= indent_size(doc, line) + then + close = str and close:gsub("$TEXT", str) or close + -- Avoid inserting `close` if it's already present + if remainder:find("^"..close) then + close = "" + end + post = string.format("\n%s%s", current_indent, close) + elseif col < #doc.lines[line] then + post = string.format("\n%s", current_indent) end - elseif col < #doc.lines[line] then - command.perform("doc:newline") - command.perform("doc:move-to-previous-line") + break end - command.perform("doc:indent") + end + + if pre or post then + fallback = false + doc:text_input(pre or "", idx) + local l, c, l2, c2 = doc:get_selection_idx(idx) + doc:text_input(post or "", idx) + doc:set_selections(idx, l, c, l2, c2) + else + table.insert(not_applied, {idx, current_indent}) + end + end + + -- Only call the fallback if no autoinsert was applied + if fallback then + command.perform("doc:newline") + else + for _,v in ipairs(not_applied) do + local idx, indent = table.unpack(v) + doc:text_input("\n"..indent, idx) end end end |