codemirror-languageserver 1.5.0 → 1.7.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 +11 -3
- package/dist/index.d.ts +82 -2
- package/dist/index.js +106 -56
- package/package.json +5 -5
- package/dist/index.d.sync-conflict-20210813-102235-QZ53W3J.ts +0 -10
package/README.md
CHANGED
|
@@ -16,9 +16,17 @@ npm i codemirror-languageserver
|
|
|
16
16
|
import { languageServer } from 'codemirror-languageserver';
|
|
17
17
|
|
|
18
18
|
var ls = languageServer({
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
// WebSocket server URI and other client options.
|
|
20
|
+
serverUri: serverUri,
|
|
21
|
+
rootUri: 'file:///',
|
|
22
|
+
|
|
23
|
+
// Alternatively, to share the same client across multiple instances of this plugin.
|
|
24
|
+
client: new LanguageServerClient({
|
|
25
|
+
serverUri: serverUri,
|
|
26
|
+
rootUri: 'file:///'
|
|
27
|
+
}),
|
|
28
|
+
|
|
29
|
+
documentUri: `file:///${filename}`,
|
|
22
30
|
languageId: 'cpp' // As defined at https://microsoft.github.io/language-server-protocol/specification#textDocumentItem.
|
|
23
31
|
});
|
|
24
32
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,88 @@
|
|
|
1
|
+
import { EditorView, 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 { Tooltip } from '@codemirror/tooltip';
|
|
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 serverUri;
|
|
19
|
+
private rootUri;
|
|
20
|
+
private workspaceFolders;
|
|
21
|
+
private autoClose?;
|
|
22
|
+
private transport;
|
|
23
|
+
private requestManager;
|
|
24
|
+
private client;
|
|
25
|
+
ready: boolean;
|
|
26
|
+
capabilities: LSP.ServerCapabilities<any>;
|
|
27
|
+
private plugins;
|
|
28
|
+
constructor(options: LanguageServerClientOptions);
|
|
29
|
+
initialize(): Promise<void>;
|
|
30
|
+
close(): void;
|
|
31
|
+
textDocumentDidOpen(params: LSP.DidOpenTextDocumentParams): Promise<LSP.DidOpenTextDocumentParams>;
|
|
32
|
+
textDocumentDidChange(params: LSP.DidChangeTextDocumentParams): Promise<LSP.DidChangeTextDocumentParams>;
|
|
33
|
+
textDocumentHover(params: LSP.HoverParams): Promise<LSP.Hover>;
|
|
34
|
+
textDocumentCompletion(params: LSP.CompletionParams): Promise<LSP.CompletionList | LSP.CompletionItem[]>;
|
|
35
|
+
attachPlugin(plugin: LanguageServerPlugin): void;
|
|
36
|
+
detachPlugin(plugin: LanguageServerPlugin): void;
|
|
37
|
+
private request;
|
|
38
|
+
private notify;
|
|
39
|
+
private processRequest;
|
|
40
|
+
private processNotification;
|
|
41
|
+
}
|
|
42
|
+
declare class LanguageServerPlugin implements PluginValue {
|
|
43
|
+
private view;
|
|
44
|
+
client: LanguageServerClient;
|
|
45
|
+
private documentUri;
|
|
46
|
+
private languageId;
|
|
47
|
+
private documentVersion;
|
|
48
|
+
private changesTimeout;
|
|
49
|
+
constructor(view: EditorView);
|
|
50
|
+
update({ docChanged }: ViewUpdate): void;
|
|
51
|
+
destroy(): void;
|
|
52
|
+
initialize({ documentText }: {
|
|
53
|
+
documentText: string;
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
sendChange({ documentText }: {
|
|
56
|
+
documentText: string;
|
|
57
|
+
}): Promise<void>;
|
|
58
|
+
requestDiagnostics(view: EditorView): void;
|
|
59
|
+
requestHoverTooltip(view: EditorView, { line, character }: {
|
|
60
|
+
line: number;
|
|
61
|
+
character: number;
|
|
62
|
+
}): Promise<Tooltip | null>;
|
|
63
|
+
requestCompletion(context: CompletionContext, { line, character }: {
|
|
64
|
+
line: number;
|
|
65
|
+
character: number;
|
|
66
|
+
}, { triggerKind, triggerCharacter, }: {
|
|
67
|
+
triggerKind: CompletionTriggerKind;
|
|
68
|
+
triggerCharacter: string | undefined;
|
|
69
|
+
}): Promise<CompletionResult | null>;
|
|
70
|
+
processNotification(notification: Notification): void;
|
|
71
|
+
processDiagnostics(params: PublishDiagnosticsParams): void;
|
|
72
|
+
}
|
|
73
|
+
interface LanguageServerClientOptions {
|
|
74
|
+
serverUri: `ws://${string}` | `wss://${string}`;
|
|
75
|
+
rootUri: string | null;
|
|
76
|
+
workspaceFolders: LSP.WorkspaceFolder[] | null;
|
|
77
|
+
autoClose?: boolean;
|
|
78
|
+
}
|
|
1
79
|
interface LanguageServerOptions {
|
|
80
|
+
client?: LanguageServerClient;
|
|
2
81
|
serverUri: `ws://${string}` | `wss://${string}`;
|
|
3
|
-
rootUri: string;
|
|
82
|
+
rootUri: string | null;
|
|
83
|
+
workspaceFolders: LSP.WorkspaceFolder[] | null;
|
|
4
84
|
documentUri: string;
|
|
5
85
|
languageId: string;
|
|
6
86
|
}
|
|
7
87
|
declare function languageServer(options: LanguageServerOptions): import("@codemirror/state").Extension[];
|
|
8
|
-
export { languageServer };
|
|
88
|
+
export { LanguageServerClient, languageServer };
|
package/dist/index.js
CHANGED
|
@@ -10,49 +10,30 @@ const timeout = 10000;
|
|
|
10
10
|
const changesDelay = 500;
|
|
11
11
|
const CompletionItemKindMap = Object.fromEntries(Object.entries(CompletionItemKind).map(([key, value]) => [value, key]));
|
|
12
12
|
const useLast = (values) => values.reduce((_, v) => v, '');
|
|
13
|
-
const
|
|
14
|
-
const rootUri = Facet.define({ combine: useLast });
|
|
13
|
+
const client = Facet.define({ combine: useLast });
|
|
15
14
|
const documentUri = Facet.define({ combine: useLast });
|
|
16
15
|
const languageId = Facet.define({ combine: useLast });
|
|
17
|
-
class
|
|
18
|
-
constructor(
|
|
19
|
-
this.
|
|
20
|
-
this.rootUri =
|
|
21
|
-
this.
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
this.transport = new WebSocketTransport(this.view.state.facet(serverUri));
|
|
16
|
+
class LanguageServerClient {
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.serverUri = options.serverUri;
|
|
19
|
+
this.rootUri = options.rootUri;
|
|
20
|
+
this.workspaceFolders = options.workspaceFolders;
|
|
21
|
+
this.autoClose = options.autoClose;
|
|
22
|
+
this.plugins = [];
|
|
23
|
+
this.transport = new WebSocketTransport(this.serverUri);
|
|
26
24
|
this.requestManager = new RequestManager([this.transport]);
|
|
27
25
|
this.client = new Client(this.requestManager);
|
|
28
26
|
this.client.onNotification((data) => {
|
|
29
27
|
this.processNotification(data);
|
|
30
28
|
});
|
|
31
|
-
this.
|
|
32
|
-
|
|
29
|
+
this.transport.connection.addEventListener('message', (message) => {
|
|
30
|
+
const data = JSON.parse(message.data);
|
|
31
|
+
if (data.method && data.id)
|
|
32
|
+
this.processRequest(data);
|
|
33
33
|
});
|
|
34
|
+
this.initialize();
|
|
34
35
|
}
|
|
35
|
-
|
|
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);
|
|
51
|
-
}
|
|
52
|
-
notify(method, params) {
|
|
53
|
-
return this.client.notify({ method, params });
|
|
54
|
-
}
|
|
55
|
-
async initialize({ documentText }) {
|
|
36
|
+
async initialize() {
|
|
56
37
|
const { capabilities } = await this.request('initialize', {
|
|
57
38
|
capabilities: {
|
|
58
39
|
textDocument: {
|
|
@@ -110,30 +91,98 @@ class LanguageServerPlugin {
|
|
|
110
91
|
initializationOptions: null,
|
|
111
92
|
processId: null,
|
|
112
93
|
rootUri: this.rootUri,
|
|
113
|
-
workspaceFolders:
|
|
114
|
-
{
|
|
115
|
-
name: 'root',
|
|
116
|
-
uri: this.rootUri,
|
|
117
|
-
},
|
|
118
|
-
],
|
|
94
|
+
workspaceFolders: this.workspaceFolders,
|
|
119
95
|
}, timeout * 3);
|
|
120
96
|
this.capabilities = capabilities;
|
|
121
97
|
this.notify('initialized', {});
|
|
122
|
-
this.
|
|
98
|
+
this.ready = true;
|
|
99
|
+
}
|
|
100
|
+
close() {
|
|
101
|
+
this.client.close();
|
|
102
|
+
}
|
|
103
|
+
textDocumentDidOpen(params) {
|
|
104
|
+
return this.notify('textDocument/didOpen', params);
|
|
105
|
+
}
|
|
106
|
+
textDocumentDidChange(params) {
|
|
107
|
+
return this.notify('textDocument/didChange', params);
|
|
108
|
+
}
|
|
109
|
+
async textDocumentHover(params) {
|
|
110
|
+
return await this.request('textDocument/hover', params, timeout);
|
|
111
|
+
}
|
|
112
|
+
async textDocumentCompletion(params) {
|
|
113
|
+
return await this.request('textDocument/completion', params, timeout);
|
|
114
|
+
}
|
|
115
|
+
attachPlugin(plugin) {
|
|
116
|
+
this.plugins.push(plugin);
|
|
117
|
+
}
|
|
118
|
+
detachPlugin(plugin) {
|
|
119
|
+
const i = this.plugins.indexOf(plugin);
|
|
120
|
+
if (i === -1)
|
|
121
|
+
return;
|
|
122
|
+
this.plugins.splice(i, 1);
|
|
123
|
+
if (this.autoClose)
|
|
124
|
+
this.close();
|
|
125
|
+
}
|
|
126
|
+
request(method, params, timeout) {
|
|
127
|
+
return this.client.request({ method, params }, timeout);
|
|
128
|
+
}
|
|
129
|
+
notify(method, params) {
|
|
130
|
+
return this.client.notify({ method, params });
|
|
131
|
+
}
|
|
132
|
+
processRequest({ id }) {
|
|
133
|
+
this.transport.connection.send(JSON.stringify({
|
|
134
|
+
jsonrpc: '2.0',
|
|
135
|
+
id,
|
|
136
|
+
result: null
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
processNotification(notification) {
|
|
140
|
+
for (const plugin of this.plugins)
|
|
141
|
+
plugin.processNotification(notification);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
class LanguageServerPlugin {
|
|
145
|
+
constructor(view) {
|
|
146
|
+
this.view = view;
|
|
147
|
+
this.client = this.view.state.facet(client);
|
|
148
|
+
this.documentUri = this.view.state.facet(documentUri);
|
|
149
|
+
this.languageId = this.view.state.facet(languageId);
|
|
150
|
+
this.documentVersion = 0;
|
|
151
|
+
this.changesTimeout = 0;
|
|
152
|
+
this.client.attachPlugin(this);
|
|
153
|
+
this.initialize({
|
|
154
|
+
documentText: this.view.state.doc.toString(),
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
update({ docChanged }) {
|
|
158
|
+
if (!docChanged)
|
|
159
|
+
return;
|
|
160
|
+
if (this.changesTimeout)
|
|
161
|
+
clearTimeout(this.changesTimeout);
|
|
162
|
+
this.changesTimeout = self.setTimeout(() => {
|
|
163
|
+
this.sendChange({
|
|
164
|
+
documentText: this.view.state.doc.toString(),
|
|
165
|
+
});
|
|
166
|
+
}, changesDelay);
|
|
167
|
+
}
|
|
168
|
+
destroy() {
|
|
169
|
+
this.client.detachPlugin(this);
|
|
170
|
+
}
|
|
171
|
+
async initialize({ documentText }) {
|
|
172
|
+
this.client.textDocumentDidOpen({
|
|
123
173
|
textDocument: {
|
|
124
174
|
uri: this.documentUri,
|
|
125
175
|
languageId: this.languageId,
|
|
126
176
|
text: documentText,
|
|
127
177
|
version: this.documentVersion,
|
|
128
|
-
}
|
|
178
|
+
}
|
|
129
179
|
});
|
|
130
|
-
this.ready = true;
|
|
131
180
|
}
|
|
132
181
|
async sendChange({ documentText }) {
|
|
133
|
-
if (!this.ready)
|
|
182
|
+
if (!this.client.ready)
|
|
134
183
|
return;
|
|
135
184
|
try {
|
|
136
|
-
await this.
|
|
185
|
+
await this.client.textDocumentDidChange({
|
|
137
186
|
textDocument: {
|
|
138
187
|
uri: this.documentUri,
|
|
139
188
|
version: this.documentVersion++,
|
|
@@ -149,13 +198,13 @@ class LanguageServerPlugin {
|
|
|
149
198
|
this.sendChange({ documentText: view.state.doc.toString() });
|
|
150
199
|
}
|
|
151
200
|
async requestHoverTooltip(view, { line, character }) {
|
|
152
|
-
if (!this.ready || !this.capabilities.hoverProvider)
|
|
201
|
+
if (!this.client.ready || !this.client.capabilities.hoverProvider)
|
|
153
202
|
return null;
|
|
154
203
|
this.sendChange({ documentText: view.state.doc.toString() });
|
|
155
|
-
const result = await this.
|
|
204
|
+
const result = await this.client.textDocumentHover({
|
|
156
205
|
textDocument: { uri: this.documentUri },
|
|
157
206
|
position: { line, character },
|
|
158
|
-
}
|
|
207
|
+
});
|
|
159
208
|
if (!result)
|
|
160
209
|
return null;
|
|
161
210
|
const { contents, range } = result;
|
|
@@ -173,19 +222,19 @@ class LanguageServerPlugin {
|
|
|
173
222
|
return { pos, end, create: (view) => ({ dom }), above: true };
|
|
174
223
|
}
|
|
175
224
|
async requestCompletion(context, { line, character }, { triggerKind, triggerCharacter, }) {
|
|
176
|
-
if (!this.ready || !this.capabilities.completionProvider)
|
|
225
|
+
if (!this.client.ready || !this.client.capabilities.completionProvider)
|
|
177
226
|
return null;
|
|
178
227
|
this.sendChange({
|
|
179
228
|
documentText: context.state.doc.toString(),
|
|
180
229
|
});
|
|
181
|
-
const result = await this.
|
|
230
|
+
const result = await this.client.textDocumentCompletion({
|
|
182
231
|
textDocument: { uri: this.documentUri },
|
|
183
232
|
position: { line, character },
|
|
184
233
|
context: {
|
|
185
234
|
triggerKind,
|
|
186
235
|
triggerCharacter,
|
|
187
|
-
}
|
|
188
|
-
}
|
|
236
|
+
}
|
|
237
|
+
});
|
|
189
238
|
if (!result)
|
|
190
239
|
return null;
|
|
191
240
|
const items = 'items' in result ? result.items : result;
|
|
@@ -243,6 +292,8 @@ class LanguageServerPlugin {
|
|
|
243
292
|
}
|
|
244
293
|
}
|
|
245
294
|
processDiagnostics(params) {
|
|
295
|
+
if (params.uri !== this.documentUri)
|
|
296
|
+
return;
|
|
246
297
|
const diagnostics = params.diagnostics
|
|
247
298
|
.map(({ range, message, severity }) => ({
|
|
248
299
|
from: posToOffset(this.view.state.doc, range.start),
|
|
@@ -271,8 +322,7 @@ class LanguageServerPlugin {
|
|
|
271
322
|
function languageServer(options) {
|
|
272
323
|
let plugin = null;
|
|
273
324
|
return [
|
|
274
|
-
|
|
275
|
-
rootUri.of(options.rootUri),
|
|
325
|
+
client.of(options.client || new LanguageServerClient({ ...options, autoClose: true })),
|
|
276
326
|
documentUri.of(options.documentUri),
|
|
277
327
|
languageId.of(options.languageId),
|
|
278
328
|
ViewPlugin.define((view) => (plugin = new LanguageServerPlugin(view))),
|
|
@@ -291,7 +341,7 @@ function languageServer(options) {
|
|
|
291
341
|
let trigKind = CompletionTriggerKind.Invoked;
|
|
292
342
|
let trigChar;
|
|
293
343
|
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]))) {
|
|
344
|
+
((_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
345
|
trigKind = CompletionTriggerKind.TriggerCharacter;
|
|
296
346
|
trigChar = line.text[pos - line.from - 1];
|
|
297
347
|
}
|
|
@@ -371,4 +421,4 @@ const baseTheme = EditorView.baseTheme({
|
|
|
371
421
|
},
|
|
372
422
|
});
|
|
373
423
|
|
|
374
|
-
export { languageServer };
|
|
424
|
+
export { LanguageServerClient, languageServer };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codemirror-languageserver",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Language Server Plugin for CodeMirror 6",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@codemirror/autocomplete": "^0.19.8",
|
|
34
34
|
"@codemirror/lint": "^0.19.3",
|
|
35
|
-
"@codemirror/state": "^0.19.
|
|
36
|
-
"@codemirror/tooltip": "^0.19.
|
|
37
|
-
"@codemirror/view": "^0.19.
|
|
38
|
-
"@open-rpc/client-js": "^1.
|
|
35
|
+
"@codemirror/state": "^0.19.8",
|
|
36
|
+
"@codemirror/tooltip": "^0.19.14",
|
|
37
|
+
"@codemirror/view": "^0.19.43",
|
|
38
|
+
"@open-rpc/client-js": "^1.7.1",
|
|
39
39
|
"vscode-languageserver-protocol": "^3.16.0"
|
|
40
40
|
},
|
|
41
41
|
"prettier": {
|
|
@@ -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 };
|