diff --git a/apps/desktop/src/components/editor/QueryEditor.vue b/apps/desktop/src/components/editor/QueryEditor.vue index dbab1dfa8a..2b9f93e4dc 100644 --- a/apps/desktop/src/components/editor/QueryEditor.vue +++ b/apps/desktop/src/components/editor/QueryEditor.vue @@ -140,7 +140,7 @@ import { sqlSemanticTableNameSpansForSyntaxTree } from "@/lib/editor/codemirrorS import { startsQueryEditorRectangularSelection, usesQueryEditorObjectNavigationModifier } from "@/lib/editor/queryEditorPointerSelection"; import { LARGE_PASTE_HISTORY_USER_EVENT, normalizeQueryEditorPasteText, recoverableNativePasteSuffix, shouldRecoverLargeTauriPaste } from "@/lib/editor/queryEditorLargePaste"; import { computePasteCaretResyncTarget } from "@/lib/editor/queryEditorPasteCaretResync"; -import { queryEditorCommentTokens, queryEditorLineCommentToken } from "@/lib/editor/queryEditorLineComment"; +import { queryEditorCommentTokens, queryEditorLineCommentToken, queryEditorWordLanguageData } from "@/lib/editor/queryEditorLineComment"; import { createShellLineCommentHighlight } from "@/lib/editor/codemirrorShellLineCommentHighlight"; import { extendQueryEditorSelection, runQueryEditorAltExtendSelection } from "@/lib/editor/queryEditorExtendSelection"; import { addNextQueryEditorSelectionOccurrence, selectAllQueryEditorSelectionOccurrences } from "@/lib/editor/queryEditorOccurrenceSelection"; @@ -6035,6 +6035,7 @@ onMounted(async () => { // Non-SQL editors (MongoDB shell) keep the SQL grammar for highlighting, so override the // comment marker that toggleLineComment reads from language data. Prec.highest(EditorState.languageData.of(() => [{ commentTokens: queryEditorCommentTokens(props.databaseType) }])), + Prec.highest(EditorState.languageData.of(() => queryEditorWordLanguageData(props.databaseType))), // The SQL grammar does not tokenize `//`, so those comments are highlighted by hand. queryEditorLineCommentToken(props.databaseType) === "//" ? shellLineCommentHighlightPlugin : [], ]; diff --git a/apps/desktop/src/lib/__tests__/editor/queryEditorLineComment.spec.ts b/apps/desktop/src/lib/__tests__/editor/queryEditorLineComment.spec.ts index 329e922ff5..af57bc884c 100644 --- a/apps/desktop/src/lib/__tests__/editor/queryEditorLineComment.spec.ts +++ b/apps/desktop/src/lib/__tests__/editor/queryEditorLineComment.spec.ts @@ -3,7 +3,7 @@ import { toggleLineComment } from "@codemirror/commands"; import { sql } from "@codemirror/lang-sql"; import { EditorState, Prec, type Transaction } from "@codemirror/state"; import { describe, expect, it, vi } from "vitest"; -import { queryEditorCommentTokens, queryEditorLineCommentToken } from "@/lib/editor/queryEditorLineComment"; +import { queryEditorCommentTokens, queryEditorLineCommentToken, queryEditorWordLanguageData } from "@/lib/editor/queryEditorLineComment"; const queryEditorSource = readFileSync(new URL("../../../components/editor/QueryEditor.vue", import.meta.url), "utf8"); const editorThemesSource = readFileSync(new URL("../../editor/editorThemes.ts", import.meta.url), "utf8"); @@ -47,6 +47,18 @@ describe("queryEditorLineCommentToken", () => { }); }); +describe("QueryEditor word selection", () => { + it("includes the @ prefix in SQL Server variable words", () => { + const sqlServer = EditorState.create({ doc: "@name", extensions: [EditorState.languageData.of(() => queryEditorWordLanguageData("sqlserver"))] }); + const mysql = EditorState.create({ doc: "@name", extensions: [EditorState.languageData.of(() => queryEditorWordLanguageData("mysql"))] }); + const systemVariable = EditorState.create({ doc: "@@ROWCOUNT", extensions: [EditorState.languageData.of(() => queryEditorWordLanguageData("sqlserver"))] }); + + for (let position = 0; position <= 5; position += 1) expect(sqlServer.wordAt(position)).toMatchObject({ from: 0, to: 5 }); + expect(mysql.wordAt(2)).toMatchObject({ from: 1, to: 5 }); + expect(systemVariable.wordAt(1)).toMatchObject({ from: 0, to: 10 }); + }); +}); + describe("QueryEditor line comment", () => { it("overrides the language comment tokens in the SQL language compartment", () => { expect(queryEditorSource).toContain("Prec.highest(EditorState.languageData.of(() => [{ commentTokens: queryEditorCommentTokens(props.databaseType) }]))"); diff --git a/apps/desktop/src/lib/editor/queryEditorLineComment.ts b/apps/desktop/src/lib/editor/queryEditorLineComment.ts index 39edfd160d..7408895b91 100644 --- a/apps/desktop/src/lib/editor/queryEditorLineComment.ts +++ b/apps/desktop/src/lib/editor/queryEditorLineComment.ts @@ -18,3 +18,7 @@ export function queryEditorCommentTokens(dbType?: DatabaseType) { block: { open: "/*", close: "*/" }, }; } + +export function queryEditorWordLanguageData(dbType?: DatabaseType) { + return dbType === "sqlserver" ? [{ wordChars: "@" }] : []; +}