@@ -20,10 +20,10 @@ import * as util from '../common';
2020import { getCrashCallStacksChannel } from '../logger' ;
2121import { PlatformInformation } from '../platform' ;
2222import * as telemetry from '../telemetry' ;
23- import { Client , DefaultClient , DoxygenCodeActionCommandArguments , openFileVersions } from './client' ;
23+ import { Client , CompletionContextsResult , DefaultClient , DoxygenCodeActionCommandArguments , GetIncludesResult , openFileVersions } from './client' ;
2424import { ClientCollection } from './clientCollection' ;
2525import { CodeActionDiagnosticInfo , CodeAnalysisDiagnosticIdentifiersAndUri , codeAnalysisAllFixes , codeAnalysisCodeToFixes , codeAnalysisFileToCodeActions } from './codeAnalysis' ;
26- import { registerRelatedFilesProvider } from './copilotProviders' ;
26+ import { getCopilotApi , registerRelatedFilesProvider } from './copilotProviders' ;
2727import { CppBuildTaskProvider } from './cppBuildTaskProvider' ;
2828import { getCustomConfigProviders } from './customProviders' ;
2929import { getLanguageConfig } from './languageConfig' ;
@@ -34,6 +34,21 @@ import { CppSettings } from './settings';
3434import { LanguageStatusUI , getUI } from './ui' ;
3535import { makeLspRange , rangeEquals , showInstallCompilerWalkthrough } from './utils' ;
3636
37+ /*
38+ interface CopilotTrait {
39+ name: string;
40+ value: string;
41+ includeInPrompt?: boolean;
42+ promptTextOverride?: string;
43+ }*/
44+
45+ export interface SnippetEntry {
46+ uri : string ;
47+ text : string ;
48+ startLine : number ;
49+ endLine : number ;
50+ }
51+
3752nls . config ( { messageFormat : nls . MessageFormat . bundle , bundleFormat : nls . BundleFormat . standalone } ) ( ) ;
3853const localize : nls . LocalizeFunc = nls . loadMessageBundle ( ) ;
3954export const CppSourceStr : string = "C/C++" ;
@@ -264,6 +279,26 @@ export async function activate(): Promise<void> {
264279 }
265280
266281 await registerRelatedFilesProvider ( ) ;
282+
283+ const isCustomSnippetProviderApiEnabled = await telemetry . isExperimentEnabled ( "CppToolsCustomSnippetsApi" ) ;
284+ if ( isCustomSnippetProviderApiEnabled ) {
285+ const api = await getCopilotApi ( ) ;
286+ if ( util . extensionContext && api ) {
287+ try {
288+ for ( const languageId of [ 'c' , 'cpp' , 'cuda-cpp' ] ) {
289+ api . registerSnippetsProvider (
290+ { extensionId : util . extensionContext . extension . id , languageId } ,
291+ async ( uri : vscode . Uri , context : { flags : Record < string , unknown > } , token : vscode . CancellationToken ) => {
292+ const result = await getCompletionContextWithCancellation ( context . flags [ 'caretOffset' ] as number , token ) ;
293+ return { entries : result . context } ;
294+ }
295+ ) ;
296+ }
297+ } catch {
298+ console . log ( "Failed to register Copilot related files provider." ) ;
299+ }
300+ }
301+ }
267302}
268303
269304export function updateLanguageConfigurations ( ) : void {
@@ -276,8 +311,8 @@ export function updateLanguageConfigurations(): void {
276311}
277312
278313/**
279- * workspace events
280- */
314+ * workspace events
315+ */
281316async function onDidChangeSettings ( event : vscode . ConfigurationChangeEvent ) : Promise < void > {
282317 const client : Client = clients . getDefaultClient ( ) ;
283318 if ( client instanceof DefaultClient ) {
@@ -488,9 +523,9 @@ async function onSwitchHeaderSource(): Promise<void> {
488523}
489524
490525/**
491- * Allow the user to select a workspace when multiple workspaces exist and get the corresponding Client back.
492- * The resulting client is used to handle some command that was previously invoked.
493- */
526+ * Allow the user to select a workspace when multiple workspaces exist and get the corresponding Client back.
527+ * The resulting client is used to handle some command that was previously invoked.
528+ */
494529async function selectClient ( ) : Promise < Client > {
495530 if ( clients . Count === 1 ) {
496531 return clients . ActiveClient ;
@@ -1387,3 +1422,39 @@ export async function preReleaseCheck(): Promise<void> {
13871422 }
13881423 }
13891424}
1425+
1426+ export async function getIncludesWithCancellation ( maxDepth : number , token : vscode . CancellationToken ) : Promise < GetIncludesResult > {
1427+ const includes = await clients . ActiveClient . getIncludes ( maxDepth , token ) ;
1428+ const wksFolder = clients . ActiveClient . RootUri ?. toString ( ) ;
1429+
1430+ if ( ! wksFolder ) {
1431+ return includes ;
1432+ }
1433+
1434+ includes . includedFiles = includes . includedFiles . filter ( header => vscode . Uri . file ( header ) . toString ( ) . startsWith ( wksFolder ) ) ;
1435+ return includes ;
1436+ }
1437+
1438+ export async function getCompletionContextWithCancellation ( caretOffset : number , token : vscode . CancellationToken ) : Promise < CompletionContextsResult > {
1439+ try {
1440+ const activeEditor : vscode . TextEditor | undefined = vscode . window . activeTextEditor ;
1441+ if ( ! activeEditor ) {
1442+ return { context : [ ] } ;
1443+ }
1444+
1445+ const snippets = await clients . ActiveClient . getCompletionContext ( activeEditor . document . uri , caretOffset , token ) ;
1446+ const wksFolder = clients . ActiveClient . RootUri ?. toString ( ) ;
1447+
1448+ if ( ! wksFolder ) {
1449+ return snippets ;
1450+ }
1451+
1452+ // Fix up URIs to be relative to the workspace folder.
1453+ // //?? TODO Fix the check, the uri do not start with wksFolder whew.
1454+ //snippets.context = snippets.context.filter(snippet =>
1455+ // vscode.Uri.file(snippet.uri).toString().startsWith(wksFolder));
1456+ return snippets ;
1457+ } catch ( e ) {
1458+ return { context : [ ] } ;
1459+ }
1460+ }
0 commit comments