From 6abd5bc8f92b7fd70e2ce8c75718e58c4001e0f8 Mon Sep 17 00:00:00 2001 From: luca cappa Date: Mon, 7 Oct 2024 10:39:59 -0700 Subject: [PATCH] add custom snippets PoC --- Extension/.vscode/launch.json | 9 +++- Extension/src/LanguageServer/extension.ts | 54 ++++++++++++++++++++--- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/Extension/.vscode/launch.json b/Extension/.vscode/launch.json index 4323f133dd..759193d510 100644 --- a/Extension/.vscode/launch.json +++ b/Extension/.vscode/launch.json @@ -14,10 +14,17 @@ "--skip-release-notes", "--disable-workspace-trust", "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionDevelopmentPath=C:/Users/lucappa/.vscode-insiders/extensions/copilot-client", + "--disable-extension=ms.vscode.cpptools", + "--disable-extension=github.synth-lab", + "--disable-extension=github.copilot", + "--disable-extension=github.copilot-nightly", + "--log=github.copilot:debug", ], "sourceMaps": true, "outFiles": [ - "${workspaceFolder}/dist/**" + "${workspaceFolder}/dist/**", + "C:/Users/lucappa/.vscode-insiders/extensions/copilot-client/dist/**" ], // you can use a watch task as a prelaunch task and it works like you'd want it to. "preLaunchTask": "watch" diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 47a7cd0342..b778056dc9 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -40,6 +40,13 @@ interface CopilotTrait { promptTextOverride?: string; } +interface SnippetEntry { + uri: string; + text: string; + startLine: number; + endLine: number; +} + interface CopilotApi { registerRelatedFilesProvider( providerId: { extensionId: string; languageId: string }, @@ -49,6 +56,15 @@ interface CopilotApi { cancellationToken: vscode.CancellationToken ) => Promise<{ entries: vscode.Uri[]; traits?: CopilotTrait[] }> ): Disposable; + registerSnippetsProvider( + providerId: { extensionId: string; languageId: string }, + callback: ( + uri: vscode.Uri, + context: { flags: Record }, + cancellationToken: vscode.CancellationToken + ) => Promise<{ entries: SnippetEntry[] }> + ): Disposable; + } nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); @@ -290,6 +306,30 @@ export async function activate(): Promise { } } } + + const isCustomSnippetProviderApiEnabled = await telemetry.isExperimentEnabled("CppToolsCustomSnippetsApi"); + if (isCustomSnippetProviderApiEnabled) { + const api = await getCopilotApi(); + if (util.extensionContext && api) { + try { + for (const languageId of ['c', 'cpp', 'cuda-cpp']) { + api.registerSnippetsProvider( + { extensionId: util.extensionContext.extension.id, languageId }, + async (_uri: vscode.Uri, _context: { flags: Record }, _: vscode.CancellationToken) => ({ + entries: [{ + uri: "file:///Users/username/Code/cpp/test.cpp", + text: "This is line 42\nThis is line 43\nThis is line 44\nThis is line 45\n", + startLine: 42, + endLine: 45 + }] + }) + ); + } + } catch { + console.log("Failed to register Copilot related files provider."); + } + } + } } export function updateLanguageConfigurations(): void { @@ -302,8 +342,8 @@ export function updateLanguageConfigurations(): void { } /** - * workspace events - */ + * workspace events + */ async function onDidChangeSettings(event: vscode.ConfigurationChangeEvent): Promise { const client: Client = clients.getDefaultClient(); if (client instanceof DefaultClient) { @@ -384,8 +424,8 @@ function onInterval(): void { } /** - * registered commands - */ + * registered commands + */ export function registerCommands(enabled: boolean, isRelatedFilesApiEnabled: boolean): void { commandDisposables.forEach(d => d.dispose()); commandDisposables.length = 0; @@ -513,9 +553,9 @@ async function onSwitchHeaderSource(): Promise { } /** - * Allow the user to select a workspace when multiple workspaces exist and get the corresponding Client back. - * The resulting client is used to handle some command that was previously invoked. - */ + * Allow the user to select a workspace when multiple workspaces exist and get the corresponding Client back. + * The resulting client is used to handle some command that was previously invoked. + */ async function selectClient(): Promise { if (clients.Count === 1) { return clients.ActiveClient;