feat(debugger): add paused editor evaluation entry points (#676)

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
Цей коміт міститься в:
l0ng-ai authored and GitHub committed 2026-11-01 17:19:00 +08:00
1 джерело f6d7facd82
коміт 87bf89d688
9 files changed
+255 -20

No files matched your search

+34
Переглянути файл
@@ -0,0 +1,34 @@
import { EditorSelection, Prec, type Extension } from "@codemirror/state";
import { EditorView } from "@codemirror/view";
import { dispatchMouseShortcut } from "@/platform/keymap";
export function mouseEvaluateTarget(arg: unknown): { view: EditorView; pos: number } | null {
if (!arg || typeof arg !== "object" || !("view" in arg) || !("pos" in arg)) return null;
return arg.view instanceof EditorView && typeof arg.pos === "number" ? { view: arg.view, pos: arg.pos } : null;
}
/** Preserve a clicked selection and anchor the value hint at the mouse position. */
export function quickEvaluateMouse(): Extension {
return Prec.highest(EditorView.domEventHandlers({ mousedown: quickEvaluateMouseDown }));
}
export function quickEvaluateMouseDown(e: MouseEvent, view: EditorView): boolean {
if (e.button !== 0) return false;
const over = e.target instanceof Element ? e.target : null;
if (over?.closest(".cm-tooltip, .cm-lsp-inlay") || (over && !over.closest(".cm-content"))) return false;
const pos = view.posAtCoords({ x: e.clientX, y: e.clientY }, false);
if (pos == null) return false;
const handled = dispatchMouseShortcut(
e,
(id) => {
if (id !== "debug.quickEvaluate") return false;
const sel = view.state.selection.main;
if (sel.empty || pos < sel.from || pos > sel.to) view.dispatch({ selection: EditorSelection.cursor(pos) });
view.focus();
return true;
},
{ view, pos },
);
if (handled) e.preventDefault();
return handled;
}