fix(editor): keep execution shortcut from popping target picker

This commit is contained in:
ooooooo authored and GitHub committed 2026-07-21 16:57:00 +08:00
1 parent fb6ef28974
commit 497d041157
2 files changed
+15 -6

No files matched your search

@@ -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([
@@ -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");
});
});