Skip to content

Commit fb9db1a

Browse files
committed
fix: comment Ruby lines inside multiline ERB tags with toggleBlockComment
1 parent bdc39ed commit fb9db1a

2 files changed

Lines changed: 65 additions & 0 deletions

File tree

javascript/packages/language-server/src/comment_service.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ export class CommentService {
9696
const startLine = range.start.line
9797
const endLine = range.end.line
9898

99+
if (this.selectionIsInsideMultilineERBTag(document, startLine, endLine)) {
100+
return this.toggleRubyLineComments(document, startLine, endLine)
101+
}
102+
99103
const firstLineText = document.getText(Range.create(startLine, 0, startLine + 1, 0)).replace(/\n$/, "")
100104
const lastLineText = document.getText(Range.create(endLine, 0, endLine + 1, 0)).replace(/\n$/, "")
101105
const isWrapped = firstLineText.trim() === "<% if false %>" && lastLineText.trim() === "<% end %>"
@@ -187,6 +191,46 @@ export class CommentService {
187191
return false
188192
}
189193

194+
private selectionIsInsideMultilineERBTag(document: TextDocument, startLine: number, endLine: number): boolean {
195+
let hasRubyLine = false
196+
197+
for (let line = startLine; line <= endLine; line++) {
198+
const lineText = document.getText(Range.create(line, 0, line + 1, 0)).replace(/\n$/, "")
199+
200+
if (lineText.trim() === "") continue
201+
if (!this.lineIsInsideMultilineERBTag(document, line)) return false
202+
203+
hasRubyLine = true
204+
}
205+
206+
return hasRubyLine
207+
}
208+
209+
private toggleRubyLineComments(document: TextDocument, startLine: number, endLine: number): TextEdit[] {
210+
const lineTexts: { line: number, text: string }[] = []
211+
212+
for (let line = startLine; line <= endLine; line++) {
213+
const text = document.getText(Range.create(line, 0, line + 1, 0)).replace(/\n$/, "")
214+
215+
if (text.trim() !== "") {
216+
lineTexts.push({ line, text })
217+
}
218+
}
219+
220+
const allCommented = lineTexts.every(({ text }) => text.trimStart().startsWith("#"))
221+
222+
return lineTexts.map(({ line, text }) => {
223+
if (allCommented) {
224+
return this.uncommentRubyLine(text, line)!
225+
}
226+
227+
const indent = this.getIndentation(text)
228+
const content = text.trimStart()
229+
230+
return TextEdit.replace(Range.create(line, 0, line, text.length), `${indent}# ${content}`)
231+
}).filter(edit => edit !== null)
232+
}
233+
190234
private uncommentLine(info: LineInfo, lineText: string, collector: LineContextCollector): TextEdit | null {
191235
const lineRange = Range.create(info.line, 0, info.line, lineText.length)
192236
const indent = this.getIndentation(lineText)

javascript/packages/language-server/test/comment_service.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,14 @@ describe("CommentService", () => {
11081108
const startEdit = edits.find(edit => edit.newText.includes("<% if false %>"))
11091109
expect(startEdit?.newText).toBe(" <% if false %>\n")
11101110
})
1111+
1112+
it("comments an internal Ruby line inside a multiline ERB tag", () => {
1113+
const original = `<%\n a\n%>`
1114+
const document = createDocument(original)
1115+
const edits = service.toggleBlockComment(document, lineRange(1))
1116+
1117+
expect(applyEdits(original, edits)).toBe(`<%\n # a\n%>`)
1118+
})
11111119
})
11121120

11131121
describe("round-trip", () => {
@@ -1132,6 +1140,19 @@ describe("CommentService", () => {
11321140
<%= render "thing" %>
11331141
`.trim())
11341142
})
1143+
1144+
it("round-trips an internal Ruby line inside a multiline ERB tag", () => {
1145+
const original = `<%\n a\n%>`
1146+
const document1 = createDocument(original)
1147+
const commented = applyEdits(original, service.toggleBlockComment(document1, lineRange(1)))
1148+
1149+
expect(commented).toBe(`<%\n # a\n%>`)
1150+
1151+
const document2 = createDocument(commented)
1152+
const uncommented = applyEdits(commented, service.toggleBlockComment(document2, lineRange(1)))
1153+
1154+
expect(uncommented).toBe(original)
1155+
})
11351156
})
11361157

11371158
describe("unwrapping", () => {

0 commit comments

Comments
 (0)