дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
Go settings, execution, debugging and test reporting were disconnected, leaving Go projects without editable build/test fields and workspace maintenance actions. - Add project build constraints that update gopls in place, and notices on excluded files. - Add editable Go Build and Go Test configurations with directory, package and file targets, separate tool and program arguments, modules, environment, output selection and build-only execution, and pass the same settings to Delve. - Decode Go JSON test output into the results view, with subtests, failures, skips and rerun failed. Add gutter targets for benchmarks and generate directives. - Add module environment and vendoring settings, read go.work members, and offer tidy, download, sync and use from file menus. - Add file and package generate actions, and format and organize imports through gopls on Save and Reformat. - Show what a Go program prints in the debug console: Delve's debuggee shares its stdio, which no DAP event carries. - Keep the default build output out of version control, and keep configurations produced by an earlier run out of the gutter choices. Fixes #507 Fixes #237
113 рядки
4.4 KiB
TypeScript
113 рядки
4.4 KiB
TypeScript
import { executeAction, getAction, registerActions } from "@/platform/actions";
|
|
import { useProject } from "@/platform/project";
|
|
import type { RunConfig } from "@/platform/ipc";
|
|
import { registerMenuGroup, maybeEditorService, type MenuGroupContext } from "@/workbench/contributions";
|
|
import { promptInput } from "@/workbench/inputDialogs";
|
|
import { goGenerateConfig, goGenerateMenu } from "./goGenerate";
|
|
import { invalidateGoModules, loadGoModules } from "./goModules";
|
|
import { loadConfigs, startRun, useRun } from "./store";
|
|
|
|
export type GoModuleOperation = "tidy" | "download" | "sync" | "use";
|
|
const ACTIONS = {
|
|
tidy: { id: "go.mod.tidy", title: "Go Mod Tidy" },
|
|
download: { id: "go.mod.download", title: "Download Go Modules" },
|
|
sync: { id: "go.work.sync", title: "Sync Go Workspace" },
|
|
use: { id: "go.work.use", title: "Add Directory to Go Workspace…" },
|
|
} as const;
|
|
|
|
export function goModuleCommand(operation: GoModuleOperation, path: string, directory?: string): RunConfig | null {
|
|
const module = operation === "tidy" || operation === "download";
|
|
if (!path.endsWith(module ? "/go.mod" : "/go.work") || path.includes("\0")) return null;
|
|
if (operation === "use" && (!directory?.trim() || directory.includes("\0"))) return null;
|
|
const args = [module ? "mod" : "work", operation, ...(operation === "use" ? ["--", directory!] : [])];
|
|
return {
|
|
id: `go:${operation}:${path}`,
|
|
name: `go ${args.slice(0, 2).join(" ")}`,
|
|
kind: "go",
|
|
command: "go",
|
|
args,
|
|
cwd: path.slice(0, path.lastIndexOf("/")),
|
|
env: {},
|
|
detected: true,
|
|
isTest: false,
|
|
debugAdapter: null,
|
|
};
|
|
}
|
|
|
|
export function goModuleMenu(ctx: MenuGroupContext) {
|
|
const path = ctx.paths.length === 1 ? ctx.paths[0]! : "";
|
|
const operations: GoModuleOperation[] = path.endsWith("/go.mod")
|
|
? ["tidy", "download"]
|
|
: path.endsWith("/go.work")
|
|
? ["sync", "use"]
|
|
: [];
|
|
return operations.map((op) => ({ kind: "action" as const, action: ACTIONS[op].id, arg: { path } }));
|
|
}
|
|
|
|
export function registerGoActions(): () => void {
|
|
const actions = registerActions([
|
|
...Object.entries(ACTIONS).map(([operation, spec]) => ({
|
|
...spec,
|
|
category: "Go",
|
|
when: "projectOpen",
|
|
run: async ({ arg }: { arg?: unknown }) => {
|
|
const params = arg && typeof arg === "object" ? (arg as { path?: string; directory?: string }) : {};
|
|
const path =
|
|
typeof arg === "string"
|
|
? arg
|
|
: typeof params.path === "string"
|
|
? params.path
|
|
: (maybeEditorService()?.activePath() ?? "");
|
|
let directory = typeof params.directory === "string" ? params.directory : undefined;
|
|
if (operation === "use" && !directory) {
|
|
directory =
|
|
(await promptInput({
|
|
title: "Add Directory to Go Workspace",
|
|
label: "Module directory",
|
|
initial: "./",
|
|
hint: "Path relative to go.work, or an absolute directory containing go.mod",
|
|
})) ?? undefined;
|
|
if (!directory) return;
|
|
}
|
|
const config = goModuleCommand(operation as GoModuleOperation, path, directory);
|
|
if (!config) return;
|
|
const root = useProject.getState().project?.root;
|
|
await startRun(config, undefined, undefined, {
|
|
onExit: () => {
|
|
if (useProject.getState().project?.root !== root) return;
|
|
invalidateGoModules();
|
|
void loadGoModules(root ?? null, useRun.getState().configs);
|
|
void loadConfigs();
|
|
if (getAction("libraries.reload")) void executeAction("libraries.reload");
|
|
},
|
|
});
|
|
},
|
|
})),
|
|
...(["file", "package"] as const).map((scope) => ({
|
|
id: `go.generate.${scope}`,
|
|
title: scope === "file" ? "Go Generate File" : "Go Generate Package",
|
|
category: "Go",
|
|
when: "projectOpen",
|
|
run: async ({ arg }: { arg?: unknown }) => {
|
|
const path =
|
|
typeof arg === "string"
|
|
? arg
|
|
: arg && typeof arg === "object" && "path" in arg && typeof arg.path === "string"
|
|
? arg.path
|
|
: (maybeEditorService()?.activePath() ?? "");
|
|
const config = goGenerateConfig(path, scope);
|
|
if (config) await startRun(config);
|
|
},
|
|
})),
|
|
]);
|
|
const menu = registerMenuGroup({
|
|
id: "go.modules",
|
|
menus: ["projectView", "editorTab", "editor"],
|
|
items: (_menu, ctx) => [...goModuleMenu(ctx), ...goGenerateMenu(ctx)],
|
|
});
|
|
return () => {
|
|
menu();
|
|
actions();
|
|
};
|
|
}
|