Skip to content

Commit db07b3c

Browse files
aminyaillright
andcommitted
feat: upgrade to LSP 3.16 and fix compiler errors
Co-Authored-By: Lev Chelyadinov <[email protected]>
1 parent b056bb2 commit db07b3c

File tree

7 files changed

+128
-74
lines changed

7 files changed

+128
-74
lines changed

lib/adapters/autocomplete-adapter.ts

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,28 @@ import {
1111
CompletionParams,
1212
CompletionTriggerKind,
1313
InsertTextFormat,
14+
InsertReplaceEdit,
1415
LanguageClientConnection,
16+
Range,
1517
ServerCapabilities,
1618
TextEdit,
1719
} from "../languageclient"
1820
import { Point, TextEditor } from "atom"
1921
import * as ac from "atom/autocomplete-plus"
2022
import { Suggestion, TextSuggestion, SnippetSuggestion } from "../types/autocomplete-extended"
2123

24+
/**
25+
* Defines the behavior of suggestion acceptance.
26+
* Assume you have "cons|ole" in the editor (`|` is the cursor position)
27+
* and the autocomplete suggestion is `const`.
28+
* - insert mode: const|ole
29+
* - replace mode: const|
30+
*/
31+
enum InsertMode {
32+
insert = 'insert',
33+
replace = 'replace',
34+
}
35+
2236
/**
2337
* Holds a list of suggestions generated from the CompletionItem[]
2438
* list sent by the server, as well as metadata about the context
@@ -73,14 +87,16 @@ export default class AutocompleteAdapter {
7387
* @param onDidConvertCompletionItem An optional function that takes a {CompletionItem},
7488
* an {atom$AutocompleteSuggestion} and a {atom$AutocompleteRequest}
7589
* allowing you to adjust converted items.
90+
* @param insertMode The behavior of suggestion acceptance (see {InsertMode}).
7691
* @returns A {Promise} of an {Array} of {atom$AutocompleteSuggestion}s containing the
7792
* AutoComplete+ suggestions to display.
7893
*/
7994
public async getSuggestions(
8095
server: ActiveServer,
8196
request: ac.SuggestionsRequestedEvent,
8297
onDidConvertCompletionItem?: CompletionItemAdjuster,
83-
minimumWordLength?: number
98+
minimumWordLength?: number,
99+
insertMode: InsertMode = InsertMode.insert
84100
): Promise<ac.AnySuggestion[]> {
85101
const triggerChars =
86102
server.capabilities.completionProvider != null
@@ -101,6 +117,7 @@ export default class AutocompleteAdapter {
101117
request,
102118
triggerChar,
103119
triggerOnly,
120+
insertMode,
104121
onDidConvertCompletionItem
105122
)
106123

@@ -140,6 +157,7 @@ export default class AutocompleteAdapter {
140157
request: ac.SuggestionsRequestedEvent,
141158
triggerChar: string,
142159
triggerOnly: boolean,
160+
insertMode: InsertMode,
143161
onDidConvertCompletionItem?: CompletionItemAdjuster
144162
): Promise<Suggestion[]> {
145163
const cache = this._suggestionCache.get(server)
@@ -181,6 +199,7 @@ export default class AutocompleteAdapter {
181199
completions,
182200
request,
183201
triggerColumns,
202+
insertMode,
184203
onDidConvertCompletionItem
185204
)
186205
this._suggestionCache.set(server, {
@@ -339,6 +358,7 @@ export default class AutocompleteAdapter {
339358
* @param completionItems An {Array} of {CompletionItem} objects or a {CompletionList} containing completion
340359
* items to be converted.
341360
* @param request The {atom$AutocompleteRequest} to satisfy.
361+
* @param insertMode The behavior of suggestion acceptance (see {InsertMode}).
342362
* @param onDidConvertCompletionItem A function that takes a {CompletionItem}, an {atom$AutocompleteSuggestion}
343363
* and a {atom$AutocompleteRequest} allowing you to adjust converted items.
344364
* @returns A {Map} of AutoComplete+ suggestions ordered by the CompletionItems sortText.
@@ -347,6 +367,7 @@ export default class AutocompleteAdapter {
347367
completionItems: CompletionItem[] | CompletionList | null,
348368
request: ac.SuggestionsRequestedEvent,
349369
triggerColumns: [number, number],
370+
insertMode: InsertMode,
350371
onDidConvertCompletionItem?: CompletionItemAdjuster
351372
): Map<Suggestion, PossiblyResolvedCompletionItem> {
352373
const completionsArray = Array.isArray(completionItems)
@@ -361,6 +382,7 @@ export default class AutocompleteAdapter {
361382
{} as Suggestion,
362383
request,
363384
triggerColumns,
385+
insertMode,
364386
onDidConvertCompletionItem
365387
),
366388
new PossiblyResolvedCompletionItem(s, false),
@@ -374,6 +396,7 @@ export default class AutocompleteAdapter {
374396
* @param item An {CompletionItem} containing a completion item to be converted.
375397
* @param suggestion A {atom$AutocompleteSuggestion} to have the conversion applied to.
376398
* @param request The {atom$AutocompleteRequest} to satisfy.
399+
* @param insertMode The behavior of suggestion acceptance (see {InsertMode}).
377400
* @param onDidConvertCompletionItem A function that takes a {CompletionItem}, an {atom$AutocompleteSuggestion}
378401
* and a {atom$AutocompleteRequest} allowing you to adjust converted items.
379402
* @returns The {atom$AutocompleteSuggestion} passed in as suggestion with the conversion applied.
@@ -383,6 +406,7 @@ export default class AutocompleteAdapter {
383406
suggestion: Suggestion,
384407
request: ac.SuggestionsRequestedEvent,
385408
triggerColumns: [number, number],
409+
insertMode: InsertMode,
386410
onDidConvertCompletionItem?: CompletionItemAdjuster
387411
): Suggestion {
388412
AutocompleteAdapter.applyCompletionItemToSuggestion(item, suggestion as TextSuggestion)
@@ -391,7 +415,8 @@ export default class AutocompleteAdapter {
391415
request.editor,
392416
triggerColumns,
393417
request.bufferPosition,
394-
suggestion as TextSuggestion
418+
suggestion as TextSuggestion,
419+
insertMode
395420
)
396421
AutocompleteAdapter.applySnippetToSuggestion(item, suggestion as SnippetSuggestion)
397422
if (onDidConvertCompletionItem != null) {
@@ -442,20 +467,29 @@ export default class AutocompleteAdapter {
442467
* @param textEdit A {TextEdit} from a CompletionItem to apply.
443468
* @param editor An Atom {TextEditor} used to obtain the necessary text replacement.
444469
* @param suggestion An {atom$AutocompleteSuggestion} to set the replacementPrefix and text properties of.
470+
* @param insertMode The behavior of suggestion acceptance (see {InsertMode}).
445471
*/
446472
public static applyTextEditToSuggestion(
447-
textEdit: TextEdit | undefined,
473+
textEdit: TextEdit | InsertReplaceEdit | undefined,
448474
editor: TextEditor,
449475
triggerColumns: [number, number],
450476
originalBufferPosition: Point,
451-
suggestion: TextSuggestion
477+
suggestion: TextSuggestion,
478+
insertMode: InsertMode,
452479
): void {
453-
if (!textEdit) {
454-
return
480+
if (!textEdit) { return; }
481+
let range: Range;
482+
if ('range' in textEdit) {
483+
range = textEdit.range;
484+
} else if (insertMode === InsertMode.insert) {
485+
range = textEdit.insert;
486+
} else {
487+
range = textEdit.replace;
455488
}
456-
if (textEdit.range.start.character !== triggerColumns[0]) {
457-
const range = Convert.lsRangeToAtomRange(textEdit.range)
458-
suggestion.customReplacmentPrefix = editor.getTextInBufferRange([range.start, originalBufferPosition])
489+
490+
if (range.start.character !== triggerColumns[0]) {
491+
const atomRange = Convert.lsRangeToAtomRange(range);
492+
suggestion.customReplacmentPrefix = editor.getTextInBufferRange([atomRange.start, originalBufferPosition]);
459493
}
460494
suggestion.text = textEdit.newText
461495
}

lib/adapters/document-sync-adapter.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,10 @@ export class TextEditorSyncAdapter {
410410

411411
const uri = this.getEditorUri()
412412
const didSaveNotification = {
413-
textDocument: { uri, version: this._getVersion(uri) },
414-
} as DidSaveTextDocumentParams
415-
if (this._documentSync.save && this._documentSync.save.includeText) {
416-
didSaveNotification.text = this._editor.getText()
413+
textDocument: { uri, version: this._getVersion((uri)) },
414+
} as DidSaveTextDocumentParams;
415+
if (typeof this._documentSync.save === 'object' && this._documentSync.save.includeText) {
416+
didSaveNotification.text = this._editor.getText();
417417
}
418418
this._connection.didSaveTextDocument(didSaveNotification)
419419
if (this._fakeDidChangeWatchedFiles) {

lib/auto-languageclient.ts

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,50 @@
1-
import * as cp from "child_process"
2-
import * as ls from "./languageclient"
3-
import * as rpc from "vscode-jsonrpc"
4-
import * as path from "path"
5-
import type * as atomIde from "atom-ide-base"
6-
import * as linter from "atom/linter"
7-
import Convert from "./convert.js"
8-
import ApplyEditAdapter from "./adapters/apply-edit-adapter"
9-
import AutocompleteAdapter from "./adapters/autocomplete-adapter"
10-
import CodeActionAdapter from "./adapters/code-action-adapter"
11-
import CodeFormatAdapter from "./adapters/code-format-adapter"
12-
import CodeHighlightAdapter from "./adapters/code-highlight-adapter"
13-
import DatatipAdapter from "./adapters/datatip-adapter"
14-
import DefinitionAdapter from "./adapters/definition-adapter"
15-
import DocumentSyncAdapter from "./adapters/document-sync-adapter"
16-
import FindReferencesAdapter from "./adapters/find-references-adapter"
17-
import LinterPushV2Adapter from "./adapters/linter-push-v2-adapter"
18-
import LoggingConsoleAdapter from "./adapters/logging-console-adapter"
19-
import NotificationsAdapter from "./adapters/notifications-adapter"
20-
import OutlineViewAdapter from "./adapters/outline-view-adapter"
21-
import RenameAdapter from "./adapters/rename-adapter"
22-
import SignatureHelpAdapter from "./adapters/signature-help-adapter"
23-
import * as Utils from "./utils"
24-
import { Socket } from "net"
25-
import { LanguageClientConnection } from "./languageclient"
26-
import { ConsoleLogger, FilteredLogger, Logger } from "./logger"
27-
import { LanguageServerProcess, ServerManager, ActiveServer } from "./server-manager.js"
28-
import { Disposable, CompositeDisposable, Point, Range, TextEditor } from "atom"
29-
import * as ac from "atom/autocomplete-plus"
30-
31-
export { ActiveServer, LanguageClientConnection, LanguageServerProcess }
32-
export type ConnectionType = "stdio" | "socket" | "ipc"
1+
import * as cp from 'child_process';
2+
import * as ls from './languageclient';
3+
import * as rpc from 'vscode-jsonrpc';
4+
import * as rpcNode from 'vscode-jsonrpc/node';
5+
import * as path from 'path';
6+
import * as atomIde from 'atom-ide';
7+
import * as linter from 'atom/linter';
8+
import Convert from './convert.js';
9+
import ApplyEditAdapter from './adapters/apply-edit-adapter';
10+
import AutocompleteAdapter from './adapters/autocomplete-adapter';
11+
import CodeActionAdapter from './adapters/code-action-adapter';
12+
import CodeFormatAdapter from './adapters/code-format-adapter';
13+
import CodeHighlightAdapter from './adapters/code-highlight-adapter';
14+
import DatatipAdapter from './adapters/datatip-adapter';
15+
import DefinitionAdapter from './adapters/definition-adapter';
16+
import DocumentSyncAdapter from './adapters/document-sync-adapter';
17+
import FindReferencesAdapter from './adapters/find-references-adapter';
18+
import LinterPushV2Adapter from './adapters/linter-push-v2-adapter';
19+
import LoggingConsoleAdapter from './adapters/logging-console-adapter';
20+
import NotificationsAdapter from './adapters/notifications-adapter';
21+
import OutlineViewAdapter from './adapters/outline-view-adapter';
22+
import RenameAdapter from './adapters/rename-adapter';
23+
import SignatureHelpAdapter from './adapters/signature-help-adapter';
24+
import * as Utils from './utils';
25+
import { Socket } from 'net';
26+
import { LanguageClientConnection } from './languageclient';
27+
import {
28+
ConsoleLogger,
29+
FilteredLogger,
30+
Logger,
31+
} from './logger';
32+
import {
33+
LanguageServerProcess,
34+
ServerManager,
35+
ActiveServer,
36+
} from './server-manager.js';
37+
import {
38+
Disposable,
39+
CompositeDisposable,
40+
Point,
41+
Range,
42+
TextEditor,
43+
} from 'atom';
44+
import * as ac from 'atom/autocomplete-plus';
45+
46+
export { ActiveServer, LanguageClientConnection, LanguageServerProcess };
47+
export type ConnectionType = 'stdio' | 'socket' | 'ipc';
3348

3449
export interface ServerAdapters {
3550
linterPushV2: LinterPushV2Adapter
@@ -185,6 +200,9 @@ export default class AutoLanguageClient {
185200
rename: {
186201
dynamicRegistration: false,
187202
},
203+
moniker: {
204+
dynamicRegistration: false,
205+
},
188206

189207
// We do not support these features yet.
190208
// Need to set to undefined to appease TypeScript weak type detection.
@@ -429,17 +447,17 @@ export default class AutoLanguageClient {
429447
const connectionType = this.getConnectionType()
430448
switch (connectionType) {
431449
case "ipc":
432-
reader = new rpc.IPCMessageReader(lsProcess as cp.ChildProcess)
433-
writer = new rpc.IPCMessageWriter(lsProcess as cp.ChildProcess)
450+
reader = new rpcNode.IPCMessageReader(lsProcess as cp.ChildProcess)
451+
writer = new rpcNode.IPCMessageWriter(lsProcess as cp.ChildProcess)
434452
break
435453
case "socket":
436-
reader = new rpc.SocketMessageReader(this.socket)
437-
writer = new rpc.SocketMessageWriter(this.socket)
454+
reader = new rpcNode.SocketMessageReader(this.socket)
455+
writer = new rpcNode.SocketMessageWriter(this.socket)
438456
break
439457
case "stdio":
440458
if (lsProcess.stdin !== null && lsProcess.stdout !== null) {
441-
reader = new rpc.StreamMessageReader(lsProcess.stdout)
442-
writer = new rpc.StreamMessageWriter(lsProcess.stdin)
459+
reader = new rpcNode.StreamMessageReader(lsProcess.stdout)
460+
writer = new rpcNode.StreamMessageWriter(lsProcess.stdin)
443461
} else {
444462
this.logger.error(
445463
`The language server process for ${this.getLanguageName()} does not have a valid stdin and stdout`

lib/languageclient.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -533,11 +533,12 @@ export class LanguageClientConnection extends EventEmitter {
533533
this._log.debug(`rpc.sendRequest ${method} received (${Math.floor(took)}ms)`, result)
534534
return result
535535
} catch (e) {
536-
const responseError = e as jsonrpc.ResponseError<any>
537-
if (cancellationToken && responseError.code === jsonrpc.ErrorCodes.RequestCancelled) {
538-
this._log.debug(`rpc.sendRequest ${method} was cancelled`)
539-
} else {
540-
this._log.error(`rpc.sendRequest ${method} threw`, e)
536+
const responseError = e as jsonrpc.ResponseError<any>;
537+
if (cancellationToken && responseError.code === lsp.LSPErrorCodes.RequestCancelled) {
538+
this._log.debug(`rpc.sendRequest ${method} was cancelled`);
539+
}
540+
else {
541+
this._log.error(`rpc.sendRequest ${method} threw`, e);
541542
}
542543

543544
throw e

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
"atomTestRunner": "./test/runner",
2727
"dependencies": {
2828
"atom-ide-base": "^2.4.0",
29-
"vscode-jsonrpc": "5.0.1",
30-
"vscode-languageserver-protocol": "3.15.3",
31-
"vscode-languageserver-types": "3.15.1",
29+
"vscode-jsonrpc": "6.0.0",
30+
"vscode-languageserver-protocol": "3.16.0",
31+
"vscode-languageserver-types": "3.16.0",
3232
"zadeh": "^2.0.2"
3333
},
3434
"devDependencies": {

pnpm-lock.yaml

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/helpers.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ export function createSpyConnection(): rpc.MessageConnection {
1919
sendProgress: sinon.spy(),
2020
trace: sinon.spy(),
2121
inspect: sinon.spy(),
22-
}
22+
end: sinon.spy(),
23+
};
2324
}
2425

2526
export function createFakeEditor(path?: string): TextEditor {

0 commit comments

Comments
 (0)