From 4d31b1bc404a56a1160f75ed82adec24042d676e Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sat, 25 Dec 2021 12:57:00 +0800 Subject: [PATCH 1/6] add toggle-block-comment --- data/core/commands/doc.lua | 48 ++++++++++++++++++++++++++++++++++ data/core/keymap.lua | 1 + data/plugins/language_c.lua | 1 + data/plugins/language_cpp.lua | 1 + data/plugins/language_css.lua | 1 + data/plugins/language_html.lua | 31 +++++++++++----------- data/plugins/language_js.lua | 1 + data/plugins/language_lua.lua | 1 + data/plugins/language_xml.lua | 1 + 9 files changed, 71 insertions(+), 15 deletions(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index 8e2078f3..1e65ad11 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -292,6 +292,54 @@ local commands = { end end, + ["doc:toggle-block-comments"] = function() + local comment = doc().syntax.multiline_comment + if not comment then return end + + for idx, line1, col1, line2, col2 in doc_multiline_selections(true) do + local text = doc():get_text(line1, col1, line2, col2) + + -- might need to deal with unicode later... + local cs, cse = text:find(comment[1], 1, true) + local ce = text:find(comment[2], #text - #comment[2] + 1, true) + + local new_col1, new_col2 = col1, col2 + -- uncomment + if cs and ce then + if line1 == line2 then + new_col2 = new_col2 - #table.concat(comment) + else + new_col2 = new_col2 - #comment[2] + end + + -- remove 1 whitespace if possible + if text:sub(cse + 1, cse + 1) == " " then + cse = cse + 1 + if line1 == line2 then + new_col2 = new_col2 - 1 + end + end + if text:sub(ce - 1, ce - 1) == " " then + ce = ce - 1 + new_col2 = new_col2 - 1 + end + + text = text:sub(cse + 1, ce - 1) + -- comment + else + text = comment[1] .. " " .. text .. " " .. comment[2] + if line1 == line2 then + new_col2 = new_col2 + #table.concat(comment) + 2 + else + new_col2 = new_col2 + #comment[2] + 1 + end + end + doc():remove(line1, col1, line2, col2) + doc():insert(line1, col1, text) + doc():set_selections(idx, line1, new_col1, line2, new_col2) + end + end, + ["doc:toggle-line-comments"] = function() local comment = doc().syntax.comment if not comment then return end diff --git a/data/core/keymap.lua b/data/core/keymap.lua index 404cff39..6716fca9 100644 --- a/data/core/keymap.lua +++ b/data/core/keymap.lua @@ -215,6 +215,7 @@ keymap.add_direct { ["ctrl+l"] = "doc:select-lines", ["ctrl+shift+l"] = { "find-replace:select-add-all", "doc:select-word" }, ["ctrl+/"] = "doc:toggle-line-comments", + ["ctrl+shift+/"] = "doc:toggle-block-comments", ["ctrl+up"] = "doc:move-lines-up", ["ctrl+down"] = "doc:move-lines-down", ["ctrl+shift+d"] = "doc:duplicate-lines", diff --git a/data/plugins/language_c.lua b/data/plugins/language_c.lua index 88cc7c5a..ecbeed7a 100644 --- a/data/plugins/language_c.lua +++ b/data/plugins/language_c.lua @@ -5,6 +5,7 @@ syntax.add { name = "C", files = { "%.c$", "%.h$", "%.inl$" }, comment = "//", + multiline_comment = { "/*", "*/" }, patterns = { { pattern = "//.-\n", type = "comment" }, { pattern = { "/%*", "%*/" }, type = "comment" }, diff --git a/data/plugins/language_cpp.lua b/data/plugins/language_cpp.lua index a945fd1f..03554a48 100644 --- a/data/plugins/language_cpp.lua +++ b/data/plugins/language_cpp.lua @@ -10,6 +10,7 @@ syntax.add { "%.c++$", "%.hh$", "%.H$", "%.hxx$", "%.hpp$", "%.h++$" }, comment = "//", + multiline_comment = { "/*", "*/" }, patterns = { { pattern = "//.-\n", type = "comment" }, { pattern = { "/%*", "%*/" }, type = "comment" }, diff --git a/data/plugins/language_css.lua b/data/plugins/language_css.lua index 395e375c..871598a2 100644 --- a/data/plugins/language_css.lua +++ b/data/plugins/language_css.lua @@ -4,6 +4,7 @@ local syntax = require "core.syntax" syntax.add { name = "CSS", files = { "%.css$" }, + multiline_comment = { "/*", "*/" }, patterns = { { pattern = "\\.", type = "normal" }, { pattern = "//.-\n", type = "comment" }, diff --git a/data/plugins/language_html.lua b/data/plugins/language_html.lua index 1f4515bc..e22e8897 100644 --- a/data/plugins/language_html.lua +++ b/data/plugins/language_html.lua @@ -4,28 +4,29 @@ local syntax = require "core.syntax" syntax.add { name = "HTML", files = { "%.html?$" }, + multiline_comment = { "" }, patterns = { - { - pattern = { + { + pattern = { "<%s*[sS][cC][rR][iI][pP][tT]%s+[tT][yY][pP][eE]%s*=%s*" .. "['\"]%a+/[jJ][aA][vV][aA][sS][cC][rR][iI][pP][tT]['\"]%s*>", - "<%s*/[sS][cC][rR][iI][pP][tT]>" - }, - syntax = ".js", - type = "function" - }, - { - pattern = { - "<%s*[sS][cC][rR][iI][pP][tT]%s*>", - "<%s*/%s*[sS][cC][rR][iI][pP][tT]>" + "<%s*/[sS][cC][rR][iI][pP][tT]>" }, syntax = ".js", type = "function" }, - { - pattern = { - "<%s*[sS][tT][yY][lL][eE][^>]*>", - "<%s*/%s*[sS][tT][yY][lL][eE]%s*>" + { + pattern = { + "<%s*[sS][cC][rR][iI][pP][tT]%s*>", + "<%s*/%s*[sS][cC][rR][iI][pP][tT]>" + }, + syntax = ".js", + type = "function" + }, + { + pattern = { + "<%s*[sS][tT][yY][lL][eE][^>]*>", + "<%s*/%s*[sS][tT][yY][lL][eE]%s*>" }, syntax = ".css", type = "function" diff --git a/data/plugins/language_js.lua b/data/plugins/language_js.lua index 94ab8499..d23e412b 100644 --- a/data/plugins/language_js.lua +++ b/data/plugins/language_js.lua @@ -5,6 +5,7 @@ syntax.add { name = "JavaScript", files = { "%.js$", "%.json$", "%.cson$" }, comment = "//", + multiline_comment = { "/*", "*/" }, patterns = { { pattern = "//.-\n", type = "comment" }, { pattern = { "/%*", "%*/" }, type = "comment" }, diff --git a/data/plugins/language_lua.lua b/data/plugins/language_lua.lua index 5c770d43..79a8289b 100644 --- a/data/plugins/language_lua.lua +++ b/data/plugins/language_lua.lua @@ -6,6 +6,7 @@ syntax.add { files = "%.lua$", headers = "^#!.*[ /]lua", comment = "--", + multiline_comment = { "--[[", "]]" }, patterns = { { pattern = { '"', '"', '\\' }, type = "string" }, { pattern = { "'", "'", '\\' }, type = "string" }, diff --git a/data/plugins/language_xml.lua b/data/plugins/language_xml.lua index c858d3cf..971a53de 100644 --- a/data/plugins/language_xml.lua +++ b/data/plugins/language_xml.lua @@ -5,6 +5,7 @@ syntax.add { name = "XML", files = { "%.xml$" }, headers = "<%?xml", + multiline_comment = { "" }, patterns = { { pattern = { "" }, type = "comment" }, { pattern = { '%f[^>][^<]', '%f[<]' }, type = "normal" }, From 69a857bbbfd4ab12dc5ef463508dc44c69c67e93 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sun, 26 Dec 2021 15:05:27 +0800 Subject: [PATCH 2/6] fallback to toggle-line-comment and vice versa if needed --- data/core/commands/doc.lua | 16 +++++++++++++--- data/plugins/language_c.lua | 2 +- data/plugins/language_cpp.lua | 2 +- data/plugins/language_css.lua | 2 +- data/plugins/language_html.lua | 2 +- data/plugins/language_js.lua | 2 +- data/plugins/language_lua.lua | 2 +- data/plugins/language_xml.lua | 2 +- 8 files changed, 20 insertions(+), 10 deletions(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index 1e65ad11..edf36bbd 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -293,8 +293,13 @@ local commands = { end, ["doc:toggle-block-comments"] = function() - local comment = doc().syntax.multiline_comment - if not comment then return end + local comment = doc().syntax.block_comment + if not comment then + if doc().syntax.comment then + command.perform "doc:toggle-line-comments" + end + return + end for idx, line1, col1, line2, col2 in doc_multiline_selections(true) do local text = doc():get_text(line1, col1, line2, col2) @@ -342,7 +347,12 @@ local commands = { ["doc:toggle-line-comments"] = function() local comment = doc().syntax.comment - if not comment then return end + if not comment then + if doc().syntax.block_comment then + command.perform "doc:toggle-block-comments" + end + return + end local indentation = doc():get_indent_string() local comment_text = comment .. " " for idx, line1, _, line2 in doc_multiline_selections(true) do diff --git a/data/plugins/language_c.lua b/data/plugins/language_c.lua index ecbeed7a..c4d3b07b 100644 --- a/data/plugins/language_c.lua +++ b/data/plugins/language_c.lua @@ -5,7 +5,7 @@ syntax.add { name = "C", files = { "%.c$", "%.h$", "%.inl$" }, comment = "//", - multiline_comment = { "/*", "*/" }, + block_comment = { "/*", "*/" }, patterns = { { pattern = "//.-\n", type = "comment" }, { pattern = { "/%*", "%*/" }, type = "comment" }, diff --git a/data/plugins/language_cpp.lua b/data/plugins/language_cpp.lua index 03554a48..2b3a104f 100644 --- a/data/plugins/language_cpp.lua +++ b/data/plugins/language_cpp.lua @@ -10,7 +10,7 @@ syntax.add { "%.c++$", "%.hh$", "%.H$", "%.hxx$", "%.hpp$", "%.h++$" }, comment = "//", - multiline_comment = { "/*", "*/" }, + block_comment = { "/*", "*/" }, patterns = { { pattern = "//.-\n", type = "comment" }, { pattern = { "/%*", "%*/" }, type = "comment" }, diff --git a/data/plugins/language_css.lua b/data/plugins/language_css.lua index 871598a2..96c3eb8d 100644 --- a/data/plugins/language_css.lua +++ b/data/plugins/language_css.lua @@ -4,7 +4,7 @@ local syntax = require "core.syntax" syntax.add { name = "CSS", files = { "%.css$" }, - multiline_comment = { "/*", "*/" }, + block_comment = { "/*", "*/" }, patterns = { { pattern = "\\.", type = "normal" }, { pattern = "//.-\n", type = "comment" }, diff --git a/data/plugins/language_html.lua b/data/plugins/language_html.lua index e22e8897..ff61fa7f 100644 --- a/data/plugins/language_html.lua +++ b/data/plugins/language_html.lua @@ -4,7 +4,7 @@ local syntax = require "core.syntax" syntax.add { name = "HTML", files = { "%.html?$" }, - multiline_comment = { "" }, + block_comment = { "" }, patterns = { { pattern = { diff --git a/data/plugins/language_js.lua b/data/plugins/language_js.lua index d23e412b..2e6d5d87 100644 --- a/data/plugins/language_js.lua +++ b/data/plugins/language_js.lua @@ -5,7 +5,7 @@ syntax.add { name = "JavaScript", files = { "%.js$", "%.json$", "%.cson$" }, comment = "//", - multiline_comment = { "/*", "*/" }, + block_comment = { "/*", "*/" }, patterns = { { pattern = "//.-\n", type = "comment" }, { pattern = { "/%*", "%*/" }, type = "comment" }, diff --git a/data/plugins/language_lua.lua b/data/plugins/language_lua.lua index 79a8289b..993e53c8 100644 --- a/data/plugins/language_lua.lua +++ b/data/plugins/language_lua.lua @@ -6,7 +6,7 @@ syntax.add { files = "%.lua$", headers = "^#!.*[ /]lua", comment = "--", - multiline_comment = { "--[[", "]]" }, + block_comment = { "--[[", "]]" }, patterns = { { pattern = { '"', '"', '\\' }, type = "string" }, { pattern = { "'", "'", '\\' }, type = "string" }, diff --git a/data/plugins/language_xml.lua b/data/plugins/language_xml.lua index 971a53de..297b6d73 100644 --- a/data/plugins/language_xml.lua +++ b/data/plugins/language_xml.lua @@ -5,7 +5,7 @@ syntax.add { name = "XML", files = { "%.xml$" }, headers = "<%?xml", - multiline_comment = { "" }, + block_comment = { "" }, patterns = { { pattern = { "" }, type = "comment" }, { pattern = { '%f[^>][^<]', '%f[<]' }, type = "normal" }, From 33f7fe4fdaf1a640dfa33b1805aa948816e0222f Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sun, 26 Dec 2021 15:12:28 +0800 Subject: [PATCH 3/6] toggle comment for whole line if nothing is selected --- data/core/commands/doc.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index edf36bbd..977f233f 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -302,6 +302,11 @@ local commands = { end for idx, line1, col1, line2, col2 in doc_multiline_selections(true) do + -- if nothing is selected, toggle the whole line + if line1 == line2 and col1 == col2 then + col1 = 1 + col2 = #doc().lines[line1] + end local text = doc():get_text(line1, col1, line2, col2) -- might need to deal with unicode later... From e079ddfa3735e37add2798cface7d877af28832b Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sun, 2 Jan 2022 19:11:48 +0800 Subject: [PATCH 4/6] refactor toggle-block-comments, make command spaces aware, set selections correctly --- data/core/commands/doc.lua | 61 +++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index 977f233f..0b040d88 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -305,48 +305,41 @@ local commands = { -- if nothing is selected, toggle the whole line if line1 == line2 and col1 == col2 then col1 = 1 - col2 = #doc().lines[line1] + col2 = #doc().lines[line2] end - local text = doc():get_text(line1, col1, line2, col2) - -- might need to deal with unicode later... - local cs, cse = text:find(comment[1], 1, true) - local ce = text:find(comment[2], #text - #comment[2] + 1, true) + -- automatically skip spaces + local word_start = doc():get_text(line1, col1, line1, math.huge):find("%S") + local word_end = doc():get_text(line2, 1, line2, col2):find("%s*$") + col1 = col1 + (word_start and (word_start - 1) or 0) + col2 = word_end and word_end or col2 - local new_col1, new_col2 = col1, col2 - -- uncomment - if cs and ce then - if line1 == line2 then - new_col2 = new_col2 - #table.concat(comment) - else - new_col2 = new_col2 - #comment[2] + local block_start = doc():get_text(line1, col1, line1, col1 + #comment[1]) + local block_end = doc():get_text(line2, col2 - #comment[2], line2, col2) + + if block_start == comment[1] and block_end == comment[2] then + -- remove up to 1 whitespace after the comment + local start_len, stop_len = #comment[1], #comment[2] + if doc():get_text(line1, col1 + #comment[1], line1, col1 + #comment[1] + 1):find("%s$") then + start_len = start_len + 1 + end + if doc():get_text(line2, col2 - #comment[2] - 1, line2, col2):find("^%s") then + stop_len = stop_len + 1 end - -- remove 1 whitespace if possible - if text:sub(cse + 1, cse + 1) == " " then - cse = cse + 1 - if line1 == line2 then - new_col2 = new_col2 - 1 - end - end - if text:sub(ce - 1, ce - 1) == " " then - ce = ce - 1 - new_col2 = new_col2 - 1 - end + doc():remove(line1, col1, line1, col1 + start_len) + col2 = col2 - (line1 == line2 and start_len or 0) + doc():remove(line2, col2 - stop_len, line2, col2) - text = text:sub(cse + 1, ce - 1) - -- comment + doc():set_selections(1, line1, col1, line2, col2 - stop_len) else - text = comment[1] .. " " .. text .. " " .. comment[2] - if line1 == line2 then - new_col2 = new_col2 + #table.concat(comment) + 2 - else - new_col2 = new_col2 + #comment[2] + 1 - end + doc():insert(line1, col1, comment[1] .. " ") + col2 = col2 + (line1 == line2 and (#comment[1] + 1) or 0) + doc():insert(line2, col2, " " .. comment[2]) + + col2 = col2 + #comment[2] + 1 + doc():set_selections(idx, line1, col1, line2, col2) end - doc():remove(line1, col1, line2, col2) - doc():insert(line1, col1, text) - doc():set_selections(idx, line1, new_col1, line2, new_col2) end end, From df0f6fb94cb0efae95b9a5c03e35abdc14951ef8 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sun, 2 Jan 2022 19:18:08 +0800 Subject: [PATCH 5/6] make set_selections consistent --- data/core/commands/doc.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index 0b040d88..6337ae89 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -337,8 +337,7 @@ local commands = { col2 = col2 + (line1 == line2 and (#comment[1] + 1) or 0) doc():insert(line2, col2, " " .. comment[2]) - col2 = col2 + #comment[2] + 1 - doc():set_selections(idx, line1, col1, line2, col2) + doc():set_selections(idx, line1, col1, line2, col2 + #comment[2] + 1) end end end, From fc809b3172b5c80f98d4f5496fa7c5a4cc903623 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sat, 8 Jan 2022 18:45:38 +0800 Subject: [PATCH 6/6] comment the entire line when using block comment --- data/core/commands/doc.lua | 133 +++++++++++++++++++++---------------- 1 file changed, 74 insertions(+), 59 deletions(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index 6337ae89..54b84921 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -97,6 +97,67 @@ local function set_cursor(x, y, snap_type) core.blink_reset() end +local function line_comment(comment, line1, line2) + local comment_text = comment .. " " + local uncomment = true + local start_offset = math.huge + for line = line1, line2 do + local text = doc().lines[line] + local s = text:find("%S") + local cs, ce = text:find(comment_text, s, true) + if s and cs ~= s then + uncomment = false + start_offset = math.min(start_offset, s) + end + end + for line = line1, line2 do + local text = doc().lines[line] + local s = text:find("%S") + if uncomment then + local cs, ce = text:find(comment_text, s, true) + if ce then + doc():remove(line, cs, line, ce + 1) + end + elseif s then + doc():insert(line, start_offset, comment_text) + end + end +end + +local function block_comment(comment, line1, col1, line2, col2) + -- automatically skip spaces + local word_start = doc():get_text(line1, col1, line1, math.huge):find("%S") + local word_end = doc():get_text(line2, 1, line2, col2):find("%s*$") + col1 = col1 + (word_start and (word_start - 1) or 0) + col2 = word_end and word_end or col2 + + local block_start = doc():get_text(line1, col1, line1, col1 + #comment[1]) + local block_end = doc():get_text(line2, col2 - #comment[2], line2, col2) + + if block_start == comment[1] and block_end == comment[2] then + -- remove up to 1 whitespace after the comment + local start_len, stop_len = #comment[1], #comment[2] + if doc():get_text(line1, col1 + #comment[1], line1, col1 + #comment[1] + 1):find("%s$") then + start_len = start_len + 1 + end + if doc():get_text(line2, col2 - #comment[2] - 1, line2, col2):find("^%s") then + stop_len = stop_len + 1 + end + + doc():remove(line1, col1, line1, col1 + start_len) + col2 = col2 - (line1 == line2 and start_len or 0) + doc():remove(line2, col2 - stop_len, line2, col2) + + return line1, col1, line2, col2 - stop_len + else + doc():insert(line1, col1, comment[1] .. " ") + col2 = col2 + (line1 == line2 and (#comment[1] + 1) or 0) + doc():insert(line2, col2, " " .. comment[2]) + + return line1, col1, line2, col2 + #comment[2] + 1 + end +end + local selection_commands = { ["doc:select-none"] = function() local line, col = doc():get_selection() @@ -308,73 +369,27 @@ local commands = { col2 = #doc().lines[line2] end - -- automatically skip spaces - local word_start = doc():get_text(line1, col1, line1, math.huge):find("%S") - local word_end = doc():get_text(line2, 1, line2, col2):find("%s*$") - col1 = col1 + (word_start and (word_start - 1) or 0) - col2 = word_end and word_end or col2 - - local block_start = doc():get_text(line1, col1, line1, col1 + #comment[1]) - local block_end = doc():get_text(line2, col2 - #comment[2], line2, col2) - - if block_start == comment[1] and block_end == comment[2] then - -- remove up to 1 whitespace after the comment - local start_len, stop_len = #comment[1], #comment[2] - if doc():get_text(line1, col1 + #comment[1], line1, col1 + #comment[1] + 1):find("%s$") then - start_len = start_len + 1 - end - if doc():get_text(line2, col2 - #comment[2] - 1, line2, col2):find("^%s") then - stop_len = stop_len + 1 - end - - doc():remove(line1, col1, line1, col1 + start_len) - col2 = col2 - (line1 == line2 and start_len or 0) - doc():remove(line2, col2 - stop_len, line2, col2) - - doc():set_selections(1, line1, col1, line2, col2 - stop_len) - else - doc():insert(line1, col1, comment[1] .. " ") - col2 = col2 + (line1 == line2 and (#comment[1] + 1) or 0) - doc():insert(line2, col2, " " .. comment[2]) - - doc():set_selections(idx, line1, col1, line2, col2 + #comment[2] + 1) - end + line1, col1, line2, col2 = block_comment(comment, line1, col1, line2, col2) + doc():set_selections(idx, line1, col1, line2, col2) end end, ["doc:toggle-line-comments"] = function() local comment = doc().syntax.comment + local block = false if not comment then - if doc().syntax.block_comment then - command.perform "doc:toggle-block-comments" - end - return + comment = doc().syntax.block_comment + if not comment then return end + block = true end - local indentation = doc():get_indent_string() - local comment_text = comment .. " " - for idx, line1, _, line2 in doc_multiline_selections(true) do - local uncomment = true - local start_offset = math.huge - for line = line1, line2 do - local text = doc().lines[line] - local s = text:find("%S") - local cs, ce = text:find(comment_text, s, true) - if s and cs ~= s then - uncomment = false - start_offset = math.min(start_offset, s) - end - end - for line = line1, line2 do - local text = doc().lines[line] - local s = text:find("%S") - if uncomment then - local cs, ce = text:find(comment_text, s, true) - if ce then - doc():remove(line, cs, line, ce + 1) - end - elseif s then - doc():insert(line, start_offset, comment_text) + + for _, line1, _, line2 in doc_multiline_selections(true) do + if block then + for line = line1, line2 do + block_comment(comment, line, 1, line, #doc().lines[line]) end + else + line_comment(comment, line1, line2) end end end,