Skip to content

Commit 8911879

Browse files
Sma1lboyautofix-ci[bot]
andauthoredMar 25, 2025··
feat(vscode): add toggle for single language (#3966)
* feat(inline-completion): add toggle for language-specific inline completion * refactor(command-palette): simplify status and completion item handling * refactor(status-bar): streamline language check and update logic * feat(inline-completion): add configuration for disabling code completion by language * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 44afe9d commit 8911879

File tree

6 files changed

+90
-25
lines changed

6 files changed

+90
-25
lines changed
 

‎clients/vscode/package.json

+13
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@
158158
"icon": "$(history)",
159159
"enablement": "tabby.chatSidePanelStatus === 'ready'",
160160
"category": "Tabby"
161+
},
162+
{
163+
"command": "tabby.toggleLanguageInlineCompletion",
164+
"title": "Toggle Language Inline Completion",
165+
"category": "Tabby"
161166
}
162167
],
163168
"submenus": [
@@ -373,6 +378,14 @@
373378
"Manual trigger by pressing `Alt + \\`"
374379
]
375380
},
381+
"inlineCompletion.disabledLanguages": {
382+
"type": "array",
383+
"items": {
384+
"type": "string"
385+
},
386+
"default": [],
387+
"description": "List of language IDs for which code completion should be disabled. Use the 'Toggle Single Language Inline Completion' command to easily enable or disable completion for the current language."
388+
},
376389
"chatEdit.history": {
377390
"type": "integer",
378391
"default": 20,

‎clients/vscode/src/Config.ts

+13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ClientProvidedConfig } from "tabby-agent";
44

55
interface AdvancedSettings {
66
"inlineCompletion.triggerMode"?: "automatic" | "manual";
7+
"inlineCompletion.disabledLanguages"?: string[];
78
"chatEdit.history"?: number;
89
useVSCodeProxy?: boolean;
910
}
@@ -94,6 +95,18 @@ export class Config extends EventEmitter {
9495
}
9596
}
9697

98+
get disabledLanguages(): string[] {
99+
const advancedSettings = this.workspace.get("settings.advanced", {}) as AdvancedSettings;
100+
return advancedSettings["inlineCompletion.disabledLanguages"] || [];
101+
}
102+
103+
async updateDisabledLanguages(value: string[]) {
104+
const advancedSettings = this.workspace.get("settings.advanced", {}) as AdvancedSettings;
105+
advancedSettings["inlineCompletion.disabledLanguages"] = value;
106+
await this.workspace.update("settings.advanced", advancedSettings, ConfigurationTarget.Global);
107+
this.emit("updated");
108+
}
109+
97110
get useVSCodeProxy(): boolean {
98111
const advancedSettings = this.workspace.get("settings.advanced", {}) as AdvancedSettings;
99112
return advancedSettings["useVSCodeProxy"] ?? true;

‎clients/vscode/src/InlineCompletionProvider.ts

+7
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ export class InlineCompletionProvider extends EventEmitter implements InlineComp
6363
return null;
6464
}
6565

66+
// Skip if the current language is disabled
67+
const currentLanguage = document.languageId;
68+
if (this.config.disabledLanguages.includes(currentLanguage)) {
69+
this.logger.debug(`Skipping completion for disabled language: ${currentLanguage}`);
70+
return null;
71+
}
72+
6673
// Skip when trigger automatically and text selected
6774
if (
6875
context.triggerKind === InlineCompletionTriggerKind.Automatic &&

‎clients/vscode/src/StatusBarItem.ts

+18
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ export class StatusBarItem {
7373
case "ready":
7474
case "readyForAutoTrigger": {
7575
if (this.checkIfVSCodeInlineCompletionEnabled()) {
76+
if (this.checkIfCurrentLanguageDisabled()) {
77+
return;
78+
}
7679
this.setColorNormal();
7780
this.setIcon(iconAutomatic);
7881
this.setTooltip(statusInfo.tooltip);
@@ -81,6 +84,9 @@ export class StatusBarItem {
8184
}
8285
case "readyForManualTrigger": {
8386
if (this.checkIfVSCodeInlineCompletionEnabled()) {
87+
if (this.checkIfCurrentLanguageDisabled()) {
88+
return;
89+
}
8490
this.setColorNormal();
8591
this.setIcon(iconManual);
8692
this.setTooltip(statusInfo.tooltip);
@@ -106,6 +112,18 @@ export class StatusBarItem {
106112
}
107113
}
108114

115+
private checkIfCurrentLanguageDisabled(): boolean {
116+
const currentLanguageId = window.activeTextEditor?.document.languageId;
117+
const isLanguageDisabled = currentLanguageId ? this.config.disabledLanguages.includes(currentLanguageId) : false;
118+
if (!isLanguageDisabled) {
119+
return false;
120+
}
121+
this.setColorNormal();
122+
this.setIcon(iconDisabled);
123+
this.setTooltip(`Tabby: disabled for ${currentLanguageId} files`);
124+
return true;
125+
}
126+
109127
private checkIfVSCodeInlineCompletionEnabled() {
110128
if (this.config.vscodeInlineSuggestEnabled) {
111129
return true;

‎clients/vscode/src/commands/commandPalette.ts

+24-25
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import { Client } from "../lsp/client";
44
import { Config } from "../Config";
55
import { isBrowser } from "../env";
66

7-
const MENU_ITEM_INDENT_SPACING = " ";
8-
97
interface CommandPaletteItem extends QuickPickItem {
108
command?: string | Command | (() => void | Promise<void>);
119
picked?: boolean;
@@ -24,13 +22,7 @@ export class CommandPalette {
2422

2523
// Status section
2624
const status = this.client.status.current?.status;
27-
items.push(
28-
{
29-
label: "status",
30-
kind: QuickPickItemKind.Separator,
31-
},
32-
this.itemForStatus(),
33-
);
25+
items.push(this.itemForStatus());
3426

3527
this.client.status.on("didChange", () => {
3628
items[1] = this.itemForStatus();
@@ -40,23 +32,30 @@ export class CommandPalette {
4032
// Features section
4133
const validStatuses = ["ready", "readyForAutoTrigger", "readyForManualTrigger"];
4234
if (status !== undefined && validStatuses.includes(status)) {
43-
const iconPath = this.config.inlineCompletionTriggerMode === "automatic" ? new ThemeIcon("check") : undefined;
44-
const labelPrefix = iconPath ? "" : MENU_ITEM_INDENT_SPACING;
35+
const isAutomatic = this.config.inlineCompletionTriggerMode === "automatic";
4536

46-
items.push(
47-
{
48-
label: "enable/disable features",
49-
kind: QuickPickItemKind.Separator,
50-
},
51-
{
52-
label: labelPrefix + "Code Completion",
53-
detail: MENU_ITEM_INDENT_SPACING + "Toggle between automatic and manual completion mode",
54-
picked: this.config.inlineCompletionTriggerMode === "automatic",
55-
command: "tabby.toggleInlineCompletionTriggerMode",
56-
iconPath: iconPath,
37+
const currentLanguageId = window.activeTextEditor?.document.languageId;
38+
const isLanguageDisabled = currentLanguageId ? this.config.disabledLanguages.includes(currentLanguageId) : false;
39+
40+
items.push({
41+
label: (isAutomatic ? "Disable" : "Enable") + " completions",
42+
picked: isAutomatic,
43+
command: "tabby.toggleInlineCompletionTriggerMode",
44+
alwaysShow: true,
45+
});
46+
47+
if (currentLanguageId) {
48+
items.push({
49+
label: (isLanguageDisabled ? "Enable" : "Disable") + ` completions for ${currentLanguageId}`,
50+
picked: !isLanguageDisabled,
51+
command: {
52+
title: "triggerLanguageInlineCompletion",
53+
command: "tabby.toggleLanguageInlineCompletion",
54+
arguments: [currentLanguageId],
55+
},
5756
alwaysShow: true,
58-
},
59-
);
57+
});
58+
}
6059
}
6160

6261
// Chat section
@@ -139,7 +138,7 @@ export class CommandPalette {
139138
}
140139

141140
private itemForStatus(): CommandPaletteItem {
142-
const STATUS_PREFIX = MENU_ITEM_INDENT_SPACING + "Status: ";
141+
const STATUS_PREFIX = "Status: ";
143142
const languageClientState = this.client.languageClient.state;
144143
switch (languageClientState) {
145144
case LanguageClientState.Stopped:

‎clients/vscode/src/commands/index.ts

+15
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,21 @@ export class Commands {
169169
const commandPalette = new CommandPalette(this.client, this.config);
170170
commandPalette.show();
171171
},
172+
toggleLanguageInlineCompletion: async (languageId?: string) => {
173+
if (!languageId) {
174+
languageId = window.activeTextEditor?.document.languageId;
175+
if (!languageId) {
176+
return;
177+
}
178+
}
179+
const isLanguageDisabled = this.config.disabledLanguages.includes(languageId);
180+
const disabledLanguages = this.config.disabledLanguages;
181+
if (isLanguageDisabled) {
182+
await this.config.updateDisabledLanguages(disabledLanguages.filter((lang) => lang !== languageId));
183+
} else {
184+
await this.config.updateDisabledLanguages([...disabledLanguages, languageId]);
185+
}
186+
},
172187
"outputPanel.focus": () => {
173188
showOutputPanel();
174189
},

0 commit comments

Comments
 (0)
Please sign in to comment.