codemirror-languageserver 1.5.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -3
- package/dist/index.d.ts +86 -5
- package/dist/index.js +104 -60
- package/package.json +5 -6
- package/dist/index.d.sync-conflict-20210813-102235-QZ53W3J.ts +0 -10
package/README.md
CHANGED
|
@@ -15,10 +15,20 @@ npm i codemirror-languageserver
|
|
|
15
15
|
``` js
|
|
16
16
|
import { languageServer } from 'codemirror-languageserver';
|
|
17
17
|
|
|
18
|
+
const transport = new WebSocketTransport(serverUri)
|
|
19
|
+
|
|
18
20
|
var ls = languageServer({
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
// WebSocket server uri and other client options.
|
|
22
|
+
serverUri,
|
|
23
|
+
rootUri: 'file:///',
|
|
24
|
+
|
|
25
|
+
// Alternatively, to share the same client across multiple instances of this plugin.
|
|
26
|
+
client: new LanguageServerClient({
|
|
27
|
+
serverUri,
|
|
28
|
+
rootUri: 'file:///'
|
|
29
|
+
}),
|
|
30
|
+
|
|
31
|
+
documentUri: `file:///${filename}`,
|
|
22
32
|
languageId: 'cpp' // As defined at https://microsoft.github.io/language-server-protocol/specification#textDocumentItem.
|
|
23
33
|
});
|
|
24
34
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,89 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { EditorView, Tooltip, ViewUpdate, PluginValue } from '@codemirror/view';
|
|
2
|
+
import * as LSP from 'vscode-languageserver-protocol';
|
|
3
|
+
import { CompletionTriggerKind, PublishDiagnosticsParams } from "vscode-languageserver-protocol";
|
|
4
|
+
import { CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
|
5
|
+
import { Transport } from '@open-rpc/client-js/build/transports/Transport';
|
|
6
|
+
interface LSPEventMap {
|
|
7
|
+
'textDocument/publishDiagnostics': LSP.PublishDiagnosticsParams;
|
|
8
|
+
}
|
|
9
|
+
type Notification = {
|
|
10
|
+
[key in keyof LSPEventMap]: {
|
|
11
|
+
jsonrpc: '2.0';
|
|
12
|
+
id?: null | undefined;
|
|
13
|
+
method: key;
|
|
14
|
+
params: LSPEventMap[key];
|
|
15
|
+
};
|
|
16
|
+
}[keyof LSPEventMap];
|
|
17
|
+
declare class LanguageServerClient {
|
|
18
|
+
private rootUri;
|
|
19
|
+
private workspaceFolders;
|
|
20
|
+
private autoClose?;
|
|
21
|
+
private transport;
|
|
22
|
+
private requestManager;
|
|
23
|
+
private client;
|
|
24
|
+
ready: boolean;
|
|
25
|
+
capabilities: LSP.ServerCapabilities<any>;
|
|
26
|
+
private plugins;
|
|
27
|
+
constructor(options: LanguageServerClientOptions);
|
|
28
|
+
initialize(): Promise<void>;
|
|
29
|
+
close(): void;
|
|
30
|
+
textDocumentDidOpen(params: LSP.DidOpenTextDocumentParams): Promise<LSP.DidOpenTextDocumentParams>;
|
|
31
|
+
textDocumentDidChange(params: LSP.DidChangeTextDocumentParams): Promise<LSP.DidChangeTextDocumentParams>;
|
|
32
|
+
textDocumentHover(params: LSP.HoverParams): Promise<LSP.Hover>;
|
|
33
|
+
textDocumentCompletion(params: LSP.CompletionParams): Promise<LSP.CompletionList | LSP.CompletionItem[]>;
|
|
34
|
+
attachPlugin(plugin: LanguageServerPlugin): void;
|
|
35
|
+
detachPlugin(plugin: LanguageServerPlugin): void;
|
|
36
|
+
private request;
|
|
37
|
+
private notify;
|
|
38
|
+
private processNotification;
|
|
39
|
+
}
|
|
40
|
+
declare class LanguageServerPlugin implements PluginValue {
|
|
41
|
+
private view;
|
|
42
|
+
client: LanguageServerClient;
|
|
43
|
+
private documentUri;
|
|
44
|
+
private languageId;
|
|
45
|
+
private documentVersion;
|
|
46
|
+
private changesTimeout;
|
|
47
|
+
constructor(view: EditorView);
|
|
48
|
+
update({ docChanged }: ViewUpdate): void;
|
|
49
|
+
destroy(): void;
|
|
50
|
+
initialize({ documentText }: {
|
|
51
|
+
documentText: string;
|
|
52
|
+
}): Promise<void>;
|
|
53
|
+
sendChange({ documentText }: {
|
|
54
|
+
documentText: string;
|
|
55
|
+
}): Promise<void>;
|
|
56
|
+
requestDiagnostics(view: EditorView): void;
|
|
57
|
+
requestHoverTooltip(view: EditorView, { line, character }: {
|
|
58
|
+
line: number;
|
|
59
|
+
character: number;
|
|
60
|
+
}): Promise<Tooltip | null>;
|
|
61
|
+
requestCompletion(context: CompletionContext, { line, character }: {
|
|
62
|
+
line: number;
|
|
63
|
+
character: number;
|
|
64
|
+
}, { triggerKind, triggerCharacter, }: {
|
|
65
|
+
triggerKind: CompletionTriggerKind;
|
|
66
|
+
triggerCharacter: string | undefined;
|
|
67
|
+
}): Promise<CompletionResult | null>;
|
|
68
|
+
processNotification(notification: Notification): void;
|
|
69
|
+
processDiagnostics(params: PublishDiagnosticsParams): void;
|
|
70
|
+
}
|
|
71
|
+
interface LanguageServerBaseOptions {
|
|
72
|
+
rootUri: string | null;
|
|
73
|
+
workspaceFolders: LSP.WorkspaceFolder[] | null;
|
|
4
74
|
documentUri: string;
|
|
5
75
|
languageId: string;
|
|
6
76
|
}
|
|
7
|
-
|
|
8
|
-
|
|
77
|
+
interface LanguageServerClientOptions extends LanguageServerBaseOptions {
|
|
78
|
+
transport: Transport;
|
|
79
|
+
autoClose?: boolean;
|
|
80
|
+
}
|
|
81
|
+
interface LanguageServerOptions extends LanguageServerClientOptions {
|
|
82
|
+
client?: LanguageServerClient;
|
|
83
|
+
}
|
|
84
|
+
interface LanguageServerWebsocketOptions extends LanguageServerBaseOptions {
|
|
85
|
+
serverUri: `ws://${string}` | `wss://${string}`;
|
|
86
|
+
}
|
|
87
|
+
declare function languageServer(options: LanguageServerWebsocketOptions): import("@codemirror/state").Extension[];
|
|
88
|
+
declare function languageServerWithTransport(options: LanguageServerOptions): import("@codemirror/state").Extension[];
|
|
89
|
+
export { LanguageServerClient, languageServer, languageServerWithTransport };
|
package/dist/index.js
CHANGED
|
@@ -1,58 +1,32 @@
|
|
|
1
1
|
import { autocompletion } from '@codemirror/autocomplete';
|
|
2
2
|
import { setDiagnostics } from '@codemirror/lint';
|
|
3
3
|
import { Facet } from '@codemirror/state';
|
|
4
|
-
import { hoverTooltip } from '@codemirror/
|
|
5
|
-
import {
|
|
6
|
-
import { WebSocketTransport, RequestManager, Client } from '@open-rpc/client-js';
|
|
4
|
+
import { ViewPlugin, hoverTooltip, EditorView } from '@codemirror/view';
|
|
5
|
+
import { RequestManager, Client, WebSocketTransport } from '@open-rpc/client-js';
|
|
7
6
|
import { CompletionItemKind, CompletionTriggerKind, DiagnosticSeverity } from 'vscode-languageserver-protocol';
|
|
8
7
|
|
|
9
8
|
const timeout = 10000;
|
|
10
9
|
const changesDelay = 500;
|
|
11
10
|
const CompletionItemKindMap = Object.fromEntries(Object.entries(CompletionItemKind).map(([key, value]) => [value, key]));
|
|
12
11
|
const useLast = (values) => values.reduce((_, v) => v, '');
|
|
13
|
-
const
|
|
14
|
-
const rootUri = Facet.define({ combine: useLast });
|
|
12
|
+
const client = Facet.define({ combine: useLast });
|
|
15
13
|
const documentUri = Facet.define({ combine: useLast });
|
|
16
14
|
const languageId = Facet.define({ combine: useLast });
|
|
17
|
-
class
|
|
18
|
-
constructor(
|
|
19
|
-
this.
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
24
|
-
this.changesTimeout = 0;
|
|
25
|
-
this.transport = new WebSocketTransport(this.view.state.facet(serverUri));
|
|
15
|
+
class LanguageServerClient {
|
|
16
|
+
constructor(options) {
|
|
17
|
+
this.rootUri = options.rootUri;
|
|
18
|
+
this.workspaceFolders = options.workspaceFolders;
|
|
19
|
+
this.autoClose = options.autoClose;
|
|
20
|
+
this.plugins = [];
|
|
21
|
+
this.transport = options.transport;
|
|
26
22
|
this.requestManager = new RequestManager([this.transport]);
|
|
27
23
|
this.client = new Client(this.requestManager);
|
|
28
24
|
this.client.onNotification((data) => {
|
|
29
25
|
this.processNotification(data);
|
|
30
26
|
});
|
|
31
|
-
this.initialize(
|
|
32
|
-
documentText: this.view.state.doc.toString(),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
update({ docChanged }) {
|
|
36
|
-
if (!docChanged)
|
|
37
|
-
return;
|
|
38
|
-
if (this.changesTimeout)
|
|
39
|
-
clearTimeout(this.changesTimeout);
|
|
40
|
-
this.changesTimeout = self.setTimeout(() => {
|
|
41
|
-
this.sendChange({
|
|
42
|
-
documentText: this.view.state.doc.toString(),
|
|
43
|
-
});
|
|
44
|
-
}, changesDelay);
|
|
45
|
-
}
|
|
46
|
-
destroy() {
|
|
47
|
-
this.client.close();
|
|
48
|
-
}
|
|
49
|
-
request(method, params, timeout) {
|
|
50
|
-
return this.client.request({ method, params }, timeout);
|
|
27
|
+
this.initialize();
|
|
51
28
|
}
|
|
52
|
-
|
|
53
|
-
return this.client.notify({ method, params });
|
|
54
|
-
}
|
|
55
|
-
async initialize({ documentText }) {
|
|
29
|
+
async initialize() {
|
|
56
30
|
const { capabilities } = await this.request('initialize', {
|
|
57
31
|
capabilities: {
|
|
58
32
|
textDocument: {
|
|
@@ -110,30 +84,91 @@ class LanguageServerPlugin {
|
|
|
110
84
|
initializationOptions: null,
|
|
111
85
|
processId: null,
|
|
112
86
|
rootUri: this.rootUri,
|
|
113
|
-
workspaceFolders:
|
|
114
|
-
{
|
|
115
|
-
name: 'root',
|
|
116
|
-
uri: this.rootUri,
|
|
117
|
-
},
|
|
118
|
-
],
|
|
87
|
+
workspaceFolders: this.workspaceFolders,
|
|
119
88
|
}, timeout * 3);
|
|
120
89
|
this.capabilities = capabilities;
|
|
121
90
|
this.notify('initialized', {});
|
|
122
|
-
this.
|
|
91
|
+
this.ready = true;
|
|
92
|
+
}
|
|
93
|
+
close() {
|
|
94
|
+
this.client.close();
|
|
95
|
+
}
|
|
96
|
+
textDocumentDidOpen(params) {
|
|
97
|
+
return this.notify('textDocument/didOpen', params);
|
|
98
|
+
}
|
|
99
|
+
textDocumentDidChange(params) {
|
|
100
|
+
return this.notify('textDocument/didChange', params);
|
|
101
|
+
}
|
|
102
|
+
async textDocumentHover(params) {
|
|
103
|
+
return await this.request('textDocument/hover', params, timeout);
|
|
104
|
+
}
|
|
105
|
+
async textDocumentCompletion(params) {
|
|
106
|
+
return await this.request('textDocument/completion', params, timeout);
|
|
107
|
+
}
|
|
108
|
+
attachPlugin(plugin) {
|
|
109
|
+
this.plugins.push(plugin);
|
|
110
|
+
}
|
|
111
|
+
detachPlugin(plugin) {
|
|
112
|
+
const i = this.plugins.indexOf(plugin);
|
|
113
|
+
if (i === -1)
|
|
114
|
+
return;
|
|
115
|
+
this.plugins.splice(i, 1);
|
|
116
|
+
if (this.autoClose)
|
|
117
|
+
this.close();
|
|
118
|
+
}
|
|
119
|
+
request(method, params, timeout) {
|
|
120
|
+
return this.client.request({ method, params }, timeout);
|
|
121
|
+
}
|
|
122
|
+
notify(method, params) {
|
|
123
|
+
return this.client.notify({ method, params });
|
|
124
|
+
}
|
|
125
|
+
processNotification(notification) {
|
|
126
|
+
for (const plugin of this.plugins)
|
|
127
|
+
plugin.processNotification(notification);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
class LanguageServerPlugin {
|
|
131
|
+
constructor(view) {
|
|
132
|
+
this.view = view;
|
|
133
|
+
this.client = this.view.state.facet(client);
|
|
134
|
+
this.documentUri = this.view.state.facet(documentUri);
|
|
135
|
+
this.languageId = this.view.state.facet(languageId);
|
|
136
|
+
this.documentVersion = 0;
|
|
137
|
+
this.changesTimeout = 0;
|
|
138
|
+
this.client.attachPlugin(this);
|
|
139
|
+
this.initialize({
|
|
140
|
+
documentText: this.view.state.doc.toString(),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
update({ docChanged }) {
|
|
144
|
+
if (!docChanged)
|
|
145
|
+
return;
|
|
146
|
+
if (this.changesTimeout)
|
|
147
|
+
clearTimeout(this.changesTimeout);
|
|
148
|
+
this.changesTimeout = self.setTimeout(() => {
|
|
149
|
+
this.sendChange({
|
|
150
|
+
documentText: this.view.state.doc.toString(),
|
|
151
|
+
});
|
|
152
|
+
}, changesDelay);
|
|
153
|
+
}
|
|
154
|
+
destroy() {
|
|
155
|
+
this.client.detachPlugin(this);
|
|
156
|
+
}
|
|
157
|
+
async initialize({ documentText }) {
|
|
158
|
+
this.client.textDocumentDidOpen({
|
|
123
159
|
textDocument: {
|
|
124
160
|
uri: this.documentUri,
|
|
125
161
|
languageId: this.languageId,
|
|
126
162
|
text: documentText,
|
|
127
163
|
version: this.documentVersion,
|
|
128
|
-
}
|
|
164
|
+
}
|
|
129
165
|
});
|
|
130
|
-
this.ready = true;
|
|
131
166
|
}
|
|
132
167
|
async sendChange({ documentText }) {
|
|
133
|
-
if (!this.ready)
|
|
168
|
+
if (!this.client.ready)
|
|
134
169
|
return;
|
|
135
170
|
try {
|
|
136
|
-
await this.
|
|
171
|
+
await this.client.textDocumentDidChange({
|
|
137
172
|
textDocument: {
|
|
138
173
|
uri: this.documentUri,
|
|
139
174
|
version: this.documentVersion++,
|
|
@@ -149,13 +184,13 @@ class LanguageServerPlugin {
|
|
|
149
184
|
this.sendChange({ documentText: view.state.doc.toString() });
|
|
150
185
|
}
|
|
151
186
|
async requestHoverTooltip(view, { line, character }) {
|
|
152
|
-
if (!this.ready || !this.capabilities.hoverProvider)
|
|
187
|
+
if (!this.client.ready || !this.client.capabilities.hoverProvider)
|
|
153
188
|
return null;
|
|
154
189
|
this.sendChange({ documentText: view.state.doc.toString() });
|
|
155
|
-
const result = await this.
|
|
190
|
+
const result = await this.client.textDocumentHover({
|
|
156
191
|
textDocument: { uri: this.documentUri },
|
|
157
192
|
position: { line, character },
|
|
158
|
-
}
|
|
193
|
+
});
|
|
159
194
|
if (!result)
|
|
160
195
|
return null;
|
|
161
196
|
const { contents, range } = result;
|
|
@@ -173,19 +208,19 @@ class LanguageServerPlugin {
|
|
|
173
208
|
return { pos, end, create: (view) => ({ dom }), above: true };
|
|
174
209
|
}
|
|
175
210
|
async requestCompletion(context, { line, character }, { triggerKind, triggerCharacter, }) {
|
|
176
|
-
if (!this.ready || !this.capabilities.completionProvider)
|
|
211
|
+
if (!this.client.ready || !this.client.capabilities.completionProvider)
|
|
177
212
|
return null;
|
|
178
213
|
this.sendChange({
|
|
179
214
|
documentText: context.state.doc.toString(),
|
|
180
215
|
});
|
|
181
|
-
const result = await this.
|
|
216
|
+
const result = await this.client.textDocumentCompletion({
|
|
182
217
|
textDocument: { uri: this.documentUri },
|
|
183
218
|
position: { line, character },
|
|
184
219
|
context: {
|
|
185
220
|
triggerKind,
|
|
186
221
|
triggerCharacter,
|
|
187
|
-
}
|
|
188
|
-
}
|
|
222
|
+
}
|
|
223
|
+
});
|
|
189
224
|
if (!result)
|
|
190
225
|
return null;
|
|
191
226
|
const items = 'items' in result ? result.items : result;
|
|
@@ -243,6 +278,8 @@ class LanguageServerPlugin {
|
|
|
243
278
|
}
|
|
244
279
|
}
|
|
245
280
|
processDiagnostics(params) {
|
|
281
|
+
if (params.uri !== this.documentUri)
|
|
282
|
+
return;
|
|
246
283
|
const diagnostics = params.diagnostics
|
|
247
284
|
.map(({ range, message, severity }) => ({
|
|
248
285
|
from: posToOffset(this.view.state.doc, range.start),
|
|
@@ -269,10 +306,17 @@ class LanguageServerPlugin {
|
|
|
269
306
|
}
|
|
270
307
|
}
|
|
271
308
|
function languageServer(options) {
|
|
309
|
+
const serverUri = options.serverUri;
|
|
310
|
+
delete options.serverUri;
|
|
311
|
+
return languageServerWithTransport({
|
|
312
|
+
...options,
|
|
313
|
+
transport: new WebSocketTransport(serverUri)
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
function languageServerWithTransport(options) {
|
|
272
317
|
let plugin = null;
|
|
273
318
|
return [
|
|
274
|
-
|
|
275
|
-
rootUri.of(options.rootUri),
|
|
319
|
+
client.of(options.client || new LanguageServerClient({ ...options, autoClose: true })),
|
|
276
320
|
documentUri.of(options.documentUri),
|
|
277
321
|
languageId.of(options.languageId),
|
|
278
322
|
ViewPlugin.define((view) => (plugin = new LanguageServerPlugin(view))),
|
|
@@ -291,7 +335,7 @@ function languageServer(options) {
|
|
|
291
335
|
let trigKind = CompletionTriggerKind.Invoked;
|
|
292
336
|
let trigChar;
|
|
293
337
|
if (!explicit &&
|
|
294
|
-
((_c = (_b = (_a = plugin.capabilities) === null || _a === void 0 ? void 0 : _a.completionProvider) === null || _b === void 0 ? void 0 : _b.triggerCharacters) === null || _c === void 0 ? void 0 : _c.includes(line.text[pos - line.from - 1]))) {
|
|
338
|
+
((_c = (_b = (_a = plugin.client.capabilities) === null || _a === void 0 ? void 0 : _a.completionProvider) === null || _b === void 0 ? void 0 : _b.triggerCharacters) === null || _c === void 0 ? void 0 : _c.includes(line.text[pos - line.from - 1]))) {
|
|
295
339
|
trigKind = CompletionTriggerKind.TriggerCharacter;
|
|
296
340
|
trigChar = line.text[pos - line.from - 1];
|
|
297
341
|
}
|
|
@@ -371,4 +415,4 @@ const baseTheme = EditorView.baseTheme({
|
|
|
371
415
|
},
|
|
372
416
|
});
|
|
373
417
|
|
|
374
|
-
export { languageServer };
|
|
418
|
+
export { LanguageServerClient, languageServer, languageServerWithTransport };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codemirror-languageserver",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Language Server Plugin for CodeMirror 6",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -30,11 +30,10 @@
|
|
|
30
30
|
"typescript": "^4.2.4"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@codemirror/autocomplete": "^0.
|
|
34
|
-
"@codemirror/lint": "^0.
|
|
35
|
-
"@codemirror/state": "^0.
|
|
36
|
-
"@codemirror/
|
|
37
|
-
"@codemirror/view": "^0.19.43",
|
|
33
|
+
"@codemirror/autocomplete": "^0.20.0",
|
|
34
|
+
"@codemirror/lint": "^0.20.0",
|
|
35
|
+
"@codemirror/state": "^0.20.0",
|
|
36
|
+
"@codemirror/view": "^0.20.0",
|
|
38
37
|
"@open-rpc/client-js": "^1.7.1",
|
|
39
38
|
"vscode-languageserver-protocol": "^3.16.0"
|
|
40
39
|
},
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
interface LanguageServerOptions {
|
|
2
|
-
serverUri: `ws://${string}` | `wss://${string}`;
|
|
3
|
-
rootUri: string;
|
|
4
|
-
documentUri: string;
|
|
5
|
-
languageId: string;
|
|
6
|
-
onConnect(): void;
|
|
7
|
-
onDisconnect(): void;
|
|
8
|
-
}
|
|
9
|
-
declare function languageServer(options: LanguageServerOptions): import("@codemirror/state").Extension[];
|
|
10
|
-
export { languageServer };
|