Skip to content

Commit

Permalink
Add preference to exclude files from code completion
Browse files Browse the repository at this point in the history
fixed #14313

Signed-off-by: Jonas Helming <jhelming@eclipsesource.com>
  • Loading branch information
JonasHelming committed Oct 14, 2024
1 parent c7fb4f5 commit 26109c6
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { PreferenceSchema } from '@theia/core/lib/browser/preferences/preference
import { AI_CORE_PREFERENCES_TITLE } from '@theia/ai-core/lib/browser/ai-core-preferences';

export const PREF_AI_INLINE_COMPLETION_ENABLE = 'ai-features.codeCompletion.enableCodeCompletion';
export const PREF_AI_INLINE_COMPLETION_EXCLUDED_EXTENSIONS = 'ai-features.codeCompletion.excludedFileExtensions';

export const AICodeCompletionPreferencesSchema: PreferenceSchema = {
type: 'object',
Expand All @@ -27,6 +28,15 @@ export const AICodeCompletionPreferencesSchema: PreferenceSchema = {
type: 'boolean',
description: 'Enable AI completions inline within any (Monaco) editor.',
default: false
},
[PREF_AI_INLINE_COMPLETION_EXCLUDED_EXTENSIONS]: {
title: 'Excluded File Extensions',
type: 'array',
description: 'Specify file extensions (e.g., .md, .txt) where AI completions should be disabled.',
items: {
type: 'string'
},
default: []
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { inject, injectable } from '@theia/core/shared/inversify';
import { AIActivationService } from '@theia/ai-core/lib/browser';
import { Disposable } from '@theia/core';
import { AICodeInlineCompletionsProvider } from './ai-code-inline-completion-provider';
import { PREF_AI_INLINE_COMPLETION_ENABLE } from './ai-code-completion-preference';
import { PREF_AI_INLINE_COMPLETION_ENABLE, PREF_AI_INLINE_COMPLETION_EXCLUDED_EXTENSIONS } from './ai-code-completion-preference';

@injectable()
export class AIFrontendApplicationContribution implements FrontendApplicationContribution {
Expand All @@ -38,27 +38,59 @@ export class AIFrontendApplicationContribution implements FrontendApplicationCon

onDidInitializeLayout(): void {
this.preferenceService.ready.then(() => {
this.handlePreference(PREF_AI_INLINE_COMPLETION_ENABLE, enable => this.handleInlineCompletions(enable));
// Handle changes in both enable and excluded file extensions preferences
this.handlePreferences();
});
}

protected handlePreference(name: string, handler: (enable: boolean) => Disposable): void {
const enable = this.preferenceService.get<boolean>(name, false) && this.activationService.isActive;
this.toDispose.set(name, handler(enable));
protected handlePreferences(): void {
const handler = () => this.handleInlineCompletions(
this.preferenceService.get<boolean>(PREF_AI_INLINE_COMPLETION_ENABLE, false) && this.activationService.isActive
);

this.toDispose.set('inlineCompletions', handler());

this.preferenceService.onPreferenceChanged(event => {
if (event.preferenceName === name) {
this.toDispose.get(name)?.dispose();
this.toDispose.set(name, handler(event.newValue && this.activationService.isActive));
if (event.preferenceName === PREF_AI_INLINE_COMPLETION_ENABLE || event.preferenceName === PREF_AI_INLINE_COMPLETION_EXCLUDED_EXTENSIONS) {
// Re-apply the completions provider when either the enable or excluded file extensions change
this.toDispose.get('inlineCompletions')?.dispose();
this.toDispose.set('inlineCompletions', handler());
}
});

this.activationService.onDidChangeActiveStatus(change => {
this.toDispose.get(name)?.dispose();
this.toDispose.set(name, handler(this.preferenceService.get<boolean>(name, false) && change));
// Re-apply the completions provider when the activation status changes
this.toDispose.get('inlineCompletions')?.dispose();
this.toDispose.set('inlineCompletions', handler());
});
}

protected handleInlineCompletions(enable: boolean): Disposable {
return enable ? monaco.languages.registerInlineCompletionsProvider({ scheme: 'file' }, this.inlineCodeCompletionProvider) : Disposable.NULL;
if (!enable) {
return Disposable.NULL;
}

// Get excluded file extensions from preferences
const excludedExtensions = this.preferenceService.get<string[]>(PREF_AI_INLINE_COMPLETION_EXCLUDED_EXTENSIONS, []);

return monaco.languages.registerInlineCompletionsProvider(
{ scheme: 'file' },
{
provideInlineCompletions: (model, position, context, token) => {
const fileName = model.uri.toString();

// Exclude specific file types based on preferences
if (excludedExtensions.some(ext => fileName.endsWith(ext))) {
return { items: [] }; // Return empty result for excluded files
}

// If file type is allowed, return the code completions
return this.inlineCodeCompletionProvider.provideInlineCompletions(model, position, context, token);
},
freeInlineCompletions: completions => {
// No clean up resources necessary
}
}
);
}
}

0 comments on commit 26109c6

Please sign in to comment.