Skip to content

Commit e512638

Browse files
committed
add support for multi-cursor comments
1 parent 5dabe17 commit e512638

2 files changed

Lines changed: 45 additions & 58 deletions

File tree

runtime/plugins/comment/comment.lua

Lines changed: 43 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION = "1.0.0"
1+
VERSION = "1.1.0"
22

33
local util = import("micro/util")
44
local config = import("micro/config")
@@ -84,66 +84,31 @@ end
8484
function isCommented(bp, lineN, commentRegex)
8585
local line = bp.Buf:Line(lineN)
8686
local regex = commentRegex:gsub("%s+", "%s*")
87-
if string.match(line, regex) then
88-
return true
89-
end
90-
return false
87+
return string.match(line, regex)
9188
end
9289

9390
function commentLine(bp, lineN, indentLen)
94-
updateCommentType(bp.Buf)
95-
9691
local line = bp.Buf:Line(lineN)
97-
local commentType = bp.Buf.Settings["comment.type"]
98-
local sel = -bp.Cursor.CurSelection
99-
local curpos = -bp.Cursor.Loc
100-
local index = string.find(commentType, "%%s") - 1
92+
local commentType = bp.Buf.Settings["commenttype"]
10193
local indent = string.sub(line, 1, indentLen)
10294
local trimmedLine = string.sub(line, indentLen + 1)
10395
trimmedLine = trimmedLine:gsub("%%", "%%%%")
10496
local commentedLine = commentType:gsub("%%s", trimmedLine)
10597
bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), indent .. commentedLine)
106-
if bp.Cursor:HasSelection() then
107-
bp.Cursor.CurSelection[1].Y = sel[1].Y
108-
bp.Cursor.CurSelection[2].Y = sel[2].Y
109-
bp.Cursor.CurSelection[1].X = sel[1].X
110-
bp.Cursor.CurSelection[2].X = sel[2].X
111-
else
112-
bp.Cursor.X = curpos.X + index
113-
bp.Cursor.Y = curpos.Y
114-
end
115-
bp.Cursor:Relocate()
116-
bp.Cursor:StoreVisualX()
11798
end
11899

119100
function uncommentLine(bp, lineN, commentRegex)
120-
updateCommentType(bp.Buf)
121-
122101
local line = bp.Buf:Line(lineN)
123-
local commentType = bp.Buf.Settings["comment.type"]
124-
local sel = -bp.Cursor.CurSelection
125-
local curpos = -bp.Cursor.Loc
126-
local index = string.find(commentType, "%%s") - 1
127102
if not string.match(line, commentRegex) then
128103
commentRegex = commentRegex:gsub("%s+", "%s*")
129104
end
130105
if string.match(line, commentRegex) then
131106
uncommentedLine = string.match(line, commentRegex)
132107
bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. uncommentedLine)
133-
if bp.Cursor:HasSelection() then
134-
bp.Cursor.CurSelection[1].Y = sel[1].Y
135-
bp.Cursor.CurSelection[2].Y = sel[2].Y
136-
bp.Cursor.CurSelection[1].X = sel[1].X
137-
bp.Cursor.CurSelection[2].X = sel[2].X
138-
else
139-
bp.Cursor.X = curpos.X - index
140-
bp.Cursor.Y = curpos.Y
141-
end
142108
end
143-
bp.Cursor:Relocate()
144-
bp.Cursor:StoreVisualX()
145109
end
146110

111+
-- unused
147112
function toggleCommentLine(bp, lineN, commentRegex)
148113
if isCommented(bp, lineN, commentRegex) then
149114
uncommentLine(bp, lineN, commentRegex)
@@ -152,9 +117,9 @@ function toggleCommentLine(bp, lineN, commentRegex)
152117
end
153118
end
154119

155-
function toggleCommentSelection(bp, startLine, endLine, commentRegex)
120+
function toggleCommentSelection(bp, lines, commentRegex)
156121
local allComments = true
157-
for line = startLine, endLine do
122+
for line,_ in pairs(lines) do
158123
if not isCommented(bp, line, commentRegex) then
159124
allComments = false
160125
break
@@ -164,21 +129,22 @@ function toggleCommentSelection(bp, startLine, endLine, commentRegex)
164129
-- NOTE: we assume that the indentation is either tabs only or spaces only
165130
local indentMin = -1
166131
if not allComments then
167-
for line = startLine, endLine do
132+
for line,_ in pairs(lines) do
168133
local indentLen = #util.GetLeadingWhitespace(bp.Buf:Line(line))
169134
if indentMin == -1 or indentLen < indentMin then
170135
indentMin = indentLen
171136
end
172137
end
173138
end
174139

175-
for line = startLine, endLine do
140+
for line,_ in pairs(lines) do
176141
if allComments then
177142
uncommentLine(bp, line, commentRegex)
178143
else
179144
commentLine(bp, line, indentMin)
180145
end
181146
end
147+
return not allComments
182148
end
183149

184150
function comment(bp, args)
@@ -187,22 +153,43 @@ function comment(bp, args)
187153
local commentType = bp.Buf.Settings["comment.type"]
188154
local commentRegex = "^%s*" .. commentType:gsub("%%","%%%%"):gsub("%$","%$"):gsub("%)","%)"):gsub("%(","%("):gsub("%?","%?"):gsub("%*", "%*"):gsub("%-", "%-"):gsub("%.", "%."):gsub("%+", "%+"):gsub("%]", "%]"):gsub("%[", "%["):gsub("%%%%s", "(.*)")
189155

190-
if bp.Cursor:HasSelection() then
191-
if bp.Cursor.CurSelection[1]:GreaterThan(-bp.Cursor.CurSelection[2]) then
192-
local endLine = bp.Cursor.CurSelection[1].Y
193-
if bp.Cursor.CurSelection[1].X == 0 then
194-
endLine = endLine - 1
156+
local lines = {}
157+
local curData = {}
158+
-- gather cursor data and lines to (un)comment
159+
for i = 0,#bp.Buf:getCursors()-1 do
160+
local cursor = bp.Buf:getCursor(i)
161+
local hasSelection = cursor:HasSelection()
162+
table.insert(curData, {
163+
sel = -cursor.CurSelection,
164+
curpos = -cursor.Loc,
165+
cursor = cursor,
166+
hasSelection = hasSelection
167+
})
168+
if hasSelection then
169+
for lineN = cursor.CurSelection[1].Y, cursor.CurSelection[2].Y do
170+
lines[lineN] = true
195171
end
196-
toggleCommentSelection(bp, bp.Cursor.CurSelection[2].Y, endLine, commentRegex)
197172
else
198-
local endLine = bp.Cursor.CurSelection[2].Y
199-
if bp.Cursor.CurSelection[2].X == 0 then
200-
endLine = endLine - 1
201-
end
202-
toggleCommentSelection(bp, bp.Cursor.CurSelection[1].Y, endLine, commentRegex)
173+
lines[cursor.Y] = true
203174
end
204-
else
205-
toggleCommentLine(bp, bp.Cursor.Y, commentRegex)
175+
end
176+
-- (un)comment selected lines
177+
local commented = toggleCommentSelection(bp, lines, commentRegex)
178+
-- restore cursors
179+
local displacement = (string.find(commentType, "%%s") - 1) * (commented and 1 or -1)
180+
for i=1,#curData do
181+
local cursor = curData[i].cursor
182+
if curData[i].hasSelection then
183+
cursor.CurSelection[1].Y = curData[i].sel[1].Y
184+
cursor.CurSelection[2].Y = curData[i].sel[2].Y
185+
cursor.CurSelection[1].X = curData[i].sel[1].X + displacement
186+
cursor.CurSelection[2].X = curData[i].sel[2].X + displacement
187+
else
188+
cursor.Y = curData[i].curpos.Y
189+
cursor.X = curData[i].curpos.X + displacement
190+
end
191+
cursor:Relocate()
192+
cursor:StoreVisualX()
206193
end
207194
end
208195

runtime/plugins/comment/help/comment.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ the binding:
1919
> comment
2020
```
2121

22-
If you have a selection, the plugin will comment all the lines
23-
selected.
22+
If you have a selection of text, or multiple cursors, the plugin
23+
will comment all the selected lines.
2424

2525
The comment type will be auto detected based on the filetype,
2626
but it is only available for certain filetypes:

0 commit comments

Comments
 (0)