From e51263820013d5e283bc724a5abbff23e930c495 Mon Sep 17 00:00:00 2001 From: Miguel Roldao Date: Thu, 21 Nov 2024 05:36:19 +0000 Subject: [PATCH 1/4] add support for multi-cursor comments --- runtime/plugins/comment/comment.lua | 99 +++++++++++-------------- runtime/plugins/comment/help/comment.md | 4 +- 2 files changed, 45 insertions(+), 58 deletions(-) diff --git a/runtime/plugins/comment/comment.lua b/runtime/plugins/comment/comment.lua index ccda2e1297..b2fab9ddde 100644 --- a/runtime/plugins/comment/comment.lua +++ b/runtime/plugins/comment/comment.lua @@ -1,4 +1,4 @@ -VERSION = "1.0.0" +VERSION = "1.1.0" local util = import("micro/util") local config = import("micro/config") @@ -84,66 +84,31 @@ end function isCommented(bp, lineN, commentRegex) local line = bp.Buf:Line(lineN) local regex = commentRegex:gsub("%s+", "%s*") - if string.match(line, regex) then - return true - end - return false + return string.match(line, regex) end function commentLine(bp, lineN, indentLen) - updateCommentType(bp.Buf) - local line = bp.Buf:Line(lineN) - local commentType = bp.Buf.Settings["comment.type"] - local sel = -bp.Cursor.CurSelection - local curpos = -bp.Cursor.Loc - local index = string.find(commentType, "%%s") - 1 + local commentType = bp.Buf.Settings["commenttype"] local indent = string.sub(line, 1, indentLen) local trimmedLine = string.sub(line, indentLen + 1) trimmedLine = trimmedLine:gsub("%%", "%%%%") local commentedLine = commentType:gsub("%%s", trimmedLine) bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), indent .. commentedLine) - if bp.Cursor:HasSelection() then - bp.Cursor.CurSelection[1].Y = sel[1].Y - bp.Cursor.CurSelection[2].Y = sel[2].Y - bp.Cursor.CurSelection[1].X = sel[1].X - bp.Cursor.CurSelection[2].X = sel[2].X - else - bp.Cursor.X = curpos.X + index - bp.Cursor.Y = curpos.Y - end - bp.Cursor:Relocate() - bp.Cursor:StoreVisualX() end function uncommentLine(bp, lineN, commentRegex) - updateCommentType(bp.Buf) - local line = bp.Buf:Line(lineN) - local commentType = bp.Buf.Settings["comment.type"] - local sel = -bp.Cursor.CurSelection - local curpos = -bp.Cursor.Loc - local index = string.find(commentType, "%%s") - 1 if not string.match(line, commentRegex) then commentRegex = commentRegex:gsub("%s+", "%s*") end if string.match(line, commentRegex) then uncommentedLine = string.match(line, commentRegex) bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. uncommentedLine) - if bp.Cursor:HasSelection() then - bp.Cursor.CurSelection[1].Y = sel[1].Y - bp.Cursor.CurSelection[2].Y = sel[2].Y - bp.Cursor.CurSelection[1].X = sel[1].X - bp.Cursor.CurSelection[2].X = sel[2].X - else - bp.Cursor.X = curpos.X - index - bp.Cursor.Y = curpos.Y - end end - bp.Cursor:Relocate() - bp.Cursor:StoreVisualX() end +-- unused function toggleCommentLine(bp, lineN, commentRegex) if isCommented(bp, lineN, commentRegex) then uncommentLine(bp, lineN, commentRegex) @@ -152,9 +117,9 @@ function toggleCommentLine(bp, lineN, commentRegex) end end -function toggleCommentSelection(bp, startLine, endLine, commentRegex) +function toggleCommentSelection(bp, lines, commentRegex) local allComments = true - for line = startLine, endLine do + for line,_ in pairs(lines) do if not isCommented(bp, line, commentRegex) then allComments = false break @@ -164,7 +129,7 @@ function toggleCommentSelection(bp, startLine, endLine, commentRegex) -- NOTE: we assume that the indentation is either tabs only or spaces only local indentMin = -1 if not allComments then - for line = startLine, endLine do + for line,_ in pairs(lines) do local indentLen = #util.GetLeadingWhitespace(bp.Buf:Line(line)) if indentMin == -1 or indentLen < indentMin then indentMin = indentLen @@ -172,13 +137,14 @@ function toggleCommentSelection(bp, startLine, endLine, commentRegex) end end - for line = startLine, endLine do + for line,_ in pairs(lines) do if allComments then uncommentLine(bp, line, commentRegex) else commentLine(bp, line, indentMin) end end + return not allComments end function comment(bp, args) @@ -187,22 +153,43 @@ function comment(bp, args) local commentType = bp.Buf.Settings["comment.type"] local commentRegex = "^%s*" .. commentType:gsub("%%","%%%%"):gsub("%$","%$"):gsub("%)","%)"):gsub("%(","%("):gsub("%?","%?"):gsub("%*", "%*"):gsub("%-", "%-"):gsub("%.", "%."):gsub("%+", "%+"):gsub("%]", "%]"):gsub("%[", "%["):gsub("%%%%s", "(.*)") - if bp.Cursor:HasSelection() then - if bp.Cursor.CurSelection[1]:GreaterThan(-bp.Cursor.CurSelection[2]) then - local endLine = bp.Cursor.CurSelection[1].Y - if bp.Cursor.CurSelection[1].X == 0 then - endLine = endLine - 1 + local lines = {} + local curData = {} + -- gather cursor data and lines to (un)comment + for i = 0,#bp.Buf:getCursors()-1 do + local cursor = bp.Buf:getCursor(i) + local hasSelection = cursor:HasSelection() + table.insert(curData, { + sel = -cursor.CurSelection, + curpos = -cursor.Loc, + cursor = cursor, + hasSelection = hasSelection + }) + if hasSelection then + for lineN = cursor.CurSelection[1].Y, cursor.CurSelection[2].Y do + lines[lineN] = true end - toggleCommentSelection(bp, bp.Cursor.CurSelection[2].Y, endLine, commentRegex) else - local endLine = bp.Cursor.CurSelection[2].Y - if bp.Cursor.CurSelection[2].X == 0 then - endLine = endLine - 1 - end - toggleCommentSelection(bp, bp.Cursor.CurSelection[1].Y, endLine, commentRegex) + lines[cursor.Y] = true end - else - toggleCommentLine(bp, bp.Cursor.Y, commentRegex) + end + -- (un)comment selected lines + local commented = toggleCommentSelection(bp, lines, commentRegex) + -- restore cursors + local displacement = (string.find(commentType, "%%s") - 1) * (commented and 1 or -1) + for i=1,#curData do + local cursor = curData[i].cursor + if curData[i].hasSelection then + cursor.CurSelection[1].Y = curData[i].sel[1].Y + cursor.CurSelection[2].Y = curData[i].sel[2].Y + cursor.CurSelection[1].X = curData[i].sel[1].X + displacement + cursor.CurSelection[2].X = curData[i].sel[2].X + displacement + else + cursor.Y = curData[i].curpos.Y + cursor.X = curData[i].curpos.X + displacement + end + cursor:Relocate() + cursor:StoreVisualX() end end diff --git a/runtime/plugins/comment/help/comment.md b/runtime/plugins/comment/help/comment.md index fc0cfe01a3..7591630c94 100644 --- a/runtime/plugins/comment/help/comment.md +++ b/runtime/plugins/comment/help/comment.md @@ -19,8 +19,8 @@ the binding: > comment ``` -If you have a selection, the plugin will comment all the lines -selected. +If you have a selection of text, or multiple cursors, the plugin +will comment all the selected lines. The comment type will be auto detected based on the filetype, but it is only available for certain filetypes: From d867ff4a1096e904e067458150552edfd8399729 Mon Sep 17 00:00:00 2001 From: Miguel Roldao Date: Thu, 21 Nov 2024 15:53:04 +0000 Subject: [PATCH 2/4] added exception for selections that end in a new line (for backwards compatibility) --- runtime/plugins/comment/comment.lua | 41 ++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/runtime/plugins/comment/comment.lua b/runtime/plugins/comment/comment.lua index b2fab9ddde..10a913158d 100644 --- a/runtime/plugins/comment/comment.lua +++ b/runtime/plugins/comment/comment.lua @@ -156,22 +156,36 @@ function comment(bp, args) local lines = {} local curData = {} -- gather cursor data and lines to (un)comment - for i = 0,#bp.Buf:getCursors()-1 do - local cursor = bp.Buf:getCursor(i) + for i = 1,#bp.Buf:getCursors() do + local cursor = bp.Buf:getCursor(i-1) local hasSelection = cursor:HasSelection() - table.insert(curData, { - sel = -cursor.CurSelection, - curpos = -cursor.Loc, - cursor = cursor, - hasSelection = hasSelection - }) + local staticEnd = false + local startSel = 1 + local endSel = 2 if hasSelection then - for lineN = cursor.CurSelection[1].Y, cursor.CurSelection[2].Y do + if cursor.CurSelection[1]:GreaterThan(-cursor.CurSelection[2]) then + startSel = 2 + endSel = 1 + end + for lineN = cursor.CurSelection[startSel].Y, cursor.CurSelection[endSel].Y do lines[lineN] = true end + if cursor.CurSelection[endSel].X == 0 then + lines[cursor.CurSelection[endSel].Y] = nil + staticEnd = true + end else lines[cursor.Y] = true end + table.insert(curData, { + sel = -cursor.CurSelection, + curpos = -cursor.Loc, + cursor = cursor, + hasSelection = hasSelection, + staticEnd = staticEnd, + startSel = startSel, + endSel = endSel + }) end -- (un)comment selected lines local commented = toggleCommentSelection(bp, lines, commentRegex) @@ -180,10 +194,11 @@ function comment(bp, args) for i=1,#curData do local cursor = curData[i].cursor if curData[i].hasSelection then - cursor.CurSelection[1].Y = curData[i].sel[1].Y - cursor.CurSelection[2].Y = curData[i].sel[2].Y - cursor.CurSelection[1].X = curData[i].sel[1].X + displacement - cursor.CurSelection[2].X = curData[i].sel[2].X + displacement + local sel, startSel, endSel = curData[i].sel, curData[i].startSel, curData[i].endSel + cursor.CurSelection[startSel].X = sel[startSel].X + displacement + cursor.CurSelection[startSel].Y = sel[startSel].Y + cursor.CurSelection[endSel].X = sel[endSel].X + (curData[i].staticEnd and 0 or displacement) + cursor.CurSelection[endSel].Y = sel[endSel].Y else cursor.Y = curData[i].curpos.Y cursor.X = curData[i].curpos.X + displacement From 1419cdceb8ef68007297574b7fcecec8f61158db Mon Sep 17 00:00:00 2001 From: Andriamanitra Date: Sun, 24 Nov 2024 08:49:23 +0200 Subject: [PATCH 3/4] bugfixes --- runtime/plugins/comment/comment.lua | 36 +++++++++++++++-------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/runtime/plugins/comment/comment.lua b/runtime/plugins/comment/comment.lua index 10a913158d..30a90a45eb 100644 --- a/runtime/plugins/comment/comment.lua +++ b/runtime/plugins/comment/comment.lua @@ -159,20 +159,25 @@ function comment(bp, args) for i = 1,#bp.Buf:getCursors() do local cursor = bp.Buf:getCursor(i-1) local hasSelection = cursor:HasSelection() - local staticEnd = false - local startSel = 1 - local endSel = 2 + local excludedEnd = nil if hasSelection then - if cursor.CurSelection[1]:GreaterThan(-cursor.CurSelection[2]) then + local startSel = 1 + local endSel = 2 + if cursor.CurSelection[startSel]:GreaterThan(-cursor.CurSelection[endSel]) then startSel = 2 endSel = 1 end - for lineN = cursor.CurSelection[startSel].Y, cursor.CurSelection[endSel].Y do - lines[lineN] = true - end + local fromLineNo = cursor.CurSelection[startSel].Y + local toLineNo = cursor.CurSelection[endSel].Y + + -- don't indent the line after when selection ends in a newline if cursor.CurSelection[endSel].X == 0 then - lines[cursor.CurSelection[endSel].Y] = nil - staticEnd = true + excludedEnd = endSel + toLineNo = toLineNo - 1 + end + + for lineN = fromLineNo,toLineNo do + lines[lineN] = true end else lines[cursor.Y] = true @@ -182,9 +187,7 @@ function comment(bp, args) curpos = -cursor.Loc, cursor = cursor, hasSelection = hasSelection, - staticEnd = staticEnd, - startSel = startSel, - endSel = endSel + excludedEnd = excludedEnd, }) end -- (un)comment selected lines @@ -194,11 +197,10 @@ function comment(bp, args) for i=1,#curData do local cursor = curData[i].cursor if curData[i].hasSelection then - local sel, startSel, endSel = curData[i].sel, curData[i].startSel, curData[i].endSel - cursor.CurSelection[startSel].X = sel[startSel].X + displacement - cursor.CurSelection[startSel].Y = sel[startSel].Y - cursor.CurSelection[endSel].X = sel[endSel].X + (curData[i].staticEnd and 0 or displacement) - cursor.CurSelection[endSel].Y = sel[endSel].Y + for j=1,2 do + cursor.CurSelection[j].Y = curData[i].sel[j].Y + cursor.CurSelection[j].X = curData[i].sel[j].X + (j == curData[i].excludedEnd and 0 or displacement) + end else cursor.Y = curData[i].curpos.Y cursor.X = curData[i].curpos.X + displacement From dba64dbbb3b44756d00fad353322d026da0ce6b1 Mon Sep 17 00:00:00 2001 From: mroldao Date: Tue, 11 Nov 2025 20:44:55 +0000 Subject: [PATCH 4/4] fixed versioning and removed unused code --- runtime/plugins/comment/comment.lua | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/runtime/plugins/comment/comment.lua b/runtime/plugins/comment/comment.lua index 30a90a45eb..916187b959 100644 --- a/runtime/plugins/comment/comment.lua +++ b/runtime/plugins/comment/comment.lua @@ -1,4 +1,4 @@ -VERSION = "1.1.0" +VERSION = "1.0.0" local util = import("micro/util") local config = import("micro/config") @@ -108,15 +108,6 @@ function uncommentLine(bp, lineN, commentRegex) end end --- unused -function toggleCommentLine(bp, lineN, commentRegex) - if isCommented(bp, lineN, commentRegex) then - uncommentLine(bp, lineN, commentRegex) - else - commentLine(bp, lineN, #util.GetLeadingWhitespace(bp.Buf:Line(lineN))) - end -end - function toggleCommentSelection(bp, lines, commentRegex) local allComments = true for line,_ in pairs(lines) do