fix(completion): always offer custom sql snippets

This commit is contained in:
Eve authored and GitHub committed 2026-09-11 14:12:42 +08:00
1 parent 0a6c10555a
commit ed810d6c92
2 files changed
+70 -4

No files matched your search

+14 -4
View File
@@ -645,6 +645,7 @@ const JOIN_MODIFIERS = new Set(["left", "right", "inner", "outer", "cross", "ful
const JOIN_MODIFIER_KEYWORD_PHRASES = ["LEFT JOIN", "RIGHT JOIN", "INNER JOIN", "FULL JOIN", "CROSS JOIN", "NATURAL JOIN", "LEFT OUTER JOIN", "RIGHT OUTER JOIN", "FULL OUTER JOIN"];
const MAX_TABLE_COMPLETION_ITEMS = 200;
const EXACT_LABEL_MATCH_BOOST = 10000;
const EXACT_CUSTOM_SNIPPET_TRIGGER_BOOST = 40000;
function isTableTriggerKeyword(keyword: string, options: SqlSemanticBuildOptions): boolean {
return TABLE_TRIGGER_KEYWORDS.has(keyword) || (keyword === "desc" && resolveSqlDialectId(options) === "mysql");
@@ -1540,15 +1541,22 @@ class SqlCompletionProvider {
return dedupeAndSort(buildMongoCompletionItemsFromContext({ mode: "root", prefix: context.prefix, from: 0 }).map(mongoCompletionItemToSqlCompletionItem));
}
const snippets = this.databaseType === "manticoresearch" ? [...(this.input.snippets ?? DEFAULT_SQL_SNIPPETS), ...MANTICORESEARCH_SQL_SNIPPETS] : (this.input.snippets ?? DEFAULT_SQL_SNIPPETS);
const customSnippetItems = buildSnippetItems(
context.prefix,
snippets.filter((snippet) => !shouldFormatBuiltinSnippet(snippet)),
this.input.keywordCase,
this.databaseType,
);
if (context.preferredValueKeywords?.length) {
return dedupeAndSort(buildPreferredKeywordItems(context.prefix, context.preferredValueKeywords, this.input.keywordCase));
return dedupeAndSort([...customSnippetItems, ...buildPreferredKeywordItems(context.prefix, context.preferredValueKeywords, this.input.keywordCase)]);
}
const preferReferencedColumns = hasMatchingReferencedColumnPrefix(context, this.input.columnsByTable);
this.items.push(...customSnippetItems);
if (!pendingJoinKeyword && !context.exclusiveTableSuggestions && !context.exclusiveColumnSuggestions && !context.exclusiveRoutineSuggestions) {
const snippets = this.databaseType === "manticoresearch" ? [...(this.input.snippets ?? DEFAULT_SQL_SNIPPETS), ...MANTICORESEARCH_SQL_SNIPPETS] : (this.input.snippets ?? DEFAULT_SQL_SNIPPETS);
if (!preferReferencedColumns) {
this.items.push(...buildSnippetItems(context.prefix, snippets, this.input.keywordCase, this.databaseType));
this.items.push(...buildSnippetItems(context.prefix, snippets.filter(shouldFormatBuiltinSnippet), this.input.keywordCase, this.databaseType));
}
if (!preferReferencedColumns || context.suggestRoutines) {
const functionItems = context.dataTypeContext ? [] : buildFunctionSnippetItems(context.prefix, getFunctionDescriptions(this.t), this.databaseType, context.openingParenAfterCursor, this.input.keywordCase, this.input.functionCase);
@@ -4999,6 +5007,7 @@ function buildSnippetItems(prefix: string, snippets: SqlSnippet[], keywordCase?:
const boostByPrefix = computeBoost(snippet.prefix, prefix);
const boostByLabel = computeBoost(snippet.label, prefix);
const matchesByPrefix = matchesPrefix(snippet.prefix, prefix);
const isExactCustomTrigger = !shouldFormatBuiltinSnippet(snippet) && snippet.prefix.toLowerCase() === prefix.toLowerCase();
// When the user types past the snippet prefix (e.g. "sele" vs prefix "sel"),
// they are likely typing the actual keyword — reduce the base boost so
// the real keyword can rank higher.
@@ -5014,7 +5023,8 @@ function buildSnippetItems(prefix: string, snippets: SqlSnippet[], keywordCase?:
type: "snippet" as const,
detail: body,
apply,
boost: Math.max(boostByPrefix, boostByLabel) + baseBoost,
exactMatch: isExactCustomTrigger || undefined,
boost: Math.max(boostByPrefix, boostByLabel) + baseBoost + (isExactCustomTrigger ? EXACT_CUSTOM_SNIPPET_TRIGGER_BOOST : 0),
};
});
}