Comment plugin: improve commenting multi-line selection (#2668)

When commenting a block of multiple lines, the comment symbol is added
right before the first non-whitespace character in each line, e.g.:

void somefunc(int a)
{
    // if (a) {
        // a += 2;
        // printf("a = %d\n", a);
    // } else {
        // printf("none");
    // }
}

which isn't quite nice.

Change it to add the comment at the same position on each line, which is
the position of the leftmost non-whitespace in the entire block, e.g.:

void somefunc(int a)
{
    // if (a) {
    //     a += 2;
    //     printf("a = %d\n", a);
    // } else {
    //     printf("none");
    // }
}

Ref #2282
This commit is contained in:
Dmitry Maluka
2023-01-12 06:54:59 +01:00
committed by GitHub
parent 443ede470d
commit f1801f1958

View File

@@ -70,13 +70,14 @@ end
function isCommented(bp, lineN, commentRegex) function isCommented(bp, lineN, commentRegex)
local line = bp.Buf:Line(lineN) local line = bp.Buf:Line(lineN)
if string.match(line, commentRegex) then local regex = commentRegex:gsub("%s+", "%s*")
if string.match(line, regex) then
return true return true
end end
return false return false
end end
function commentLine(bp, lineN) function commentLine(bp, lineN, indentLen)
updateCommentType(bp.Buf) updateCommentType(bp.Buf)
local line = bp.Buf:Line(lineN) local line = bp.Buf:Line(lineN)
@@ -84,8 +85,11 @@ function commentLine(bp, lineN)
local sel = -bp.Cursor.CurSelection local sel = -bp.Cursor.CurSelection
local curpos = -bp.Cursor.Loc local curpos = -bp.Cursor.Loc
local index = string.find(commentType, "%%s") - 1 local index = string.find(commentType, "%%s") - 1
local commentedLine = commentType:gsub("%%s", trim(line)) local indent = string.sub(line, 1, indentLen)
bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. commentedLine) 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 if bp.Cursor:HasSelection() then
bp.Cursor.CurSelection[1].Y = sel[1].Y bp.Cursor.CurSelection[1].Y = sel[1].Y
bp.Cursor.CurSelection[2].Y = sel[2].Y bp.Cursor.CurSelection[2].Y = sel[2].Y
@@ -107,6 +111,9 @@ function uncommentLine(bp, lineN, commentRegex)
local sel = -bp.Cursor.CurSelection local sel = -bp.Cursor.CurSelection
local curpos = -bp.Cursor.Loc local curpos = -bp.Cursor.Loc
local index = string.find(commentType, "%%s") - 1 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 if string.match(line, commentRegex) then
uncommentedLine = string.match(line, commentRegex) uncommentedLine = string.match(line, commentRegex)
bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. uncommentedLine) bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. uncommentedLine)
@@ -128,7 +135,7 @@ function toggleCommentLine(bp, lineN, commentRegex)
if isCommented(bp, lineN, commentRegex) then if isCommented(bp, lineN, commentRegex) then
uncommentLine(bp, lineN, commentRegex) uncommentLine(bp, lineN, commentRegex)
else else
commentLine(bp, lineN) commentLine(bp, lineN, #util.GetLeadingWhitespace(bp.Buf:Line(lineN)))
end end
end end
@@ -141,11 +148,22 @@ function toggleCommentSelection(bp, startLine, endLine, commentRegex)
end end
end end
-- 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
local indentLen = #util.GetLeadingWhitespace(bp.Buf:Line(line))
if indentMin == -1 or indentLen < indentMin then
indentMin = indentLen
end
end
end
for line = startLine, endLine do for line = startLine, endLine do
if allComments then if allComments then
uncommentLine(bp, line, commentRegex) uncommentLine(bp, line, commentRegex)
else else
commentLine(bp, line) commentLine(bp, line, indentMin)
end end
end end
end end
@@ -154,7 +172,7 @@ function comment(bp, args)
updateCommentType(bp.Buf) updateCommentType(bp.Buf)
local commentType = bp.Buf.Settings["commenttype"] local commentType = bp.Buf.Settings["commenttype"]
local commentRegex = "^%s*" .. commentType:gsub("%%","%%%%"):gsub("%$","%$"):gsub("%)","%)"):gsub("%(","%("):gsub("%?","%?"):gsub("%*", "%*"):gsub("%-", "%-"):gsub("%.", "%."):gsub("%+", "%+"):gsub("%]", "%]"):gsub("%[", "%["):gsub("%%%%s", "(.*)"):gsub("%s+", "%s*") 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:HasSelection() then
if bp.Cursor.CurSelection[1]:GreaterThan(-bp.Cursor.CurSelection[2]) then if bp.Cursor.CurSelection[1]:GreaterThan(-bp.Cursor.CurSelection[2]) then
@@ -175,11 +193,6 @@ function comment(bp, args)
end end
end end
function trim(s)
local trimmed = s:gsub("^%s*(.-)%s*$", "%1"):gsub("%%","%%%%")
return trimmed
end
function string.starts(String,Start) function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start return string.sub(String,1,string.len(Start))==Start
end end