Skip to content

Commit 8c2aab9

Browse files
committed
Handle custom PeekDocumentsRequest to show macro expansions in a peeked editor
1 parent bf7c689 commit 8c2aab9

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

src/sourcekit-lsp/LanguageClientManager.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { isPathInsidePath, swiftRuntimeEnv } from "../utilities/utilities";
2020
import { Version } from "../utilities/version";
2121
import { FolderEvent, WorkspaceContext } from "../WorkspaceContext";
2222
import { activateLegacyInlayHints } from "./inlayHints";
23+
import { activatePeekDocuments } from "./peekDocuments";
2324
import { FolderContext } from "../FolderContext";
2425
import { LanguageClient } from "vscode-languageclient/node";
2526
import { ArgumentFilter, BuildFlags } from "../toolchain/BuildFlags";
@@ -108,6 +109,7 @@ export class LanguageClientManager {
108109
private languageClient: langclient.LanguageClient | null | undefined;
109110
private cancellationToken?: vscode.CancellationTokenSource;
110111
private legacyInlayHints?: vscode.Disposable;
112+
private peekDocuments?: vscode.Disposable;
111113
private restartedPromise?: Promise<void>;
112114
private currentWorkspaceFolder?: vscode.Uri;
113115
private waitingOnRestartCount: number;
@@ -244,6 +246,7 @@ export class LanguageClientManager {
244246
this.cancellationToken?.cancel();
245247
this.cancellationToken?.dispose();
246248
this.legacyInlayHints?.dispose();
249+
this.peekDocuments?.dispose();
247250
this.subscriptions.forEach(item => item.dispose());
248251
this.languageClient?.stop();
249252
this.namedOutputChannels.forEach(channel => channel.dispose());
@@ -392,6 +395,8 @@ export class LanguageClientManager {
392395
this.currentWorkspaceFolder = workspaceFolder?.uri;
393396
this.legacyInlayHints?.dispose();
394397
this.legacyInlayHints = undefined;
398+
this.peekDocuments?.dispose();
399+
this.peekDocuments = undefined;
395400
if (client) {
396401
this.cancellationToken?.cancel();
397402
this.cancellationToken?.dispose();
@@ -559,6 +564,9 @@ export class LanguageClientManager {
559564
})(),
560565
},
561566
errorHandler: new SourceKitLSPErrorHandler(5),
567+
initializationOptions: {
568+
"workspace/peekDocuments": true, // workaround for client capability to handle `PeekDocumentsRequest`
569+
},
562570
};
563571

564572
return new langclient.LanguageClient(
@@ -604,6 +612,8 @@ export class LanguageClientManager {
604612
if (this.workspaceContext.swiftVersion.isLessThan(new Version(5, 7, 0))) {
605613
this.legacyInlayHints = activateLegacyInlayHints(client);
606614
}
615+
616+
this.peekDocuments = activatePeekDocuments(client);
607617
})
608618
.catch(reason => {
609619
this.workspaceContext.outputChannel.log(`${reason}`);

src/sourcekit-lsp/lspExtensions.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,48 @@
1414

1515
import * as ls from "vscode-languageserver-protocol";
1616
import * as langclient from "vscode-languageclient/node";
17+
import * as vscode from "vscode";
1718

1819
// Definitions for non-standard requests used by sourcekit-lsp
1920

21+
// Peek Documents
22+
export interface PeekDocumentsParams {
23+
/**
24+
* The `DocumentUri` of the text document in which to show the "peeked" editor
25+
*/
26+
uri: langclient.DocumentUri;
27+
28+
/**
29+
* The `Position` in the given text document in which to show the "peeked editor"
30+
*/
31+
position: vscode.Position;
32+
33+
/**
34+
* An array `DocumentUri` of the documents to appear inside the "peeked" editor
35+
*/
36+
locations: langclient.DocumentUri[];
37+
}
38+
39+
/**
40+
* Response to indicate the `success` of the `PeekDocumentsRequest`
41+
*/
42+
export interface PeekDocumentsResult {
43+
success: boolean;
44+
}
45+
46+
/**
47+
* Request from the server to the client to show the given documents in a "peeked" editor.
48+
*
49+
* This request is handled by the client to show the given documents in a "peeked" editor (i.e. inline with / inside the editor canvas).
50+
*
51+
* It requires the experimental client capability `"workspace/peekDocuments"` to use.
52+
*/
53+
export const PeekDocumentsRequest = new langclient.RequestType<
54+
PeekDocumentsParams,
55+
PeekDocumentsResult,
56+
unknown
57+
>("workspace/peekDocuments");
58+
2059
// Inlay Hints (pre Swift 5.6)
2160
export interface LegacyInlayHintsParams {
2261
/**

src/sourcekit-lsp/peekDocuments.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as vscode from "vscode";
2+
import * as langclient from "vscode-languageclient/node";
3+
import { PeekDocumentsParams, PeekDocumentsRequest } from "./lspExtensions";
4+
5+
export function activatePeekDocuments(client: langclient.LanguageClient): vscode.Disposable {
6+
const peekDocuments = client.onRequest(
7+
PeekDocumentsRequest.method,
8+
async (params: PeekDocumentsParams) => {
9+
const locations = params.locations.map(uri => {
10+
const location = new vscode.Location(
11+
vscode.Uri.from({
12+
scheme: "file",
13+
path: new URL(uri).pathname,
14+
}),
15+
new vscode.Position(0, 0)
16+
);
17+
18+
return location;
19+
});
20+
21+
await vscode.commands.executeCommand(
22+
"editor.action.peekLocations",
23+
vscode.Uri.from({
24+
scheme: "file",
25+
path: new URL(params.uri).pathname,
26+
}),
27+
new vscode.Position(params.position.line, params.position.character),
28+
locations,
29+
"peek"
30+
);
31+
32+
return { success: true };
33+
}
34+
);
35+
36+
return peekDocuments;
37+
}

0 commit comments

Comments
 (0)