From f90f323b794cefa75d4d785569dd7239a0589a52 Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Mon, 14 Jul 2025 16:45:18 +0200 Subject: [PATCH 1/2] When running against SourceKit-LSP 6.3, use a dictionary to communicate experimental client capabilities Companion of https://github.com/swiftlang/sourcekit-lsp/pull/2204 --- .../LanguageClientConfiguration.ts | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/sourcekit-lsp/LanguageClientConfiguration.ts b/src/sourcekit-lsp/LanguageClientConfiguration.ts index 6947a4f4c..80ce1f126 100644 --- a/src/sourcekit-lsp/LanguageClientConfiguration.ts +++ b/src/sourcekit-lsp/LanguageClientConfiguration.ts @@ -32,8 +32,6 @@ import { SourceKitLSPErrorHandler } from "./LanguageClientManager"; /* eslint-disable @typescript-eslint/no-explicit-any */ function initializationOptions(swiftVersion: Version): any { let options: any = { - "workspace/peekDocuments": true, // workaround for client capability to handle `PeekDocumentsRequest` - "workspace/getReferenceDocument": true, // the client can handle URIs with scheme `sourcekit-lsp:` "textDocument/codeLens": { supportedCommands: { "swift.run": "swift.run", @@ -42,6 +40,25 @@ function initializationOptions(swiftVersion: Version): any { }, }; + // Swift 6.3 changed the value to enable experimental client capabilities from `true` to `{ "supported": true }` + // (https://github.com/swiftlang/sourcekit-lsp/pull/2204) + if (swiftVersion.isGreaterThanOrEqual(new Version(6, 3, 0))) { + options = { + "workspace/peekDocuments": { + supported: true, // workaround for client capability to handle `PeekDocumentsRequest` + }, + "workspace/getReferenceDocument": { + supported: true, // the client can handle URIs with scheme `sourcekit-lsp:` + }, + }; + } else { + options = { + ...options, + "workspace/peekDocuments": true, // workaround for client capability to handle `PeekDocumentsRequest` + "workspace/getReferenceDocument": true, // the client can handle URIs with scheme `sourcekit-lsp:` + }; + } + // Swift 6.0.0 and later supports background indexing. // In 6.0.0 it is experimental so only "true" enables it. // In 6.1.0 it is no longer experimental, and so "auto" or "true" enables it. @@ -58,7 +75,14 @@ function initializationOptions(swiftVersion: Version): any { }; } - if (swiftVersion.isGreaterThanOrEqual(new Version(6, 1, 0))) { + if (swiftVersion.isGreaterThanOrEqual(new Version(6, 3, 0))) { + options = { + ...options, + "window/didChangeActiveDocument": { + "supported": true, // the client can send `window/didChangeActiveDocument` notifications + }, + }; + } else if (swiftVersion.isGreaterThanOrEqual(new Version(6, 1, 0))) { options = { ...options, "window/didChangeActiveDocument": true, // the client can send `window/didChangeActiveDocument` notifications From b30cc380fa5fd9a305419ea84552e578e5582b76 Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Mon, 14 Jul 2025 17:05:45 +0200 Subject: [PATCH 2/2] Accept `Location` for `workspace/peekDocument` This allows the peek window to scroll to a position within the peeked document. --- src/sourcekit-lsp/LanguageClientConfiguration.ts | 3 ++- .../extensions/PeekDocumentsRequest.ts | 6 +++--- src/sourcekit-lsp/peekDocuments.ts | 15 ++++++++++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/sourcekit-lsp/LanguageClientConfiguration.ts b/src/sourcekit-lsp/LanguageClientConfiguration.ts index 80ce1f126..c31a80e38 100644 --- a/src/sourcekit-lsp/LanguageClientConfiguration.ts +++ b/src/sourcekit-lsp/LanguageClientConfiguration.ts @@ -46,6 +46,7 @@ function initializationOptions(swiftVersion: Version): any { options = { "workspace/peekDocuments": { supported: true, // workaround for client capability to handle `PeekDocumentsRequest` + peekLocation: true, // allow SourceKit-LSP to send `Location` instead of `DocumentUri` for the locations to peek. }, "workspace/getReferenceDocument": { supported: true, // the client can handle URIs with scheme `sourcekit-lsp:` @@ -79,7 +80,7 @@ function initializationOptions(swiftVersion: Version): any { options = { ...options, "window/didChangeActiveDocument": { - "supported": true, // the client can send `window/didChangeActiveDocument` notifications + supported: true, // the client can send `window/didChangeActiveDocument` notifications }, }; } else if (swiftVersion.isGreaterThanOrEqual(new Version(6, 1, 0))) { diff --git a/src/sourcekit-lsp/extensions/PeekDocumentsRequest.ts b/src/sourcekit-lsp/extensions/PeekDocumentsRequest.ts index ea1302b40..ca38a5136 100644 --- a/src/sourcekit-lsp/extensions/PeekDocumentsRequest.ts +++ b/src/sourcekit-lsp/extensions/PeekDocumentsRequest.ts @@ -15,7 +15,7 @@ // We use namespaces to store request information just like vscode-languageclient /* eslint-disable @typescript-eslint/no-namespace */ -import { DocumentUri, Position, MessageDirection, RequestType } from "vscode-languageclient"; +import { DocumentUri, Position, Location, MessageDirection, RequestType } from "vscode-languageclient"; /** Parameters used to make a {@link PeekDocumentsRequest}. */ export interface PeekDocumentsParams { @@ -30,9 +30,9 @@ export interface PeekDocumentsParams { position: Position; /** - * An array `DocumentUri` of the documents to appear inside the "peeked" editor + * An array `DocumentUri` or `Location` of the documents to appear inside the "peeked" editor */ - locations: DocumentUri[]; + locations: DocumentUri[] | Location[]; } /** Response to indicate the `success` of the {@link PeekDocumentsRequest}. */ diff --git a/src/sourcekit-lsp/peekDocuments.ts b/src/sourcekit-lsp/peekDocuments.ts index bfbfb44fa..27881d431 100644 --- a/src/sourcekit-lsp/peekDocuments.ts +++ b/src/sourcekit-lsp/peekDocuments.ts @@ -89,11 +89,16 @@ export function activatePeekDocuments(client: langclient.LanguageClient): vscode ); const peekLocations = params.locations.map( - location => - new vscode.Location( - client.protocol2CodeConverter.asUri(location), - new vscode.Position(0, 0) - ) + location => { + if (typeof location === "string") { // DocumentUri is a typedef of `string`, so effectively we are checking for DocumentUri here + return new vscode.Location( + client.protocol2CodeConverter.asUri(location), + new vscode.Position(0, 0) + ) + } else { + return client.protocol2CodeConverter.asLocation(location) + } + } ); await openPeekedEditorIn(peekURI, peekPosition, peekLocations);