Skip to content

Commit 36130fb

Browse files
committed
Add folding support
Fixes microsoft#61
1 parent c71ea49 commit 36130fb

File tree

4 files changed

+86
-5
lines changed

4 files changed

+86
-5
lines changed

e2e/tests/outliningSpans.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//@ts-check
2+
const path = require('path');
3+
const assert = require('chai').assert;
4+
const createServer = require('../server-fixture');
5+
const { openMockFile, getFirstResponseOfType } = require('./_helpers');
6+
7+
const mockFileName = path.join(__dirname, '..', 'project-fixture', 'main.ts');
8+
9+
describe('OutliningSpans', () => {
10+
it('should return basic css outlining spans', async () => {
11+
const spans = await getOutlingSpansForMockFile([
12+
'const q = css`',
13+
'a {',
14+
'color: red;',
15+
'}',
16+
'div {',
17+
'',
18+
'}',
19+
'`'
20+
].join('\n'));
21+
22+
assert.strictEqual(spans.length, 2);
23+
24+
const [span1, span2] = spans;
25+
assertPosition(span1.textSpan.start, 2, 1);
26+
assertPosition(span1.textSpan.end, 3, 1);
27+
28+
assertPosition(span2.textSpan.start, 5, 1);
29+
assertPosition(span2.textSpan.end, 6, 1);
30+
});
31+
});
32+
33+
function getOutlingSpansForMockFile(contents) {
34+
const server = createServer();
35+
openMockFile(server, mockFileName, contents);
36+
server.sendCommand('getOutliningSpans', { file: mockFileName });
37+
38+
return server.close().then(() => getFirstResponseOfType('getOutliningSpans', server).body);
39+
}
40+
41+
function assertPosition(pos, line, offset) {
42+
assert.strictEqual(pos.line, line);
43+
assert.strictEqual(pos.offset, offset);
44+
}

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"url": "https://github.com/Microsoft/typescript-styled-plugin/issues"
2121
},
2222
"dependencies": {
23-
"typescript-template-language-service-decorator": "^1.5.0",
23+
"typescript-template-language-service-decorator": "^1.7.0",
2424
"vscode-css-languageservice": "^3.0.9-next.19",
2525
"vscode-languageserver-types": "^3.8.2",
2626
"vscode-emmet-helper": "1.2.10"

src/_language-service.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { Logger, TemplateContext, TemplateLanguageService } from 'typescript-template-language-service-decorator';
77
import * as ts from 'typescript/lib/tsserverlibrary';
8-
import { getCSSLanguageService, getSCSSLanguageService, LanguageService } from 'vscode-css-languageservice';
8+
import { getCSSLanguageService, getSCSSLanguageService, LanguageService, FoldingRange } from 'vscode-css-languageservice';
99
import { getEmmetCompletionParticipants } from 'vscode-emmet-helper';
1010
import * as vscode from 'vscode-languageserver-types';
1111
import * as config from './_config';
@@ -175,6 +175,23 @@ export class StyledTemplateLanguageService implements TemplateLanguageService {
175175
this.scssLanguageService.doCodeActions(doc, range, { diagnostics }, stylesheet));
176176
}
177177

178+
public getOutliningSpans(
179+
context: TemplateContext
180+
): ts.OutliningSpan[] {
181+
const doc = this.virtualDocumentFactory.createVirtualDocument(context);
182+
const ranges = this.scssLanguageService.getFoldingRanges(doc);
183+
return ranges
184+
.filter(range => {
185+
// Filter out ranges outside on last line
186+
const end = context.toOffset({
187+
line: range.endLine,
188+
character: range.endCharacter || 0,
189+
});
190+
return end < context.text.length;
191+
})
192+
.map(range => this.translateOutliningSpan(context, range));
193+
}
194+
178195
private toVsRange(
179196
context: TemplateContext,
180197
start: number,
@@ -325,6 +342,26 @@ export class StyledTemplateLanguageService implements TemplateLanguageService {
325342
}],
326343
};
327344
}
345+
346+
private translateOutliningSpan(
347+
context: TemplateContext,
348+
range: FoldingRange
349+
): ts.OutliningSpan {
350+
const startOffset = context.toOffset(this.virtualDocumentFactory.fromVirtualDocPosition({ line: range.startLine, character: range.startCharacter || 0 }));
351+
const endOffset = context.toOffset(this.virtualDocumentFactory.fromVirtualDocPosition({ line: range.endLine, character: range.endCharacter || 0 }));
352+
const span = {
353+
start: startOffset,
354+
length: endOffset - startOffset,
355+
};
356+
357+
return {
358+
autoCollapse: false,
359+
kind: this.typescript.OutliningSpanKind.Code,
360+
bannerText: '',
361+
textSpan: span,
362+
hintSpan: span,
363+
};
364+
}
328365
}
329366

330367
function filterScssCompletionItems(

0 commit comments

Comments
 (0)