дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 03:05:40 +02:00
feat(run): Stop lists the running processes with Stop All when several run (#1113)
Stop from the shortcut, menu or Find Action stopped the selected configuration's process whenever it was running, so with several processes there was no way to pick another or stop them all. Like IDEA's Stop it now stops the only stoppable process or lists them all with Stop All; the run widget's stop button keeps stopping the selected configuration and the Run tool window its active tab.
Цей коміт міститься в:
1 джерело
cd77c9c6fb
коміт
2bb8f3b091
3 files changed
+51
-16
No files matched your search
@@ -3,7 +3,8 @@ import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
||||
import { executeAction } from "@/platform/actions";
|
||||
import { setContext } from "@/platform/context";
|
||||
import type { RunConfig } from "@/platform/ipc";
|
||||
import { useDebugRunSessions, type DebugRunSession } from "@/workbench/contributions";
|
||||
import { registerMenuGroup, useDebugRunSessions, type DebugRunSession } from "@/workbench/contributions";
|
||||
import { useContextMenuStore } from "@/ui";
|
||||
import { applicationConfig } from "./application";
|
||||
import { activate } from "./index";
|
||||
import { RunWidget } from "./RunWidget";
|
||||
@@ -93,11 +94,39 @@ it("targets the selected debug session while npm runs, through buttons and short
|
||||
await executeAction("run.run");
|
||||
expect(session.rerun).toHaveBeenCalledTimes(2);
|
||||
fireEvent.click(screen.getByRole("button", { name: `Stop '${app.name}'` }));
|
||||
await executeAction("run.stop");
|
||||
expect(session.stop).toHaveBeenCalledTimes(2);
|
||||
await vi.waitFor(() => expect(session.stop).toHaveBeenCalledOnce());
|
||||
expect(useRun.getState().sessions[0]?.stopped).toBeUndefined();
|
||||
});
|
||||
|
||||
it("lists every running process with Stop All for the Stop shortcut, like IDEA", async () => {
|
||||
const session = debug(app);
|
||||
useRun.setState({ sessions: [run(npm, 3)] });
|
||||
useDebugRunSessions.setState({ sessions: [session] });
|
||||
const unregister = registerMenuGroup({
|
||||
id: "test.stopDebug",
|
||||
menus: ["stopProcess"],
|
||||
items: () => [{ label: app.name, run: () => session.stop() }],
|
||||
});
|
||||
try {
|
||||
render(<RunWidget />);
|
||||
await executeAction("run.stop");
|
||||
const items = useContextMenuStore.getState().menu!.items;
|
||||
expect(items.map((i) => ("label" in i ? i.label : i.kind))).toEqual([
|
||||
"Stop Process",
|
||||
npm.name,
|
||||
app.name,
|
||||
"separator",
|
||||
"Stop All",
|
||||
]);
|
||||
const stopAll = items.at(-1) as { run: () => void };
|
||||
stopAll.run();
|
||||
expect(session.stop).toHaveBeenCalledOnce();
|
||||
expect(useRun.getState().sessions[0]?.stopped).toBe(true);
|
||||
} finally {
|
||||
unregister();
|
||||
}
|
||||
});
|
||||
|
||||
it("ignores an unrelated debug session for an idle selection", () => {
|
||||
useDebugRunSessions.setState({ sessions: [debug(npm)] });
|
||||
render(<RunWidget />);
|
||||
|
||||
@@ -144,7 +144,7 @@ export function RunWidget() {
|
||||
className={clsx(styles.widgetButton, styles.widgetFilled, styles.widgetFilledStop)}
|
||||
title={active || count === 1 ? tx`Stop '${stopName ?? ""}'` : tx`Stop (${count} running)`}
|
||||
shortcut={shortcutLabel("run.stop")}
|
||||
onClick={() => void executeAction("run.stop")}
|
||||
onClick={() => void executeAction("run.stop", "widget")}
|
||||
/>
|
||||
)}
|
||||
<IconButton
|
||||
|
||||
@@ -195,7 +195,12 @@ function configFromArg(arg: unknown): RunConfig | undefined {
|
||||
* Stop: in the Run or Debug tool window, the selected tab's process; otherwise the selected
|
||||
* configuration's session, or a chooser of every running process.
|
||||
*/
|
||||
function stopAction() {
|
||||
/**
|
||||
* Stop. In the Run tool window: its active tab. From the run widget (`arg` "widget"): the selected
|
||||
* configuration's process. Elsewhere (shortcut, menu, Find Action), like IDEA's Stop: the only
|
||||
* stoppable process, or a list of them with Stop All when there are several.
|
||||
*/
|
||||
function stopAction(arg?: unknown) {
|
||||
const ctx = getContext();
|
||||
if (ctx.toolWindowFocus && ctx.activeToolWindow === "debug" && getAction("debug.stop")) {
|
||||
void executeAction("debug.stop");
|
||||
@@ -210,16 +215,17 @@ function stopAction() {
|
||||
}
|
||||
}
|
||||
const debug = useDebugRunSessions.getState().sessions;
|
||||
const selected = selectedConfig();
|
||||
const compound = compoundTargets(selected, running, debug);
|
||||
if (compound.length) {
|
||||
compound.forEach((s) => s.stop());
|
||||
return;
|
||||
}
|
||||
const target = selectedTarget(useRun.getState().selectedId, running, debug);
|
||||
if (target) {
|
||||
target.stop();
|
||||
return;
|
||||
if (arg === "widget") {
|
||||
const compound = compoundTargets(selectedConfig(), running, debug);
|
||||
if (compound.length) {
|
||||
compound.forEach((s) => s.stop());
|
||||
return;
|
||||
}
|
||||
const target = selectedTarget(useRun.getState().selectedId, running, debug);
|
||||
if (target) {
|
||||
target.stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
const items = [
|
||||
...running.map((s): MenuItem => ({
|
||||
@@ -357,7 +363,7 @@ export function activate(): () => void {
|
||||
category: "Run",
|
||||
icon: "stop",
|
||||
when: "projectOpen",
|
||||
run: () => stopAction(),
|
||||
run: ({ arg }) => stopAction(arg),
|
||||
},
|
||||
{
|
||||
id: "run.rerun",
|
||||
|
||||
Reference in new issue
Заблокувати користувача