Skip to content

Commit

Permalink
Handle custom PeekDocumentsRequest to show macro expansions in a pe…
Browse files Browse the repository at this point in the history
…eked editor
  • Loading branch information
lokesh-tr committed Jul 4, 2024
1 parent bf7c689 commit 8c2aab9
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/sourcekit-lsp/LanguageClientManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { isPathInsidePath, swiftRuntimeEnv } from "../utilities/utilities";
import { Version } from "../utilities/version";
import { FolderEvent, WorkspaceContext } from "../WorkspaceContext";
import { activateLegacyInlayHints } from "./inlayHints";
import { activatePeekDocuments } from "./peekDocuments";
import { FolderContext } from "../FolderContext";
import { LanguageClient } from "vscode-languageclient/node";
import { ArgumentFilter, BuildFlags } from "../toolchain/BuildFlags";
Expand Down Expand Up @@ -108,6 +109,7 @@ export class LanguageClientManager {
private languageClient: langclient.LanguageClient | null | undefined;
private cancellationToken?: vscode.CancellationTokenSource;
private legacyInlayHints?: vscode.Disposable;
private peekDocuments?: vscode.Disposable;
private restartedPromise?: Promise<void>;
private currentWorkspaceFolder?: vscode.Uri;
private waitingOnRestartCount: number;
Expand Down Expand Up @@ -244,6 +246,7 @@ export class LanguageClientManager {
this.cancellationToken?.cancel();
this.cancellationToken?.dispose();
this.legacyInlayHints?.dispose();
this.peekDocuments?.dispose();
this.subscriptions.forEach(item => item.dispose());
this.languageClient?.stop();
this.namedOutputChannels.forEach(channel => channel.dispose());
Expand Down Expand Up @@ -392,6 +395,8 @@ export class LanguageClientManager {
this.currentWorkspaceFolder = workspaceFolder?.uri;
this.legacyInlayHints?.dispose();
this.legacyInlayHints = undefined;
this.peekDocuments?.dispose();
this.peekDocuments = undefined;
if (client) {
this.cancellationToken?.cancel();
this.cancellationToken?.dispose();
Expand Down Expand Up @@ -559,6 +564,9 @@ export class LanguageClientManager {
})(),
},
errorHandler: new SourceKitLSPErrorHandler(5),
initializationOptions: {
"workspace/peekDocuments": true, // workaround for client capability to handle `PeekDocumentsRequest`
},
};

return new langclient.LanguageClient(
Expand Down Expand Up @@ -604,6 +612,8 @@ export class LanguageClientManager {
if (this.workspaceContext.swiftVersion.isLessThan(new Version(5, 7, 0))) {
this.legacyInlayHints = activateLegacyInlayHints(client);
}

this.peekDocuments = activatePeekDocuments(client);
})
.catch(reason => {
this.workspaceContext.outputChannel.log(`${reason}`);
Expand Down
39 changes: 39 additions & 0 deletions src/sourcekit-lsp/lspExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,48 @@

import * as ls from "vscode-languageserver-protocol";
import * as langclient from "vscode-languageclient/node";
import * as vscode from "vscode";

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

// Peek Documents
export interface PeekDocumentsParams {
/**
* The `DocumentUri` of the text document in which to show the "peeked" editor
*/
uri: langclient.DocumentUri;

/**
* The `Position` in the given text document in which to show the "peeked editor"
*/
position: vscode.Position;

/**
* An array `DocumentUri` of the documents to appear inside the "peeked" editor
*/
locations: langclient.DocumentUri[];
}

/**
* Response to indicate the `success` of the `PeekDocumentsRequest`
*/
export interface PeekDocumentsResult {
success: boolean;
}

/**
* Request from the server to the client to show the given documents in a "peeked" editor.
*
* This request is handled by the client to show the given documents in a "peeked" editor (i.e. inline with / inside the editor canvas).
*
* It requires the experimental client capability `"workspace/peekDocuments"` to use.
*/
export const PeekDocumentsRequest = new langclient.RequestType<
PeekDocumentsParams,
PeekDocumentsResult,
unknown
>("workspace/peekDocuments");

// Inlay Hints (pre Swift 5.6)
export interface LegacyInlayHintsParams {
/**
Expand Down
37 changes: 37 additions & 0 deletions src/sourcekit-lsp/peekDocuments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as vscode from "vscode";
import * as langclient from "vscode-languageclient/node";
import { PeekDocumentsParams, PeekDocumentsRequest } from "./lspExtensions";

export function activatePeekDocuments(client: langclient.LanguageClient): vscode.Disposable {
const peekDocuments = client.onRequest(
PeekDocumentsRequest.method,
async (params: PeekDocumentsParams) => {
const locations = params.locations.map(uri => {
const location = new vscode.Location(
vscode.Uri.from({
scheme: "file",
path: new URL(uri).pathname,
}),
new vscode.Position(0, 0)
);

return location;
});

await vscode.commands.executeCommand(
"editor.action.peekLocations",
vscode.Uri.from({
scheme: "file",
path: new URL(params.uri).pathname,
}),
new vscode.Position(params.position.line, params.position.character),
locations,
"peek"
);

return { success: true };
}
);

return peekDocuments;
}

0 comments on commit 8c2aab9

Please sign in to comment.