148 lines
4.7 KiB
TypeScript
148 lines
4.7 KiB
TypeScript
import { StatusBarAlignment, ThemeColor, window, workspace } from "vscode";
|
|
import { createMachine, interpret } from "@xstate/fsm";
|
|
import { agent } from "./agent";
|
|
import { notifications } from "./notifications";
|
|
|
|
const label = "Tabby";
|
|
const iconLoading = "$(loading~spin)";
|
|
const iconReady = "$(check)";
|
|
const iconDisconnected = "$(plug)";
|
|
const iconUnauthorized = "$(key)";
|
|
const iconDisabled = "$(x)";
|
|
const colorNormal = new ThemeColor("statusBar.foreground");
|
|
const colorWarning = new ThemeColor("statusBarItem.warningForeground");
|
|
const backgroundColorNormal = new ThemeColor("statusBar.background");
|
|
const backgroundColorWarning = new ThemeColor("statusBarItem.warningBackground");
|
|
|
|
const item = window.createStatusBarItem(StatusBarAlignment.Right);
|
|
const fsm = createMachine({
|
|
id: "statusBarItem",
|
|
initial: "loading",
|
|
states: {
|
|
loading: {
|
|
on: { ready: "ready", disconnected: "disconnected", unauthorized: "unauthorized", disabled: "disabled" },
|
|
entry: () => toLoading(),
|
|
},
|
|
ready: {
|
|
on: { disconnected: "disconnected", unauthorized: "unauthorized", disabled: "disabled" },
|
|
entry: () => toReady(),
|
|
},
|
|
disconnected: {
|
|
on: { ready: "ready", unauthorized: "unauthorized", disabled: "disabled" },
|
|
entry: () => toDisconnected(),
|
|
},
|
|
unauthorized: {
|
|
on: {
|
|
ready: "ready",
|
|
disconnected: "disconnected",
|
|
disabled: "disabled",
|
|
authStart: "unauthorizedAndAuthInProgress",
|
|
},
|
|
entry: () => toUnauthorized(),
|
|
},
|
|
unauthorizedAndAuthInProgress: {
|
|
// if auth succeeds, we will get `ready` before `authEnd` event
|
|
on: { ready: "ready", disconnected: "disconnected", disabled: "disabled", authEnd: "unauthorized" },
|
|
entry: () => toUnauthorizedAndAuthInProgress(),
|
|
},
|
|
disabled: {
|
|
on: { loading: "loading", ready: "ready", disconnected: "disconnected", unauthorized: "unauthorized" },
|
|
entry: () => toDisabled(),
|
|
},
|
|
},
|
|
});
|
|
const fsmService = interpret(fsm);
|
|
|
|
function toLoading() {
|
|
item.color = colorNormal;
|
|
item.backgroundColor = backgroundColorNormal;
|
|
item.text = `${iconLoading} ${label}`;
|
|
item.tooltip = "Tabby is initializing.";
|
|
item.command = { title: "", command: "tabby.statusBarItemClicked", arguments: ["loading"] };
|
|
}
|
|
|
|
function toReady() {
|
|
item.color = colorNormal;
|
|
item.backgroundColor = backgroundColorNormal;
|
|
item.text = `${iconReady} ${label}`;
|
|
item.tooltip = "Tabby is providing code suggestions for you.";
|
|
item.command = { title: "", command: "tabby.statusBarItemClicked", arguments: ["ready"] };
|
|
}
|
|
|
|
function toDisconnected() {
|
|
item.color = colorWarning;
|
|
item.backgroundColor = backgroundColorWarning;
|
|
item.text = `${iconDisconnected} ${label}`;
|
|
item.tooltip = "Cannot connect to Tabby Server. Click to open settings.";
|
|
item.command = { title: "", command: "tabby.statusBarItemClicked", arguments: ["disconnected"] };
|
|
}
|
|
|
|
function toUnauthorized() {
|
|
item.color = colorWarning;
|
|
item.backgroundColor = backgroundColorWarning;
|
|
item.text = `${iconUnauthorized} ${label}`;
|
|
item.tooltip = "Tabby Server requires authorization. Click to continue.";
|
|
item.command = { title: "", command: "tabby.statusBarItemClicked", arguments: ["unauthorized"] };
|
|
}
|
|
|
|
function toUnauthorizedAndAuthInProgress() {
|
|
item.color = colorWarning;
|
|
item.backgroundColor = backgroundColorWarning;
|
|
item.text = `${iconUnauthorized} ${label}`;
|
|
item.tooltip = "Waiting for authorization.";
|
|
item.command = undefined;
|
|
}
|
|
|
|
function toDisabled() {
|
|
item.color = colorWarning;
|
|
item.backgroundColor = backgroundColorWarning;
|
|
item.text = `${iconDisabled} ${label}`;
|
|
item.tooltip = "Tabby is disabled.";
|
|
item.command = { title: "", command: "tabby.statusBarItemClicked", arguments: ["disabled"] };
|
|
}
|
|
|
|
function updateStatusBarItem() {
|
|
const enabled = workspace.getConfiguration("tabby").get("codeCompletion", true);
|
|
if (!enabled) {
|
|
fsmService.send("disabled");
|
|
} else {
|
|
const status = agent().getStatus();
|
|
switch (status) {
|
|
case "notInitialized":
|
|
fsmService.send("loading");
|
|
break;
|
|
case "ready":
|
|
case "disconnected":
|
|
case "unauthorized":
|
|
fsmService.send(status);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
export const tabbyStatusBarItem = () => {
|
|
fsmService.start();
|
|
updateStatusBarItem();
|
|
|
|
workspace.onDidChangeConfiguration((event) => {
|
|
if (event.affectsConfiguration("tabby")) {
|
|
updateStatusBarItem();
|
|
}
|
|
});
|
|
agent().on("statusChanged", updateStatusBarItem);
|
|
|
|
agent().on("authRequired", () => {
|
|
notifications.showInformationStartAuth({
|
|
onAuthStart: () => {
|
|
fsmService.send("authStart");
|
|
},
|
|
onAuthEnd: () => {
|
|
fsmService.send("authEnd");
|
|
},
|
|
});
|
|
});
|
|
|
|
item.show();
|
|
return item;
|
|
};
|