mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-21 06:00:39 +00:00
feat(editor): add toggle case shortcut for selection
This commit is contained in:
@@ -2124,6 +2124,7 @@ const formatterEditorShortcutIds: ShortcutActionId[] = [
|
||||
"selectAll",
|
||||
"uppercaseSelection",
|
||||
"lowercaseSelection",
|
||||
"toggleCaseSelection",
|
||||
"toggleFold",
|
||||
"foldAll",
|
||||
"unfoldAll",
|
||||
|
||||
@@ -1396,6 +1396,7 @@ function runKeymapExtension(codeMirrorKeymap: (typeof import("@codemirror/view")
|
||||
...binding(shortcuts.selectAllSelectionOccurrences, selectAllQueryEditorSelectionOccurrences),
|
||||
...createQueryEditorSelectionCaseShortcutBindings(shortcuts.uppercaseSelection, () => convertSelectedSqlCase("upper")),
|
||||
...createQueryEditorSelectionCaseShortcutBindings(shortcuts.lowercaseSelection, () => convertSelectedSqlCase("lower")),
|
||||
...createQueryEditorSelectionCaseShortcutBindings(shortcuts.toggleCaseSelection, () => convertSelectedSqlCase("toggle")),
|
||||
...createQueryEditorSelectionCaseShortcutBindings(shortcuts.convertNamingStyle, () => convertSelectedNamingStyle()),
|
||||
...binding(shortcuts.toggleLineComment, (view) => codeMirrorRuntime.codeMirrorToggleLineComment?.(view) ?? false),
|
||||
...binding(shortcuts.toggleBlockComment, (view) => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { computed } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import {
|
||||
AlignLeft,
|
||||
ArrowDownUp,
|
||||
Camera,
|
||||
CaseLower,
|
||||
CaseSensitive,
|
||||
@@ -39,6 +40,7 @@ import { supportsQueryEditorBlockComments } from "@/lib/database/databaseFeature
|
||||
import { normalizeShortcutSettings, type ShortcutSettings } from "@/lib/editor/shortcutRegistry";
|
||||
import { queryContextObjectActions, type QueryContextObjectAction } from "@/lib/sql/queryCursorTableTarget";
|
||||
import type { SqlObjectNavigationTarget } from "@/lib/sql/sqlNavigation";
|
||||
import type { SqlSelectionCaseMode } from "@/lib/sql/sqlSelectionCase";
|
||||
import type { QueryEditorProps } from "./queryEditorTypes";
|
||||
|
||||
export interface QueryEditorContextMenuState {
|
||||
@@ -70,7 +72,7 @@ export interface QueryEditorContextMenuActions {
|
||||
cutSelectedSqlFromContextMenu: () => void;
|
||||
pasteClipboardSqlFromContextMenu: () => void;
|
||||
pasteClipboardSqlRestoringSource: () => void;
|
||||
convertSelectedSqlCase: (mode: "upper" | "lower") => void;
|
||||
convertSelectedSqlCase: (mode: SqlSelectionCaseMode) => void;
|
||||
convertSelectedNamingStyle: () => void;
|
||||
openDelimitedListDialog: () => void;
|
||||
addNextSelectionOccurrenceFromContextMenu: () => void;
|
||||
@@ -300,6 +302,13 @@ const contextMenuItems = computed<ContextMenuItem[]>(() => {
|
||||
icon: Sparkles,
|
||||
shortcut: shortcuts.sendSelectionToAi,
|
||||
},
|
||||
{
|
||||
label: t("editor.contextMenu.toggleCaseSelection"),
|
||||
action: () => actions.convertSelectedSqlCase("toggle"),
|
||||
disabled: !canCopySelectedSql,
|
||||
icon: ArrowDownUp,
|
||||
shortcut: shortcuts.toggleCaseSelection,
|
||||
},
|
||||
{
|
||||
label: t("editor.contextMenu.uppercaseSelection"),
|
||||
action: () => actions.convertSelectedSqlCase("upper"),
|
||||
|
||||
@@ -1505,6 +1505,7 @@ export default withEnglishFallback({
|
||||
pasteRestoringSourceSql: "Yapışdır və mənbə SQL-i bərpa et",
|
||||
pasteClipboardReadFailed: "Mübadilə buferini oxumaq mümkün olmadı: {message}",
|
||||
sendToAi: "Süni intellektə göndər",
|
||||
toggleCaseSelection: "Registri dəyiş",
|
||||
uppercaseSelection: "Böyük hərflərə çevir",
|
||||
lowercaseSelection: "Kiçik hərflərə çevir",
|
||||
convertNamingStyle: "Adlandırma üslubunu dəyiş",
|
||||
@@ -8222,6 +8223,7 @@ export default withEnglishFallback({
|
||||
changelogSectionRemoved: "Çıxarılanlar",
|
||||
shortcutUppercaseSelection: "Seçimi böyük hərflərə çevir",
|
||||
shortcutLowercaseSelection: "Seçimi kiçik hərflərə çevir",
|
||||
shortcutToggleCaseSelection: "Seçimin hərf registrini dəyiş",
|
||||
shortcutConvertNamingStyle: "Adlandırma üslubunu dəyiş",
|
||||
shortcutExPasteSqlInCondition: "ExPaste: IN şərti kimi yerləşdir",
|
||||
},
|
||||
|
||||
@@ -1802,6 +1802,7 @@ export default {
|
||||
pasteRestoringSourceSql: "Paste and restore source SQL",
|
||||
pasteClipboardReadFailed: "Failed to read clipboard: {message}",
|
||||
sendToAi: "Send to AI",
|
||||
toggleCaseSelection: "Toggle case",
|
||||
uppercaseSelection: "Convert to uppercase",
|
||||
lowercaseSelection: "Convert to lowercase",
|
||||
convertNamingStyle: "Toggle naming style",
|
||||
@@ -9163,6 +9164,7 @@ export default {
|
||||
changelogSectionRemoved: "Removed",
|
||||
shortcutUppercaseSelection: "Convert selection to uppercase",
|
||||
shortcutLowercaseSelection: "Convert selection to lowercase",
|
||||
shortcutToggleCaseSelection: "Toggle selection case",
|
||||
shortcutConvertNamingStyle: "Toggle naming style",
|
||||
shortcutExPasteSqlInCondition: "ExPaste: paste as IN condition",
|
||||
},
|
||||
|
||||
@@ -1787,6 +1787,7 @@ export default withEnglishFallback({
|
||||
foldAll: "Contraer todo",
|
||||
unfoldAll: "Expandir todo",
|
||||
sendToAi: "Enviar a IA",
|
||||
toggleCaseSelection: "Alternar mayúsculas/minúsculas",
|
||||
uppercaseSelection: "Convertir a mayusculas",
|
||||
lowercaseSelection: "Convertir a minusculas",
|
||||
selectAll: "Seleccionar todo",
|
||||
@@ -8460,6 +8461,7 @@ export default withEnglishFallback({
|
||||
changelogSectionRemoved: "Eliminado",
|
||||
shortcutUppercaseSelection: "Convertir selección a mayúsculas",
|
||||
shortcutLowercaseSelection: "Convertir selección a minúsculas",
|
||||
shortcutToggleCaseSelection: "Alternar mayúsculas y minúsculas de la selección",
|
||||
shortcutExPasteSqlInCondition: "ExPaste: pegar como condición IN",
|
||||
dateTimeSection: "Fecha y hora",
|
||||
globalDateTimeDisplayFormat: "Formato de visualización global",
|
||||
|
||||
@@ -1740,6 +1740,7 @@ export default withEnglishFallback({
|
||||
pasteRestoringSourceSql: "Tempel dan pulihkan SQL sumber",
|
||||
pasteClipboardReadFailed: "Gagal membaca clipboard: {message}",
|
||||
sendToAi: "Kirim ke AI",
|
||||
toggleCaseSelection: "Alihkan huruf besar/kecil",
|
||||
uppercaseSelection: "Konversi ke huruf besar",
|
||||
lowercaseSelection: "Konversi ke huruf kecil",
|
||||
convertNamingStyle: "Alihkan gaya penamaan",
|
||||
@@ -8956,6 +8957,7 @@ export default withEnglishFallback({
|
||||
changelogSectionRemoved: "Dihapus",
|
||||
shortcutUppercaseSelection: "Ubah seleksi menjadi huruf besar",
|
||||
shortcutLowercaseSelection: "Ubah seleksi menjadi huruf kecil",
|
||||
shortcutToggleCaseSelection: "Alihkan huruf besar/kecil seleksi",
|
||||
shortcutConvertNamingStyle: "Alihkan gaya penamaan",
|
||||
shortcutExPasteSqlInCondition: "ExPaste: tempel sebagai kondisi IN",
|
||||
},
|
||||
|
||||
@@ -1696,6 +1696,7 @@ export default withEnglishFallback({
|
||||
foldAll: "Comprimi tutto",
|
||||
unfoldAll: "Espandi tutto",
|
||||
sendToAi: "Invia ad AI",
|
||||
toggleCaseSelection: "Inverti maiuscole/minuscole",
|
||||
uppercaseSelection: "Converti in maiuscolo",
|
||||
lowercaseSelection: "Converti in minuscolo",
|
||||
selectAll: "Seleziona tutto",
|
||||
@@ -8206,6 +8207,7 @@ export default withEnglishFallback({
|
||||
changelogSectionRemoved: "Rimossi",
|
||||
shortcutUppercaseSelection: "Converti selezione in maiuscolo",
|
||||
shortcutLowercaseSelection: "Converti selezione in minuscolo",
|
||||
shortcutToggleCaseSelection: "Inverti maiuscole/minuscole della selezione",
|
||||
shortcutExPasteSqlInCondition: "ExPaste: incolla come condizione IN",
|
||||
dateTimeSection: "Data e Ora",
|
||||
globalDateTimeDisplayFormat: "Formato di visualizzazione globale",
|
||||
|
||||
@@ -1716,6 +1716,7 @@ export default withEnglishFallback({
|
||||
foldAll: "すべて折りたたむ",
|
||||
unfoldAll: "すべて展開",
|
||||
sendToAi: "AIに送信",
|
||||
toggleCaseSelection: "大文字/小文字を切り替え",
|
||||
uppercaseSelection: "大文字に変換",
|
||||
lowercaseSelection: "小文字に変換",
|
||||
selectAll: "すべて選択",
|
||||
@@ -8222,6 +8223,7 @@ export default withEnglishFallback({
|
||||
changelogSectionRemoved: "削除",
|
||||
shortcutUppercaseSelection: "選択範囲を大文字に変換",
|
||||
shortcutLowercaseSelection: "選択範囲を小文字に変換",
|
||||
shortcutToggleCaseSelection: "選択範囲の大文字/小文字を切り替え",
|
||||
shortcutExPasteSqlInCondition: "ExPaste: IN条件として貼り付け",
|
||||
dateTimeSection: "日付と時刻",
|
||||
globalDateTimeDisplayFormat: "グローバル表示形式",
|
||||
|
||||
@@ -1627,6 +1627,7 @@ export default withEnglishFallback({
|
||||
pasteRestoringSourceSql: "붙여넣고 소스 SQL 복원",
|
||||
pasteClipboardReadFailed: "클립보드 읽기 실패: {message}",
|
||||
sendToAi: "AI로 보내기",
|
||||
toggleCaseSelection: "대소문자 전환",
|
||||
uppercaseSelection: "대문자로 변환",
|
||||
lowercaseSelection: "소문자로 변환",
|
||||
delimitedList: "구분자 목록으로 변환",
|
||||
@@ -8012,6 +8013,7 @@ export default withEnglishFallback({
|
||||
changelogSectionRemoved: "제거된 항목",
|
||||
shortcutUppercaseSelection: "선택 영역을 대문자로 변환",
|
||||
shortcutLowercaseSelection: "선택 영역을 소문자로 변환",
|
||||
shortcutToggleCaseSelection: "선택 영역 대소문자 전환",
|
||||
shortcutExPasteSqlInCondition: "ExPaste: IN 조건으로 붙여넣기",
|
||||
shortcutToggleFold: "접기/펼치기",
|
||||
shortcutFoldAll: "모두 접기",
|
||||
|
||||
@@ -1697,6 +1697,7 @@ export default withEnglishFallback({
|
||||
foldAll: "Recolher tudo",
|
||||
unfoldAll: "Expandir tudo",
|
||||
sendToAi: "Enviar para IA",
|
||||
toggleCaseSelection: "Alternar maiúsculas/minúsculas",
|
||||
uppercaseSelection: "Converter para maiúsculas",
|
||||
lowercaseSelection: "Converter para minúsculas",
|
||||
selectAll: "Selecionar tudo",
|
||||
@@ -8207,6 +8208,7 @@ export default withEnglishFallback({
|
||||
changelogSectionRemoved: "Removido",
|
||||
shortcutUppercaseSelection: "Converter seleção em maiúsculas",
|
||||
shortcutLowercaseSelection: "Converter seleção em minúsculas",
|
||||
shortcutToggleCaseSelection: "Alternar maiúsculas/minúsculas da seleção",
|
||||
shortcutExPasteSqlInCondition: "ExPaste: colar como condição IN",
|
||||
dateTimeSection: "Data e Hora",
|
||||
globalDateTimeDisplayFormat: "Formato de exibição global",
|
||||
|
||||
@@ -1710,6 +1710,7 @@ export default withEnglishFallback({
|
||||
pasteRestoringSourceSql: "Вставить и восстановить SQL из кода",
|
||||
pasteClipboardReadFailed: "Не удалось прочитать буфер обмена: {message}",
|
||||
sendToAi: "Отправить в AI",
|
||||
toggleCaseSelection: "Переключить регистр",
|
||||
uppercaseSelection: "Преобразовать в верхний регистр",
|
||||
lowercaseSelection: "Преобразовать в нижний регистр",
|
||||
convertNamingStyle: "Переключить стиль именования",
|
||||
@@ -9465,6 +9466,7 @@ export default withEnglishFallback({
|
||||
changelogSectionRemoved: "Удалено",
|
||||
shortcutUppercaseSelection: "Преобразовать выделенное в верхний регистр",
|
||||
shortcutLowercaseSelection: "Преобразовать выделенное в нижний регистр",
|
||||
shortcutToggleCaseSelection: "Переключить регистр выделенного",
|
||||
shortcutConvertNamingStyle: "Переключить стиль именования",
|
||||
shortcutExPasteSqlInCondition: "ExPaste: вставить как условие IN",
|
||||
showColumnHeaderTooltips: "Всплывающие подсказки при наведении на имена полей",
|
||||
|
||||
@@ -1505,6 +1505,7 @@ export default withEnglishFallback({
|
||||
pasteRestoringSourceSql: "Yapıştır ve kaynak SQL'i geri yükle",
|
||||
pasteClipboardReadFailed: "Pano okunamadı: {message}",
|
||||
sendToAi: "Yapay Zekâya Gönder",
|
||||
toggleCaseSelection: "Büyük/küçük harf değiştir",
|
||||
uppercaseSelection: "Büyük harfe dönüştür",
|
||||
lowercaseSelection: "Küçük harfe dönüştür",
|
||||
delimitedList: "Ayırıcılı listeye dönüştür",
|
||||
@@ -8096,6 +8097,7 @@ export default withEnglishFallback({
|
||||
changelogSectionRemoved: "Kaldırıldı",
|
||||
shortcutUppercaseSelection: "Seçimi büyük harfe dönüştür",
|
||||
shortcutLowercaseSelection: "Seçimi küçük harfe dönüştür",
|
||||
shortcutToggleCaseSelection: "Seçimin büyük/küçük harf durumunu değiştir",
|
||||
shortcutExPasteSqlInCondition: "ExPaste: IN koşulu olarak yapıştır",
|
||||
},
|
||||
driverStore: {
|
||||
|
||||
@@ -1738,6 +1738,7 @@ export default withEnglishFallback({
|
||||
pasteRestoringSourceSql: "粘贴并还原源码 SQL",
|
||||
pasteClipboardReadFailed: "读取剪贴板失败:{message}",
|
||||
sendToAi: "发送到 AI",
|
||||
toggleCaseSelection: "切换大小写",
|
||||
uppercaseSelection: "转为大写",
|
||||
lowercaseSelection: "转为小写",
|
||||
convertNamingStyle: "切换命名风格",
|
||||
@@ -8624,6 +8625,7 @@ export default withEnglishFallback({
|
||||
shortcutExtendSelection: "扩展选择",
|
||||
shortcutUppercaseSelection: "选中内容转为大写",
|
||||
shortcutLowercaseSelection: "选中内容转为小写",
|
||||
shortcutToggleCaseSelection: "切换选中内容大小写",
|
||||
shortcutConvertNamingStyle: "切换命名风格",
|
||||
shortcutExPasteSqlInCondition: "ExPaste:粘贴为 IN 条件",
|
||||
shortcutEditTableStructure: "编辑表结构",
|
||||
|
||||
@@ -1700,6 +1700,7 @@ export default withEnglishFallback({
|
||||
foldAll: "全部折疊",
|
||||
unfoldAll: "全部展開",
|
||||
sendToAi: "傳送至 AI",
|
||||
toggleCaseSelection: "切換大小寫",
|
||||
uppercaseSelection: "轉為大寫",
|
||||
lowercaseSelection: "轉為小寫",
|
||||
selectAll: "全選",
|
||||
@@ -7573,6 +7574,7 @@ export default withEnglishFallback({
|
||||
queryExportKeysetOptimizationEnabledDescription: "僅適用於可安全識別的單表查詢;複雜查詢會自動回退。",
|
||||
shortcutUppercaseSelection: "選取內容轉為大寫",
|
||||
shortcutLowercaseSelection: "選取內容轉為小寫",
|
||||
shortcutToggleCaseSelection: "切換選取內容大小寫",
|
||||
shortcutExPasteSqlInCondition: "ExPaste:貼上為 IN 條件",
|
||||
routineSourceOpenMode: "函式/程序/檢視開啟方式",
|
||||
routineSourceOpenModeQueryTab: "資料標籤頁",
|
||||
|
||||
@@ -41,6 +41,7 @@ describe("shortcutRegistry editor actions", () => {
|
||||
"selectAllSelectionOccurrences",
|
||||
"uppercaseSelection",
|
||||
"lowercaseSelection",
|
||||
"toggleCaseSelection",
|
||||
"exPasteSqlInCondition",
|
||||
"toggleFold",
|
||||
"foldAll",
|
||||
@@ -292,6 +293,7 @@ describe("shortcutRegistry editor actions", () => {
|
||||
expect(shortcuts.selectAllSelectionOccurrences).toBe(selectionOccurrenceDefaultShortcut("selectAllSelectionOccurrences"));
|
||||
expect(shortcuts.uppercaseSelection).toBe("Shift+Alt+U");
|
||||
expect(shortcuts.lowercaseSelection).toBe("Shift+Alt+L");
|
||||
expect(shortcuts.toggleCaseSelection).toBe("Mod+Shift+U");
|
||||
expect(shortcuts.exPasteSqlInCondition).toBe("");
|
||||
expect(shortcuts.toggleFold).toBe("Mod+.");
|
||||
expect(shortcuts.foldAll).toBe(foldAllDefaultShortcut("foldAll"));
|
||||
@@ -308,6 +310,13 @@ describe("shortcutRegistry editor actions", () => {
|
||||
expect(normalizeShortcutSettings({ foldAll: "", unfoldAll: "" }, "Win32")).toMatchObject({ foldAll: "", unfoldAll: "" });
|
||||
});
|
||||
|
||||
it("registers toggle case as a configurable editor shortcut (#5085)", () => {
|
||||
const definition = SHORTCUT_DEFINITIONS.find((item) => item.id === "toggleCaseSelection");
|
||||
|
||||
expect(definition).toMatchObject({ scope: "editor", defaultShortcut: "Mod+Shift+U", labelKey: "settings.shortcutToggleCaseSelection" });
|
||||
expect(DEFAULT_SHORTCUT_SETTINGS.toggleCaseSelection).toBe("Mod+Shift+U");
|
||||
});
|
||||
|
||||
it("registers IntelliJ-style extend selection as a configurable editor shortcut", () => {
|
||||
const definition = SHORTCUT_DEFINITIONS.find((item) => item.id === "extendSelection");
|
||||
|
||||
|
||||
@@ -98,4 +98,51 @@ describe("convertSqlSelectionCase", () => {
|
||||
|
||||
expect(convertSqlSelectionCase(sql, { from, to: sql.length }, "upper")).toBe("> 60 AND GRADE = 'AbC'");
|
||||
});
|
||||
|
||||
describe("toggle mode (#5085)", () => {
|
||||
it("converts lowercase text to uppercase", () => {
|
||||
const sql = "select id, name from users";
|
||||
expect(convertSqlSelectionCase(sql, { from: 0, to: sql.length }, "toggle")).toBe("SELECT ID, NAME FROM USERS");
|
||||
});
|
||||
|
||||
it("defaults mixed case to uppercase first", () => {
|
||||
const sql = "Select id, userName From Users";
|
||||
expect(convertSqlSelectionCase(sql, { from: 0, to: sql.length }, "toggle")).toBe("SELECT ID, USERNAME FROM USERS");
|
||||
});
|
||||
|
||||
it("converts all-uppercase text to lowercase", () => {
|
||||
const sql = "SELECT ID, NAME FROM USERS";
|
||||
expect(convertSqlSelectionCase(sql, { from: 0, to: sql.length }, "toggle")).toBe("select id, name from users");
|
||||
});
|
||||
|
||||
it("cycles between uppercase and lowercase on repeated toggles", () => {
|
||||
const initial = "Select Name From Users";
|
||||
const first = convertSqlSelectionCase(initial, { from: 0, to: initial.length }, "toggle");
|
||||
expect(first).toBe("SELECT NAME FROM USERS");
|
||||
|
||||
const second = convertSqlSelectionCase(first, { from: 0, to: first.length }, "toggle");
|
||||
expect(second).toBe("select name from users");
|
||||
|
||||
const third = convertSqlSelectionCase(second, { from: 0, to: second.length }, "toggle");
|
||||
expect(third).toBe("SELECT NAME FROM USERS");
|
||||
});
|
||||
|
||||
it("protects string literals when toggling case", () => {
|
||||
const sql = "select name from users where status = 'active'";
|
||||
const upper = convertSqlSelectionCase(sql, { from: 0, to: sql.length }, "toggle");
|
||||
expect(upper).toBe("SELECT NAME FROM USERS WHERE STATUS = 'active'");
|
||||
|
||||
const lower = convertSqlSelectionCase(upper, { from: 0, to: upper.length }, "toggle");
|
||||
expect(lower).toBe("select name from users where status = 'active'");
|
||||
});
|
||||
|
||||
it("toggles bare string literals when selected directly", () => {
|
||||
const sql = "('first', 'second')";
|
||||
const upper = convertSqlSelectionCase(sql, { from: 0, to: sql.length }, "toggle");
|
||||
expect(upper).toBe("('FIRST', 'SECOND')");
|
||||
|
||||
const lower = convertSqlSelectionCase(upper, { from: 0, to: upper.length }, "toggle");
|
||||
expect(lower).toBe("('first', 'second')");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,6 +29,7 @@ export type ShortcutActionId =
|
||||
| "selectAllSelectionOccurrences"
|
||||
| "uppercaseSelection"
|
||||
| "lowercaseSelection"
|
||||
| "toggleCaseSelection"
|
||||
| "convertNamingStyle"
|
||||
| "exPasteSqlInCondition"
|
||||
| "toggleFold"
|
||||
@@ -330,6 +331,12 @@ export const SHORTCUT_DEFINITIONS: ShortcutDefinition[] = [
|
||||
scope: "editor",
|
||||
defaultShortcut: "Shift+Alt+L",
|
||||
},
|
||||
{
|
||||
id: "toggleCaseSelection",
|
||||
labelKey: "settings.shortcutToggleCaseSelection",
|
||||
scope: "editor",
|
||||
defaultShortcut: "Mod+Shift+U",
|
||||
},
|
||||
{
|
||||
id: "convertNamingStyle",
|
||||
labelKey: "settings.shortcutConvertNamingStyle",
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
import { tokenizeSqlSemantic } from "@/lib/sql/semantic/tokens";
|
||||
|
||||
export type SqlSelectionCaseMode = "upper" | "lower";
|
||||
export type SqlSelectionCaseMode = "upper" | "lower" | "toggle";
|
||||
|
||||
type SqlSelectionRange = {
|
||||
from: number;
|
||||
to: number;
|
||||
};
|
||||
|
||||
function convertCase(text: string, mode: SqlSelectionCaseMode): string {
|
||||
function convertCase(text: string, mode: "upper" | "lower"): string {
|
||||
return mode === "upper" ? text.toUpperCase() : text.toLowerCase();
|
||||
}
|
||||
|
||||
export function convertSqlSelectionCase(sql: string, range: SqlSelectionRange, mode: SqlSelectionCaseMode, dialectId?: "mysql" | "postgres" | "sqlserver"): string {
|
||||
const from = Math.max(0, Math.min(range.from, sql.length));
|
||||
const to = Math.max(from, Math.min(range.to, sql.length));
|
||||
if (mode === "toggle") {
|
||||
const upperResult = convertSqlSelectionCase(sql, range, "upper", dialectId);
|
||||
const currentText = sql.slice(from, to);
|
||||
if (upperResult !== currentText) {
|
||||
return upperResult;
|
||||
}
|
||||
return convertSqlSelectionCase(sql, range, "lower", dialectId);
|
||||
}
|
||||
const protectedTokens = tokenizeSqlSemantic(sql, dialectId).filter((item) => {
|
||||
if (item.span.end <= from || item.span.start >= to) return false;
|
||||
if (item.kind === "string") return true;
|
||||
|
||||
@@ -24,6 +24,7 @@ DBX 的快捷键来自同一份可配置 action registry。**设置 → 快捷
|
||||
| `Shift+Mod+K` | 删除当前行 |
|
||||
| `Alt+↑` / `Alt+↓` | 上下移动当前行 |
|
||||
| `Shift+Alt+↑` / `Shift+Alt+↓` | 向上/下复制当前行 |
|
||||
| `Mod+Shift+U` | 切换选中内容大小写(首次默认转为大写) |
|
||||
| `Shift+Alt+U` / `Shift+Alt+L` | 选中内容转大写/小写 |
|
||||
| `Shift+Alt+C` | 切换选中内容的命名风格(camelCase → PascalCase → snake_case → SCREAMING_SNAKE_CASE → kebab-case) |
|
||||
| `Mod+.` | 折叠或展开代码块 |
|
||||
|
||||
@@ -24,6 +24,7 @@ DBX shortcuts come from one configurable action registry. **Settings → Shortcu
|
||||
| `Shift+Mod+K` | Delete current line |
|
||||
| `Alt+↑` / `Alt+↓` | Move current line up/down |
|
||||
| `Shift+Alt+↑` / `Shift+Alt+↓` | Copy current line up/down |
|
||||
| `Mod+Shift+U` | Toggle selection case (defaults to uppercase first) |
|
||||
| `Shift+Alt+U` / `Shift+Alt+L` | Convert selection to uppercase/lowercase |
|
||||
| `Shift+Alt+C` | Toggle selection naming style (camelCase → PascalCase → snake_case → SCREAMING_SNAKE_CASE → kebab-case) |
|
||||
| `Mod+.` | Toggle code folding |
|
||||
|
||||
Reference in New Issue
Block a user