feat(editor): add whitespace display toggle for SQL editor

This commit is contained in:
Melody Ruch authored and GitHub committed 2026-09-20 00:50:44 +08:00
1 parent fff07eff00
commit fa3925ca52
18 files changed
+184

No files matched your search

@@ -584,6 +584,7 @@ const completionTriggerModeDescription = computed(() => {
return t(key, { shortcut: formatShortcutDisplay(editShortcuts.value.triggerCompletion) });
});
const editWordWrap = ref(settingsStore.editorSettings.wordWrap);
const editShowWhitespace = ref(settingsStore.editorSettings.showWhitespace);
const editVimModeEnabled = ref(settingsStore.editorSettings.vimModeEnabled);
const editAutoCloseBrackets = ref(settingsStore.editorSettings.autoCloseBrackets);
const editSqlSemanticDiagnosticsMode = ref<SqlSemanticDiagnosticsMode>(settingsStore.editorSettings.sqlSemanticDiagnosticsMode);
@@ -913,6 +914,7 @@ function currentEditorSettingsDraft(): EditorSettingsDraft {
selectFirstCompletionOnOpen: editSelectFirstCompletionOnOpen.value,
completionTriggerMode: editCompletionTriggerMode.value,
wordWrap: editWordWrap.value,
showWhitespace: editShowWhitespace.value,
vimModeEnabled: editVimModeEnabled.value,
autoCloseBrackets: editAutoCloseBrackets.value,
sqlSemanticDiagnosticsMode: editSqlSemanticDiagnosticsMode.value,
@@ -1551,6 +1553,7 @@ function syncEditorSettingsDraftFromStore() {
editSelectFirstCompletionOnOpen.value = settingsStore.editorSettings.selectFirstCompletionOnOpen;
editCompletionTriggerMode.value = settingsStore.editorSettings.completionTriggerMode;
editWordWrap.value = settingsStore.editorSettings.wordWrap;
editShowWhitespace.value = settingsStore.editorSettings.showWhitespace;
editVimModeEnabled.value = settingsStore.editorSettings.vimModeEnabled;
editAutoCloseBrackets.value = settingsStore.editorSettings.autoCloseBrackets;
editSqlSemanticDiagnosticsMode.value = settingsStore.editorSettings.sqlSemanticDiagnosticsMode;
@@ -1681,6 +1684,7 @@ const editorSettingsDraftRefs: EditorSettingsDraftRefMap = {
sortCompletionColumnsAlphabetically: editSortCompletionColumnsAlphabetically,
selectFirstCompletionOnOpen: editSelectFirstCompletionOnOpen,
wordWrap: editWordWrap,
showWhitespace: editShowWhitespace,
vimModeEnabled: editVimModeEnabled,
autoCloseBrackets: editAutoCloseBrackets,
sqlSemanticDiagnosticsMode: editSqlSemanticDiagnosticsMode,
@@ -2126,6 +2130,7 @@ function resetDefaultsForTab(tab: SettingsCategory) {
editSelectFirstCompletionOnOpen.value = DEFAULT_EDITOR_SETTINGS.selectFirstCompletionOnOpen;
editCompletionTriggerMode.value = DEFAULT_EDITOR_SETTINGS.completionTriggerMode;
editWordWrap.value = DEFAULT_EDITOR_SETTINGS.wordWrap;
editShowWhitespace.value = DEFAULT_EDITOR_SETTINGS.showWhitespace;
editVimModeEnabled.value = DEFAULT_EDITOR_SETTINGS.vimModeEnabled;
editAutoCloseBrackets.value = DEFAULT_EDITOR_SETTINGS.autoCloseBrackets;
editSqlSemanticDiagnosticsMode.value = DEFAULT_EDITOR_SETTINGS.sqlSemanticDiagnosticsMode;
@@ -2271,6 +2276,7 @@ function resetAllDefaults() {
editSortCompletionColumnsAlphabetically.value = DEFAULT_EDITOR_SETTINGS.sortCompletionColumnsAlphabetically;
editSelectFirstCompletionOnOpen.value = DEFAULT_EDITOR_SETTINGS.selectFirstCompletionOnOpen;
editWordWrap.value = DEFAULT_EDITOR_SETTINGS.wordWrap;
editShowWhitespace.value = DEFAULT_EDITOR_SETTINGS.showWhitespace;
editVimModeEnabled.value = DEFAULT_EDITOR_SETTINGS.vimModeEnabled;
editAutoCloseBrackets.value = DEFAULT_EDITOR_SETTINGS.autoCloseBrackets;
editSqlSemanticDiagnosticsMode.value = DEFAULT_EDITOR_SETTINGS.sqlSemanticDiagnosticsMode;
@@ -6099,6 +6105,16 @@ onUnmounted(() => {
<Switch id="editor-show-insert-value-hints" v-model="editShowInsertValueHints" class="mt-0.5" />
</div>
<div class="settings-item flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
<div class="space-y-1">
<Label for="editor-show-whitespace">{{ t("settings.showWhitespace") }}</Label>
<p class="text-xs text-muted-foreground">
{{ t("settings.showWhitespaceDescription") }}
</p>
</div>
<Switch id="editor-show-whitespace" v-model="editShowWhitespace" class="mt-0.5" />
</div>
<div class="settings-item flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
<div class="space-y-1">
<Label for="editor-word-wrap">{{ t("settings.wordWrap") }}</Label>
@@ -163,6 +163,7 @@ import { createQueryEditorEscapeHandler } from "@/lib/editor/queryEditorEscape";
import { buildQueryEditorLineNumbersExtension, createQueryEditorLineNumberAlignmentExtension } from "@/lib/editor/queryEditorLineNumbers";
import { searchKeymapWithoutModD } from "@/lib/editor/codemirrorSearchKeymap";
import { defaultKeymapForGlobalShortcuts } from "@/lib/editor/codemirrorDefaultKeymap";
import { createShowWhitespaceExtension } from "@/lib/editor/codemirrorShowWhitespace";
import { appendSqlCompletionSpace } from "@/lib/editor/sqlCompletionInsertion";
import { batchColumnSelectionColumnList, batchColumnSelectionInsertReplacement, batchColumnSelectionReplaceTo, completionReplacementTo, isBatchColumnSelectionCompletionActive, shouldResolveSqlColumnCompletion } from "@/lib/editor/batchColumnSelection";
import { compareSqlCompletions, completionLabelPresentation } from "@/lib/editor/sqlCompletionPresentation";
@@ -701,6 +702,7 @@ let hoverCloseEffect: StateEffect<unknown> | null = null;
let fontThemeComp: import("@codemirror/state").Compartment | null = null;
let codeMirrorTheme: import("@codemirror/state").Compartment | null = null;
let wordWrapComp: import("@codemirror/state").Compartment | null = null;
let showWhitespaceComp: import("@codemirror/state").Compartment | null = null;
let lineNumbersComp: import("@codemirror/state").Compartment | null = null;
let vimModeComp: import("@codemirror/state").Compartment | null = null;
let closeBracketsComp: import("@codemirror/state").Compartment | null = null;
@@ -1022,6 +1024,7 @@ const queryEditorAppearanceSettings = computed(() => {
customThemes: settings.customThemes,
activeCustomThemeId: settings.activeCustomThemeId,
wordWrap: settings.wordWrap,
showWhitespace: settings.showWhitespace,
vimModeEnabled: settings.vimModeEnabled,
autoCloseBrackets: settings.autoCloseBrackets,
showLineNumbers: settings.showLineNumbers,
@@ -2782,6 +2785,11 @@ function wordWrapExtension() {
return props.forceWordWrap || settingsStore.editorSettings.wordWrap ? editorViewModule.EditorView.lineWrapping : [];
}
function showWhitespaceExtension(enabled = settingsStore.editorSettings.showWhitespace) {
if (!editorViewModule) return [];
return createShowWhitespaceExtension(editorViewModule, enabled);
}
function lineNumbersExtension(enabled = settingsStore.editorSettings.showLineNumbers) {
return buildQueryEditorLineNumbersExtension(codeMirrorLineNumbers, enabled, {
domEventHandlers: {
@@ -6307,6 +6315,8 @@ onMounted(async () => {
lineNumbers,
highlightActiveLineGutter,
highlightSpecialChars,
highlightWhitespace,
WidgetType,
drawSelection,
dropCursor,
crosshairCursor,
@@ -6343,6 +6353,10 @@ onMounted(async () => {
EditorView,
keymap,
rectangularSelection,
highlightWhitespace,
WidgetType,
Decoration,
ViewPlugin,
} as typeof import("@codemirror/view");
hoverCloseEffect = closeHoverTooltips;
codeMirrorLineNumbers = lineNumbers;
@@ -6352,6 +6366,7 @@ onMounted(async () => {
fontThemeComp = new Compartment();
codeMirrorTheme = new Compartment();
wordWrapComp = new Compartment();
showWhitespaceComp = new Compartment();
lineNumbersComp = new Compartment();
vimModeComp = new Compartment();
closeBracketsComp = new Compartment();
@@ -7083,6 +7098,7 @@ onMounted(async () => {
}),
),
wordWrapComp.of(props.forceWordWrap || initialSettings.wordWrap ? EditorView.lineWrapping : []),
showWhitespaceComp.of(showWhitespaceExtension(initialSettings.showWhitespace)),
readOnlyComp.of([EditorState.readOnly.of(!!props.readOnly), EditorView.editable.of(!props.readOnly)]),
indentComp.of(indentExtension()),
// Alt+drag belongs exclusively to rectangular selection. Registering the
@@ -7885,6 +7901,7 @@ async function applyEditorAppearance() {
effects: [
codeMirrorTheme.reconfigure(themeExt),
wordWrapComp.reconfigure(props.forceWordWrap || ss.wordWrap ? editorViewModule.EditorView.lineWrapping : []),
...(showWhitespaceComp ? [showWhitespaceComp.reconfigure(showWhitespaceExtension(ss.showWhitespace))] : []),
lineNumbersComp.reconfigure(lineNumbersExtension(ss.showLineNumbers)),
vimModeComp.reconfigure(vimModeExtension(settingsStore.editorSettings.vimModeEnabled)),
closeBracketsComp.reconfigure(closeBracketsExtension(settingsStore.editorSettings.autoCloseBrackets)),