From dfd1e7e6d197e222050437de618561589bc0487f Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Wed, 1 Jul 2026 20:23:51 +0800 Subject: [PATCH] fix(editor): preserve snippet tab navigation --- .../src/components/editor/QueryEditor.vue | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/apps/desktop/src/components/editor/QueryEditor.vue b/apps/desktop/src/components/editor/QueryEditor.vue index 6ef6e69af..079666aa4 100644 --- a/apps/desktop/src/components/editor/QueryEditor.vue +++ b/apps/desktop/src/components/editor/QueryEditor.vue @@ -201,6 +201,8 @@ let codeMirrorSnippetCompletion: typeof import("@codemirror/autocomplete").snipp let codeMirrorCompletionStatus: typeof import("@codemirror/autocomplete").completionStatus | null = null; let codeMirrorAcceptCompletion: typeof import("@codemirror/autocomplete").acceptCompletion | null = null; let codeMirrorStartCompletion: typeof import("@codemirror/autocomplete").startCompletion | null = null; +let codeMirrorInsertCompletionText: typeof import("@codemirror/autocomplete").insertCompletionText | null = null; +let codeMirrorNextSnippetField: typeof import("@codemirror/autocomplete").nextSnippetField | null = null; let codeMirrorIndentMore: typeof import("@codemirror/commands").indentMore | null = null; let codeMirrorIndentLess: typeof import("@codemirror/commands").indentLess | null = null; let codeMirrorCopyLineDown: typeof import("@codemirror/commands").copyLineDown | null = null; @@ -653,7 +655,7 @@ function runKeymapExtension(codeMirrorKeymap: (typeof import("@codemirror/view") ]), ) ?? [], codeMirrorKeymap.of( - binding(shortcuts.acceptCompletion, (view) => codeMirrorAcceptCompletion?.(view) ?? false).map((item) => ({ + binding(shortcuts.acceptCompletion, acceptCompletionOrNextSnippetField).map((item) => ({ ...item, preventDefault: false, })), @@ -661,6 +663,15 @@ function runKeymapExtension(codeMirrorKeymap: (typeof import("@codemirror/view") ]; } +function acceptCompletionOrNextSnippetField(view: EditorViewType): boolean { + if (codeMirrorCompletionStatus?.(view.state) && (codeMirrorAcceptCompletion?.(view) ?? false)) { + return true; + } + // Table/column completions can happen inside a CodeMirror snippet field. When + // the completion popup is gone, Tab should continue through the snippet fields. + return codeMirrorNextSnippetField?.(view) ?? false; +} + function wordWrapExtension() { if (!editorViewModule) return []; return props.forceWordWrap || settingsStore.editorSettings.wordWrap ? editorViewModule.EditorView.lineWrapping : []; @@ -1341,10 +1352,14 @@ function completionOptionForItem(item: QueryCompletionItem) { apply(view: EditorViewType, _completionItem: unknown, from: number, to: number) { record(); const insert = item.apply ?? item.label; - view.dispatch({ - changes: { from, to, insert }, - selection: { anchor: from + insert.length }, - }); + if (codeMirrorInsertCompletionText) { + view.dispatch(codeMirrorInsertCompletionText(view.state, insert, from, to)); + } else { + view.dispatch({ + changes: { from, to, insert }, + selection: { anchor: from + insert.length }, + }); + } }, }; } @@ -2009,7 +2024,7 @@ onMounted(async () => { { EditorView, keymap, rectangularSelection, hoverTooltip, showTooltip, Decoration, tooltips, gutter, GutterMarker, lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, dropCursor, crosshairCursor, ViewPlugin }, { EditorState, Compartment, Prec, StateEffect, StateField }, langSql, - { autocompletion, startCompletion, acceptCompletion, closeBrackets, closeBracketsKeymap, snippetCompletion, completionStatus, completionKeymap }, + { autocompletion, startCompletion, acceptCompletion, closeBrackets, closeBracketsKeymap, snippetCompletion, completionStatus, completionKeymap, insertCompletionText, nextSnippetField }, { copyLineDown, copyLineUp, deleteLine, indentLess, indentMore, insertNewlineKeepIndent, moveLineDown, moveLineUp, redo, selectAll, undo, history, defaultKeymap, historyKeymap }, { bracketMatching, foldGutter, indentOnInput, indentUnit, syntaxHighlighting, defaultHighlightStyle, foldKeymap }, { searchKeymap }, @@ -2030,6 +2045,8 @@ onMounted(async () => { codeMirrorCompletionStatus = completionStatus; codeMirrorAcceptCompletion = acceptCompletion; codeMirrorStartCompletion = startCompletion; + codeMirrorInsertCompletionText = insertCompletionText; + codeMirrorNextSnippetField = nextSnippetField; codeMirrorIndentMore = indentMore; codeMirrorIndentLess = indentLess; codeMirrorCopyLineDown = copyLineDown;