Skip to content

Commit

Permalink
feat(vscode): use CommandPalette to display tabby menu (#2917)
Browse files Browse the repository at this point in the history
* feat(vscode): use CommandPalette to display tabby menu

* update

* [autofix.ci] apply automated fixes

* Apply suggestions from code review

* update

* Update clients/vscode/src/Commands.ts

Co-authored-by: Zhiming Ma <[email protected]>

* chore(vscode): display issues help message in CommandPalette

* update label

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Zhiming Ma <[email protected]>
  • Loading branch information
3 people authored Aug 21, 2024
1 parent af51b79 commit 8cdf6a5
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 106 deletions.
135 changes: 135 additions & 0 deletions clients/vscode/src/CommandPalette.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { commands, QuickPick, QuickPickItem, QuickPickItemKind, ThemeIcon, window } from "vscode";
import { State as LanguageClientState } from "vscode-languageclient";
import { Client } from "./lsp/Client";
import { Config } from "./Config";
import { Issues } from "./Issues";

export default class CommandPalette {
quickPick: QuickPick<CommandPaletteItem>;

constructor(
private readonly client: Client,
private readonly config: Config,
private readonly issues: Issues,
) {
this.quickPick = window.createQuickPick();
this.quickPick.title = "Tabby Command Palette";

let items: CommandPaletteItem[] = [this.itemForStatus()];

if (this.client.chat.isAvailable) {
items.push({
label: "Chat",
command: "tabby.chatView.focus",
iconPath: new ThemeIcon("comment"),
});
}

items = items.concat([
{
label: "",
kind: QuickPickItemKind.Separator,
},
{
label: this.config.inlineCompletionTriggerMode === "manual" ? "Enable Completions" : "Disable Completions",
command: "tabby.toggleInlineCompletionTriggerMode",
},
{
label: "",
kind: QuickPickItemKind.Separator,
},
{
label: "Set Credentials",
command: "tabby.setApiToken",
iconPath: new ThemeIcon("key"),
},
{
label: "Settings...",
command: "tabby.openSettings",
iconPath: new ThemeIcon("extensions-manage"),
},
{
label: "Agent Settings...",
command: "tabby.openTabbyAgentSettings",
iconPath: new ThemeIcon("console"),
},
{
label: "Show Logs...",
command: "tabby.outputPanel.focus",
},
{
label: "",
kind: QuickPickItemKind.Separator,
},
{
label: "Help",
command: "tabby.openOnlineHelp",
iconPath: new ThemeIcon("question"),
},
]);

this.quickPick.items = items;
this.quickPick.onDidAccept(this.onDidAccept, this);
this.quickPick.show();
}

onDidAccept() {
this.quickPick.hide();
const item = this.quickPick.activeItems[0];
if (item?.command) {
if (typeof item.command === "function") {
item.command();
} else {
commands.executeCommand(item.command);
}
}
}

private itemForStatus(): CommandPaletteItem {
const lspState = this.client.languageClient.state;
const agentStatus = this.client.agent.status;
const item: CommandPaletteItem = {
label: "Status",
iconPath: new ThemeIcon("warning"),
};
if (lspState === LanguageClientState.Starting || agentStatus === "notInitialized") {
item.label = "Starting...";
item.iconPath = new ThemeIcon("sync");
} else if (lspState === LanguageClientState.Stopped || agentStatus === "finalized") {
item.label = "Disabled";
item.iconPath = new ThemeIcon("circle-slash");
} else if (agentStatus === "disconnected" || this.issues.first === "connectionFailed") {
item.label = "Disconnected";
item.description = "Cannot connect to Tabby Server";
item.command = "tabby.openSettings";
} else if (agentStatus === "unauthorized") {
item.label = "Unauthorized";
item.description = "Your credentials are invalid";
item.command = "tabby.setApiToken";
} else if (this.issues.length > 0) {
switch (this.issues.first) {
case "highCompletionTimeoutRate":
item.label = "Timeout";
item.description = "Most completion requests timed out.";
break;
case "slowCompletionResponseTime":
item.label = "Slow Response";
item.description = "Completion requests appear to take too much time.";
break;
}
item.command = () => this.issues.showHelpMessage();
} else if (agentStatus === "ready") {
item.label = "Ready";
item.iconPath = new ThemeIcon("check");
item.command = "tabby.outputPanel.focus";
}

return item;
}
}

interface CommandPaletteItem extends QuickPickItem {
command?: string | CallbackCommand;
}

type CallbackCommand = () => void;
28 changes: 15 additions & 13 deletions clients/vscode/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ import { ContextVariables } from "./ContextVariables";
import { InlineCompletionProvider } from "./InlineCompletionProvider";
import { ChatViewProvider } from "./chat/ChatViewProvider";
import { GitProvider, Repository } from "./git/GitProvider";
import CommandPalette from "./CommandPalette";
import { showOutputPanel } from "./logger";
import { Issues } from "./Issues";

export class Commands {
private chatEditCancellationTokenSource: CancellationTokenSource | null = null;
Expand All @@ -33,6 +36,7 @@ export class Commands {
private readonly context: ExtensionContext,
private readonly client: Client,
private readonly config: Config,
private readonly issues: Issues,
private readonly contextVariables: ContextVariables,
private readonly inlineCompletionProvider: InlineCompletionProvider,
private readonly chatViewProvider: ChatViewProvider,
Expand Down Expand Up @@ -165,38 +169,30 @@ export class Commands {
window
.showQuickPick([
{
label: "Online Documentation",
label: "Website",
iconPath: new ThemeIcon("book"),
alwaysShow: true,
},
{
label: "Model Registry",
description: "Explore more recommend models from Tabby's model registry",
iconPath: new ThemeIcon("library"),
alwaysShow: true,
description: "Visit Tabby's website to learn more about features and use cases",
},
{
label: "Tabby Slack Community",
description: "Join Tabby's Slack community to get help or feed back",
description: "Join Tabby's Slack community to get help or share feedback",
iconPath: new ThemeIcon("comment-discussion"),
alwaysShow: true,
},
{
label: "Tabby GitHub Repository",
description: "View the source code for Tabby, and open issues",
description: "Open issues for bugs or feature requests",
iconPath: new ThemeIcon("github"),
alwaysShow: true,
},
])
.then((selection) => {
if (selection) {
switch (selection.label) {
case "Online Documentation":
case "Website":
env.openExternal(Uri.parse("https://tabby.tabbyml.com/"));
break;
case "Model Registry":
env.openExternal(Uri.parse("https://tabby.tabbyml.com/docs/models/"));
break;
case "Tabby Slack Community":
env.openExternal(Uri.parse("https://links.tabbyml.com/join-slack-extensions/"));
break;
Expand All @@ -213,6 +209,12 @@ export class Commands {
gettingStarted: () => {
commands.executeCommand("workbench.action.openWalkthrough", "TabbyML.vscode-tabby#gettingStarted");
},
"commandPalette.trigger": () => {
new CommandPalette(this.client, this.config, this.issues);
},
"outputPanel.focus": () => {
showOutputPanel();
},
"inlineCompletion.trigger": () => {
commands.executeCommand("editor.action.inlineSuggest.trigger");
},
Expand Down
97 changes: 4 additions & 93 deletions clients/vscode/src/StatusBarItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export class StatusBarItem {
) {
this.updateStatus();
this.item.show();
this.item.command = {
title: "Show Tabby Command Palette",
command: "tabby.commandPalette.trigger",
};
this.context.subscriptions.push(this.item);

this.client.languageClient.onDidChangeState(() => this.updateStatus());
Expand Down Expand Up @@ -100,11 +104,6 @@ export class StatusBarItem {
this.item.backgroundColor = backgroundColorNormal;
this.item.text = `${iconLoading} ${label}`;
this.item.tooltip = "Tabby is initializing.";
this.item.command = {
title: "",
command: "tabby.applyCallback",
arguments: [() => this.showInformationWhenInitializing()],
};
}

private toAutomatic() {
Expand All @@ -116,11 +115,6 @@ export class StatusBarItem {
this.item.backgroundColor = backgroundColorNormal;
this.item.text = `${iconAutomatic} ${label}`;
this.item.tooltip = "Tabby automatic code completion is enabled.";
this.item.command = {
title: "",
command: "tabby.applyCallback",
arguments: [() => this.showInformationWhenAutomaticTrigger()],
};
}

private toManual() {
Expand All @@ -132,11 +126,6 @@ export class StatusBarItem {
this.item.backgroundColor = backgroundColorNormal;
this.item.text = `${iconManual} ${label}`;
this.item.tooltip = "Tabby is standing by, click or press `Alt + \\` to trigger code completion.";
this.item.command = {
title: "",
command: "tabby.applyCallback",
arguments: [() => this.showInformationWhenManualTrigger()],
};
}

private toDisabled() {
Expand All @@ -148,11 +137,6 @@ export class StatusBarItem {
this.item.backgroundColor = backgroundColorWarning;
this.item.text = `${iconDisabled} ${label}`;
this.item.tooltip = "Tabby is disabled. Click to check settings.";
this.item.command = {
title: "",
command: "tabby.applyCallback",
arguments: [() => this.showInformationWhenInlineSuggestDisabled()],
};
this.showInformationWhenInlineSuggestDisabled();
}

Expand All @@ -165,11 +149,6 @@ export class StatusBarItem {
this.item.backgroundColor = backgroundColorNormal;
this.item.text = `${iconLoading} ${label}`;
this.item.tooltip = "Tabby is generating code completions.";
this.item.command = {
title: "",
command: "tabby.applyCallback",
arguments: [() => this.showInformationWhenLoading()],
};
}

private toDisconnected() {
Expand All @@ -181,11 +160,6 @@ export class StatusBarItem {
this.item.backgroundColor = backgroundColorWarning;
this.item.text = `${iconDisconnected} ${label}`;
this.item.tooltip = "Cannot connect to Tabby Server. Click to open settings.";
this.item.command = {
title: "",
command: "tabby.applyCallback",
arguments: [() => this.issues.showHelpMessage("connectionFailed")],
};
}

private toUnauthorized() {
Expand All @@ -197,11 +171,6 @@ export class StatusBarItem {
this.item.backgroundColor = backgroundColorWarning;
this.item.text = `${iconUnauthorized} ${label}`;
this.item.tooltip = "Tabby Server requires authorization. Please set your personal token.";
this.item.command = {
title: "",
command: "tabby.applyCallback",
arguments: [() => this.showInformationWhenUnauthorized()],
};
this.showInformationWhenUnauthorized();
}

Expand All @@ -224,64 +193,6 @@ export class StatusBarItem {
this.item.tooltip = "";
break;
}
this.item.command = {
title: "",
command: "tabby.applyCallback",
arguments: [() => this.issues.showHelpMessage()],
};
}

private showInformationWhenInitializing() {
window.showInformationMessage("Tabby is initializing.", "Settings").then((selection) => {
switch (selection) {
case "Settings":
commands.executeCommand("tabby.openSettings");
break;
}
});
}

private showInformationWhenAutomaticTrigger() {
window.showInformationMessage("Tabby automatic code completion is enabled.", "Settings").then((selection) => {
switch (selection) {
case "Settings":
commands.executeCommand("tabby.openSettings");
break;
}
});
}

private showInformationWhenManualTrigger() {
window
.showInformationMessage(
"Tabby is standing by. Trigger code completion manually?",
"Trigger",
"Automatic Mode",
"Settings",
)
.then((selection) => {
switch (selection) {
case "Trigger":
commands.executeCommand("editor.action.inlineSuggest.trigger");
break;
case "Automatic Mode":
commands.executeCommand("tabby.toggleInlineCompletionTriggerMode", "automatic");
break;
case "Settings":
commands.executeCommand("tabby.openSettings");
break;
}
});
}

private showInformationWhenLoading() {
window.showInformationMessage("Tabby is generating code completions.", "Settings").then((selection) => {
switch (selection) {
case "Settings":
commands.executeCommand("tabby.openSettings");
break;
}
});
}

private showInformationWhenInlineSuggestDisabled() {
Expand Down
1 change: 1 addition & 0 deletions clients/vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export async function activate(context: ExtensionContext) {
context,
client,
config,
issues,
contextVariables,
inlineCompletionProvider,
chatViewProvider,
Expand Down
4 changes: 4 additions & 0 deletions clients/vscode/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,7 @@ export function getLogger(tag = "Tabby"): LogOutputChannel {
},
});
}

export function showOutputPanel(): void {
outputChannel.show();
}

0 comments on commit 8cdf6a5

Please sign in to comment.