fix(editor): continue completion after selecting schemas

This commit is contained in:
zipg authored and GitHub committed 2026-07-13 17:16:23 +08:00
1 parent 35ca4e3a37
commit d794bbe768
3 files changed
+22 -4

No files matched your search

@@ -31,6 +31,7 @@ import {
isSqlLikeCompletionStatement, isSqlLikeCompletionStatement,
recordCompletionSelection, recordCompletionSelection,
shouldAutoOpenSqlCompletion, shouldAutoOpenSqlCompletion,
shouldChainSqlCompletionAfterAccept,
extractCteDefinitions, extractCteDefinitions,
} from "@/lib/sql/sqlCompletion"; } from "@/lib/sql/sqlCompletion";
import { sqlCompletionContextFromSemantic } from "@/lib/sql/semantic/completion"; import { sqlCompletionContextFromSemantic } from "@/lib/sql/semantic/completion";
@@ -1762,8 +1763,8 @@ function isTypedCompletionActivation(explicit: boolean) {
return explicit && typedCompletionActivationUntil >= Date.now(); return explicit && typedCompletionActivationUntil >= Date.now();
} }
function markCompletionAccepted() { function markCompletionAccepted(item: QueryCompletionItem) {
suppressNextSqlCompletionAutoStartUntil = Date.now() + 750; suppressNextSqlCompletionAutoStartUntil = shouldChainSqlCompletionAfterAccept(item) ? 0 : Date.now() + 750;
completionEpoch++; completionEpoch++;
} }
@@ -1820,7 +1821,7 @@ function completionOptionForItem(item: QueryCompletionItem) {
...completion, ...completion,
apply(view: EditorViewType, completionItem: unknown, from: number, to: number) { apply(view: EditorViewType, completionItem: unknown, from: number, to: number) {
record(); record();
markCompletionAccepted(); markCompletionAccepted(item);
if (typeof originalApply === "function") { if (typeof originalApply === "function") {
originalApply(view, completionItem as never, from, to); originalApply(view, completionItem as never, from, to);
} else { } else {
@@ -1841,7 +1842,7 @@ function completionOptionForItem(item: QueryCompletionItem) {
boost: item.boost, boost: item.boost,
apply(view: EditorViewType, _completionItem: unknown, from: number, to: number) { apply(view: EditorViewType, _completionItem: unknown, from: number, to: number) {
record(); record();
markCompletionAccepted(); markCompletionAccepted(item);
const insert = item.apply ?? item.label; const insert = item.apply ?? item.label;
if (codeMirrorInsertCompletionText) { if (codeMirrorInsertCompletionText) {
view.dispatch(codeMirrorInsertCompletionText(view.state, insert, from, to)); view.dispatch(codeMirrorInsertCompletionText(view.state, insert, from, to));
@@ -1121,6 +1121,10 @@ export interface SqlCompletionItem {
exactMatch?: boolean; exactMatch?: boolean;
} }
export function shouldChainSqlCompletionAfterAccept(item: { type?: string; apply?: string }): boolean {
return item.type === "schema" && item.apply?.endsWith(".") === true;
}
export type SqlKeywordCase = "preserve" | "upper" | "lower"; export type SqlKeywordCase = "preserve" | "upper" | "lower";
export interface SqlCompletionReferencedTable { export interface SqlCompletionReferencedTable {
+13
View File
@@ -10,6 +10,7 @@ import {
extractCteDefinitions, extractCteDefinitions,
getSqlCompletionContext, getSqlCompletionContext,
recordCompletionSelection, recordCompletionSelection,
shouldChainSqlCompletionAfterAccept,
type SqlCompletionColumn, type SqlCompletionColumn,
type SqlCompletionForeignKey, type SqlCompletionForeignKey,
type SqlCompletionObject, type SqlCompletionObject,
@@ -623,6 +624,16 @@ test("keeps schema-qualified FROM object input in table suggestion mode", () =>
); );
}); });
test("keeps an accepted schema with trailing dot in table suggestion mode", () => {
const sql = "SELECT *\nFROM DBX_TEST.";
const context = getSqlCompletionContext(sql, sql.length);
assert.equal(context.qualifier, "DBX_TEST");
assert.equal(context.prefix, "");
assert.equal(context.suggestTables, true);
assert.equal(context.exclusiveTableSuggestions, true);
});
test("keeps database-qualified FROM input in table suggestion mode", () => { test("keeps database-qualified FROM input in table suggestion mode", () => {
const sql = "select * from other_db.or"; const sql = "select * from other_db.or";
const context = getSqlCompletionContext(sql, sql.length); const context = getSqlCompletionContext(sql, sql.length);
@@ -1827,6 +1838,8 @@ test("schema items include apply value with trailing dot", () => {
const schemaItems = items.filter((item) => item.type === "schema"); const schemaItems = items.filter((item) => item.type === "schema");
assert.equal(schemaItems.length, 1); assert.equal(schemaItems.length, 1);
assert.equal(schemaItems[0]?.apply, "public."); assert.equal(schemaItems[0]?.apply, "public.");
assert.equal(shouldChainSqlCompletionAfterAccept(schemaItems[0]!), true);
assert.equal(shouldChainSqlCompletionAfterAccept({ type: "table", apply: "users" }), false);
}); });
// --- Quoted identifier fix --- // --- Quoted identifier fix ---