Skip to content

Commit

Permalink
WIP #239 Add initial support for textDocument/semanticTokens
Browse files Browse the repository at this point in the history
Signed-off-by: Remy Suen <[email protected]>
  • Loading branch information
Remy Suen authored and rcjsuen committed Feb 13, 2020
1 parent 508d4b0 commit ef0d0ec
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 36 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ All notable changes to this project will be documented in this file.
- add validation of FROM's `--platform` flag introduced in Docker CE 18.04 ([rcjsuen/dockerfile-utils#68](https://github.com/rcjsuen/dockerfile-utils/issues/68))
- `ValidationCode.UNKNOWN_FROM_FLAG`
- warn if two escape parser directives are defined ([rcjsuen/dockerfile-utils#70](https://github.com/rcjsuen/dockerfile-utils/issues/70))
- textDocument/semanticTokens
- experimental work-in-progress support to allow semantic tokens to be calculated and returned ([#239](https://github.com/rcjsuen/dockerfile-language-server-nodejs/issues/239))
- as the language server protocol API is still in flux, the exact request parameters and response results may change
- it is also possible that this request will not be fulfilled in a future release as a decision may be made to drop support for this

### Fixed
- textDocument/formatting
Expand Down
37 changes: 12 additions & 25 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"dependencies": {
"dockerfile-language-service": "0.0.9",
"dockerfile-utils": "0.0.11",
"vscode-languageserver": "^5.1.0"
"vscode-languageserver": "^6.1.0"
},
"devDependencies": {
"@types/mocha": "^2.2.33",
Expand Down
55 changes: 45 additions & 10 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import {
RenameParams, Range, WorkspaceEdit, Location,
DidChangeTextDocumentParams, DidOpenTextDocumentParams, DidCloseTextDocumentParams, TextDocumentContentChangeEvent,
DidChangeConfigurationNotification, ConfigurationItem, DocumentLinkParams, DocumentLink, MarkupKind,
VersionedTextDocumentIdentifier, TextDocumentEdit, CodeAction, CodeActionKind, FoldingRangeRequestParam
VersionedTextDocumentIdentifier, TextDocumentEdit, CodeAction, CodeActionKind, FoldingRangeRequestParam, ProposedFeatures
} from 'vscode-languageserver';
import { ValidatorSettings, ValidationSeverity } from 'dockerfile-utils';
import { CommandIds, DockerfileLanguageServiceFactory } from 'dockerfile-language-service';
import { SemanticTokenModifiers, SemanticTokenTypes, SemanticTokensParams } from "vscode-languageserver-protocol/lib/protocol.sematicTokens.proposed";

/**
* The settings to use for the validator if the client doesn't support
Expand All @@ -31,7 +32,7 @@ let validatorSettings: ValidatorSettings | null = null;
*/
let validatorConfigurations: Map<string, Thenable<ValidatorConfiguration>> = new Map();

let connection = createConnection();
let connection = createConnection(ProposedFeatures.all);
let service = DockerfileLanguageServiceFactory.createLanguageService();
service.setLogger({
log(message): void {
Expand Down Expand Up @@ -187,6 +188,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
documentChangesSupport = params.capabilities.workspace && params.capabilities.workspace.workspaceEdit && params.capabilities.workspace.workspaceEdit.documentChanges === true;
configurationSupport = params.capabilities.workspace && params.capabilities.workspace.configuration === true;
const renamePrepareSupport = params.capabilities.textDocument && params.capabilities.textDocument.rename && params.capabilities.textDocument.rename.prepareSupport === true;
const semanticTokensSupport = params.capabilities.textDocument && (params.capabilities.textDocument as any).semanticTokens;
codeActionQuickFixSupport = supportsCodeActionQuickFixes(params.capabilities);
return {
capabilities: {
Expand Down Expand Up @@ -243,8 +245,29 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
documentLinkProvider: {
resolveProvider: true
},
semanticTokensProvider: semanticTokensSupport ? {
legend: {
tokenTypes: [
SemanticTokenTypes.keyword,
SemanticTokenTypes.comment,
SemanticTokenTypes.parameter,
SemanticTokenTypes.property,
SemanticTokenTypes.label,
SemanticTokenTypes.class,
SemanticTokenTypes.marco,
SemanticTokenTypes.string,
SemanticTokenTypes.variable,
],
tokenModifiers: [
SemanticTokenModifiers.declaration,
SemanticTokenModifiers.definition,
SemanticTokenModifiers.deprecated,
SemanticTokenModifiers.reference
]
}
} : undefined,
foldingRangeProvider: true
}
} as any
}
});

Expand Down Expand Up @@ -595,26 +618,38 @@ connection.onDidOpenTextDocument((didOpenTextDocumentParams: DidOpenTextDocument
validateTextDocument(document);
});

connection.languages.semanticTokens.on((semanticTokenParams: SemanticTokensParams) => {
return getDocument(semanticTokenParams.textDocument.uri).then((document) => {
if (document) {
return service.computeSemanticTokens(document.getText());
}
return {
data: []
}
});
});

connection.onDidChangeTextDocument((didChangeTextDocumentParams: DidChangeTextDocumentParams): void => {
let document = documents[didChangeTextDocumentParams.textDocument.uri];
let buffer = document.getText();
let content = buffer;
let changes = didChangeTextDocumentParams.contentChanges;
for (let i = 0; i < changes.length; i++) {
if (!changes[i].range && !changes[i].rangeLength) {
const change = changes[i] as any;
if (!change.range && !change.rangeLength) {
// no ranges defined, the text is the entire document then
buffer = changes[i].text;
buffer = change.text;
break;
}

let offset = document.offsetAt(changes[i].range.start);
let offset = document.offsetAt(change.range.start);
let end = null;
if (changes[i].range.end) {
end = document.offsetAt(changes[i].range.end);
if (change.range.end) {
end = document.offsetAt(change.range.end);
} else {
end = offset + changes[i].rangeLength;
end = offset + change.rangeLength;
}
buffer = buffer.substring(0, offset) + changes[i].text + buffer.substring(end);
buffer = buffer.substring(0, offset) + change.text + buffer.substring(end);
}
document = TextDocument.create(didChangeTextDocumentParams.textDocument.uri, document.languageId, didChangeTextDocumentParams.textDocument.version, buffer);
documents[didChangeTextDocumentParams.textDocument.uri] = document;
Expand Down

0 comments on commit ef0d0ec

Please sign in to comment.