8383function isCommented (bp , lineN , commentRegex )
8484 local line = bp .Buf :Line (lineN )
8585 local regex = commentRegex :gsub (" %s+" , " %s*" )
86- if string.match (line , regex ) then
87- return true
88- end
89- return false
86+ return string.match (line , regex )
9087end
9188
9289function commentLine (bp , lineN , indentLen )
93- updateCommentType (bp .Buf )
94-
9590 local line = bp .Buf :Line (lineN )
9691 local commentType = bp .Buf .Settings [" comment.type" ]
9792 local sel = - bp .Cursor .CurSelection
@@ -102,22 +97,9 @@ function commentLine(bp, lineN, indentLen)
10297 trimmedLine = trimmedLine :gsub (" %%" , " %%%%" )
10398 local commentedLine = commentType :gsub (" %%s" , trimmedLine )
10499 bp .Buf :Replace (buffer .Loc (0 , lineN ), buffer .Loc (# line , lineN ), indent .. commentedLine )
105- if bp .Cursor :HasSelection () then
106- bp .Cursor .CurSelection [1 ].Y = sel [1 ].Y
107- bp .Cursor .CurSelection [2 ].Y = sel [2 ].Y
108- bp .Cursor .CurSelection [1 ].X = sel [1 ].X
109- bp .Cursor .CurSelection [2 ].X = sel [2 ].X
110- else
111- bp .Cursor .X = curpos .X + index
112- bp .Cursor .Y = curpos .Y
113- end
114- bp .Cursor :Relocate ()
115- bp .Cursor :StoreVisualX ()
116100end
117101
118102function uncommentLine (bp , lineN , commentRegex )
119- updateCommentType (bp .Buf )
120-
121103 local line = bp .Buf :Line (lineN )
122104 local commentType = bp .Buf .Settings [" comment.type" ]
123105 local sel = - bp .Cursor .CurSelection
@@ -129,20 +111,10 @@ function uncommentLine(bp, lineN, commentRegex)
129111 if string.match (line , commentRegex ) then
130112 uncommentedLine = string.match (line , commentRegex )
131113 bp .Buf :Replace (buffer .Loc (0 , lineN ), buffer .Loc (# line , lineN ), util .GetLeadingWhitespace (line ) .. uncommentedLine )
132- if bp .Cursor :HasSelection () then
133- bp .Cursor .CurSelection [1 ].Y = sel [1 ].Y
134- bp .Cursor .CurSelection [2 ].Y = sel [2 ].Y
135- bp .Cursor .CurSelection [1 ].X = sel [1 ].X
136- bp .Cursor .CurSelection [2 ].X = sel [2 ].X
137- else
138- bp .Cursor .X = curpos .X - index
139- bp .Cursor .Y = curpos .Y
140- end
141114 end
142- bp .Cursor :Relocate ()
143- bp .Cursor :StoreVisualX ()
144115end
145116
117+ -- unused
146118function toggleCommentLine (bp , lineN , commentRegex )
147119 if isCommented (bp , lineN , commentRegex ) then
148120 uncommentLine (bp , lineN , commentRegex )
@@ -151,9 +123,9 @@ function toggleCommentLine(bp, lineN, commentRegex)
151123 end
152124end
153125
154- function toggleCommentSelection (bp , startLine , endLine , commentRegex )
126+ function toggleCommentSelection (bp , lines , commentRegex )
155127 local allComments = true
156- for line = startLine , endLine do
128+ for line , _ in pairs ( lines ) do
157129 if not isCommented (bp , line , commentRegex ) then
158130 allComments = false
159131 break
@@ -163,21 +135,22 @@ function toggleCommentSelection(bp, startLine, endLine, commentRegex)
163135 -- NOTE: we assume that the indentation is either tabs only or spaces only
164136 local indentMin = - 1
165137 if not allComments then
166- for line = startLine , endLine do
138+ for line , _ in pairs ( lines ) do
167139 local indentLen = # util .GetLeadingWhitespace (bp .Buf :Line (line ))
168140 if indentMin == - 1 or indentLen < indentMin then
169141 indentMin = indentLen
170142 end
171143 end
172144 end
173145
174- for line = startLine , endLine do
146+ for line , _ in pairs ( lines ) do
175147 if allComments then
176148 uncommentLine (bp , line , commentRegex )
177149 else
178150 commentLine (bp , line , indentMin )
179151 end
180152 end
153+ return not allComments
181154end
182155
183156function comment (bp , args )
@@ -186,22 +159,60 @@ function comment(bp, args)
186159 local commentType = bp .Buf .Settings [" comment.type" ]
187160 local commentRegex = " ^%s*" .. commentType :gsub (" %%" ," %%%%" ):gsub (" %$" ," %$" ):gsub (" %)" ," %)" ):gsub (" %(" ," %(" ):gsub (" %?" ," %?" ):gsub (" %*" , " %*" ):gsub (" %-" , " %-" ):gsub (" %." , " %." ):gsub (" %+" , " %+" ):gsub (" %]" , " %]" ):gsub (" %[" , " %[" ):gsub (" %%%%s" , " (.*)" )
188161
189- if bp .Cursor :HasSelection () then
190- if bp .Cursor .CurSelection [1 ]:GreaterThan (- bp .Cursor .CurSelection [2 ]) then
191- local endLine = bp .Cursor .CurSelection [1 ].Y
192- if bp .Cursor .CurSelection [1 ].X == 0 then
193- endLine = endLine - 1
162+ local lines = {}
163+ local curData = {}
164+ -- gather cursor data and lines to (un)comment
165+ for i = 1 ,# bp .Buf :getCursors () do
166+ local cursor = bp .Buf :getCursor (i - 1 )
167+ local hasSelection = cursor :HasSelection ()
168+ local excludedEnd = nil
169+ if hasSelection then
170+ local startSel = 1
171+ local endSel = 2
172+ if cursor .CurSelection [startSel ]:GreaterThan (- cursor .CurSelection [endSel ]) then
173+ startSel = 2
174+ endSel = 1
175+ end
176+ local fromLineNo = cursor .CurSelection [startSel ].Y
177+ local toLineNo = cursor .CurSelection [endSel ].Y
178+
179+ -- don't indent the line after when selection ends in a newline
180+ if cursor .CurSelection [endSel ].X == 0 then
181+ excludedEnd = endSel
182+ toLineNo = toLineNo - 1
183+ end
184+
185+ for lineN = fromLineNo ,toLineNo do
186+ lines [lineN ] = true
194187 end
195- toggleCommentSelection (bp , bp .Cursor .CurSelection [2 ].Y , endLine , commentRegex )
196188 else
197- local endLine = bp .Cursor .CurSelection [2 ].Y
198- if bp .Cursor .CurSelection [2 ].X == 0 then
199- endLine = endLine - 1
189+ lines [cursor .Y ] = true
190+ end
191+ table.insert (curData , {
192+ sel = - cursor .CurSelection ,
193+ curpos = - cursor .Loc ,
194+ cursor = cursor ,
195+ hasSelection = hasSelection ,
196+ excludedEnd = excludedEnd ,
197+ })
198+ end
199+ -- (un)comment selected lines
200+ local commented = toggleCommentSelection (bp , lines , commentRegex )
201+ -- restore cursors
202+ local displacement = (string.find (commentType , " %%s" ) - 1 ) * (commented and 1 or - 1 )
203+ for i = 1 ,# curData do
204+ local cursor = curData [i ].cursor
205+ if curData [i ].hasSelection then
206+ for j = 1 ,2 do
207+ cursor .CurSelection [j ].Y = curData [i ].sel [j ].Y
208+ cursor .CurSelection [j ].X = curData [i ].sel [j ].X + (j == curData [i ].excludedEnd and 0 or displacement )
200209 end
201- toggleCommentSelection (bp , bp .Cursor .CurSelection [1 ].Y , endLine , commentRegex )
210+ else
211+ cursor .Y = curData [i ].curpos .Y
212+ cursor .X = curData [i ].curpos .X + displacement
202213 end
203- else
204- toggleCommentLine ( bp , bp . Cursor . Y , commentRegex )
214+ cursor : Relocate ()
215+ cursor : StoreVisualX ( )
205216 end
206217end
207218
0 commit comments