feat: format sql (#19)

Co-authored-by: SuLe <sule@SuLedeMacBook-Air.local>
This commit is contained in:
SuLea-IT
2026-04-30 15:56:16 +08:00
committed by GitHub
co-authored by SuLe
parent ac76aadbed
commit 5ee4f9300f
8 changed files with 196 additions and 1 deletions
+36
View File
@@ -2,15 +2,19 @@
import { ref, onMounted, onBeforeUnmount, watch, shallowRef } from "vue";
import type { EditorView as EditorViewType } from "@codemirror/view";
import { resolveExecutableSql } from "@/lib/sqlExecutionTarget";
import { formatSqlText, type SqlFormatDialect } from "@/lib/sqlFormatter";
const props = defineProps<{
modelValue: string;
dialect?: "mysql" | "postgres";
formatDialect?: SqlFormatDialect;
formatRequestId?: number;
}>();
const emit = defineEmits<{
"update:modelValue": [value: string];
"selectionChange": [value: string];
"formatError": [message: string];
execute: [sql: string];
}>();
@@ -69,6 +73,31 @@ function executableSqlFromView(currentView: EditorViewType): string {
return resolveExecutableSql(currentView.state.doc.toString(), selectedSqlFromView(currentView));
}
async function formatCurrentSql() {
const currentView = view.value;
if (!currentView) return;
const selection = currentView.state.selection.main;
const formatsSelection = !selection.empty;
const from = formatsSelection ? selection.from : 0;
const to = formatsSelection ? selection.to : currentView.state.doc.length;
const source = currentView.state.sliceDoc(from, to);
if (!source.trim()) return;
try {
const formatted = await formatSqlText(source, props.formatDialect ?? props.dialect ?? "generic");
if (formatted === source) return;
currentView.dispatch({
changes: { from, to, insert: formatted },
selection: formatsSelection
? { anchor: from, head: from + formatted.length }
: { anchor: from + formatted.length },
});
} catch (e: any) {
emit("formatError", String(e?.message || e));
}
}
onMounted(async () => {
if (!editorRef.value) return;
@@ -170,6 +199,13 @@ watch(
}
);
watch(
() => props.formatRequestId,
(val, oldVal) => {
if (val && val !== oldVal) formatCurrentSql();
}
);
onBeforeUnmount(() => {
view.value?.destroy();
});