[html] adopt folding APIs

This commit is contained in:
Martin Aeschlimann 2018-04-17 19:04:59 +02:00
parent 4fca46dcc8
commit a322ceb0f6
11 changed files with 70 additions and 50 deletions

View file

@ -14,7 +14,7 @@ import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared';
import { activateTagClosing } from './tagClosing';
import TelemetryReporter from 'vscode-extension-telemetry';
import { FoldingRangesRequest, FoldingRangeRequestParam } from 'vscode-languageserver-protocol-foldingprovider';
import { FoldingRangeRequest, FoldingRangeRequestParam, FoldingRangeClientCapabilities } from 'vscode-languageserver-protocol-foldingprovider';
namespace TagCloseRequest {
export const type: RequestType<TextDocumentPositionParams, string, any, any> = new RequestType('html/tag');
@ -64,6 +64,21 @@ export function activate(context: ExtensionContext) {
// Create the language client and start the client.
let client = new LanguageClient('html', localize('htmlserver.name', 'HTML Language Server'), serverOptions, clientOptions);
client.registerProposedFeatures();
client.registerFeature({
fillClientCapabilities(capabilities: FoldingRangeClientCapabilities): void {
let textDocumentCap = capabilities.textDocument;
if (!textDocumentCap) {
textDocumentCap = capabilities.textDocument = {};
}
textDocumentCap.foldingRange = {
dynamicRegistration: false,
rangeLimit: 5000,
lineFoldingOnly: true
};
},
initialize(capabilities, documentSelector): void {
}
});
let disposable = client.start();
toDispose.push(disposable);
@ -162,16 +177,15 @@ export function activate(context: ExtensionContext) {
return languages.registerFoldingProvider(documentSelector, {
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) {
const param: FoldingRangeRequestParam = {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
maxRanges: context.maxRanges
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document)
};
return client.sendRequest(FoldingRangesRequest.type, param, token).then(res => {
if (res && Array.isArray(res.ranges)) {
return new FoldingRangeList(res.ranges.map(r => new FoldingRange(r.startLine, r.endLine, r.type)));
return client.sendRequest(FoldingRangeRequest.type, param, token).then(ranges => {
if (Array.isArray(ranges)) {
return new FoldingRangeList(ranges.map(r => new FoldingRange(r.startLine, r.endLine, r.kind)));
}
return null;
}, error => {
client.logFailedRequest(FoldingRangesRequest.type, error);
client.logFailedRequest(FoldingRangeRequest.type, error);
return null;
});
}

View file

@ -22,8 +22,8 @@
"install-client-next": "yarn add vscode-languageclient@next"
},
"categories": [
"Programming Languages"
],
"Programming Languages"
],
"contributes": {
"configuration": {
"id": "html",
@ -174,7 +174,7 @@
"dependencies": {
"vscode-extension-telemetry": "0.0.15",
"vscode-languageclient": "^4.0.0",
"vscode-languageserver-protocol-foldingprovider": "^1.0.1",
"vscode-languageserver-protocol-foldingprovider": "^2.0.0-next.2",
"vscode-nls": "^3.2.2"
},
"devDependencies": {

View file

@ -8,11 +8,11 @@
"node": "*"
},
"dependencies": {
"vscode-css-languageservice": "^3.0.9-next.6",
"vscode-css-languageservice": "^3.0.9-next.7",
"vscode-emmet-helper": "1.2.5",
"vscode-html-languageservice": "^2.1.3-next.1",
"vscode-html-languageservice": "^2.1.3-next.2",
"vscode-languageserver": "^4.0.0",
"vscode-languageserver-protocol-foldingprovider": "^1.0.1",
"vscode-languageserver-protocol-foldingprovider": "^2.0.0-next.2",
"vscode-languageserver-types": "^3.6.1",
"vscode-nls": "^3.2.2",
"vscode-uri": "^1.0.3"

View file

@ -20,7 +20,7 @@ import uri from 'vscode-uri';
import { formatError, runSafe, runSafeAsync } from './utils/runner';
import { doComplete as emmetDoComplete, updateExtensionsPath as updateEmmetExtensionsPath, getEmmetCompletionParticipants } from 'vscode-emmet-helper';
import { FoldingRangesRequest, FoldingProviderServerCapabilities } from 'vscode-languageserver-protocol-foldingprovider';
import { FoldingRangeRequest, FoldingRangeServerCapabilities } from 'vscode-languageserver-protocol-foldingprovider';
import { getFoldingRanges } from './modes/htmlFolding';
namespace TagCloseRequest {
@ -55,6 +55,7 @@ let clientSnippetSupport = false;
let clientDynamicRegisterSupport = false;
let scopedSettingsSupport = false;
let workspaceFoldersSupport = false;
let foldingRangeLimit = Number.MAX_VALUE;
var globalSettings: Settings = {};
let documentSettings: { [key: string]: Thenable<Settings> } = {};
@ -106,19 +107,24 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
languageModes.dispose();
});
function hasClientCapability(...keys: string[]) {
let c = <any>params.capabilities;
function getClientCapability<T>(name: string, def: T) {
let keys = name.split('.');
let c: any = params.capabilities;
for (let i = 0; c && i < keys.length; i++) {
if (!c.hasOwnProperty(keys[i])) {
return def;
}
c = c[keys[i]];
}
return !!c;
return c;
}
clientSnippetSupport = hasClientCapability('textDocument', 'completion', 'completionItem', 'snippetSupport');
clientDynamicRegisterSupport = hasClientCapability('workspace', 'symbol', 'dynamicRegistration');
scopedSettingsSupport = hasClientCapability('workspace', 'configuration');
workspaceFoldersSupport = hasClientCapability('workspace', 'workspaceFolders');
let capabilities: ServerCapabilities & FoldingProviderServerCapabilities = {
clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false);
clientDynamicRegisterSupport = getClientCapability('workspace.symbol.dynamicRegistration', false);
scopedSettingsSupport = getClientCapability('workspace.configuration', false);
workspaceFoldersSupport = getClientCapability('workspace.workspaceFolders', false);
foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
let capabilities: ServerCapabilities & FoldingRangeServerCapabilities = {
// Tell the client that the server works in FULL text document sync mode
textDocumentSync: documents.syncKind,
completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: [...emmetTriggerCharacters, '.', ':', '<', '"', '=', '/'] } : undefined,
@ -131,7 +137,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
signatureHelpProvider: { triggerCharacters: ['('] },
referencesProvider: true,
colorProvider: true,
foldingProvider: true
foldingRangeProvider: true
};
return { capabilities };
});
@ -461,11 +467,11 @@ connection.onRequest(TagCloseRequest.type, (params, token) => {
}, null, `Error while computing tag close actions for ${params.textDocument.uri}`, token);
});
connection.onRequest(FoldingRangesRequest.type, (params, token) => {
connection.onRequest(FoldingRangeRequest.type, (params, token) => {
return runSafe(() => {
let document = documents.get(params.textDocument.uri);
if (document) {
return getFoldingRanges(languageModes, document, params.maxRanges, token);
return getFoldingRanges(languageModes, document, foldingRangeLimit, token);
}
return null;
}, null, `Error while computing folding regions for ${params.textDocument.uri}`, token);

View file

@ -77,7 +77,7 @@ export function getCSSMode(documentRegions: LanguageModelCache<HTMLDocumentRegio
},
getFoldingRanges(document: TextDocument, range: Range): FoldingRange[] {
let embedded = embeddedCSSDocuments.get(document);
let ranges = cssLanguageService.getFoldingRanges(embedded, {}).ranges;
let ranges = cssLanguageService.getFoldingRanges(embedded, {});
return ranges.filter(r => r.startLine >= range.start.line && r.endLine < range.end.line);
},
onDocumentRemoved(document: TextDocument) {

View file

@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TextDocument, CancellationToken, Position, Range } from 'vscode-languageserver';
import { FoldingRange, FoldingRangeList } from 'vscode-languageserver-protocol-foldingprovider';
import { FoldingRange } from 'vscode-languageserver-protocol-foldingprovider';
import { LanguageModes } from './languageModes';
export function getFoldingRanges(languageModes: LanguageModes, document: TextDocument, maxRanges: number | undefined, cancellationToken: CancellationToken | null): FoldingRangeList {
export function getFoldingRanges(languageModes: LanguageModes, document: TextDocument, maxRanges: number | undefined, cancellationToken: CancellationToken | null): FoldingRange[] {
let htmlMode = languageModes.getMode('html');
let range = Range.create(Position.create(0, 0), Position.create(document.lineCount, 0));
let ranges: FoldingRange[] = [];
@ -24,7 +24,7 @@ export function getFoldingRanges(languageModes: LanguageModes, document: TextDoc
if (maxRanges && ranges.length > maxRanges) {
ranges = limitRanges(ranges, maxRanges);
}
return { ranges };
return ranges;
}
function limitRanges(ranges: FoldingRange[], maxRanges: number) {

View file

@ -64,7 +64,7 @@ export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace:
return htmlLanguageService.format(document, range, formatSettings);
},
getFoldingRanges(document: TextDocument, range: Range): FoldingRange[] {
let ranges = htmlLanguageService.getFoldingRanges(document).ranges;
let ranges = htmlLanguageService.getFoldingRanges(document);
return ranges.filter(r => r.startLine >= range.start.line && r.endLine < range.end.line);
},
doAutoClose(document: TextDocument, position: Position) {

View file

@ -12,7 +12,7 @@ import { HTMLDocumentRegions } from './embeddedSupport';
import * as ts from 'typescript';
import { join } from 'path';
import { FoldingRange, FoldingRangeType } from 'vscode-languageserver-protocol-foldingprovider';
import { FoldingRange, FoldingRangeKind } from 'vscode-languageserver-protocol-foldingprovider';
const FILE_NAME = 'vscode://javascript/1'; // the same 'file' is used for all contents
const JQUERY_D_TS = join(__dirname, '../../lib/jquery.d.ts');
@ -291,7 +291,7 @@ export function getJavaScriptMode(documentRegions: LanguageModelCache<HTMLDocume
let foldingRange: FoldingRange = { startLine, endLine };
let match = document.getText(curr).match(/^\s*\/(?:(\/\s*#(?:end)?region\b)|(\*|\/))/);
if (match) {
foldingRange.type = match[1] ? FoldingRangeType.Region : FoldingRangeType.Comment;
foldingRange.kind = match[1] ? FoldingRangeKind.Region : FoldingRangeKind.Comment;
}
ranges.push(foldingRange);
}

View file

@ -14,7 +14,7 @@ import { getLanguageModes } from '../modes/languageModes';
interface ExpectedIndentRange {
startLine: number;
endLine: number;
type?: string;
kind?: string;
}
function assertRanges(lines: string[], expected: ExpectedIndentRange[], message?: string, nRanges?: number): void {
@ -24,18 +24,18 @@ function assertRanges(lines: string[], expected: ExpectedIndentRange[], message?
folders: [{ name: 'foo', uri: 'test://foo' }]
};
let languageModes = getLanguageModes({ css: true, javascript: true }, workspace);
let actual = getFoldingRanges(languageModes, document, nRanges, null)!.ranges;
let actual = getFoldingRanges(languageModes, document, nRanges, null);
let actualRanges = [];
for (let i = 0; i < actual.length; i++) {
actualRanges[i] = r(actual[i].startLine, actual[i].endLine, actual[i].type);
actualRanges[i] = r(actual[i].startLine, actual[i].endLine, actual[i].kind);
}
actualRanges = actualRanges.sort((r1, r2) => r1.startLine - r2.startLine);
assert.deepEqual(actualRanges, expected, message);
}
function r(startLine: number, endLine: number, type?: string): ExpectedIndentRange {
return { startLine, endLine, type };
function r(startLine: number, endLine: number, kind?: string): ExpectedIndentRange {
return { startLine, endLine, kind };
}
suite('HTML Folding', () => {
@ -160,7 +160,7 @@ suite('HTML Folding', () => {
/*10*/'</html>',
];
assertRanges(input, [r(0, 9), r(1, 8), r(2, 7), r(3, 7, 'region'), r(4, 6, 'region')]);
});
});
// test('Embedded JavaScript - multi line comment', () => {

View file

@ -18,9 +18,9 @@ jsonc-parser@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-1.0.0.tgz#ddcc864ae708e60a7a6dd36daea00172fa8d9272"
vscode-css-languageservice@^3.0.9-next.6:
version "3.0.9-next.6"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.9-next.6.tgz#4da4d25eabb101713f21e8eb60b6042e504fbd97"
vscode-css-languageservice@^3.0.9-next.7:
version "3.0.9-next.7"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.9-next.7.tgz#1eb8deadaa6bfaf55187656ea6fb6b7e8d71cd7f"
dependencies:
vscode-languageserver-types "^3.6.1"
vscode-nls "^3.2.1"
@ -33,9 +33,9 @@ vscode-emmet-helper@1.2.5:
jsonc-parser "^1.0.0"
vscode-languageserver-types "^3.6.0-next.1"
vscode-html-languageservice@^2.1.3-next.1:
version "2.1.3-next.1"
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.1.3-next.1.tgz#bf8a36fc87d10b833211ff7adeb142a06fd18c61"
vscode-html-languageservice@^2.1.3-next.2:
version "2.1.3-next.2"
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.1.3-next.2.tgz#911821cada8a237bd6773569851658c733409d65"
dependencies:
vscode-languageserver-types "^3.6.1"
vscode-nls "^3.2.1"
@ -45,9 +45,9 @@ vscode-jsonrpc@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.0.tgz#848d56995d5168950d84feb5d9c237ae5c6a02d4"
vscode-languageserver-protocol-foldingprovider@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-1.0.1.tgz#85514aaf8fe905e91bf21e4106e0847f60d40f44"
vscode-languageserver-protocol-foldingprovider@^2.0.0-next.2:
version "2.0.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-2.0.0-next.2.tgz#fbb9cfdf5b8c4ac451826ba6312f1f88379f35b0"
dependencies:
vscode-languageserver-protocol "^3.6.0"
vscode-languageserver-types "^3.6.0"

View file

@ -44,9 +44,9 @@ vscode-languageclient@^4.0.0:
dependencies:
vscode-languageserver-protocol "^3.6.0"
vscode-languageserver-protocol-foldingprovider@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-1.0.1.tgz#85514aaf8fe905e91bf21e4106e0847f60d40f44"
vscode-languageserver-protocol-foldingprovider@^2.0.0-next.2:
version "2.0.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-2.0.0-next.2.tgz#fbb9cfdf5b8c4ac451826ba6312f1f88379f35b0"
dependencies:
vscode-languageserver-protocol "^3.6.0"
vscode-languageserver-types "^3.6.0"