This commit is contained in:
Pine Wu
2018-09-05 00:40:46 -07:00
parent b250b88695
commit 0fda4ad8a1
5 changed files with 110 additions and 6 deletions

View File

@ -1,10 +1,29 @@
# LSP Example
# LSP Example for Log Streaming
This is a repository adapted from [lsp-sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/lsp-sample) to demonstrate
- Usage of the JSON output
- Streaming the JSON into [LSP Inspector](https://github.com/Microsoft/language-server-protocol-inspector)
## Synopsis
- With `vscode-languageclient@5.1.0-next.9`, you can specify a JSON log output format with `[langId].trace.server` as follows:
```json
"languageServerExample.trace.server": {
"format": "json",
"verbosity": "verbose"
}
```
- A [webview](https://github.com/Microsoft/language-server-protocol-inspector/tree/master/lsp-inspector-webview) build of the LSP Inspector can be downloaded here:
- When using the Webview LSP Inspector, it will open a WebSocket Server taking incoming connection that sends logs following [this format](https://github.com/Microsoft/language-server-protocol-inspector#log-format).
- You can stream the JSON log of any Language Server using `vscode-languageclient` to the LSP Inspector, and it will show a live view of the LSP connection.
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
@ -35,4 +54,4 @@ It also includes an End-to-End test.
- 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.
- Enter text content such as `AAA aaa BBB`. The extension will emit diagnostics for all words in all-uppercase.

View File

@ -4,6 +4,28 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/events": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz",
"integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==",
"dev": true
},
"@types/node": {
"version": "10.9.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.9.4.tgz",
"integrity": "sha512-fCHV45gS+m3hH17zgkgADUSi2RR1Vht6wOZ0jyHP8rjiQra9f+mIcgwPQHllmDocYOstIEbKlxbFDYlgrTPYqw==",
"dev": true
},
"@types/ws": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.0.tgz",
"integrity": "sha512-i/dVaSjmTM92EFFFhmGL6AmHzvJ70XpAXmMLvNKh3JrRTGOiXvejfxe5+OSxcJK0paGOYHDaRLS8nXW6/FxSxg==",
"dev": true,
"requires": {
"@types/events": "1.2.0",
"@types/node": "10.9.4"
}
},
"ajv": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
@ -101,6 +123,11 @@
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"async-limiter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@ -1801,6 +1828,14 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"ws": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.0.0.tgz",
"integrity": "sha512-c2UlYcAZp1VS8AORtpq6y4RJIkJ9dQz18W32SpR/qXGfLDZ2jU4y4wKvvZwqbi7U6gxFQTeE+urMbXU/tsDy4w==",
"requires": {
"async-limiter": "1.0.0"
}
},
"xtend": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",

View File

@ -18,6 +18,10 @@
},
"dependencies": {
"vscode": "^1.1.21",
"vscode-languageclient": "^5.1.0-next.9"
"vscode-languageclient": "^5.1.0-next.9",
"ws": "^6.0.0"
},
"devDependencies": {
"@types/ws": "^6.0.0"
}
}

View File

@ -5,7 +5,8 @@
'use strict';
import * as path from 'path';
import { workspace, ExtensionContext } from 'vscode';
import { workspace, commands, ExtensionContext, OutputChannel } from 'vscode';
import * as WebSocket from 'ws';
import {
LanguageClient,
@ -17,6 +18,14 @@ import {
let client: LanguageClient;
export function activate(context: ExtensionContext) {
const socketPort = workspace.getConfiguration('languageServerExample').get('port', 7000);
let socket: WebSocket | null = null
commands.registerCommand('languageServerExample.startStreaming', () => {
// Establish websocket connection
socket = new WebSocket(`ws://localhost:${socketPort}`)
})
// The server is implemented in node
let serverModule = context.asAbsolutePath(
path.join('server', 'out', 'server.js')
@ -36,6 +45,29 @@ export function activate(context: ExtensionContext) {
}
};
// The log to send
let log = ''
const websocketOutputChannel: OutputChannel = {
name: 'websocket',
// Only append the logs but send them later
append(value: string) {
log += value
console.log(value)
},
appendLine(value: string) {
log += value
// Don't send logs until WebSocket initialization
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(log)
}
log = ''
},
clear() {},
show() {},
hide() {},
dispose() {}
}
// Options to control the language client
let clientOptions: LanguageClientOptions = {
// Register the server for plain text documents
@ -43,7 +75,9 @@ export function activate(context: ExtensionContext) {
synchronize: {
// Notify the server about file changes to '.clientrc files contained in the workspace
fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
}
},
// Hijacks all LSP logs and redirect them to a specific port through WebSocket connection
outputChannel: websocketOutputChannel
};
// Create the language client and start the client.

View File

@ -21,6 +21,12 @@
],
"main": "./client/out/extension",
"contributes": {
"commands": [
{
"command": "languageServerExample.startStreaming",
"title": "Start Stream Logs into languageServerExample.port"
}
],
"configuration": {
"type": "object",
"title": "Example configuration",
@ -31,6 +37,12 @@
"default": 100,
"description": "Controls the maximum number of problems produced by the server."
},
"languageServerExample.port": {
"type": "number",
"default": 7000,
"scope": "window",
"description": "The WebSocket port to stream LSP log data into."
},
"languageServerExample.trace.server": {
"scope": "window",
"type": "object",