mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-08 08:52:12 +00:00
Apple's clangd (/usr/bin/clangd, Xcode and CommandLineTools toolchains) is built without clang-tidy, so on a Mac without a managed clangd the checks from .clang-tidy never appear. When a clangd server for C, C++, Objective-C or Objective-C++ resolves to Apple's binary and the project has a .clang-tidy, show one warning per session with Install (managed LLVM clangd, which already takes precedence once installed) and Language Servers… actions. Fixes #692.
87 lines
3.3 KiB
TypeScript
87 lines
3.3 KiB
TypeScript
/**
|
|
* "rust-analyzer is not installed — Install": when a language server reports
|
|
* `missing` and we know how to install it, offer a one-click install that
|
|
* restarts the server when done. Uses the same notification key as the
|
|
* generic code-insight notice so it replaces it.
|
|
*/
|
|
import { executeAction } from "@/platform/actions";
|
|
import { onIdeEvent } from "@/platform/ipc";
|
|
import { notifications } from "@/workbench/contributions";
|
|
import { installTool, refreshTools, SETTINGS_PAGE_ID, toolByName, useTools } from "./store";
|
|
import { tx } from "@/platform/i18n";
|
|
|
|
export const missingKey = (name: string) => `lsp-missing-${name}`;
|
|
|
|
export async function promptInstall(name: string, sticky = true): Promise<boolean> {
|
|
if (!useTools.getState().loaded) await refreshTools();
|
|
const tool = toolByName(name);
|
|
if (!tool || !tool.canInstall || tool.status !== "missing") return false;
|
|
// An installed alternative (typescript-language-server for vtsls) already serves these files.
|
|
const served = useTools
|
|
.getState()
|
|
.tools.some(
|
|
(t) =>
|
|
t.name !== name &&
|
|
t.kind === tool.kind &&
|
|
t.status !== "missing" &&
|
|
t.languages.some((l) => tool.languages.includes(l)),
|
|
);
|
|
if (tool.kind !== "formatter" && served) return false;
|
|
const key = missingKey(name);
|
|
const langs = tool.languages.length ? tool.languages.join(", ") : "these files";
|
|
notifications().notify({
|
|
group: "tools",
|
|
level: "warning",
|
|
title: tx`${tool.displayName} is not installed`,
|
|
body:
|
|
tool.kind === "formatter"
|
|
? tx`Reformat Code needs ${tool.displayName}. Install it via ${tool.installMethod}?`
|
|
: tx`Code insight for ${langs} needs ${tool.command}. Install it via ${tool.installMethod}?`,
|
|
key,
|
|
sticky,
|
|
actions: [
|
|
{ label: "Install", run: () => void installTool(name, { notificationKey: key }) },
|
|
{ label: "Language Servers…", run: () => void executeAction("file.settings", SETTINGS_PAGE_ID) },
|
|
],
|
|
});
|
|
return true;
|
|
}
|
|
|
|
export function installMissingServerPrompts(): () => void {
|
|
const prompted = new Set<string>();
|
|
return onIdeEvent("languageServer", (e) => {
|
|
if (e.status !== "missing" || prompted.has(e.name)) return;
|
|
prompted.add(e.name);
|
|
// Async on purpose: lands after the synchronous generic notice and replaces it.
|
|
void promptInstall(e.name).catch(() => {});
|
|
});
|
|
}
|
|
|
|
/** A system server that lacks a capability can be replaced by the managed tool. */
|
|
export function installServerWarningPrompts(): () => void {
|
|
const prompted = new Set<string>();
|
|
return onIdeEvent("languageServerWarning", (e) => {
|
|
const key = `lsp-warning-${e.name}-${e.installTool}`;
|
|
if (prompted.has(key)) return;
|
|
prompted.add(key);
|
|
void (async () => {
|
|
if (!useTools.getState().loaded) await refreshTools();
|
|
const tool = toolByName(e.installTool);
|
|
notifications().notify({
|
|
group: "lsp",
|
|
level: "warning",
|
|
title: e.name,
|
|
body: tx(e.message),
|
|
key,
|
|
sticky: true,
|
|
actions: [
|
|
...(tool?.canInstall
|
|
? [{ label: "Install", run: () => void installTool(e.installTool, { notificationKey: key }) }]
|
|
: []),
|
|
{ label: "Language Servers…", run: () => void executeAction("file.settings", SETTINGS_PAGE_ID) },
|
|
],
|
|
});
|
|
})();
|
|
});
|
|
}
|