feat(editor): add whitespace display toggle for SQL editor
This commit is contained in:
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)),
|
||||
|
||||
@@ -7415,6 +7415,8 @@ export default withEnglishFallback({
|
||||
previewStatementRunButton: "Əmri işlətmə düyməsinə önbaxış",
|
||||
wordWrap: "Sətirləri bük",
|
||||
wordWrapDescription: "Uzun sətirləri redaktorun eninə uyğun bük",
|
||||
showWhitespace: "Boşluq simvollarını göstər",
|
||||
showWhitespaceDescription: "SQL redaktorunda boşluqları ·, tabulyasiyaları → kimi göstərir. Yalnız görünüş dəyişir, SQL mətni dəyişmir.",
|
||||
vimMode: "Vim rejimi",
|
||||
vimModeDescription: "SQL redaktorunda Vim üslublu modal redaktədən istifadə et",
|
||||
autoCloseBrackets: "Mötərizələri avtomatik bağla",
|
||||
|
||||
@@ -7649,6 +7649,8 @@ export default {
|
||||
previewStatementRunButton: "Preview statement run button",
|
||||
wordWrap: "Word wrap",
|
||||
wordWrapDescription: "Wrap long lines within the editor width",
|
||||
showWhitespace: "Show whitespace",
|
||||
showWhitespaceDescription: "Show spaces as · and tabs as → in the SQL editor. Only the display changes, not the SQL text.",
|
||||
vimMode: "Vim mode",
|
||||
vimModeDescription: "Use Vim-style modal editing in the SQL editor",
|
||||
autoCloseBrackets: "Auto-close brackets",
|
||||
|
||||
@@ -7165,6 +7165,8 @@ export default withEnglishFallback({
|
||||
previewStatementRunButton: "Botón de ejecución de sentencia en vista previa",
|
||||
wordWrap: "Ajuste de línea",
|
||||
wordWrapDescription: "Ajustar las líneas largas al ancho del editor",
|
||||
showWhitespace: "Mostrar espacios en blanco",
|
||||
showWhitespaceDescription: "Mostrar espacios como · y tabulaciones como → en el editor SQL. Solo cambia la visualización, no el texto SQL.",
|
||||
vimMode: "Modo Vim",
|
||||
vimModeDescription: "Usar edición modal estilo Vim en el editor SQL",
|
||||
autoCloseBrackets: "Cerrar paréntesis automáticamente",
|
||||
|
||||
@@ -7165,6 +7165,8 @@ export default withEnglishFallback({
|
||||
previewStatementRunButton: "Pulsante di esecuzione istruzione in anteprima",
|
||||
wordWrap: "A capo automatico",
|
||||
wordWrapDescription: "Manda a capo le righe lunghe entro la larghezza dell'editor",
|
||||
showWhitespace: "Mostra spazi bianchi",
|
||||
showWhitespaceDescription: "Mostra gli spazi come · e le tabulazioni come → nell'editor SQL. Cambia solo la visualizzazione, non il testo SQL.",
|
||||
vimMode: "Modalita Vim",
|
||||
vimModeDescription: "Usa la modifica modale in stile Vim nell'editor SQL",
|
||||
autoCloseBrackets: "Chiusura automatica parentesi",
|
||||
|
||||
@@ -7189,6 +7189,8 @@ export default withEnglishFallback({
|
||||
previewStatementRunButton: "文の実行ボタンのプレビュー",
|
||||
wordWrap: "折り返し",
|
||||
wordWrapDescription: "長い行をエディタ幅内で折り返します",
|
||||
showWhitespace: "空白文字を表示",
|
||||
showWhitespaceDescription: "SQL エディタでスペースを ·、タブを → で表示します。表示のみ変わり、SQL テキストは変わりません。",
|
||||
vimMode: "Vimモード",
|
||||
vimModeDescription: "SQLエディタでVim形式のモーダル編集を使用します",
|
||||
autoCloseBrackets: "自動括弧補完",
|
||||
|
||||
@@ -6941,6 +6941,8 @@ export default withEnglishFallback({
|
||||
previewStatementRunButton: "구문 실행 버튼 미리보기",
|
||||
wordWrap: "자동 줄바꿈",
|
||||
wordWrapDescription: "편집기 너비 내에서 긴 줄을 줄바꿈합니다",
|
||||
showWhitespace: "공백 문자 표시",
|
||||
showWhitespaceDescription: "SQL 편집기에서 공백을 ·, 탭을 →로 표시합니다. 표시만 바뀌며 SQL 텍스트는 변경되지 않습니다.",
|
||||
vimMode: "Vim 모드",
|
||||
vimModeDescription: "SQL 편집기에서 Vim 스타일의 모달 편집을 사용합니다",
|
||||
autoCloseBrackets: "괄호 자동 닫기",
|
||||
|
||||
@@ -7167,6 +7167,8 @@ export default withEnglishFallback({
|
||||
previewStatementRunButton: "Botão de execução de instrução na prévia",
|
||||
wordWrap: "Quebra de linha",
|
||||
wordWrapDescription: "Quebrar linhas longas dentro da largura do editor",
|
||||
showWhitespace: "Mostrar espaços em branco",
|
||||
showWhitespaceDescription: "Mostrar espaços como · e tabulações como → no editor SQL. Altera apenas a exibição, não o texto SQL.",
|
||||
vimMode: "Modo Vim",
|
||||
vimModeDescription: "Usar edição modal no estilo Vim no editor SQL",
|
||||
autoCloseBrackets: "Fechar parênteses automaticamente",
|
||||
|
||||
@@ -7296,6 +7296,8 @@ export default withEnglishFallback({
|
||||
previewStatementRunButton: "İfade çalıştırma düğmesini önizle",
|
||||
wordWrap: "Sözcük kaydırma",
|
||||
wordWrapDescription: "Uzun satırları düzenleyici genişliğinde kaydır",
|
||||
showWhitespace: "Boşluk karakterlerini göster",
|
||||
showWhitespaceDescription: "SQL düzenleyicide boşlukları ·, sekmeleri → olarak gösterir. Yalnızca görünüm değişir, SQL metni değişmez.",
|
||||
vimMode: "Vim modu",
|
||||
vimModeDescription: "SQL düzenleyicisinde Vim biçemli kipli düzenleme kullan",
|
||||
autoCloseBrackets: "Parantezleri otomatik kapat",
|
||||
|
||||
@@ -7620,6 +7620,8 @@ export default withEnglishFallback({
|
||||
previewStatementRunButton: "预览语句执行按钮",
|
||||
wordWrap: "自动换行",
|
||||
wordWrapDescription: "长内容在编辑器宽度内自动折行显示",
|
||||
showWhitespace: "显示空白字符",
|
||||
showWhitespaceDescription: "在 SQL 编辑器中将空格显示为 ·,制表符显示为 →。仅影响显示,不改变 SQL 文本。",
|
||||
vimMode: "Vim 模式",
|
||||
vimModeDescription: "在 SQL 编辑器中使用 Vim 风格的模态编辑",
|
||||
autoCloseBrackets: "自动成对补全",
|
||||
|
||||
@@ -6489,6 +6489,8 @@ export default withEnglishFallback({
|
||||
previewStatementRunButton: "預覽語句執行按鈕",
|
||||
wordWrap: "自動換行",
|
||||
wordWrapDescription: "長內容在編輯器寬度內自動折行顯示",
|
||||
showWhitespace: "顯示空白字元",
|
||||
showWhitespaceDescription: "在 SQL 編輯器中將空格顯示為 ·,定位字元顯示為 →。僅影響顯示,不改變 SQL 文字。",
|
||||
vimMode: "Vim 模式",
|
||||
vimModeDescription: "在 SQL 編輯器中使用 Vim 風格的模態編輯",
|
||||
autoCloseBrackets: "自動成對補全",
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// @vitest-environment happy-dom
|
||||
import { EditorState } from "@codemirror/state";
|
||||
import * as viewModule from "@codemirror/view";
|
||||
import { EditorView } from "@codemirror/view";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { NEWLINE_MARKER, NEWLINE_MARKER_CLASS, createShowWhitespaceExtension } from "@/lib/editor/codemirrorShowWhitespace";
|
||||
|
||||
let view: EditorView | null = null;
|
||||
|
||||
function mount(doc: string, enabled: boolean) {
|
||||
const parent = document.createElement("div");
|
||||
document.body.appendChild(parent);
|
||||
view = new EditorView({ parent, state: EditorState.create({ doc, extensions: [createShowWhitespaceExtension(viewModule, enabled)] }) });
|
||||
return view;
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
view?.destroy();
|
||||
view = null;
|
||||
document.body.innerHTML = "";
|
||||
});
|
||||
|
||||
describe("createShowWhitespaceExtension", () => {
|
||||
it("adds nothing when disabled", () => {
|
||||
expect(createShowWhitespaceExtension(viewModule, false)).toEqual([]);
|
||||
const v = mount("select 1\n\tfrom t", false);
|
||||
expect(v.dom.querySelectorAll(`.${NEWLINE_MARKER_CLASS}`)).toHaveLength(0);
|
||||
expect(v.dom.querySelector(".cm-highlightSpace, .cm-highlightTab")).toBeNull();
|
||||
});
|
||||
|
||||
it("marks a line break after every line except the last", () => {
|
||||
const v = mount("select 1\n\tfrom t\nwhere x", true);
|
||||
const markers = v.dom.querySelectorAll(`.${NEWLINE_MARKER_CLASS}`);
|
||||
expect(markers).toHaveLength(2);
|
||||
expect(markers[0]!.textContent).toBe(NEWLINE_MARKER);
|
||||
});
|
||||
|
||||
it("marks spaces and tabs and never changes the document text", () => {
|
||||
const doc = "select 1\n\tfrom t";
|
||||
const v = mount(doc, true);
|
||||
expect(v.dom.querySelector(".cm-highlightSpace")).not.toBeNull();
|
||||
expect(v.dom.querySelector(".cm-highlightTab")).not.toBeNull();
|
||||
expect(v.state.doc.toString()).toBe(doc);
|
||||
});
|
||||
|
||||
it("keeps marking empty lines and follows edits", () => {
|
||||
const v = mount("a\n\nb", true);
|
||||
expect(v.dom.querySelectorAll(`.${NEWLINE_MARKER_CLASS}`)).toHaveLength(2);
|
||||
v.dispatch({ changes: { from: v.state.doc.length, insert: "\nc" } });
|
||||
expect(v.dom.querySelectorAll(`.${NEWLINE_MARKER_CLASS}`)).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
import type { Extension } from "@codemirror/state";
|
||||
|
||||
type ViewModule = typeof import("@codemirror/view");
|
||||
type EditorViewType = import("@codemirror/view").EditorView;
|
||||
type DecorationSet = import("@codemirror/view").DecorationSet;
|
||||
|
||||
export const NEWLINE_MARKER = "↵";
|
||||
export const NEWLINE_MARKER_CLASS = "cm-dbx-newline-marker";
|
||||
|
||||
/**
|
||||
* Display-only whitespace markers for the SQL editor: spaces as "·", tabs as "→"
|
||||
* (CodeMirror's highlightWhitespace) plus a "↵" at every line end that is followed
|
||||
* by a line break. The document text itself is never touched.
|
||||
*/
|
||||
export function createShowWhitespaceExtension(view: Pick<ViewModule, "highlightWhitespace" | "ViewPlugin" | "Decoration" | "WidgetType" | "EditorView">, enabled: boolean): Extension {
|
||||
if (!enabled) return [];
|
||||
const { highlightWhitespace, ViewPlugin, Decoration, WidgetType, EditorView } = view;
|
||||
|
||||
class NewlineMarkerWidget extends WidgetType {
|
||||
eq(): boolean {
|
||||
return true;
|
||||
}
|
||||
toDOM(): HTMLElement {
|
||||
const el = document.createElement("span");
|
||||
el.className = NEWLINE_MARKER_CLASS;
|
||||
el.setAttribute("aria-hidden", "true");
|
||||
el.textContent = NEWLINE_MARKER;
|
||||
return el;
|
||||
}
|
||||
ignoreEvent(): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
const marker = Decoration.widget({ widget: new NewlineMarkerWidget(), side: 1 });
|
||||
|
||||
function buildDecorations(editorView: EditorViewType): DecorationSet {
|
||||
const doc = editorView.state.doc;
|
||||
const ranges = [];
|
||||
let lastLine = -1;
|
||||
for (const { from, to } of editorView.visibleRanges) {
|
||||
for (let pos = from; pos <= to; ) {
|
||||
const line = doc.lineAt(pos);
|
||||
if (line.number !== lastLine) {
|
||||
lastLine = line.number;
|
||||
if (line.number < doc.lines) ranges.push(marker.range(line.to));
|
||||
}
|
||||
pos = line.to + 1;
|
||||
}
|
||||
}
|
||||
return Decoration.set(ranges);
|
||||
}
|
||||
|
||||
const newlinePlugin = ViewPlugin.fromClass(
|
||||
class {
|
||||
decorations: DecorationSet;
|
||||
constructor(editorView: EditorViewType) {
|
||||
this.decorations = buildDecorations(editorView);
|
||||
}
|
||||
update(update: import("@codemirror/view").ViewUpdate) {
|
||||
if (update.docChanged || update.viewportChanged) this.decorations = buildDecorations(update.view);
|
||||
}
|
||||
},
|
||||
{ decorations: (plugin) => plugin.decorations },
|
||||
);
|
||||
|
||||
const markerTheme = EditorView.baseTheme({
|
||||
[`.${NEWLINE_MARKER_CLASS}`]: { opacity: "0.35", pointerEvents: "none", userSelect: "none" },
|
||||
});
|
||||
|
||||
return [highlightWhitespace(), newlinePlugin, markerTheme];
|
||||
}
|
||||
@@ -30,6 +30,7 @@ export const EDITOR_SETTINGS_DRAFT_KEYS = [
|
||||
"sortCompletionColumnsAlphabetically",
|
||||
"selectFirstCompletionOnOpen",
|
||||
"wordWrap",
|
||||
"showWhitespace",
|
||||
"vimModeEnabled",
|
||||
"autoCloseBrackets",
|
||||
"sqlSemanticDiagnosticsMode",
|
||||
|
||||
@@ -128,6 +128,7 @@ export const SETTINGS_SEARCH_DEFINITIONS: readonly SettingsSearchDefinition[] =
|
||||
{ id: "editor-line-numbers", category: "editor", titleKey: "settings.showLineNumbers", descriptionKey: "settings.showLineNumbersDescription", targetId: "editor" },
|
||||
{ id: "editor-statement-frame", category: "editor", titleKey: "settings.showCurrentStatementFrame", descriptionKey: "settings.showCurrentStatementFrameDescription", targetId: "editor" },
|
||||
{ id: "editor-value-hints", category: "editor", titleKey: "settings.showInsertValueHints", descriptionKey: "settings.showInsertValueHintsDescription", targetId: "editor" },
|
||||
{ id: "editor-show-whitespace", category: "editor", titleKey: "settings.showWhitespace", descriptionKey: "settings.showWhitespaceDescription", targetId: "editor" },
|
||||
{ id: "editor-word-wrap", category: "editor", titleKey: "settings.wordWrap", descriptionKey: "settings.wordWrapDescription", targetId: "editor" },
|
||||
{ id: "editor-vim", category: "editor", titleKey: "settings.vimMode", descriptionKey: "settings.vimModeDescription", targetId: "editor" },
|
||||
{ id: "editor-brackets", category: "editor", titleKey: "settings.autoCloseBrackets", descriptionKey: "settings.autoCloseBracketsDescription", targetId: "editor" },
|
||||
|
||||
@@ -88,6 +88,7 @@ const SETTINGS_TRANSFER_CATEGORY_KEYS: Record<SettingsTransferCategoryId, readon
|
||||
"selectFirstCompletionOnOpen",
|
||||
"completionTriggerMode",
|
||||
"wordWrap",
|
||||
"showWhitespace",
|
||||
"vimModeEnabled",
|
||||
"autoCloseBrackets",
|
||||
"sqlSemanticDiagnosticsMode",
|
||||
@@ -255,6 +256,7 @@ const EXPECTED_JSON_KINDS = new Map<string, string>(EDITOR_SETTINGS_DRAFT_KEYS.m
|
||||
*/
|
||||
const PASS_THROUGH_BOOLEAN_KEYS = [
|
||||
"wordWrap",
|
||||
"showWhitespace",
|
||||
"showExecutionTargetPicker",
|
||||
"autoAliasTables",
|
||||
"confirmDangerousSqlExecution",
|
||||
|
||||
@@ -775,6 +775,7 @@ export interface EditorSettings {
|
||||
sortCompletionColumnsAlphabetically: boolean;
|
||||
selectFirstCompletionOnOpen: boolean;
|
||||
wordWrap: boolean;
|
||||
showWhitespace: boolean;
|
||||
tableDdlWordWrap: boolean;
|
||||
refreshDdlOnOpen: boolean;
|
||||
excludeDdlStorage: boolean;
|
||||
@@ -1033,6 +1034,7 @@ export const DEFAULT_EDITOR_SETTINGS: EditorSettings = {
|
||||
sortCompletionColumnsAlphabetically: true,
|
||||
selectFirstCompletionOnOpen: true,
|
||||
wordWrap: false,
|
||||
showWhitespace: false,
|
||||
tableDdlWordWrap: true,
|
||||
refreshDdlOnOpen: false,
|
||||
excludeDdlStorage: true,
|
||||
@@ -1538,6 +1540,7 @@ export function normalizeEditorSettings(settings: Partial<EditorSettings>, exist
|
||||
sortCompletionColumnsAlphabetically: typeof settings.sortCompletionColumnsAlphabetically === "boolean" ? settings.sortCompletionColumnsAlphabetically : DEFAULT_EDITOR_SETTINGS.sortCompletionColumnsAlphabetically,
|
||||
selectFirstCompletionOnOpen: typeof settings.selectFirstCompletionOnOpen === "boolean" ? settings.selectFirstCompletionOnOpen : DEFAULT_EDITOR_SETTINGS.selectFirstCompletionOnOpen,
|
||||
wordWrap: settings.wordWrap ?? DEFAULT_EDITOR_SETTINGS.wordWrap,
|
||||
showWhitespace: typeof settings.showWhitespace === "boolean" ? settings.showWhitespace : DEFAULT_EDITOR_SETTINGS.showWhitespace,
|
||||
tableDdlWordWrap: typeof settings.tableDdlWordWrap === "boolean" ? settings.tableDdlWordWrap : DEFAULT_EDITOR_SETTINGS.tableDdlWordWrap,
|
||||
excludeDdlStorage: typeof settings.excludeDdlStorage === "boolean" ? settings.excludeDdlStorage : DEFAULT_EDITOR_SETTINGS.excludeDdlStorage,
|
||||
refreshDdlOnOpen: typeof settings.refreshDdlOnOpen === "boolean" ? settings.refreshDdlOnOpen : DEFAULT_EDITOR_SETTINGS.refreshDdlOnOpen,
|
||||
@@ -2315,6 +2318,7 @@ export const useSettingsStore = defineStore("settings", () => {
|
||||
if (partial.sortCompletionColumnsAlphabetically !== undefined) editorSettings.value.sortCompletionColumnsAlphabetically = partial.sortCompletionColumnsAlphabetically === true;
|
||||
if (partial.selectFirstCompletionOnOpen !== undefined) editorSettings.value.selectFirstCompletionOnOpen = partial.selectFirstCompletionOnOpen === true;
|
||||
if (partial.wordWrap !== undefined) editorSettings.value.wordWrap = partial.wordWrap;
|
||||
if (partial.showWhitespace !== undefined) editorSettings.value.showWhitespace = partial.showWhitespace === true;
|
||||
if (partial.tableDdlWordWrap !== undefined) editorSettings.value.tableDdlWordWrap = partial.tableDdlWordWrap === true;
|
||||
if (partial.excludeDdlStorage !== undefined) editorSettings.value.excludeDdlStorage = partial.excludeDdlStorage === true;
|
||||
if (partial.refreshDdlOnOpen !== undefined) editorSettings.value.refreshDdlOnOpen = partial.refreshDdlOnOpen === true;
|
||||
|
||||
Reference in new issue
Block a user