дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
While a debug session is paused, Alt/Option+click on a variable or expression runs Quick Evaluate at the clicked position (the selection when the click falls inside it) and shows the value next to it; outside a paused session Alt+click keeps its editor behaviour. The editor context menu offers Evaluate Expression… seeded with the selection or the expression at the caret while paused. Mouse shortcuts now pass the clicked editor and position to the action, and the binding is only consumed when its action is enabled. Fixes #664
110 рядки
4.1 KiB
TypeScript
110 рядки
4.1 KiB
TypeScript
/**
|
||
* Debugger: breakpoints (editor gutter + per-project store synced to the
|
||
* backend), DAP sessions driven by `IdeEvent::Debug`, the Debug tool window,
|
||
* execution point + inline values, Evaluate / View Breakpoints dialogs.
|
||
*/
|
||
import { lazyComponent } from "@/ui";
|
||
import { onIdeEvent } from "@/platform/ipc";
|
||
import { useProject } from "@/platform/project";
|
||
import { selectionValueTooltip, valueTooltip } from "./editor/valueTooltip";
|
||
import { quickEvaluateMouse } from "./editor/quickEvaluate";
|
||
import { registerEditorContribution } from "@/editor/api";
|
||
import {
|
||
registerMenuGroup,
|
||
registerOverlay,
|
||
registerRunConfigType,
|
||
registerToolWindow,
|
||
useDebugRunSessions,
|
||
} from "@/workbench/contributions";
|
||
import { registerDebugActions } from "./actions";
|
||
import { loadBreakpoints } from "./breakpoints/store";
|
||
import { loadExceptionBreakpoints } from "./breakpoints/exceptions";
|
||
import { loadSpecialBreakpoints } from "./breakpoints/special";
|
||
import { breakpointGutter } from "./editor/breakpointGutter";
|
||
import { executionPoint } from "./editor/execution";
|
||
import { runToCursorInlay } from "./editor/runToCursor";
|
||
import { installSmartStepPicking, smartStepTargets } from "./editor/smartStep";
|
||
import { onHotCodeReplace } from "./hotswap";
|
||
import {
|
||
activeSession,
|
||
handleDebugEvent,
|
||
isLive,
|
||
loadWatches,
|
||
publishContext,
|
||
resetSessions,
|
||
stopSession,
|
||
useDebug,
|
||
} from "./state";
|
||
import { DebuggerOverlays } from "./ui/Overlays";
|
||
import { REMOTE_TYPES } from "./remote";
|
||
|
||
export function activate(): () => void {
|
||
useDebugRunSessions.setState({
|
||
Console: lazyComponent(() => import("./ui/DebugConsole").then((m) => m.DebugServiceConsole)),
|
||
});
|
||
loadWatches();
|
||
publishContext();
|
||
loadBreakpoints(useProject.getState().project?.root ?? null);
|
||
loadExceptionBreakpoints(useProject.getState().project?.root ?? null);
|
||
loadSpecialBreakpoints(useProject.getState().project?.root ?? null);
|
||
const disposers = [
|
||
() => useDebugRunSessions.setState({ sessions: [], serviceSessions: [], Console: null }),
|
||
registerDebugActions(),
|
||
// Remote JVM Debug, Go Remote, …: Run/Debug Configurations › Add New Configuration.
|
||
...REMOTE_TYPES.map(registerRunConfigType),
|
||
registerToolWindow({
|
||
id: "debug",
|
||
title: "Debug",
|
||
icon: "toolwindow-debug",
|
||
anchor: "bottom",
|
||
stripe: "onUse",
|
||
order: 20,
|
||
component: lazyComponent(() => import("./ui/DebugToolWindow").then((m) => m.DebugToolWindow)),
|
||
headerContent: lazyComponent(() => import("./ui/DebugToolWindow").then((m) => m.DebugTabs)),
|
||
}),
|
||
registerOverlay({ id: "debugger", component: DebuggerOverlays }),
|
||
registerMenuGroup({
|
||
id: "debugger.evaluate",
|
||
menus: ["editor"],
|
||
items: () => (activeSession()?.status === "paused" ? [{ kind: "action", action: "debug.evaluate" }] : []),
|
||
}),
|
||
// Stop (⌘F2) offers the running debug sessions beside run processes.
|
||
registerMenuGroup({
|
||
id: "debugger.stop",
|
||
menus: ["stopProcess"],
|
||
items: () =>
|
||
Object.values(useDebug.getState().sessions)
|
||
.filter((s) => s.parent == null && isLive(s))
|
||
.map((s) => ({ label: s.name, verbatim: true, icon: "debug", run: () => void stopSession(s.id) })),
|
||
}),
|
||
registerEditorContribution({
|
||
id: "debugger",
|
||
order: 60,
|
||
extensions: (ctx) => [
|
||
breakpointGutter(ctx),
|
||
executionPoint(ctx),
|
||
runToCursorInlay(ctx),
|
||
valueTooltip(),
|
||
selectionValueTooltip(),
|
||
quickEvaluateMouse(),
|
||
smartStepTargets(ctx),
|
||
],
|
||
}),
|
||
installSmartStepPicking(),
|
||
onIdeEvent("debug", (e) => {
|
||
if (e.event.kind === "hotCodeReplace") onHotCodeReplace(e.session, e.event);
|
||
else handleDebugEvent(e.session, e.event);
|
||
}),
|
||
useProject.subscribe((s, prev) => {
|
||
const root = s.project?.root ?? null;
|
||
if (root !== (prev.project?.root ?? null) || s.project?.trusted !== prev.project?.trusted) {
|
||
resetSessions();
|
||
loadBreakpoints(root);
|
||
loadExceptionBreakpoints(root);
|
||
loadSpecialBreakpoints(root);
|
||
}
|
||
}),
|
||
];
|
||
return () => disposers.reverse().forEach((d) => d());
|
||
}
|