From 497d041157f864fe318ec613815954d6ad691635 Mon Sep 17 00:00:00 2001 From: ooooooo <139197180+TongEc@users.noreply.github.com> Date: Tue, 21 Jul 2026 16:57:00 +0800 Subject: [PATCH] fix(editor): keep execution shortcut from popping target picker --- apps/desktop/src/components/editor/QueryEditor.vue | 12 ++++++++---- .../__tests__/editor/queryEditorExecution.spec.ts | 9 +++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/desktop/src/components/editor/QueryEditor.vue b/apps/desktop/src/components/editor/QueryEditor.vue index 2710225559..df31062816 100644 --- a/apps/desktop/src/components/editor/QueryEditor.vue +++ b/apps/desktop/src/components/editor/QueryEditor.vue @@ -467,6 +467,7 @@ function handleTab(view: EditorViewType): boolean { interface RequestExecuteOptions { ignoreSelection?: boolean; + bypassPicker?: boolean; } function requestExecute(options: RequestExecuteOptions = {}) { @@ -486,11 +487,13 @@ function requestExecuteFromView(currentView: EditorViewType, cursorPos: number, emit("execute", sqlExecutionSnapshotFromView(currentView)); return true; } - // No selection → show the execution target picker. + // No selection → resolve the execution target, optionally via the picker. const doc = currentView.state.doc.toString(); const candidates = buildExecutionCandidates(doc, cursorPos, props.databaseType); if (candidates.length === 0) return false; - if (!settingsStore.editorSettings.showExecutionTargetPicker || !hasMultipleExecutionTargets(doc, props.databaseType)) { + // The execution shortcut keeps executing the configured target (cursor/all) directly: + // it stays keyboard-driven and never pops the picker, which is reserved for click entry points. + if (options.bypassPicker || !settingsStore.editorSettings.showExecutionTargetPicker || !hasMultipleExecutionTargets(doc, props.databaseType)) { const preferredKind = settingsStore.editorSettings.executeMode === "current" ? "cursor" : "all"; const candidate = candidates.find((item) => item.kind === preferredKind) ?? candidates[0]; emit("execute", candidate.sql); @@ -1161,8 +1164,9 @@ function runKeymapExtension(codeMirrorKeymap: (typeof import("@codemirror/view") const shortcuts = normalizeShortcutSettings(settingsStore.editorSettings.shortcuts); const Prec = codeMirrorPrec; const binding = (shortcut: string, run: (view: EditorViewType) => boolean) => (shortcut ? [{ key: shortcutToCodeMirrorKey(shortcut), preventDefault: true, run }] : []); - // Keep the shortcut on the shared path so selection, picker, and execute-mode behavior stay aligned with other execution entry points. - const executeBindings = props.hideExecutionControls ? [] : binding(shortcuts.executeSql, () => requestExecute()); + // Keep the shortcut on the shared execution-mode path (selection priority + configured cursor/all target), + // but bypass the picker so the keyboard shortcut always executes directly instead of popping a dialog. + const executeBindings = props.hideExecutionControls ? [] : binding(shortcuts.executeSql, () => requestExecute({ bypassPicker: true })); return [ Prec?.high( codeMirrorKeymap.of([ diff --git a/apps/desktop/src/lib/__tests__/editor/queryEditorExecution.spec.ts b/apps/desktop/src/lib/__tests__/editor/queryEditorExecution.spec.ts index 8d8b1af917..bba4bb0df0 100644 --- a/apps/desktop/src/lib/__tests__/editor/queryEditorExecution.spec.ts +++ b/apps/desktop/src/lib/__tests__/editor/queryEditorExecution.spec.ts @@ -4,8 +4,8 @@ import { describe, expect, it } from "vitest"; const queryEditorSource = readFileSync(new URL("../../../components/editor/QueryEditor.vue", import.meta.url), "utf8"); describe("QueryEditor execution routing", () => { - it("routes the execution shortcut through the shared execution-mode contract", () => { - expect(queryEditorSource).toContain("binding(shortcuts.executeSql, () => requestExecute())"); + it("routes the execution shortcut through the shared execution-mode contract while bypassing the picker", () => { + expect(queryEditorSource).toContain("binding(shortcuts.executeSql, () => requestExecute({ bypassPicker: true }))"); expect(queryEditorSource).not.toContain("forceCurrent"); }); @@ -16,4 +16,9 @@ describe("QueryEditor execution routing", () => { expect(selectionBranch).toBeGreaterThan(-1); expect(executeModeBranch).toBeGreaterThan(selectionBranch); }); + + it("lets the shortcut skip the picker without affecting other execution entry points", () => { + // The picker guard must also honor the shortcut's bypass flag, otherwise Ctrl+Enter would keep popping the dialog. + expect(queryEditorSource).toContain("if (options.bypassPicker || !settingsStore.editorSettings.showExecutionTargetPicker"); + }); });