Skip to content

Commit f95b2fe

Browse files
committed
Folding mix of Attributes and single-line comments
It removes the possibility to have Folding range for the first group of attributes or first group of single-line comments. This is due to a limitation of VS Code which doesn't handle several folding ranges starting on the same line. resolves #719 Signed-off-by: Aurélien Pupier <[email protected]>
1 parent 45302b5 commit f95b2fe

File tree

3 files changed

+143
-9
lines changed

3 files changed

+143
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Improvements
66

77
- provide folding for list of sibling attributes by @apupier (#719)
8+
- provide folding for mix of attributes and single line comments by @apupier (#719)
89

910
### Bug fixes
1011

src/features/foldingProvider.ts

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,12 @@ export default class AsciidocFoldingRangeProvider implements vscode.FoldingRange
9393
}
9494
}
9595

96-
private static handleSingleLineCommentFoldingRanges (singleLineCommentStartIndexes: any[], foldingRanges: any[], lineIndex: number, lineText: string,
96+
private static handleSingleLineCommentFoldingRanges (
97+
singleLineCommentStartIndexes: any[],
98+
mixOfMultiAttributesAndSingleLineCommentsIndexes: any[],
99+
foldingRanges: any[],
100+
lineIndex: number,
101+
lineText: string,
97102
documentLineCount: number) {
98103
if (lineText.startsWith('//')) {
99104
if (singleLineCommentStartIndexes.length === 0) {
@@ -102,7 +107,7 @@ export default class AsciidocFoldingRangeProvider implements vscode.FoldingRange
102107
if (lineIndex >= documentLineCount - 1) {
103108
// comment on last line of the document
104109
const startIndex = singleLineCommentStartIndexes.pop()
105-
if (lineIndex > startIndex) {
110+
if (lineIndex > startIndex && !(lineText.startsWith(':') && mixOfMultiAttributesAndSingleLineCommentsIndexes[0] === startIndex)) {
106111
foldingRanges.push(new vscode.FoldingRange(
107112
startIndex,
108113
lineIndex,
@@ -114,7 +119,7 @@ export default class AsciidocFoldingRangeProvider implements vscode.FoldingRange
114119
if (singleLineCommentStartIndexes.length !== 0) {
115120
const startIndex = singleLineCommentStartIndexes.pop()
116121
const endIndex = lineIndex - 1
117-
if (endIndex > startIndex) {
122+
if (endIndex > startIndex && !(lineText.startsWith(':') && mixOfMultiAttributesAndSingleLineCommentsIndexes[0] === startIndex)) {
118123
foldingRanges.push(new vscode.FoldingRange(
119124
startIndex,
120125
endIndex,
@@ -124,15 +129,21 @@ export default class AsciidocFoldingRangeProvider implements vscode.FoldingRange
124129
}
125130
}
126131

127-
private static handleMultiAttributesFoldingRanges (multiAttributesIndexes: any[], foldingRanges: any[], lineIndex: number, lineText: string, documentLineCount: number) {
132+
private static handleMultiAttributesFoldingRanges (
133+
multiAttributesIndexes: any[],
134+
mixOfMultiAttributesAndSingleLineCommentsIndexes: any[],
135+
foldingRanges: any[],
136+
lineIndex: number,
137+
lineText: string,
138+
documentLineCount: number) {
128139
if (lineText.startsWith(':')) {
129140
if (multiAttributesIndexes.length === 0) {
130141
multiAttributesIndexes.push(lineIndex)
131142
}
132143
if (lineIndex >= documentLineCount - 1) {
133144
// Attribute on last line of the document
134145
const startIndex = multiAttributesIndexes.pop()
135-
if (lineIndex > startIndex) {
146+
if (lineIndex > startIndex && !(lineText.startsWith('//') && mixOfMultiAttributesAndSingleLineCommentsIndexes[0] === startIndex)) {
136147
foldingRanges.push(new vscode.FoldingRange(
137148
startIndex,
138149
lineIndex)
@@ -143,11 +154,47 @@ export default class AsciidocFoldingRangeProvider implements vscode.FoldingRange
143154
if (multiAttributesIndexes.length !== 0) {
144155
const startIndex = multiAttributesIndexes.pop()
145156
const endIndex = lineIndex - 1
146-
if (endIndex > startIndex) {
157+
if (endIndex > startIndex && !(lineText.startsWith('//') && mixOfMultiAttributesAndSingleLineCommentsIndexes[0] === startIndex)) {
158+
foldingRanges.push(new vscode.FoldingRange(
159+
startIndex,
160+
endIndex))
161+
}
162+
}
163+
}
164+
}
165+
166+
private static handleMixOfMultiAttributesAndSingleLineCommentsFoldingRanges (
167+
mixOfMultiAttributesAndSingleLineCommentsIndexes: any[],
168+
mixOfMultiAttributesAndSingleLineCommentsCharacters: Set<string>,
169+
foldingRanges: any[],
170+
lineIndex: number,
171+
lineText: string,
172+
documentLineCount: number) {
173+
if (lineText.startsWith(':') || lineText.startsWith('//')) {
174+
if (mixOfMultiAttributesAndSingleLineCommentsIndexes.length === 0) {
175+
mixOfMultiAttributesAndSingleLineCommentsIndexes.push(lineIndex)
176+
}
177+
mixOfMultiAttributesAndSingleLineCommentsCharacters.add(lineText.charAt(0))
178+
if (lineIndex >= documentLineCount - 1) {
179+
// Attribute on last line of the document
180+
const startIndex = mixOfMultiAttributesAndSingleLineCommentsIndexes.pop()
181+
if (lineIndex > startIndex && mixOfMultiAttributesAndSingleLineCommentsCharacters.size === 2) {
182+
foldingRanges.push(new vscode.FoldingRange(
183+
startIndex,
184+
lineIndex)
185+
)
186+
}
187+
}
188+
} else {
189+
if (mixOfMultiAttributesAndSingleLineCommentsIndexes.length !== 0) {
190+
const startIndex = mixOfMultiAttributesAndSingleLineCommentsIndexes.pop()
191+
const endIndex = lineIndex - 1
192+
if (endIndex > startIndex && mixOfMultiAttributesAndSingleLineCommentsCharacters.size === 2) {
147193
foldingRanges.push(new vscode.FoldingRange(
148194
startIndex,
149195
endIndex))
150196
}
197+
mixOfMultiAttributesAndSingleLineCommentsCharacters.clear()
151198
}
152199
}
153200
}
@@ -158,14 +205,29 @@ export default class AsciidocFoldingRangeProvider implements vscode.FoldingRange
158205
const commentBlockIndexes = []
159206
const singleLineCommentStartIndexes = []
160207
const multiAttributesIndexes = []
208+
const mixOfMultiAttributesAndSingleLineCommentsIndexes = []
209+
const mixOfMultiAttributesAndSingleLineCommentsCharacters = new Set<string>()
161210
const documentLineCount = document.lineCount
162211
for (let lineIndex = 0; lineIndex < documentLineCount; lineIndex++) {
163212
const line = document.lineAt(lineIndex)
164213
const lineText = line.text
165214
this.handleOpenBlockFoldingRanges(openBlockIndexes, foldingRanges, lineIndex, lineText, documentLineCount)
166215
this.handleCommentBlockFoldingRanges(commentBlockIndexes, foldingRanges, lineIndex, lineText, documentLineCount)
167-
this.handleSingleLineCommentFoldingRanges(singleLineCommentStartIndexes, foldingRanges, lineIndex, lineText, documentLineCount)
168-
this.handleMultiAttributesFoldingRanges(multiAttributesIndexes, foldingRanges, lineIndex, lineText, documentLineCount)
216+
this.handleSingleLineCommentFoldingRanges(
217+
singleLineCommentStartIndexes,
218+
mixOfMultiAttributesAndSingleLineCommentsIndexes,
219+
foldingRanges,
220+
lineIndex,
221+
lineText,
222+
documentLineCount)
223+
this.handleMultiAttributesFoldingRanges(multiAttributesIndexes, mixOfMultiAttributesAndSingleLineCommentsIndexes, foldingRanges, lineIndex, lineText, documentLineCount)
224+
this.handleMixOfMultiAttributesAndSingleLineCommentsFoldingRanges(
225+
mixOfMultiAttributesAndSingleLineCommentsIndexes,
226+
mixOfMultiAttributesAndSingleLineCommentsCharacters,
227+
foldingRanges,
228+
lineIndex,
229+
lineText,
230+
documentLineCount)
169231
}
170232
return foldingRanges
171233
}

src/test/foldingProvider.test.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { InMemoryDocument } from './inMemoryDocument'
1111

1212
const testFileName = vscode.Uri.file('test.adoc')
1313

14-
suite('asciidoc.FoldingProvider', () => {
14+
suite.only('asciidoc.FoldingProvider', () => {
1515
suite('getHeaderFoldingRanges', () => {
1616
test('Should not return anything for empty document', () => {
1717
const folds = getFoldsForDocument('')
@@ -413,6 +413,77 @@ this is a paragraph`)
413413
])
414414
})
415415
})
416+
417+
suite('getMultiAttributeAndSingleLineCommentsFoldingRanges', () => {
418+
test('Should fold on a group of mix of attributes and single line comments ', () => {
419+
const folds = getFoldsForDocument(
420+
`this is a paragraph
421+
422+
// A single-line comment.
423+
:an-attribute: value of attribute
424+
// A second single-line comment.
425+
:a-second-attribute: value of second attribute
426+
427+
this is a paragraph`)
428+
assert.strictEqual(folds.length, 1, 'expecting 1 fold')
429+
assert.deepStrictEqual(folds, [
430+
new vscode.FoldingRange(2, 5),
431+
])
432+
})
433+
test('Should fold on a group of mix of attributes and single line comments starting with 2 attributes', () => {
434+
const folds = getFoldsForDocument(
435+
`this is a paragraph
436+
437+
:an-attribute1: value of attribute
438+
:an-attribute2: value of attribute
439+
// A single-line comment.
440+
:an-attribute: value of attribute
441+
// A second single-line comment.
442+
:a-second-attribute: value of second attribute
443+
444+
this is a paragraph`)
445+
assert.strictEqual(folds.length, 1, 'expecting 1 fold')
446+
assert.deepStrictEqual(folds, [
447+
new vscode.FoldingRange(2, 7),
448+
])
449+
})
450+
test('Should fold on a group of mix of attributes and single line comments starting with 2 line comments', () => {
451+
const folds = getFoldsForDocument(
452+
`this is a paragraph
453+
454+
// A single-line comment.
455+
// A second single-line comment.
456+
:an-attribute: value of attribute
457+
// A third line comment
458+
:a-second-attribute: value of second attribute
459+
460+
this is a paragraph`)
461+
assert.strictEqual(folds.length, 1, 'expecting 1 fold')
462+
assert.deepStrictEqual(folds, [
463+
new vscode.FoldingRange(2, 6),
464+
])
465+
})
466+
test('Should fold on a group of mix of attributes and single line comments and include next groups', () => {
467+
const folds = getFoldsForDocument(
468+
`this is a paragraph
469+
470+
// A single-line comment.
471+
// A second single-line comment.
472+
:an-attribute: value of attribute
473+
:another-attribute:
474+
// A third line comment
475+
// as a potential folded group
476+
:a-third-attribute: value of third attribute
477+
478+
this is a paragraph`)
479+
assert.strictEqual(folds.length, 3, 'expecting 3 folds')
480+
assert.deepStrictEqual(folds, [
481+
new vscode.FoldingRange(4, 5),
482+
new vscode.FoldingRange(6, 7, vscode.FoldingRangeKind.Comment),
483+
new vscode.FoldingRange(2, 8),
484+
])
485+
})
486+
})
416487
})
417488

418489
function getFoldsForDocument (contents: string) {

0 commit comments

Comments
 (0)