From e92824e78ece2ec156f5391874903515605c0c10 Mon Sep 17 00:00:00 2001 From: hverlin Date: Tue, 14 Jan 2025 21:55:09 +0100 Subject: [PATCH] feat: Use a status bar item instead of a notification for missing tools --- docs/src/content/docs/reference/Settings.md | 8 +++ package.json | 25 +++++++-- src/commands.ts | 1 + src/configuration.ts | 8 +++ src/extensionMenu.ts | 18 +++++++ src/miseExtension.ts | 57 ++++++++++++++++----- src/utils/fn.ts | 7 +++ 7 files changed, 105 insertions(+), 19 deletions(-) diff --git a/docs/src/content/docs/reference/Settings.md b/docs/src/content/docs/reference/Settings.md index 4ef2ae7..60098bb 100644 --- a/docs/src/content/docs/reference/Settings.md +++ b/docs/src/content/docs/reference/Settings.md @@ -118,6 +118,14 @@ Check if a new mise version is available on startup. --- +##### `mise.showNotificationIfMissingTools` +- **Type:** `boolean` +- **Default:** `true` + +Show notification if tools are not installed. + +--- + ##### `mise.updateEnvAutomatically` - **Type:** `boolean` - **Default:** `true` diff --git a/package.json b/package.json index 66c38b4..94719c1 100644 --- a/package.json +++ b/package.json @@ -188,36 +188,43 @@ "default": true, "markdownDescription": "Check if a new mise version is available on startup." }, - "mise.updateEnvAutomatically": { + "mise.showNotificationIfMissingTools": { "order": 11, "type": "boolean", + "title": "Show notification if missing tools", + "default": true, + "markdownDescription": "Show notification if tools are not installed." + }, + "mise.updateEnvAutomatically": { + "order": 12, + "type": "boolean", "title": "Update environment variables automatically", "default": true, "markdownDescription": "Update VSCode and terminal environment variables automatically based on the mise configuration. Note that depending on the extensions loading order, other extensions might not see all mise environment variables." }, "mise.updateOpenTerminalsEnvAutomatically": { - "order": 12, + "order": 13, "type": "boolean", "title": "Update terminal environment variables automatically", "default": false, "markdownDescription": "Update terminal environment variables automatically based on the mise configuration. This will send `unset` and `eval $(mise env)` commands to the terminal. If you don't enable this, you will need to restart the integrated terminals to get the new environment variables." }, "mise.teraAutoCompletion": { - "order": 13, + "order": 14, "type": "boolean", "title": "Enable Tera auto-completion", "default": true, "markdownDescription": "Enable experimental Tera auto-completion in `mise.toml` files." }, "mise.automaticallyTrustMiseConfigFiles": { - "order": 14, + "order": 15, "type": "boolean", "title": "Automatically trust mise config files", "default": true, "markdownDescription": "Automatically trust mise config files when opening them in a trusted worskspace." }, "mise.commandTTLCacheSeconds": { - "order": 15, + "order": 16, "type": "number", "title": "Command TTL cache seconds", "default": 2, @@ -319,6 +326,10 @@ "command": "mise.openMenu", "title": "Mise: Open Menu" }, + { + "command": "mise.openMissingToolsMenu", + "title": "Mise: Open Missing Tools Menu" + }, { "command": "mise.openToolRepository", "title": "Mise: Open Tool Repository" @@ -474,6 +485,10 @@ { "command": "mise.useToolTopMenu", "when": "false" + }, + { + "command": "mise.openMissingToolsMenu", + "when": "false" } ], "view/title": [ diff --git a/src/commands.ts b/src/commands.ts index f6c5970..45d93b5 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -17,6 +17,7 @@ export const MISE_OPEN_ENV_VAR_DEFINITION = "mise.openEnvVariableDefinition"; export const MISE_OPEN_FILE = "mise.openFile"; export const MISE_OPEN_LOGS = "mise.openLogs"; export const MISE_OPEN_MENU = "mise.openMenu"; +export const MISE_MISSING_TOOLS_MENU = "mise.openMissingToolsMenu"; export const MISE_OPEN_EXTENSION_SETTINGS = "mise.openExtensionSettings"; export const MISE_OPEN_TASK_DEFINITION = "mise.openTaskDefinition"; export const MISE_OPEN_TOOL_DEFINITION = "mise.openToolDefinition"; diff --git a/src/configuration.ts b/src/configuration.ts index a69a24a..e3d0d04 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -20,6 +20,7 @@ export const CONFIGURATION_FLAGS = { teraAutoCompletion: "teraAutoCompletion", automaticallyTrustMiseConfigFiles: "automaticallyTrustMiseConfigFiles", commandTTLCacheSeconds: "commandTTLCacheSeconds", + showNotificationIfMissingTools: "showNotificationIfMissingTools", } as const; const getExtensionConfig = () => { @@ -131,6 +132,13 @@ export const shouldAutomaticallyTrustMiseConfigFiles = () => { ); }; +export const shouldShowNotificationIfMissingTools = () => { + return getConfOrElse( + CONFIGURATION_FLAGS.showNotificationIfMissingTools, + true, + ); +}; + export const isTeraAutoCompletionEnabled = () => { return getConfOrElse(CONFIGURATION_FLAGS.teraAutoCompletion, false); }; diff --git a/src/extensionMenu.ts b/src/extensionMenu.ts index 3ee773d..d4e02ef 100644 --- a/src/extensionMenu.ts +++ b/src/extensionMenu.ts @@ -1,6 +1,8 @@ import vscode from "vscode"; import { + MISE_INSTALL_ALL, MISE_LIST_ALL_TOOLS, + MISE_MISSING_TOOLS_MENU, MISE_OPEN_EXTENSION_SETTINGS, MISE_OPEN_MENU, MISE_RELOAD, @@ -110,3 +112,19 @@ export function createMenu(miseService: MiseService) { } }); } + +export const createMissingToolsMenu = () => + vscode.commands.registerCommand(MISE_MISSING_TOOLS_MENU, async () => { + const pick = await vscode.window.showQuickPick( + [{ label: "Install all missing tools" }], + { title: "Mise - Missing tools" }, + ); + + switch (pick?.label) { + case "Install all missing tools": + await vscode.commands.executeCommand(MISE_INSTALL_ALL); + break; + default: + break; + } + }); diff --git a/src/miseExtension.ts b/src/miseExtension.ts index 99a3d74..847b82f 100644 --- a/src/miseExtension.ts +++ b/src/miseExtension.ts @@ -5,8 +5,8 @@ import { MISE_CONFIGURE_ALL_SKD_PATHS, MISE_EDIT_SETTING, MISE_FMT, - MISE_INSTALL_ALL, MISE_LIST_ALL_TOOLS, + MISE_MISSING_TOOLS_MENU, MISE_OPEN_EXTENSION_SETTINGS, MISE_OPEN_FILE, MISE_OPEN_LOGS, @@ -24,8 +24,9 @@ import { isMiseExtensionEnabled, shouldAutomaticallyTrustMiseConfigFiles, shouldConfigureExtensionsAutomatically, + shouldShowNotificationIfMissingTools, } from "./configuration"; -import { createMenu } from "./extensionMenu"; +import { createMenu, createMissingToolsMenu } from "./extensionMenu"; import { MiseFileWatcher } from "./miseFileWatcher"; import { MiseService } from "./miseService"; import { TaskDefinitionProvider } from "./providers/TaskDefinitionProvider"; @@ -58,6 +59,7 @@ import { } from "./providers/toolsProvider"; import { VsCodeTaskProvider } from "./providers/vsCodeTaskProvider"; import { displayPathRelativeTo } from "./utils/fileUtils"; +import { truncateStr } from "./utils/fn"; import { logger } from "./utils/logger"; import { allowedFileTaskDirs } from "./utils/miseUtilts"; import WebViewPanel from "./webviewPanel"; @@ -69,6 +71,11 @@ export class MiseExtension { vscode.StatusBarAlignment.Left, 0, ); + private missingToolBarItem = vscode.window.createStatusBarItem( + vscode.StatusBarAlignment.Left, + 0, + ); + private miseFileWatcher: MiseFileWatcher | undefined; async activate(context: vscode.ExtensionContext) { @@ -105,7 +112,10 @@ export class MiseExtension { ); this.miseFileWatcher.initialize(); - context.subscriptions.push(createMenu(this.miseService)); + context.subscriptions.push( + createMenu(this.miseService), + createMissingToolsMenu(), + ); this.statusBarItem.command = MISE_OPEN_MENU; const tasksProvider = new MiseTasksProvider(this.miseService); @@ -622,21 +632,40 @@ export class MiseExtension { } private checkForMissingMiseTools() { + if (!isMiseExtensionEnabled()) { + return; + } + + if (!shouldShowNotificationIfMissingTools()) { + return; + } + this.miseService.getCurrentTools().then(async (tools) => { const missingTools = tools.filter((tool) => !tool.installed); - if (missingTools.length > 0) { - const selection = await vscode.window.showWarningMessage( - `Mise: Missing tools: ${missingTools - .map( - (tool) => tool.name + (tool.version ? ` (${tool.version})` : ""), - ) - .join(", ")}`, - { title: "Install missing tools", command: MISE_INSTALL_ALL }, - ); - if (selection?.command) { - await vscode.commands.executeCommand(selection.command); + + if (!missingTools.length) { + if (this.missingToolBarItem) { + this.missingToolBarItem.hide(); } + return; } + + if (!this.missingToolBarItem) { + this.missingToolBarItem = vscode.window.createStatusBarItem( + vscode.StatusBarAlignment.Left, + 0, + ); + } + const list = missingTools + .map((tool) => tool.name + (tool.version ? ` (${tool.version})` : "")) + .join(", "); + + this.missingToolBarItem.text = `Missing tools: ${truncateStr(list, 50)}`; + this.missingToolBarItem.color = new vscode.ThemeColor("errorForeground"); + this.missingToolBarItem.show(); + + this.missingToolBarItem.tooltip = "Mise: Click to install missing tools"; + this.missingToolBarItem.command = MISE_MISSING_TOOLS_MENU; }); } } diff --git a/src/utils/fn.ts b/src/utils/fn.ts index bc53064..c539d1d 100644 --- a/src/utils/fn.ts +++ b/src/utils/fn.ts @@ -14,3 +14,10 @@ export function uniqBy(array: T[], iteratee: (value: T) => string): T[] { return Array.from(seen.values()); } + +export const truncateStr = (str: string, maxLen: number) => { + if (str.length <= maxLen) { + return str; + } + return `${str.slice(0, maxLen)}...`; +};