mirror of
https://github.com/microsoft/vscode-extension-samples.git
synced 2026-04-27 16:55:44 +08:00
cp -r lsp-sample lsp-log-streaming-sample
This commit is contained in:
4
lsp-log-streaming-sample/.gitignore
vendored
Normal file
4
lsp-log-streaming-sample/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
out
|
||||
node_modules
|
||||
client/server
|
||||
.vscode-test
|
||||
47
lsp-log-streaming-sample/.vscode/launch.json
vendored
Normal file
47
lsp-log-streaming-sample/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// A launch configuration that compiles the extension and then opens it inside a new window
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"name": "Launch Client",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": ["--extensionDevelopmentPath=${workspaceRoot}"],
|
||||
"stopOnEntry": false,
|
||||
"sourceMaps": true,
|
||||
"outFiles": ["${workspaceRoot}/client/out/**/*.js"],
|
||||
"preLaunchTask": "npm: watch:client"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"name": "Attach to Server",
|
||||
"address": "localhost",
|
||||
"protocol": "inspector",
|
||||
"port": 6009,
|
||||
"sourceMaps": true,
|
||||
"outFiles": ["${workspaceRoot}/server/out/**/*.js"]
|
||||
},
|
||||
{
|
||||
"name": "Language Server E2E Test",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceRoot}",
|
||||
"--extensionTestsPath=${workspaceRoot}/client/out/test",
|
||||
"${workspaceRoot}/client/testFixture"
|
||||
],
|
||||
"stopOnEntry": false,
|
||||
"sourceMaps": true,
|
||||
"outFiles": ["${workspaceRoot}/client/out/test/**/*.js"]
|
||||
}
|
||||
],
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Client + Server",
|
||||
"configurations": ["Launch Client", "Attach to Server"]
|
||||
}
|
||||
]
|
||||
}
|
||||
12
lsp-log-streaming-sample/.vscode/settings.json
vendored
Normal file
12
lsp-log-streaming-sample/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"files.exclude": {
|
||||
"out": false // set this to true to hide the "out" folder with the compiled JS files
|
||||
},
|
||||
"search.exclude": {
|
||||
"out": true // set this to false to include "out" folder in search results
|
||||
},
|
||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
"npm.exclude": ["**/client", "**/server"],
|
||||
"npm.enableScriptExplorer": true
|
||||
}
|
||||
87
lsp-log-streaming-sample/.vscode/tasks.json
vendored
Normal file
87
lsp-log-streaming-sample/.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "compile",
|
||||
"dependsOn": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "compile:client"
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "compile:server"
|
||||
}
|
||||
],
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "compile:client",
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "compile:server",
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "watch",
|
||||
"dependsOn": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch:client"
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch:server"
|
||||
}
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch:client",
|
||||
"isBackground": true,
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc-watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch:server",
|
||||
"isBackground": true,
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc-watch"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
13
lsp-log-streaming-sample/.vscodeignore
Normal file
13
lsp-log-streaming-sample/.vscodeignore
Normal file
@ -0,0 +1,13 @@
|
||||
.vscode/**
|
||||
**/*.ts
|
||||
**/*.map
|
||||
.gitignore
|
||||
**/tsconfig.json
|
||||
**/tsconfig.base.json
|
||||
contributing.md
|
||||
.travis.yml
|
||||
client/node_modules/**
|
||||
!client/node_modules/vscode-jsonrpc/**
|
||||
!client/node_modules/vscode-languageclient/**
|
||||
!client/node_modules/vscode-languageserver-protocol/**
|
||||
!client/node_modules/vscode-languageserver-types/**
|
||||
17
lsp-log-streaming-sample/License.txt
Normal file
17
lsp-log-streaming-sample/License.txt
Normal file
@ -0,0 +1,17 @@
|
||||
Copyright (c) Microsoft Corporation
|
||||
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
38
lsp-log-streaming-sample/README.md
Normal file
38
lsp-log-streaming-sample/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# LSP Example
|
||||
|
||||
Heavily documented sample code for https://code.visualstudio.com/docs/extensions/example-language-server.
|
||||
|
||||
## Functionality
|
||||
|
||||
This Language Server works for plain text file. It has the following language features:
|
||||
- Completions
|
||||
- Diagnostics regenerated on each file change or configuration change
|
||||
|
||||
It also includes an End-to-End test.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── client // Language Client
|
||||
│ ├── src
|
||||
│ │ ├── test // End to End tests for Language Client / Server
|
||||
│ │ └── extension.ts // Language Client entry point
|
||||
├── package.json // The extension manifest.
|
||||
└── server // Language Server
|
||||
└── src
|
||||
└── server.ts // Language Server entry point
|
||||
```
|
||||
|
||||
## Compile and Run
|
||||
|
||||
- Run `npm install` in this folder. This installs all necessary npm modules in both the client and server folder
|
||||
- Open VS Code on this folder.
|
||||
- Press Ctrl+Shift+B to compile the client and server.
|
||||
- Switch to the Debug viewlet.
|
||||
- Select `Launch Client` from the drop down.
|
||||
- Run the lauch config.
|
||||
- If you want to debug the server as well use the launch configuration `Attach to Server`
|
||||
- In the [Extension Development Host] instance of VSCode, open a document in 'plain text' language mode.
|
||||
- Type `j` or `t` to see `Javascript` and `TypeScript` completion.
|
||||
- Enter text content such as `AAA aaa BBB`. The extension will emit diagnostics for all words in all-uppercase.
|
||||
31
lsp-log-streaming-sample/ThirdPartyNotices.txt
Normal file
31
lsp-log-streaming-sample/ThirdPartyNotices.txt
Normal file
@ -0,0 +1,31 @@
|
||||
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
|
||||
For Microsoft vscode-languageserver-node-example
|
||||
|
||||
This project incorporates material from the project(s) listed below (collectively, “Third Party Code”).
|
||||
Microsoft is not the original author of the Third Party Code. The original copyright notice and license
|
||||
under which Microsoft received such Third Party Code are set out below. This Third Party Code is licensed
|
||||
to you under their original license terms set forth below. Microsoft reserves all other rights not expressly
|
||||
granted, whether by implication, estoppel or otherwise.
|
||||
|
||||
1. DefinitelyTyped version 0.0.1 (https://github.com/borisyankov/DefinitelyTyped)
|
||||
|
||||
This project is licensed under the MIT license.
|
||||
Copyrights are respective of each contributor listed at the beginning of each definition file.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
1826
lsp-log-streaming-sample/client/package-lock.json
generated
Normal file
1826
lsp-log-streaming-sample/client/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
23
lsp-log-streaming-sample/client/package.json
Normal file
23
lsp-log-streaming-sample/client/package.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "lsp-sample-client",
|
||||
"description": "VSCode part of a language server",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"version": "0.0.1",
|
||||
"publisher": "vscode",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.23.0"
|
||||
},
|
||||
"scripts": {
|
||||
"update-vscode": "vscode-install",
|
||||
"postinstall": "vscode-install"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode": "^1.1.21",
|
||||
"vscode-languageclient": "^4.1.4"
|
||||
}
|
||||
}
|
||||
66
lsp-log-streaming-sample/client/src/extension.ts
Normal file
66
lsp-log-streaming-sample/client/src/extension.ts
Normal file
@ -0,0 +1,66 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
'use strict';
|
||||
|
||||
import * as path from 'path';
|
||||
import { workspace, ExtensionContext } from 'vscode';
|
||||
|
||||
import {
|
||||
LanguageClient,
|
||||
LanguageClientOptions,
|
||||
ServerOptions,
|
||||
TransportKind
|
||||
} from 'vscode-languageclient';
|
||||
|
||||
let client: LanguageClient;
|
||||
|
||||
export function activate(context: ExtensionContext) {
|
||||
// The server is implemented in node
|
||||
let serverModule = context.asAbsolutePath(
|
||||
path.join('server', 'out', 'server.js')
|
||||
);
|
||||
// The debug options for the server
|
||||
// --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
|
||||
let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };
|
||||
|
||||
// If the extension is launched in debug mode then the debug server options are used
|
||||
// Otherwise the run options are used
|
||||
let serverOptions: ServerOptions = {
|
||||
run: { module: serverModule, transport: TransportKind.ipc },
|
||||
debug: {
|
||||
module: serverModule,
|
||||
transport: TransportKind.ipc,
|
||||
options: debugOptions
|
||||
}
|
||||
};
|
||||
|
||||
// Options to control the language client
|
||||
let clientOptions: LanguageClientOptions = {
|
||||
// Register the server for plain text documents
|
||||
documentSelector: [{ scheme: 'file', language: 'plaintext' }],
|
||||
synchronize: {
|
||||
// Notify the server about file changes to '.clientrc files contained in the workspace
|
||||
fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
|
||||
}
|
||||
};
|
||||
|
||||
// Create the language client and start the client.
|
||||
client = new LanguageClient(
|
||||
'languageServerExample',
|
||||
'Language Server Example',
|
||||
serverOptions,
|
||||
clientOptions
|
||||
);
|
||||
|
||||
// Start the client. This will also launch the server
|
||||
client.start();
|
||||
}
|
||||
|
||||
export function deactivate(): Thenable<void> {
|
||||
if (!client) {
|
||||
return undefined;
|
||||
}
|
||||
return client.stop();
|
||||
}
|
||||
44
lsp-log-streaming-sample/client/src/test/completion.test.ts
Normal file
44
lsp-log-streaming-sample/client/src/test/completion.test.ts
Normal file
@ -0,0 +1,44 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
'use strict';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as assert from 'assert';
|
||||
import { getDocUri, activate } from './helper';
|
||||
|
||||
describe('Should do completion', () => {
|
||||
const docUri = getDocUri('completion.txt');
|
||||
|
||||
it('Completes JS/TS in txt file', async () => {
|
||||
await testCompletion(docUri, new vscode.Position(0, 0), {
|
||||
items: [
|
||||
{ label: 'JavaScript', kind: vscode.CompletionItemKind.Text },
|
||||
{ label: 'TypeScript', kind: vscode.CompletionItemKind.Text }
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
async function testCompletion(
|
||||
docUri: vscode.Uri,
|
||||
position: vscode.Position,
|
||||
expectedCompletionList: vscode.CompletionList
|
||||
) {
|
||||
await activate(docUri);
|
||||
|
||||
// Executing the command `vscode.executeCompletionItemProvider` to simulate triggering completion
|
||||
const actualCompletionList = (await vscode.commands.executeCommand(
|
||||
'vscode.executeCompletionItemProvider',
|
||||
docUri,
|
||||
position
|
||||
)) as vscode.CompletionList;
|
||||
|
||||
assert.equal(actualCompletionList.items.length, expectedCompletionList.items.length);
|
||||
expectedCompletionList.items.forEach((expectedItem, i) => {
|
||||
const actualItem = actualCompletionList.items[i];
|
||||
assert.equal(actualItem.label, expectedItem.label);
|
||||
assert.equal(actualItem.kind, expectedItem.kind);
|
||||
});
|
||||
}
|
||||
42
lsp-log-streaming-sample/client/src/test/diagnostics.test.ts
Normal file
42
lsp-log-streaming-sample/client/src/test/diagnostics.test.ts
Normal file
@ -0,0 +1,42 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
'use strict';
|
||||
|
||||
import * as vscode from 'vscode'
|
||||
import * as assert from 'assert'
|
||||
import { getDocUri, activate } from './helper'
|
||||
|
||||
describe('Should get diagnostics', () => {
|
||||
const docUri = getDocUri('diagnostics.txt')
|
||||
|
||||
it('Diagnoses uppercase texts', async () => {
|
||||
await testDiagnostics(docUri, [
|
||||
{ message: 'ANY is all uppercase.', range: toRange(0, 0, 0, 3), severity: vscode.DiagnosticSeverity.Warning, source: 'ex' },
|
||||
{ message: 'ANY is all uppercase.', range: toRange(0, 14, 0, 17), severity: vscode.DiagnosticSeverity.Warning, source: 'ex' },
|
||||
{ message: 'OS is all uppercase.', range: toRange(0, 18, 0, 20), severity: vscode.DiagnosticSeverity.Warning, source: 'ex' }
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
function toRange(sLine: number, sChar: number, eLine: number, eChar: number) {
|
||||
const start = new vscode.Position(sLine, sChar)
|
||||
const end = new vscode.Position(eLine, eChar)
|
||||
return new vscode.Range(start, end)
|
||||
}
|
||||
|
||||
async function testDiagnostics(docUri: vscode.Uri, expectedDiagnostics: vscode.Diagnostic[]) {
|
||||
await activate(docUri)
|
||||
|
||||
const actualDiagnostics = vscode.languages.getDiagnostics(docUri);
|
||||
|
||||
assert.equal(actualDiagnostics.length, expectedDiagnostics.length);
|
||||
|
||||
expectedDiagnostics.forEach((expectedDiagnostic, i) => {
|
||||
const actualDiagnostic = actualDiagnostics[i]
|
||||
assert.equal(actualDiagnostic.message, expectedDiagnostic.message)
|
||||
assert.deepEqual(actualDiagnostic.range, expectedDiagnostic.range)
|
||||
assert.equal(actualDiagnostic.severity, expectedDiagnostic.severity)
|
||||
})
|
||||
}
|
||||
48
lsp-log-streaming-sample/client/src/test/helper.ts
Normal file
48
lsp-log-streaming-sample/client/src/test/helper.ts
Normal file
@ -0,0 +1,48 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
'use strict';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
|
||||
export let doc: vscode.TextDocument;
|
||||
export let editor: vscode.TextEditor;
|
||||
export let documentEol: string;
|
||||
export let platformEol: string;
|
||||
|
||||
/**
|
||||
* Activates the vscode.lsp-sample extension
|
||||
*/
|
||||
export async function activate(docUri: vscode.Uri) {
|
||||
// The extensionId is `publisher.name` from package.json
|
||||
const ext = vscode.extensions.getExtension('vscode.lsp-sample');
|
||||
await ext.activate();
|
||||
try {
|
||||
doc = await vscode.workspace.openTextDocument(docUri);
|
||||
editor = await vscode.window.showTextDocument(doc);
|
||||
await sleep(2000); // Wait for server activation
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function sleep(ms: number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export const getDocPath = (p: string) => {
|
||||
return path.resolve(__dirname, '../../testFixture', p);
|
||||
};
|
||||
export const getDocUri = (p: string) => {
|
||||
return vscode.Uri.file(getDocPath(p));
|
||||
};
|
||||
|
||||
export async function setTestContent(content: string): Promise<boolean> {
|
||||
const all = new vscode.Range(
|
||||
doc.positionAt(0),
|
||||
doc.positionAt(doc.getText().length)
|
||||
);
|
||||
return editor.edit(eb => eb.replace(all, content));
|
||||
}
|
||||
15
lsp-log-streaming-sample/client/src/test/index.ts
Normal file
15
lsp-log-streaming-sample/client/src/test/index.ts
Normal file
@ -0,0 +1,15 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
'use strict';
|
||||
|
||||
import * as testRunner from 'vscode/lib/testrunner';
|
||||
|
||||
testRunner.configure({
|
||||
ui: 'bdd',
|
||||
useColors: true,
|
||||
timeout: 100000
|
||||
});
|
||||
|
||||
module.exports = testRunner;
|
||||
@ -0,0 +1 @@
|
||||
ANY browsers, ANY OS.
|
||||
17
lsp-log-streaming-sample/client/tsconfig.json
Normal file
17
lsp-log-streaming-sample/client/tsconfig.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"outDir": "out",
|
||||
"rootDir": "src",
|
||||
"lib": [ "es6" ],
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
26
lsp-log-streaming-sample/package-lock.json
generated
Normal file
26
lsp-log-streaming-sample/package-lock.json
generated
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "lsp-sample",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/mocha": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.0.tgz",
|
||||
"integrity": "sha512-YeDiSEzznwZwwp766SJ6QlrTyBYUGPSIwmREHVTmktUYiT/WADdWtpt9iH0KuUSf8lZLdI4lP0X6PBzPo5//JQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "8.10.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.18.tgz",
|
||||
"integrity": "sha512-WoepSz+wJlU5Bjq5oK6cO1oXe2FgPcjMtQPgKPS8fVaTAD0lxkScMCCbMimdkVCsykqaA4lvHWz3cmj28yimhA==",
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "2.8.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.8.3.tgz",
|
||||
"integrity": "sha512-K7g15Bb6Ra4lKf7Iq2l/I5/En+hLIHmxWZGq3D4DIRNFxMNV6j2SHSvDOqs2tGd4UvD/fJvrwopzQXjLrT7Itw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
63
lsp-log-streaming-sample/package.json
Normal file
63
lsp-log-streaming-sample/package.json
Normal file
@ -0,0 +1,63 @@
|
||||
{
|
||||
"name": "lsp-sample",
|
||||
"description": "A language server example",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"version": "1.0.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
||||
},
|
||||
"publisher": "vscode",
|
||||
"categories": [],
|
||||
"keywords": [
|
||||
"multi-root ready"
|
||||
],
|
||||
"engines": {
|
||||
"vscode": "^1.23.0"
|
||||
},
|
||||
"activationEvents": [
|
||||
"onLanguage:plaintext"
|
||||
],
|
||||
"main": "./client/out/extension",
|
||||
"contributes": {
|
||||
"configuration": {
|
||||
"type": "object",
|
||||
"title": "Example configuration",
|
||||
"properties": {
|
||||
"languageServerExample.maxNumberOfProblems": {
|
||||
"scope": "resource",
|
||||
"type": "number",
|
||||
"default": 100,
|
||||
"description": "Controls the maximum number of problems produced by the server."
|
||||
},
|
||||
"languageServerExample.trace.server": {
|
||||
"scope": "window",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"off",
|
||||
"messages",
|
||||
"verbose"
|
||||
],
|
||||
"default": "off",
|
||||
"description": "Traces the communication between VS Code and the language server."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "cd client && npm run update-vscode && cd .. && npm run compile",
|
||||
"compile:client": "tsc -p ./client/tsconfig.json",
|
||||
"compile:server": "tsc -p ./server/tsconfig.json",
|
||||
"watch:client": "tsc -w -p ./client/tsconfig.json",
|
||||
"watch:server": "tsc -w -p ./server/tsconfig.json",
|
||||
"compile": "npm run compile:client && npm run compile:server",
|
||||
"postinstall": "cd client && npm install && cd ../server && npm install && cd ..",
|
||||
"test": "sh ./scripts/e2e.sh"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.0",
|
||||
"@types/node": "^8.0.0",
|
||||
"typescript": "2.8.3"
|
||||
}
|
||||
}
|
||||
6
lsp-log-streaming-sample/scripts/e2e.sh
Executable file
6
lsp-log-streaming-sample/scripts/e2e.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
export CODE_TESTS_PATH="$(pwd)/client/out/test"
|
||||
export CODE_TESTS_WORKSPACE="$(pwd)/client/testFixture"
|
||||
|
||||
node "$(pwd)/client/node_modules/vscode/bin/test"
|
||||
41
lsp-log-streaming-sample/server/package-lock.json
generated
Normal file
41
lsp-log-streaming-sample/server/package-lock.json
generated
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "lsp-sample-server",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"vscode-jsonrpc": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz",
|
||||
"integrity": "sha512-T24Jb5V48e4VgYliUXMnZ379ItbrXgOimweKaJshD84z+8q7ZOZjJan0MeDe+Ugb+uqERDVV8SBmemaGMSMugA=="
|
||||
},
|
||||
"vscode-languageserver": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-4.1.3.tgz",
|
||||
"integrity": "sha512-D6p3q9x8QPtPLRUO5d2UKizjFYfg8zLVJqKoMpAaom8Wuhl1oKRCjeLg+Cp4mgPeCwR71wbgX2BM/jL51ni/0g==",
|
||||
"requires": {
|
||||
"vscode-languageserver-protocol": "3.7.2",
|
||||
"vscode-uri": "1.0.3"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-protocol": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.7.2.tgz",
|
||||
"integrity": "sha512-VVJwIA/FPl/FnVtrns0FPK6TLi/ET7n1Yo6tCrm6aG7+yAVwIGWdpTmKE+nbP8wEMMbHCkIabk63IJvfz2HNRg==",
|
||||
"requires": {
|
||||
"vscode-jsonrpc": "3.6.2",
|
||||
"vscode-languageserver-types": "3.7.2"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.7.2.tgz",
|
||||
"integrity": "sha512-L9D2RA+PDS2CiyhLQY5ZrOmyRvXyjc4Ha8s9PqS6mIgGxj00R5Xx2vLKBnAOVfrawJXYZST+2hioMks6SQVU7A=="
|
||||
},
|
||||
"vscode-uri": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.3.tgz",
|
||||
"integrity": "sha1-Yxvb9xbcyrDmUpGo3CXCMjIIWlI="
|
||||
}
|
||||
}
|
||||
}
|
||||
18
lsp-log-streaming-sample/server/package.json
Normal file
18
lsp-log-streaming-sample/server/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "lsp-sample-server",
|
||||
"description": "Example implementation of a language server in node.",
|
||||
"version": "1.0.0",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageserver": "^4.1.3"
|
||||
},
|
||||
"scripts": {}
|
||||
}
|
||||
240
lsp-log-streaming-sample/server/src/server.ts
Normal file
240
lsp-log-streaming-sample/server/src/server.ts
Normal file
@ -0,0 +1,240 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
'use strict';
|
||||
|
||||
import {
|
||||
createConnection,
|
||||
TextDocuments,
|
||||
TextDocument,
|
||||
Diagnostic,
|
||||
DiagnosticSeverity,
|
||||
ProposedFeatures,
|
||||
InitializeParams,
|
||||
DidChangeConfigurationNotification,
|
||||
CompletionItem,
|
||||
CompletionItemKind,
|
||||
TextDocumentPositionParams
|
||||
} from 'vscode-languageserver';
|
||||
|
||||
// Create a connection for the server. The connection uses Node's IPC as a transport.
|
||||
// Also include all preview / proposed LSP features.
|
||||
let connection = createConnection(ProposedFeatures.all);
|
||||
|
||||
// Create a simple text document manager. The text document manager
|
||||
// supports full document sync only
|
||||
let documents: TextDocuments = new TextDocuments();
|
||||
|
||||
let hasConfigurationCapability: boolean = false;
|
||||
let hasWorkspaceFolderCapability: boolean = false;
|
||||
let hasDiagnosticRelatedInformationCapability: boolean = false;
|
||||
|
||||
connection.onInitialize((params: InitializeParams) => {
|
||||
let capabilities = params.capabilities;
|
||||
|
||||
// Does the client support the `workspace/configuration` request?
|
||||
// If not, we will fall back using global settings
|
||||
hasConfigurationCapability =
|
||||
capabilities.workspace && !!capabilities.workspace.configuration;
|
||||
hasWorkspaceFolderCapability =
|
||||
capabilities.workspace && !!capabilities.workspace.workspaceFolders;
|
||||
hasDiagnosticRelatedInformationCapability =
|
||||
capabilities.textDocument &&
|
||||
capabilities.textDocument.publishDiagnostics &&
|
||||
capabilities.textDocument.publishDiagnostics.relatedInformation;
|
||||
|
||||
return {
|
||||
capabilities: {
|
||||
textDocumentSync: documents.syncKind,
|
||||
// Tell the client that the server supports code completion
|
||||
completionProvider: {
|
||||
resolveProvider: true
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
connection.onInitialized(() => {
|
||||
if (hasConfigurationCapability) {
|
||||
// Register for all configuration changes.
|
||||
connection.client.register(
|
||||
DidChangeConfigurationNotification.type,
|
||||
undefined
|
||||
);
|
||||
}
|
||||
if (hasWorkspaceFolderCapability) {
|
||||
connection.workspace.onDidChangeWorkspaceFolders(_event => {
|
||||
connection.console.log('Workspace folder change event received.');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// The example settings
|
||||
interface ExampleSettings {
|
||||
maxNumberOfProblems: number;
|
||||
}
|
||||
|
||||
// The global settings, used when the `workspace/configuration` request is not supported by the client.
|
||||
// Please note that this is not the case when using this server with the client provided in this example
|
||||
// but could happen with other clients.
|
||||
const defaultSettings: ExampleSettings = { maxNumberOfProblems: 1000 };
|
||||
let globalSettings: ExampleSettings = defaultSettings;
|
||||
|
||||
// Cache the settings of all open documents
|
||||
let documentSettings: Map<string, Thenable<ExampleSettings>> = new Map();
|
||||
|
||||
connection.onDidChangeConfiguration(change => {
|
||||
if (hasConfigurationCapability) {
|
||||
// Reset all cached document settings
|
||||
documentSettings.clear();
|
||||
} else {
|
||||
globalSettings = <ExampleSettings>(
|
||||
(change.settings.languageServerExample || defaultSettings)
|
||||
);
|
||||
}
|
||||
|
||||
// Revalidate all open text documents
|
||||
documents.all().forEach(validateTextDocument);
|
||||
});
|
||||
|
||||
function getDocumentSettings(resource: string): Thenable<ExampleSettings> {
|
||||
if (!hasConfigurationCapability) {
|
||||
return Promise.resolve(globalSettings);
|
||||
}
|
||||
let result = documentSettings.get(resource);
|
||||
if (!result) {
|
||||
result = connection.workspace.getConfiguration({
|
||||
scopeUri: resource,
|
||||
section: 'languageServerExample'
|
||||
});
|
||||
documentSettings.set(resource, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Only keep settings for open documents
|
||||
documents.onDidClose(e => {
|
||||
documentSettings.delete(e.document.uri);
|
||||
});
|
||||
|
||||
// The content of a text document has changed. This event is emitted
|
||||
// when the text document first opened or when its content has changed.
|
||||
documents.onDidChangeContent(change => {
|
||||
validateTextDocument(change.document);
|
||||
});
|
||||
|
||||
async function validateTextDocument(textDocument: TextDocument): Promise<void> {
|
||||
// In this simple example we get the settings for every validate run.
|
||||
let settings = await getDocumentSettings(textDocument.uri);
|
||||
|
||||
// The validator creates diagnostics for all uppercase words length 2 and more
|
||||
let text = textDocument.getText();
|
||||
let pattern = /\b[A-Z]{2,}\b/g;
|
||||
let m: RegExpExecArray;
|
||||
|
||||
let problems = 0;
|
||||
let diagnostics: Diagnostic[] = [];
|
||||
while ((m = pattern.exec(text)) && problems < settings.maxNumberOfProblems) {
|
||||
problems++;
|
||||
let diagnosic: Diagnostic = {
|
||||
severity: DiagnosticSeverity.Warning,
|
||||
range: {
|
||||
start: textDocument.positionAt(m.index),
|
||||
end: textDocument.positionAt(m.index + m[0].length)
|
||||
},
|
||||
message: `${m[0]} is all uppercase.`,
|
||||
source: 'ex'
|
||||
};
|
||||
if (hasDiagnosticRelatedInformationCapability) {
|
||||
diagnosic.relatedInformation = [
|
||||
{
|
||||
location: {
|
||||
uri: textDocument.uri,
|
||||
range: Object.assign({}, diagnosic.range)
|
||||
},
|
||||
message: 'Spelling matters'
|
||||
},
|
||||
{
|
||||
location: {
|
||||
uri: textDocument.uri,
|
||||
range: Object.assign({}, diagnosic.range)
|
||||
},
|
||||
message: 'Particularly for names'
|
||||
}
|
||||
];
|
||||
}
|
||||
diagnostics.push(diagnosic);
|
||||
}
|
||||
|
||||
// Send the computed diagnostics to VSCode.
|
||||
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
|
||||
}
|
||||
|
||||
connection.onDidChangeWatchedFiles(_change => {
|
||||
// Monitored files have change in VSCode
|
||||
connection.console.log('We received an file change event');
|
||||
});
|
||||
|
||||
// This handler provides the initial list of the completion items.
|
||||
connection.onCompletion(
|
||||
(_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {
|
||||
// The pass parameter contains the position of the text document in
|
||||
// which code complete got requested. For the example we ignore this
|
||||
// info and always provide the same completion items.
|
||||
return [
|
||||
{
|
||||
label: 'TypeScript',
|
||||
kind: CompletionItemKind.Text,
|
||||
data: 1
|
||||
},
|
||||
{
|
||||
label: 'JavaScript',
|
||||
kind: CompletionItemKind.Text,
|
||||
data: 2
|
||||
}
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
// This handler resolve additional information for the item selected in
|
||||
// the completion list.
|
||||
connection.onCompletionResolve(
|
||||
(item: CompletionItem): CompletionItem => {
|
||||
if (item.data === 1) {
|
||||
(item.detail = 'TypeScript details'),
|
||||
(item.documentation = 'TypeScript documentation');
|
||||
} else if (item.data === 2) {
|
||||
(item.detail = 'JavaScript details'),
|
||||
(item.documentation = 'JavaScript documentation');
|
||||
}
|
||||
return item;
|
||||
}
|
||||
);
|
||||
|
||||
/*
|
||||
connection.onDidOpenTextDocument((params) => {
|
||||
// A text document got opened in VSCode.
|
||||
// params.uri uniquely identifies the document. For documents store on disk this is a file URI.
|
||||
// params.text the initial full content of the document.
|
||||
connection.console.log(`${params.textDocument.uri} opened.`);
|
||||
});
|
||||
connection.onDidChangeTextDocument((params) => {
|
||||
// The content of a text document did change in VSCode.
|
||||
// params.uri uniquely identifies the document.
|
||||
// params.contentChanges describe the content changes to the document.
|
||||
connection.console.log(`${params.textDocument.uri} changed: ${JSON.stringify(params.contentChanges)}`);
|
||||
});
|
||||
connection.onDidCloseTextDocument((params) => {
|
||||
// A text document got closed in VSCode.
|
||||
// params.uri uniquely identifies the document.
|
||||
connection.console.log(`${params.textDocument.uri} closed.`);
|
||||
});
|
||||
*/
|
||||
|
||||
// Make the text document manager listen on the connection
|
||||
// for open, change and close text document events
|
||||
documents.listen(connection);
|
||||
|
||||
// Listen on the connection
|
||||
connection.listen();
|
||||
18
lsp-log-streaming-sample/server/tsconfig.json
Normal file
18
lsp-log-streaming-sample/server/tsconfig.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"outDir": "out",
|
||||
"rootDir": "src",
|
||||
"lib": [ "es6" ]
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
8
lsp-log-streaming-sample/tsconfig.base.json
Normal file
8
lsp-log-streaming-sample/tsconfig.base.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user