Add a client feature for requesting document settings (#29)

This commit is contained in:
Brandon Waterloo [MSFT] 2021-09-13 09:47:48 -04:00 коммит произвёл GitHub
Родитель 554ab9b05c
Коммит 6cd9343459
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 179 добавлений и 13 удалений

Просмотреть файл

@ -9,6 +9,7 @@
"project": "tsconfig.json",
"sourceType": "module"
},
"ignorePatterns": "src/test/clientExtension",
"plugins": [
"@typescript-eslint"
],

1
.gitignore поставляемый
Просмотреть файл

@ -1,3 +1,4 @@
lib
dist
node_modules
*.tgz

2
.vscode/launch.json поставляемый
Просмотреть файл

@ -58,7 +58,7 @@
"--extensionDevelopmentPath=${workspaceFolder}/src/test/clientExtension",
"--disable-extension=ms-azuretools.vscode-docker", // Keep the Docker extension from running so it doesn't interfere with testing
],
"preLaunchTask": "${defaultBuildTask}",
"preLaunchTask": "tsc-watch: client extension",
"presentation": {
"hidden": true,
}

16
.vscode/tasks.json поставляемый
Просмотреть файл

@ -16,7 +16,21 @@
"reveal": "never"
},
"isBackground": true,
"label": "tsc: watch"
"label": "tsc-watch: language service"
},
{
"type": "typescript",
"tsconfig": "src/test/clientExtension/tsconfig.json",
"option": "watch",
"problemMatcher": [
"$tsc-watch"
],
"group": "build",
"presentation": {
"reveal": "never"
},
"isBackground": true,
"label": "tsc-watch: client extension"
}
]
}

Просмотреть файл

@ -0,0 +1,32 @@
/*!--------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ProtocolNotificationType, ProtocolRequestType } from 'vscode-languageserver-protocol';
import { TextDocumentIdentifier } from 'vscode-languageserver-types';
// TODO: should we get these from @types/vscode instead? It seems there's some type conflict between `Thenable<T>` from @types/vscode and vscode-jsonrpc
type LF = 1;
type CRLF = 2;
export type EndOfLine = LF | CRLF;
export interface DocumentSettings {
tabSize: number;
eol: EndOfLine;
}
export interface DocumentSettingsParams {
textDocument: TextDocumentIdentifier;
}
export interface DocumentSettingsClientCapabilities {
request: boolean;
notify: boolean;
}
export type DocumentSettingsNotificationParams = DocumentSettingsParams & DocumentSettings;
export const DocumentSettingsRequestType = new ProtocolRequestType<DocumentSettingsParams, DocumentSettings, never, never, never>('$/textDocument/documentSettings');
export const DocumentSettingsNotificationType = new ProtocolNotificationType<DocumentSettingsNotificationParams, never>('$/textDocument/documentSettings/didChange');

Просмотреть файл

@ -0,0 +1,70 @@
/*!--------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { ClientCapabilities, StaticFeature } from 'vscode-languageclient';
import { LanguageClient } from 'vscode-languageclient/node';
import { DocumentSettings, DocumentSettingsClientCapabilities, DocumentSettingsNotificationParams, DocumentSettingsParams } from '../../../lib/client/DocumentSettings'; // Dev-time-only imports
// Duplicating these from src/client/DocumentSettings means the above imports can stay dev-time-only
const DocumentSettingsRequestMethodType = '$/textDocument/documentSettings';
const DocumentSettingsChangeNotificationMethodType = '$/textDocument/documentSettings/didChange';
export class DocumentSettingsClientFeature implements StaticFeature {
private disposables: vscode.Disposable[] = [];
public constructor(private readonly client: LanguageClient) { }
public fillClientCapabilities(capabilities: ClientCapabilities): void {
const documentSettings: DocumentSettingsClientCapabilities = {
notify: true,
request: true,
};
capabilities.experimental = {
...capabilities.experimental,
documentSettings,
};
}
public initialize(): void {
this.disposables.push(
this.client.onRequest(
DocumentSettingsRequestMethodType,
(params: DocumentSettingsParams): DocumentSettings | undefined => {
const textEditor = vscode.window.visibleTextEditors.find(e => e.document.uri.toString() === params.textDocument.uri);
if (!textEditor) {
return undefined;
}
return {
eol: textEditor.document.eol,
tabSize: Number(textEditor.options.tabSize),
};
}
)
);
this.disposables.push(
vscode.window.onDidChangeTextEditorOptions(
(e: vscode.TextEditorOptionsChangeEvent) => {
const params: DocumentSettingsNotificationParams = {
textDocument: { uri: e.textEditor.document.uri.toString() },
eol: e.textEditor.document.eol,
tabSize: Number(e.options.tabSize),
};
this.client.sendNotification(DocumentSettingsChangeNotificationMethodType, params);
}
)
);
}
public dispose(): void {
this.disposables.forEach(d => d.dispose());
}
}

Просмотреть файл

@ -3,24 +3,26 @@
* Licensed under the MIT License. See LICENSE in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const langClient = require("vscode-languageclient/node");
import * as vscode from 'vscode';
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient/node';
import { DocumentSettingsClientFeature } from './DocumentSettingsClientFeature';
exports.activate = function activate(context) {
export function activate(context: vscode.ExtensionContext): void {
const serverModule = context.asAbsolutePath('../../../lib/server.js');
const serverOptions = {
const serverOptions: ServerOptions = {
run: {
module: serverModule,
transport: langClient.TransportKind.ipc,
transport: TransportKind.ipc,
},
debug: {
module: serverModule,
transport: langClient.TransportKind.ipc,
transport: TransportKind.ipc,
options: { execArgv: ['--nolazy', '--inspect=6009'] },
},
};
const clientOptions = {
const clientOptions: LanguageClientOptions = {
documentSelector: [
{
language: 'dockercompose'
@ -28,9 +30,12 @@ exports.activate = function activate(context) {
],
};
const client = new langClient.LanguageClient('compose-language-server', serverOptions, clientOptions, true);
const client = new LanguageClient('compose-language-server', serverOptions, clientOptions, true);
client.registerFeature(new DocumentSettingsClientFeature(client));
context.subscriptions.push(client.start());
}
exports.deactivate = function deactivate() { }
export function deactivate(): void {
// Do nothing
}

15
src/test/clientExtension/package-lock.json сгенерированный
Просмотреть файл

@ -10,10 +10,19 @@
"dependencies": {
"vscode-languageclient": "^7.0.0"
},
"devDependencies": {
"@types/vscode": "1.52"
},
"engines": {
"vscode": "^1.52.0"
}
},
"node_modules/@types/vscode": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.52.0.tgz",
"integrity": "sha512-Kt3bvWzAvvF/WH9YEcrCICDp0Z7aHhJGhLJ1BxeyNP6yRjonWqWnAIh35/pXAjswAnWOABrYlF7SwXR9+1nnLA==",
"dev": true
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -111,6 +120,12 @@
}
},
"dependencies": {
"@types/vscode": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.52.0.tgz",
"integrity": "sha512-Kt3bvWzAvvF/WH9YEcrCICDp0Z7aHhJGhLJ1BxeyNP6yRjonWqWnAIh35/pXAjswAnWOABrYlF7SwXR9+1nnLA==",
"dev": true
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",

Просмотреть файл

@ -9,8 +9,11 @@
"onLanguage:dockercompose",
"onStartupFinished"
],
"main": "./extension.js",
"main": "./dist/extension.js",
"dependencies": {
"vscode-languageclient": "^7.0.0"
},
"devDependencies": {
"@types/vscode": "1.52"
}
}

Просмотреть файл

@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "es2018",
"module": "commonjs",
"lib": [
"es2018",
],
"moduleResolution": "node",
"sourceMap": true,
"inlineSources": false,
"declaration": true,
"outDir": "./dist",
"rootDir": ".",
"alwaysStrict": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"stripInternal": true,
}
}

Просмотреть файл

@ -16,6 +16,10 @@
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"stripInternal": true
}
"stripInternal": true,
},
"exclude": [
"src/test/clientExtension",
"lib"
],
}