Skip to content

Commit f4d7b88

Browse files
authored
Merge pull request #122 from atom-community/upgrade-lsp
2 parents b056bb2 + 34853bc commit f4d7b88

File tree

8 files changed

+327
-52
lines changed

8 files changed

+327
-52
lines changed

lib/adapters/autocomplete-adapter.ts

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,25 @@ 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+
* - if `false` -> the edits are inserted : const|ole
29+
* - if `true`` -> the edits are replaced: const|
30+
*/
31+
type ShouldReplace = boolean
32+
2233
/**
2334
* Holds a list of suggestions generated from the CompletionItem[]
2435
* list sent by the server, as well as metadata about the context
@@ -73,14 +84,16 @@ export default class AutocompleteAdapter {
7384
* @param onDidConvertCompletionItem An optional function that takes a {CompletionItem},
7485
* an {atom$AutocompleteSuggestion} and a {atom$AutocompleteRequest}
7586
* allowing you to adjust converted items.
87+
* @param shouldReplace The behavior of suggestion acceptance (see {ShouldReplace}).
7688
* @returns A {Promise} of an {Array} of {atom$AutocompleteSuggestion}s containing the
7789
* AutoComplete+ suggestions to display.
7890
*/
7991
public async getSuggestions(
8092
server: ActiveServer,
8193
request: ac.SuggestionsRequestedEvent,
8294
onDidConvertCompletionItem?: CompletionItemAdjuster,
83-
minimumWordLength?: number
95+
minimumWordLength?: number,
96+
shouldReplace: ShouldReplace = false
8497
): Promise<ac.AnySuggestion[]> {
8598
const triggerChars =
8699
server.capabilities.completionProvider != null
@@ -101,6 +114,7 @@ export default class AutocompleteAdapter {
101114
request,
102115
triggerChar,
103116
triggerOnly,
117+
shouldReplace,
104118
onDidConvertCompletionItem
105119
)
106120

@@ -140,6 +154,7 @@ export default class AutocompleteAdapter {
140154
request: ac.SuggestionsRequestedEvent,
141155
triggerChar: string,
142156
triggerOnly: boolean,
157+
shouldReplace: ShouldReplace,
143158
onDidConvertCompletionItem?: CompletionItemAdjuster
144159
): Promise<Suggestion[]> {
145160
const cache = this._suggestionCache.get(server)
@@ -181,6 +196,7 @@ export default class AutocompleteAdapter {
181196
completions,
182197
request,
183198
triggerColumns,
199+
shouldReplace,
184200
onDidConvertCompletionItem
185201
)
186202
this._suggestionCache.set(server, {
@@ -339,6 +355,7 @@ export default class AutocompleteAdapter {
339355
* @param completionItems An {Array} of {CompletionItem} objects or a {CompletionList} containing completion
340356
* items to be converted.
341357
* @param request The {atom$AutocompleteRequest} to satisfy.
358+
* @param shouldReplace The behavior of suggestion acceptance (see {ShouldReplace}).
342359
* @param onDidConvertCompletionItem A function that takes a {CompletionItem}, an {atom$AutocompleteSuggestion}
343360
* and a {atom$AutocompleteRequest} allowing you to adjust converted items.
344361
* @returns A {Map} of AutoComplete+ suggestions ordered by the CompletionItems sortText.
@@ -347,6 +364,7 @@ export default class AutocompleteAdapter {
347364
completionItems: CompletionItem[] | CompletionList | null,
348365
request: ac.SuggestionsRequestedEvent,
349366
triggerColumns: [number, number],
367+
shouldReplace: ShouldReplace,
350368
onDidConvertCompletionItem?: CompletionItemAdjuster
351369
): Map<Suggestion, PossiblyResolvedCompletionItem> {
352370
const completionsArray = Array.isArray(completionItems)
@@ -361,6 +379,7 @@ export default class AutocompleteAdapter {
361379
{} as Suggestion,
362380
request,
363381
triggerColumns,
382+
shouldReplace,
364383
onDidConvertCompletionItem
365384
),
366385
new PossiblyResolvedCompletionItem(s, false),
@@ -374,6 +393,7 @@ export default class AutocompleteAdapter {
374393
* @param item An {CompletionItem} containing a completion item to be converted.
375394
* @param suggestion A {atom$AutocompleteSuggestion} to have the conversion applied to.
376395
* @param request The {atom$AutocompleteRequest} to satisfy.
396+
* @param shouldReplace The behavior of suggestion acceptance (see {ShouldReplace}).
377397
* @param onDidConvertCompletionItem A function that takes a {CompletionItem}, an {atom$AutocompleteSuggestion}
378398
* and a {atom$AutocompleteRequest} allowing you to adjust converted items.
379399
* @returns The {atom$AutocompleteSuggestion} passed in as suggestion with the conversion applied.
@@ -383,6 +403,7 @@ export default class AutocompleteAdapter {
383403
suggestion: Suggestion,
384404
request: ac.SuggestionsRequestedEvent,
385405
triggerColumns: [number, number],
406+
shouldReplace: ShouldReplace,
386407
onDidConvertCompletionItem?: CompletionItemAdjuster
387408
): Suggestion {
388409
AutocompleteAdapter.applyCompletionItemToSuggestion(item, suggestion as TextSuggestion)
@@ -391,7 +412,8 @@ export default class AutocompleteAdapter {
391412
request.editor,
392413
triggerColumns,
393414
request.bufferPosition,
394-
suggestion as TextSuggestion
415+
suggestion as TextSuggestion,
416+
shouldReplace
395417
)
396418
AutocompleteAdapter.applySnippetToSuggestion(item, suggestion as SnippetSuggestion)
397419
if (onDidConvertCompletionItem != null) {
@@ -442,20 +464,31 @@ export default class AutocompleteAdapter {
442464
* @param textEdit A {TextEdit} from a CompletionItem to apply.
443465
* @param editor An Atom {TextEditor} used to obtain the necessary text replacement.
444466
* @param suggestion An {atom$AutocompleteSuggestion} to set the replacementPrefix and text properties of.
467+
* @param shouldReplace The behavior of suggestion acceptance (see {ShouldReplace}).
445468
*/
446469
public static applyTextEditToSuggestion(
447-
textEdit: TextEdit | undefined,
470+
textEdit: TextEdit | InsertReplaceEdit | undefined,
448471
editor: TextEditor,
449472
triggerColumns: [number, number],
450473
originalBufferPosition: Point,
451-
suggestion: TextSuggestion
474+
suggestion: TextSuggestion,
475+
shouldReplace: ShouldReplace
452476
): void {
453477
if (!textEdit) {
454478
return
455479
}
456-
if (textEdit.range.start.character !== triggerColumns[0]) {
457-
const range = Convert.lsRangeToAtomRange(textEdit.range)
458-
suggestion.customReplacmentPrefix = editor.getTextInBufferRange([range.start, originalBufferPosition])
480+
let range: Range
481+
if ("range" in textEdit) {
482+
range = textEdit.range
483+
} else if (shouldReplace) {
484+
range = textEdit.replace
485+
} else {
486+
range = textEdit.insert
487+
}
488+
489+
if (range.start.character !== triggerColumns[0]) {
490+
const atomRange = Convert.lsRangeToAtomRange(range)
491+
suggestion.customReplacmentPrefix = editor.getTextInBufferRange([atomRange.start, originalBufferPosition])
459492
}
460493
suggestion.text = textEdit.newText
461494
}

lib/adapters/document-sync-adapter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ export class TextEditorSyncAdapter {
412412
const didSaveNotification = {
413413
textDocument: { uri, version: this._getVersion(uri) },
414414
} as DidSaveTextDocumentParams
415-
if (this._documentSync.save && this._documentSync.save.includeText) {
415+
if (typeof this._documentSync.save === "object" && this._documentSync.save.includeText) {
416416
didSaveNotification.text = this._editor.getText()
417417
}
418418
this._connection.didSaveTextDocument(didSaveNotification)

lib/auto-languageclient.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import * as cp from "child_process"
22
import * as ls from "./languageclient"
33
import * as rpc from "vscode-jsonrpc"
4+
import * as rpcNode from "vscode-jsonrpc/node"
45
import * as path from "path"
5-
import type * as atomIde from "atom-ide-base"
6+
import * as atomIde from "atom-ide"
67
import * as linter from "atom/linter"
78
import Convert from "./convert.js"
89
import ApplyEditAdapter from "./adapters/apply-edit-adapter"
@@ -185,6 +186,9 @@ export default class AutoLanguageClient {
185186
rename: {
186187
dynamicRegistration: false,
187188
},
189+
moniker: {
190+
dynamicRegistration: false,
191+
},
188192

189193
// We do not support these features yet.
190194
// Need to set to undefined to appease TypeScript weak type detection.
@@ -429,17 +433,17 @@ export default class AutoLanguageClient {
429433
const connectionType = this.getConnectionType()
430434
switch (connectionType) {
431435
case "ipc":
432-
reader = new rpc.IPCMessageReader(lsProcess as cp.ChildProcess)
433-
writer = new rpc.IPCMessageWriter(lsProcess as cp.ChildProcess)
436+
reader = new rpcNode.IPCMessageReader(lsProcess as cp.ChildProcess)
437+
writer = new rpcNode.IPCMessageWriter(lsProcess as cp.ChildProcess)
434438
break
435439
case "socket":
436-
reader = new rpc.SocketMessageReader(this.socket)
437-
writer = new rpc.SocketMessageWriter(this.socket)
440+
reader = new rpcNode.SocketMessageReader(this.socket)
441+
writer = new rpcNode.SocketMessageWriter(this.socket)
438442
break
439443
case "stdio":
440444
if (lsProcess.stdin !== null && lsProcess.stdout !== null) {
441-
reader = new rpc.StreamMessageReader(lsProcess.stdout)
442-
writer = new rpc.StreamMessageWriter(lsProcess.stdin)
445+
reader = new rpcNode.StreamMessageReader(lsProcess.stdout)
446+
writer = new rpcNode.StreamMessageWriter(lsProcess.stdin)
443447
} else {
444448
this.logger.error(
445449
`The language server process for ${this.getLanguageName()} does not have a valid stdin and stdout`

lib/languageclient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ export class LanguageClientConnection extends EventEmitter {
534534
return result
535535
} catch (e) {
536536
const responseError = e as jsonrpc.ResponseError<any>
537-
if (cancellationToken && responseError.code === jsonrpc.ErrorCodes.RequestCancelled) {
537+
if (cancellationToken && responseError.code === lsp.LSPErrorCodes.RequestCancelled) {
538538
this._log.debug(`rpc.sendRequest ${method} was cancelled`)
539539
} else {
540540
this._log.error(`rpc.sendRequest ${method} threw`, 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.

0 commit comments

Comments
 (0)