mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-02 02:34:42 +08:00
feat(editor): add double-click string selection mode option
This commit is contained in:
@@ -664,6 +664,7 @@ const editWordWrap = ref(settingsStore.editorSettings.wordWrap);
|
||||
const editShowWhitespace = ref(settingsStore.editorSettings.showWhitespace);
|
||||
const editDdlOpenMode = ref<EditorSettings["ddlOpenMode"]>(settingsStore.editorSettings.ddlOpenMode);
|
||||
const editVimModeEnabled = ref(settingsStore.editorSettings.vimModeEnabled);
|
||||
const editDoubleClickStringSelectionMode = ref<EditorSettings["doubleClickStringSelectionMode"]>(settingsStore.editorSettings.doubleClickStringSelectionMode);
|
||||
const editAutoCloseBrackets = ref(settingsStore.editorSettings.autoCloseBrackets);
|
||||
const editSqlSemanticDiagnosticsMode = ref<SqlSemanticDiagnosticsMode>(settingsStore.editorSettings.sqlSemanticDiagnosticsMode);
|
||||
const editSqlSemanticDiagnosticsEnabled = ref(settingsStore.editorSettings.sqlSemanticDiagnosticsEnabled);
|
||||
@@ -1024,6 +1025,7 @@ function currentEditorSettingsDraft(): EditorSettingsDraft {
|
||||
showWhitespace: editShowWhitespace.value,
|
||||
ddlOpenMode: editDdlOpenMode.value,
|
||||
vimModeEnabled: editVimModeEnabled.value,
|
||||
doubleClickStringSelectionMode: editDoubleClickStringSelectionMode.value,
|
||||
autoCloseBrackets: editAutoCloseBrackets.value,
|
||||
sqlSemanticDiagnosticsMode: editSqlSemanticDiagnosticsMode.value,
|
||||
confirmDangerousSqlExecution: editConfirmDangerousSqlExecution.value,
|
||||
@@ -1684,6 +1686,7 @@ function syncEditorSettingsDraftFromStore() {
|
||||
editShowWhitespace.value = settingsStore.editorSettings.showWhitespace;
|
||||
editDdlOpenMode.value = settingsStore.editorSettings.ddlOpenMode;
|
||||
editVimModeEnabled.value = settingsStore.editorSettings.vimModeEnabled;
|
||||
editDoubleClickStringSelectionMode.value = settingsStore.editorSettings.doubleClickStringSelectionMode;
|
||||
editAutoCloseBrackets.value = settingsStore.editorSettings.autoCloseBrackets;
|
||||
editSqlSemanticDiagnosticsMode.value = settingsStore.editorSettings.sqlSemanticDiagnosticsMode;
|
||||
editSqlSemanticDiagnosticsEnabled.value = settingsStore.editorSettings.sqlSemanticDiagnosticsEnabled;
|
||||
@@ -1822,6 +1825,7 @@ const editorSettingsDraftRefs: EditorSettingsDraftRefMap = {
|
||||
showWhitespace: editShowWhitespace,
|
||||
ddlOpenMode: editDdlOpenMode,
|
||||
vimModeEnabled: editVimModeEnabled,
|
||||
doubleClickStringSelectionMode: editDoubleClickStringSelectionMode,
|
||||
autoCloseBrackets: editAutoCloseBrackets,
|
||||
sqlSemanticDiagnosticsMode: editSqlSemanticDiagnosticsMode,
|
||||
confirmDangerousSqlExecution: editConfirmDangerousSqlExecution,
|
||||
@@ -2312,6 +2316,7 @@ function resetDefaultsForTab(tab: SettingsCategory) {
|
||||
editShowWhitespace.value = DEFAULT_EDITOR_SETTINGS.showWhitespace;
|
||||
editDdlOpenMode.value = DEFAULT_EDITOR_SETTINGS.ddlOpenMode;
|
||||
editVimModeEnabled.value = DEFAULT_EDITOR_SETTINGS.vimModeEnabled;
|
||||
editDoubleClickStringSelectionMode.value = DEFAULT_EDITOR_SETTINGS.doubleClickStringSelectionMode;
|
||||
editAutoCloseBrackets.value = DEFAULT_EDITOR_SETTINGS.autoCloseBrackets;
|
||||
editSqlSemanticDiagnosticsMode.value = DEFAULT_EDITOR_SETTINGS.sqlSemanticDiagnosticsMode;
|
||||
editSqlSemanticDiagnosticsEnabled.value = DEFAULT_EDITOR_SETTINGS.sqlSemanticDiagnosticsEnabled;
|
||||
@@ -2470,6 +2475,7 @@ function resetAllDefaults() {
|
||||
editShowWhitespace.value = DEFAULT_EDITOR_SETTINGS.showWhitespace;
|
||||
editDdlOpenMode.value = DEFAULT_EDITOR_SETTINGS.ddlOpenMode;
|
||||
editVimModeEnabled.value = DEFAULT_EDITOR_SETTINGS.vimModeEnabled;
|
||||
editDoubleClickStringSelectionMode.value = DEFAULT_EDITOR_SETTINGS.doubleClickStringSelectionMode;
|
||||
editAutoCloseBrackets.value = DEFAULT_EDITOR_SETTINGS.autoCloseBrackets;
|
||||
editSqlSemanticDiagnosticsMode.value = DEFAULT_EDITOR_SETTINGS.sqlSemanticDiagnosticsMode;
|
||||
editSqlSemanticDiagnosticsEnabled.value = DEFAULT_EDITOR_SETTINGS.sqlSemanticDiagnosticsEnabled;
|
||||
@@ -2869,6 +2875,10 @@ function setDdlOpenMode(value: unknown) {
|
||||
if (value === "dialog" || value === "tab") editDdlOpenMode.value = value;
|
||||
}
|
||||
|
||||
function setDoubleClickStringSelectionMode(value: unknown) {
|
||||
if (value === "content" || value === "word") editDoubleClickStringSelectionMode.value = value;
|
||||
}
|
||||
|
||||
function setIconTheme(value: DesktopIconTheme) {
|
||||
editIconTheme.value = value;
|
||||
}
|
||||
@@ -6605,6 +6615,22 @@ onUnmounted(() => {
|
||||
</Select>
|
||||
</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-double-click-string">{{ t("settings.doubleClickStringSelectionMode") }}</Label>
|
||||
<p class="text-xs text-muted-foreground">{{ t("settings.doubleClickStringSelectionModeDescription") }}</p>
|
||||
</div>
|
||||
<Select :model-value="editDoubleClickStringSelectionMode" @update:model-value="setDoubleClickStringSelectionMode">
|
||||
<SelectTrigger id="editor-double-click-string" class="h-8 w-36 shrink-0">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="content">{{ t("settings.doubleClickStringSelectionModeContent") }}</SelectItem>
|
||||
<SelectItem value="word">{{ t("settings.doubleClickStringSelectionModeWord") }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</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-vim-mode">{{ t("settings.vimMode") }}</Label>
|
||||
|
||||
@@ -1909,6 +1909,7 @@ const codeMirrorLifecycle = useQueryEditorCodeMirror({
|
||||
dialect: sqlBehaviorDialect(),
|
||||
language: queryEditorSelectionLanguage(),
|
||||
composing: isEditorComposing(currentView),
|
||||
selectStringContent: settingsStore.editorSettings.doubleClickStringSelectionMode !== "word",
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import az from "../locales/az";
|
||||
import en from "../locales/en";
|
||||
import es from "../locales/es";
|
||||
import it_ from "../locales/it";
|
||||
import ja from "../locales/ja";
|
||||
import ko from "../locales/ko";
|
||||
import ptBR from "../locales/pt-BR";
|
||||
import ru from "../locales/ru";
|
||||
import tr from "../locales/tr";
|
||||
import zhCN from "../locales/zh-CN";
|
||||
import zhTW from "../locales/zh-TW";
|
||||
|
||||
const locales: Array<[string, Record<string, unknown>]> = [
|
||||
["az", az],
|
||||
["en", en],
|
||||
["es", es],
|
||||
["it", it_],
|
||||
["ja", ja],
|
||||
["ko", ko],
|
||||
["pt-BR", ptBR],
|
||||
["ru", ru],
|
||||
["tr", tr],
|
||||
["zh-CN", zhCN],
|
||||
["zh-TW", zhTW],
|
||||
];
|
||||
|
||||
// The editor settings page renders in whatever locale the user runs, so a
|
||||
// missing key would show a raw key on the "double click inside a string" row.
|
||||
const DOUBLE_CLICK_STRING_KEYS = ["doubleClickStringSelectionMode", "doubleClickStringSelectionModeDescription", "doubleClickStringSelectionModeContent", "doubleClickStringSelectionModeWord"] as const;
|
||||
|
||||
describe("double-click string selection locale parity", () => {
|
||||
it.each(locales)("%s exposes the double-click string copy", (_name, locale) => {
|
||||
const settings = (locale as { settings: Record<string, unknown> }).settings;
|
||||
for (const key of DOUBLE_CLICK_STRING_KEYS) {
|
||||
expect(settings[key], `${_name}: settings.${key}`).toBeTypeOf("string");
|
||||
expect(settings[key] as string, `${_name}: settings.${key}`).not.toHaveLength(0);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -7690,6 +7690,10 @@ export default withEnglishFallback({
|
||||
ddlOpenModeDescription: "Cədvəlin DDL-inə baxarkən standart olaraq dialoqun, yoxsa yeni vərəqin açılacağını seçin",
|
||||
ddlOpenModeDialog: "Dialoq (standart)",
|
||||
ddlOpenModeTab: "Yeni vərəq",
|
||||
doubleClickStringSelectionMode: "Sətir daxilində ikiqat klik",
|
||||
doubleClickStringSelectionModeDescription: "Sətir literalı daxilində ikiqat klik edildikdə bütün dəyərin, yoxsa yalnız kursorun altındakı sözün seçiləcəyini təyin edir",
|
||||
doubleClickStringSelectionModeContent: "Bütün dəyəri seç (standart)",
|
||||
doubleClickStringSelectionModeWord: "Yalnız sözü seç",
|
||||
vimMode: "Vim rejimi",
|
||||
vimModeDescription: "SQL redaktorunda Vim üslublu modal redaktədən istifadə et",
|
||||
autoCloseBrackets: "Mötərizələri avtomatik bağla",
|
||||
|
||||
@@ -8384,6 +8384,10 @@ export default {
|
||||
ddlOpenModeDescription: "Choose whether viewing table DDL opens a dialog or a new tab by default",
|
||||
ddlOpenModeDialog: "Dialog (default)",
|
||||
ddlOpenModeTab: "New tab",
|
||||
doubleClickStringSelectionMode: "Double-click inside a string",
|
||||
doubleClickStringSelectionModeDescription: "Choose whether double-clicking inside a string literal selects the whole string value or only the word under the cursor",
|
||||
doubleClickStringSelectionModeContent: "Select whole value (default)",
|
||||
doubleClickStringSelectionModeWord: "Select single word",
|
||||
vimMode: "Vim mode",
|
||||
vimModeDescription: "Use Vim-style modal editing in the SQL editor",
|
||||
autoCloseBrackets: "Auto-close brackets",
|
||||
|
||||
@@ -7702,6 +7702,10 @@ export default withEnglishFallback({
|
||||
ddlOpenModeDescription: "Elige si, al ver el DDL de una tabla, se abre un diálogo o una pestaña nueva de forma predeterminada",
|
||||
ddlOpenModeDialog: "Diálogo (predeterminado)",
|
||||
ddlOpenModeTab: "Nueva pestaña",
|
||||
doubleClickStringSelectionMode: "Doble clic dentro de una cadena",
|
||||
doubleClickStringSelectionModeDescription: "Elige si al hacer doble clic dentro de un literal de cadena se selecciona todo el valor o solo la palabra bajo el cursor",
|
||||
doubleClickStringSelectionModeContent: "Seleccionar todo el valor (predeterminado)",
|
||||
doubleClickStringSelectionModeWord: "Seleccionar una sola palabra",
|
||||
vimMode: "Modo Vim",
|
||||
vimModeDescription: "Usar edición modal estilo Vim en el editor SQL",
|
||||
autoCloseBrackets: "Cerrar paréntesis automáticamente",
|
||||
|
||||
@@ -7627,6 +7627,10 @@ export default withEnglishFallback({
|
||||
ddlOpenModeDescription: "Scegli se la visualizzazione del DDL di una tabella si apre per impostazione predefinita in una finestra di dialogo o in una nuova scheda",
|
||||
ddlOpenModeDialog: "Finestra di dialogo (predefinita)",
|
||||
ddlOpenModeTab: "Nuova scheda",
|
||||
doubleClickStringSelectionMode: "Doppio clic dentro una stringa",
|
||||
doubleClickStringSelectionModeDescription: "Scegli se il doppio clic all'interno di un letterale stringa seleziona l'intero valore o solo la parola sotto il cursore",
|
||||
doubleClickStringSelectionModeContent: "Seleziona l'intero valore (predefinito)",
|
||||
doubleClickStringSelectionModeWord: "Seleziona solo la parola",
|
||||
vimMode: "Modalita Vim",
|
||||
vimModeDescription: "Usa la modifica modale in stile Vim nell'editor SQL",
|
||||
autoCloseBrackets: "Chiusura automatica parentesi",
|
||||
|
||||
@@ -7643,6 +7643,10 @@ export default withEnglishFallback({
|
||||
ddlOpenModeDescription: "テーブルのDDLを表示するとき、ダイアログと新しいタブのどちらを既定にするか選択します",
|
||||
ddlOpenModeDialog: "ダイアログ(既定)",
|
||||
ddlOpenModeTab: "新しいタブ",
|
||||
doubleClickStringSelectionMode: "文字列のダブルクリック",
|
||||
doubleClickStringSelectionModeDescription: "SQL エディターで文字列リテラルをダブルクリックしたとき、文字列全体を選択するか、カーソル位置の単語だけを選択するかを選びます",
|
||||
doubleClickStringSelectionModeContent: "文字列全体を選択(既定)",
|
||||
doubleClickStringSelectionModeWord: "単語だけを選択",
|
||||
vimMode: "Vimモード",
|
||||
vimModeDescription: "SQLエディタでVim形式のモーダル編集を使用します",
|
||||
autoCloseBrackets: "自動括弧補完",
|
||||
|
||||
@@ -7417,6 +7417,10 @@ export default withEnglishFallback({
|
||||
ddlOpenModeDescription: "테이블 DDL을 볼 때 대화상자와 새 탭 중 기본 열기 방식을 선택합니다",
|
||||
ddlOpenModeDialog: "대화상자 (기본값)",
|
||||
ddlOpenModeTab: "새 탭",
|
||||
doubleClickStringSelectionMode: "문자열 더블 클릭",
|
||||
doubleClickStringSelectionModeDescription: "SQL 편집기에서 문자열 리터럴을 더블 클릭했을 때 문자열 전체를 선택할지, 커서 위치의 단어만 선택할지 정합니다",
|
||||
doubleClickStringSelectionModeContent: "전체 문자열 선택(기본)",
|
||||
doubleClickStringSelectionModeWord: "단어만 선택",
|
||||
vimMode: "Vim 모드",
|
||||
vimModeDescription: "SQL 편집기에서 Vim 스타일의 모달 편집을 사용합니다",
|
||||
autoCloseBrackets: "괄호 자동 닫기",
|
||||
|
||||
@@ -7628,6 +7628,10 @@ export default withEnglishFallback({
|
||||
ddlOpenModeDescription: "Escolha se a visualização do DDL de uma tabela abre em um diálogo ou em uma nova aba por padrão",
|
||||
ddlOpenModeDialog: "Diálogo (padrão)",
|
||||
ddlOpenModeTab: "Nova aba",
|
||||
doubleClickStringSelectionMode: "Duplo clique dentro de uma string",
|
||||
doubleClickStringSelectionModeDescription: "Escolha se o duplo clique dentro de um literal de string seleciona o valor inteiro ou apenas a palavra sob o cursor",
|
||||
doubleClickStringSelectionModeContent: "Selecionar o valor inteiro (padrão)",
|
||||
doubleClickStringSelectionModeWord: "Selecionar apenas a palavra",
|
||||
vimMode: "Modo Vim",
|
||||
vimModeDescription: "Usar edição modal no estilo Vim no editor SQL",
|
||||
autoCloseBrackets: "Fechar parênteses automaticamente",
|
||||
|
||||
@@ -8887,6 +8887,10 @@ export default withEnglishFallback({
|
||||
vimModeDescription: "Использовать модальное редактирование в стиле Vim в SQL-редакторе",
|
||||
autoCloseBrackets: "Автозакрытие скобок",
|
||||
autoCloseBracketsDescription: "Автоматически вставлять закрывающие скобки и кавычки при вводе открывающих",
|
||||
doubleClickStringSelectionMode: "Двойной щелчок внутри строки",
|
||||
doubleClickStringSelectionModeDescription: "Выберите, что выделять двойным щелчком внутри строкового литерала: всё значение целиком или только слово под курсором",
|
||||
doubleClickStringSelectionModeContent: "Выделять всё значение (по умолчанию)",
|
||||
doubleClickStringSelectionModeWord: "Выделять только слово",
|
||||
sqlCompletionSection: "Автодополнение SQL",
|
||||
insertSpaceAfterCompletion: "Вставлять пробел после автодополнения",
|
||||
insertSpaceAfterCompletionDescription: "Добавлять пробел после принятия автодополнения ключевого слова, таблицы или столбца, если следующий символ это позволяет",
|
||||
|
||||
@@ -7586,6 +7586,10 @@ export default withEnglishFallback({
|
||||
ddlOpenModeDescription: "Tablo DDL'sini görüntülerken varsayılan olarak iletişim kutusunun mu yoksa yeni sekmenin mi açılacağını seçin",
|
||||
ddlOpenModeDialog: "İletişim kutusu (varsayılan)",
|
||||
ddlOpenModeTab: "Yeni sekme",
|
||||
doubleClickStringSelectionMode: "Dize içinde çift tıklama",
|
||||
doubleClickStringSelectionModeDescription: "Bir dize değişmezi içinde çift tıklandığında tüm değerin mi yoksa yalnızca imlecin altındaki sözcüğün mü seçileceğini belirler",
|
||||
doubleClickStringSelectionModeContent: "Tüm değeri seç (varsayılan)",
|
||||
doubleClickStringSelectionModeWord: "Yalnızca sözcüğü seç",
|
||||
vimMode: "Vim modu",
|
||||
vimModeDescription: "SQL düzenleyicisinde Vim biçemli kipli düzenleme kullan",
|
||||
autoCloseBrackets: "Parantezleri otomatik kapat",
|
||||
|
||||
@@ -8347,6 +8347,10 @@ export default withEnglishFallback({
|
||||
ddlOpenModeDescription: "设置查看所有表 DDL 时默认使用弹框还是新标签",
|
||||
ddlOpenModeDialog: "弹框(默认)",
|
||||
ddlOpenModeTab: "新标签",
|
||||
doubleClickStringSelectionMode: "双击字符串时选中",
|
||||
doubleClickStringSelectionModeDescription: "在 SQL 编辑器中双击字符串时,选择整段字符串内容,还是只选择双击处的单词",
|
||||
doubleClickStringSelectionModeContent: "选中整段内容(默认)",
|
||||
doubleClickStringSelectionModeWord: "只选中单词",
|
||||
vimMode: "Vim 模式",
|
||||
vimModeDescription: "在 SQL 编辑器中使用 Vim 风格的模态编辑",
|
||||
autoCloseBrackets: "自动成对补全",
|
||||
|
||||
@@ -6943,6 +6943,10 @@ export default withEnglishFallback({
|
||||
ddlOpenModeDescription: "設定檢視資料表 DDL 時,預設以對話框或新標籤開啟",
|
||||
ddlOpenModeDialog: "對話框(預設)",
|
||||
ddlOpenModeTab: "新標籤",
|
||||
doubleClickStringSelectionMode: "雙擊字串時選取",
|
||||
doubleClickStringSelectionModeDescription: "在 SQL 編輯器中雙擊字串時,要選取整段字串內容,還是只選取雙擊處的單詞",
|
||||
doubleClickStringSelectionModeContent: "選取整段內容(預設)",
|
||||
doubleClickStringSelectionModeWord: "只選取單詞",
|
||||
vimMode: "Vim 模式",
|
||||
vimModeDescription: "在 SQL 編輯器中使用 Vim 風格的模態編輯",
|
||||
autoCloseBrackets: "自動成對補全",
|
||||
|
||||
+14
@@ -162,6 +162,20 @@ describe("query editor SQL string mouse selection", () => {
|
||||
expect(selection && doc.slice(selection.main.from, selection.main.to)).toBe("%%");
|
||||
});
|
||||
|
||||
it("returns null when the caller opted into plain word selection", () => {
|
||||
const doc = "EXEC sp_executesql N'SELECT * FROM my_table WHERE a = 1';";
|
||||
const state = EditorState.create({ doc });
|
||||
const view = fakeView(state).view;
|
||||
const insideString = eventAt(doc.indexOf("my_table"));
|
||||
const outsideString = eventAt(doc.indexOf("sp_executesql"));
|
||||
|
||||
expect(createQueryEditorStringMouseSelection(view, insideString)).not.toBeNull();
|
||||
expect(createQueryEditorStringMouseSelection(view, insideString, { selectStringContent: false })).toBeNull();
|
||||
expect(createQueryEditorStringMouseSelection(view, outsideString, { selectStringContent: false })).toBeNull();
|
||||
// Explicitly asking for the historical behaviour keeps working.
|
||||
expect(createQueryEditorStringMouseSelection(view, insideString, { selectStringContent: true })).not.toBeNull();
|
||||
});
|
||||
|
||||
it("trimSqlStringWildcardBoundaries shrinks past boundary wildcards only", () => {
|
||||
const doc = "%a_b%";
|
||||
expect(trimSqlStringWildcardBoundaries(doc, { from: 0, to: doc.length })).toEqual({ from: 1, to: 4 });
|
||||
|
||||
@@ -5,6 +5,12 @@ import { analyzeSqlSemanticSelectionRanges, sqlStringContentRangeAt, trimSqlStri
|
||||
export interface QueryEditorStringMouseSelectionOptions extends SqlSemanticSelectionOptions {
|
||||
language?: "sql" | "text";
|
||||
composing?: boolean;
|
||||
/**
|
||||
* When false the double click keeps the platform default "select one word"
|
||||
* behaviour instead of selecting the whole string literal. Defaults to true
|
||||
* so callers that do not opt in keep the historical behaviour.
|
||||
*/
|
||||
selectStringContent?: boolean;
|
||||
}
|
||||
|
||||
interface PointerPosition {
|
||||
@@ -47,6 +53,7 @@ function semanticOrDefaultRange(state: EditorState, position: PointerPosition, o
|
||||
}
|
||||
|
||||
export function createQueryEditorStringMouseSelection(view: EditorView, event: MouseEvent, options: QueryEditorStringMouseSelectionOptions = {}): MouseSelectionStyle | null {
|
||||
if (options.selectStringContent === false) return null;
|
||||
if (event.button !== 0 || event.detail !== 2 || event.altKey || options.composing || options.language === "text") return null;
|
||||
let start = view.posAndSideAtCoords({ x: event.clientX, y: event.clientY }, false);
|
||||
let analysis = analyzeSqlSemanticSelectionRanges(view.state.doc.toString(), options);
|
||||
|
||||
@@ -35,6 +35,7 @@ export const EDITOR_SETTINGS_DRAFT_KEYS = [
|
||||
"showWhitespace",
|
||||
"ddlOpenMode",
|
||||
"vimModeEnabled",
|
||||
"doubleClickStringSelectionMode",
|
||||
"autoCloseBrackets",
|
||||
"sqlSemanticDiagnosticsMode",
|
||||
"confirmDangerousSqlExecution",
|
||||
|
||||
@@ -142,6 +142,7 @@ export const SETTINGS_SEARCH_DEFINITIONS: readonly SettingsSearchDefinition[] =
|
||||
{ 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" },
|
||||
{ id: "editor-double-click-string", category: "editor", titleKey: "settings.doubleClickStringSelectionMode", descriptionKey: "settings.doubleClickStringSelectionModeDescription", targetId: "editor" },
|
||||
{ id: "editor-completion-spacing", category: "editor", titleKey: "settings.insertSpaceAfterCompletion", descriptionKey: "settings.insertSpaceAfterCompletionDescription", targetId: "editor" },
|
||||
{ id: "editor-sqlserver-space-completion", category: "editor", titleKey: "settings.sqlServerSpaceConfirmsCompletion", descriptionKey: "settings.sqlServerSpaceConfirmsCompletionDescription", targetId: "editor", visible: sqlServerSpaceCompletionVisible },
|
||||
{ id: "editor-completion-trigger-mode", category: "editor", titleKey: "settings.completionTriggerMode", descriptionKey: "settings.completionTriggerModeDescription", targetId: "editor" },
|
||||
|
||||
@@ -92,6 +92,7 @@ const SETTINGS_TRANSFER_CATEGORY_KEYS: Record<SettingsTransferCategoryId, readon
|
||||
"wordWrap",
|
||||
"showWhitespace",
|
||||
"vimModeEnabled",
|
||||
"doubleClickStringSelectionMode",
|
||||
"autoCloseBrackets",
|
||||
"sqlSemanticDiagnosticsMode",
|
||||
"confirmDangerousSqlExecution",
|
||||
|
||||
@@ -411,6 +411,12 @@ describe("normalizeEditorSettings", () => {
|
||||
expect(normalizeEditorSettings({ dataGridSearchMode: "invalid" as any }).dataGridSearchMode).toBe("filter");
|
||||
});
|
||||
|
||||
it("defaults double-click inside a string to selecting the whole value and preserves word mode", () => {
|
||||
expect(normalizeEditorSettings({}).doubleClickStringSelectionMode).toBe("content");
|
||||
expect(normalizeEditorSettings({ doubleClickStringSelectionMode: "word" }).doubleClickStringSelectionMode).toBe("word");
|
||||
expect(normalizeEditorSettings({ doubleClickStringSelectionMode: "invalid" as any }).doubleClickStringSelectionMode).toBe("content");
|
||||
});
|
||||
|
||||
it("defaults the data grid row number column to the view position and preserves original row numbers", () => {
|
||||
expect(normalizeEditorSettings({}).dataGridRowNumberMode).toBe("view");
|
||||
expect(normalizeEditorSettings({ dataGridRowNumberMode: "source" }).dataGridRowNumberMode).toBe("source");
|
||||
|
||||
@@ -718,6 +718,9 @@ const DATA_GRID_SEARCH_MODES = ["filter", "highlight"] as const;
|
||||
export type DataGridSearchMode = (typeof DATA_GRID_SEARCH_MODES)[number];
|
||||
const DATA_GRID_ROW_NUMBER_MODES = ["view", "source"] as const;
|
||||
export type DataGridRowNumberMode = (typeof DATA_GRID_ROW_NUMBER_MODES)[number];
|
||||
/** How a double click inside a SQL string literal picks text: the whole string value, or just one word. */
|
||||
export const DOUBLE_CLICK_STRING_SELECTION_MODES = ["content", "word"] as const;
|
||||
export type DoubleClickStringSelectionMode = (typeof DOUBLE_CLICK_STRING_SELECTION_MODES)[number];
|
||||
export type DataGridFilterEditorView = "quick" | "conditions" | "text";
|
||||
export type DataGridToolbarLayout = "single" | "split";
|
||||
const RESULT_RUN_DISPLAY_MODES = ["tabs", "list"] as const;
|
||||
@@ -864,6 +867,8 @@ export interface EditorSettings {
|
||||
refreshDdlOnOpen: boolean;
|
||||
excludeDdlStorage: boolean;
|
||||
vimModeEnabled: boolean;
|
||||
/** Double click inside a string literal selects the whole value ("content") or a single word ("word"). */
|
||||
doubleClickStringSelectionMode: DoubleClickStringSelectionMode;
|
||||
autoCloseBrackets: boolean;
|
||||
sqlSemanticDiagnosticsMode: SqlSemanticDiagnosticsMode;
|
||||
sqlSemanticDiagnosticsEnabled: boolean;
|
||||
@@ -1151,6 +1156,7 @@ export const DEFAULT_EDITOR_SETTINGS: EditorSettings = {
|
||||
refreshDdlOnOpen: false,
|
||||
excludeDdlStorage: true,
|
||||
vimModeEnabled: false,
|
||||
doubleClickStringSelectionMode: "content",
|
||||
autoCloseBrackets: true,
|
||||
sqlSemanticDiagnosticsMode: "auto",
|
||||
sqlSemanticDiagnosticsEnabled: SQL_SEMANTIC_DIAGNOSTICS_AUTO_ENABLED,
|
||||
@@ -1383,6 +1389,10 @@ function normalizeDataGridRowNumberMode(value: unknown): DataGridRowNumberMode {
|
||||
return DATA_GRID_ROW_NUMBER_MODES.includes(value as DataGridRowNumberMode) ? (value as DataGridRowNumberMode) : DEFAULT_EDITOR_SETTINGS.dataGridRowNumberMode;
|
||||
}
|
||||
|
||||
function normalizeDoubleClickStringSelectionMode(value: unknown): DoubleClickStringSelectionMode {
|
||||
return DOUBLE_CLICK_STRING_SELECTION_MODES.includes(value as DoubleClickStringSelectionMode) ? (value as DoubleClickStringSelectionMode) : DEFAULT_EDITOR_SETTINGS.doubleClickStringSelectionMode;
|
||||
}
|
||||
|
||||
function normalizeDataGridFilterEditorView(value: unknown): DataGridFilterEditorView {
|
||||
return value === "conditions" || value === "text" ? value : DEFAULT_EDITOR_SETTINGS.dataGridFilterEditorView;
|
||||
}
|
||||
@@ -1716,6 +1726,7 @@ export function normalizeEditorSettings(settings: Partial<EditorSettings>, exist
|
||||
ddlOpenMode: settings.ddlOpenMode === "tab" ? "tab" : DEFAULT_EDITOR_SETTINGS.ddlOpenMode,
|
||||
refreshDdlOnOpen: typeof settings.refreshDdlOnOpen === "boolean" ? settings.refreshDdlOnOpen : DEFAULT_EDITOR_SETTINGS.refreshDdlOnOpen,
|
||||
vimModeEnabled: typeof settings.vimModeEnabled === "boolean" ? settings.vimModeEnabled : DEFAULT_EDITOR_SETTINGS.vimModeEnabled,
|
||||
doubleClickStringSelectionMode: normalizeDoubleClickStringSelectionMode(settings.doubleClickStringSelectionMode),
|
||||
autoCloseBrackets: typeof settings.autoCloseBrackets === "boolean" ? settings.autoCloseBrackets : DEFAULT_EDITOR_SETTINGS.autoCloseBrackets,
|
||||
sqlSemanticDiagnosticsMode,
|
||||
sqlSemanticDiagnosticsEnabled: sqlSemanticDiagnosticsEnabledForMode(sqlSemanticDiagnosticsMode),
|
||||
@@ -2548,6 +2559,7 @@ export const useSettingsStore = defineStore("settings", () => {
|
||||
if (partial.ddlOpenMode !== undefined) editorSettings.value.ddlOpenMode = partial.ddlOpenMode === "tab" ? "tab" : "dialog";
|
||||
if (partial.refreshDdlOnOpen !== undefined) editorSettings.value.refreshDdlOnOpen = partial.refreshDdlOnOpen === true;
|
||||
if (partial.vimModeEnabled !== undefined) editorSettings.value.vimModeEnabled = partial.vimModeEnabled === true;
|
||||
if (partial.doubleClickStringSelectionMode !== undefined) editorSettings.value.doubleClickStringSelectionMode = normalizeDoubleClickStringSelectionMode(partial.doubleClickStringSelectionMode);
|
||||
if (partial.autoCloseBrackets !== undefined) editorSettings.value.autoCloseBrackets = partial.autoCloseBrackets === true;
|
||||
if (partial.sqlSemanticDiagnosticsMode !== undefined || partial.sqlSemanticDiagnosticsEnabled !== undefined) {
|
||||
const nextMode = normalizeSqlSemanticDiagnosticsMode(partial.sqlSemanticDiagnosticsMode, partial.sqlSemanticDiagnosticsEnabled);
|
||||
|
||||
Reference in New Issue
Block a user