diff --git a/frontend/src/components/toolbar/index.vue b/frontend/src/components/toolbar/index.vue
index 7253fbc..1adc952 100644
--- a/frontend/src/components/toolbar/index.vue
+++ b/frontend/src/components/toolbar/index.vue
@@ -18,7 +18,7 @@ const editorStore = useEditorStore();
-
+
{{ editorStore.fontSize }}px
diff --git a/frontend/src/editor/extensions/basicSetup.ts b/frontend/src/editor/extensions/basicSetup.ts
new file mode 100644
index 0000000..0cd1c1e
--- /dev/null
+++ b/frontend/src/editor/extensions/basicSetup.ts
@@ -0,0 +1,79 @@
+import {Extension} from '@codemirror/state';
+import {
+ crosshairCursor,
+ drawSelection,
+ dropCursor,
+ EditorView,
+ highlightActiveLine,
+ highlightActiveLineGutter,
+ highlightSpecialChars,
+ keymap,
+ lineNumbers,
+ rectangularSelection,
+} from '@codemirror/view';
+import {
+ bracketMatching,
+ defaultHighlightStyle,
+ foldGutter,
+ foldKeymap,
+ indentOnInput,
+ syntaxHighlighting,
+} from '@codemirror/language';
+import {
+ defaultKeymap,
+ history,
+ historyKeymap,
+} from '@codemirror/commands';
+import {highlightSelectionMatches, searchKeymap} from '@codemirror/search';
+import {autocompletion, closeBrackets, closeBracketsKeymap, completionKeymap} from '@codemirror/autocomplete';
+import {lintKeymap} from '@codemirror/lint';
+import {baseDark, customHighlightActiveLine} from '@/editor/theme/base-dark';
+
+// 基本编辑器设置,包含常用扩展
+export const createBasicSetup = (): Extension[] => {
+ return [
+ // 主题相关
+ baseDark,
+
+ // 基础UI
+ lineNumbers(),
+ highlightActiveLineGutter(),
+ highlightSpecialChars(),
+ dropCursor(),
+ EditorView.lineWrapping,
+
+ // 历史记录
+ history(),
+
+ // 代码折叠
+ foldGutter(),
+
+ // 选择与高亮
+ drawSelection(),
+ customHighlightActiveLine,
+ highlightActiveLine(),
+ highlightSelectionMatches(),
+ rectangularSelection(),
+ crosshairCursor(),
+
+ // 缩进和编辑辅助
+ indentOnInput(),
+ syntaxHighlighting(defaultHighlightStyle, {fallback: true}),
+ bracketMatching(),
+ closeBrackets(),
+
+ // 自动完成
+ autocompletion(),
+
+ // 键盘映射
+ keymap.of([
+ ...closeBracketsKeymap,
+ ...defaultKeymap,
+ ...searchKeymap,
+ ...historyKeymap,
+ ...foldKeymap,
+ ...completionKeymap,
+ ...lintKeymap
+ ]),
+ ];
+};
\ No newline at end of file
diff --git a/frontend/src/editor/extensions/index.ts b/frontend/src/editor/extensions/index.ts
new file mode 100644
index 0000000..233c8ce
--- /dev/null
+++ b/frontend/src/editor/extensions/index.ts
@@ -0,0 +1,4 @@
+// 统一导出所有扩展
+export * from './tabExtension';
+export * from './wheelZoomExtension';
+export * from './statsExtension';
\ No newline at end of file
diff --git a/frontend/src/editor/extensions/statsExtension.ts b/frontend/src/editor/extensions/statsExtension.ts
new file mode 100644
index 0000000..ed71a51
--- /dev/null
+++ b/frontend/src/editor/extensions/statsExtension.ts
@@ -0,0 +1,42 @@
+import {Extension} from '@codemirror/state';
+import {EditorView} from '@codemirror/view';
+import {DocumentStats} from '@/types/editor';
+
+// 更新编辑器文档统计信息
+export const updateStats = (
+ view: EditorView,
+ updateDocumentStats: (stats: DocumentStats) => void
+) => {
+ if (!view) return;
+
+ const state = view.state;
+ const doc = state.doc;
+ const text = doc.toString();
+
+ // 计算选中的字符数
+ let selectedChars = 0;
+ const selections = state.selection;
+ if (selections) {
+ for (let i = 0; i < selections.ranges.length; i++) {
+ const range = selections.ranges[i];
+ selectedChars += range.to - range.from;
+ }
+ }
+
+ updateDocumentStats({
+ lines: doc.lines,
+ characters: text.length,
+ selectedCharacters: selectedChars
+ });
+};
+
+// 创建统计信息更新监听器扩展
+export const createStatsUpdateExtension = (
+ updateDocumentStats: (stats: DocumentStats) => void
+): Extension => {
+ return EditorView.updateListener.of(update => {
+ if (update.docChanged || update.selectionSet) {
+ updateStats(update.view, updateDocumentStats);
+ }
+ });
+};
\ No newline at end of file
diff --git a/frontend/src/editor/extensions/tabExtension.ts b/frontend/src/editor/extensions/tabExtension.ts
new file mode 100644
index 0000000..abccd63
--- /dev/null
+++ b/frontend/src/editor/extensions/tabExtension.ts
@@ -0,0 +1,74 @@
+import {Compartment, Extension} from '@codemirror/state';
+import {EditorView, keymap} from '@codemirror/view';
+import {indentSelection} from '@codemirror/commands';
+import {indentUnit} from '@codemirror/language';
+
+// Tab设置相关的compartment
+export const tabSizeCompartment = new Compartment();
+export const tabKeyCompartment = new Compartment();
+
+// 自定义Tab键处理函数
+export const tabHandler = (view: EditorView, tabSize: number): boolean => {
+ // 如果有选中文本,使用indentSelection
+ if (!view.state.selection.main.empty) {
+ return indentSelection(view);
+ }
+
+ // 创建相应数量的空格
+ const spaces = ' '.repeat(tabSize);
+
+ // 在光标位置插入空格
+ const {state, dispatch} = view;
+ dispatch(state.update(state.replaceSelection(spaces), {scrollIntoView: true}));
+ return true;
+};
+
+// 获取Tab相关的扩展
+export const getTabExtensions = (tabSize: number, enableTabIndent: boolean): Extension[] => {
+ const extensions: Extension[] = [];
+
+ // 设置缩进单位
+ extensions.push(tabSizeCompartment.of(indentUnit.of(' '.repeat(tabSize))));
+
+ // 如果启用了Tab缩进,添加自定义Tab键映射
+ if (enableTabIndent) {
+ extensions.push(
+ tabKeyCompartment.of(
+ keymap.of([{
+ key: "Tab",
+ run: (view) => tabHandler(view, tabSize)
+ }])
+ )
+ );
+ } else {
+ extensions.push(tabKeyCompartment.of([]));
+ }
+
+ return extensions;
+};
+
+// 更新Tab配置
+export const updateTabConfig = (
+ view: EditorView | null,
+ tabSize: number,
+ enableTabIndent: boolean
+) => {
+ if (!view) return;
+
+ // 更新indentUnit配置
+ view.dispatch({
+ effects: tabSizeCompartment.reconfigure(indentUnit.of(' '.repeat(tabSize)))
+ });
+
+ // 更新Tab键映射
+ const tabKeymap = enableTabIndent
+ ? keymap.of([{
+ key: "Tab",
+ run: (view) => tabHandler(view, tabSize)
+ }])
+ : [];
+
+ view.dispatch({
+ effects: tabKeyCompartment.reconfigure(tabKeymap)
+ });
+};
\ No newline at end of file
diff --git a/frontend/src/editor/extensions/wheelZoomExtension.ts b/frontend/src/editor/extensions/wheelZoomExtension.ts
new file mode 100644
index 0000000..92b674c
--- /dev/null
+++ b/frontend/src/editor/extensions/wheelZoomExtension.ts
@@ -0,0 +1,35 @@
+import {EditorView} from '@codemirror/view';
+
+// 处理滚轮缩放字体的事件处理函数
+export const createWheelZoomHandler = (
+ increaseFontSize: () => void,
+ decreaseFontSize: () => void
+) => {
+ return (event: WheelEvent) => {
+ // 检查是否按住了Ctrl键
+ if (event.ctrlKey) {
+ // 阻止默认行为(防止页面缩放)
+ event.preventDefault();
+
+ // 根据滚轮方向增大或减小字体
+ if (event.deltaY < 0) {
+ // 向上滚动,增大字体
+ increaseFontSize();
+ } else {
+ // 向下滚动,减小字体
+ decreaseFontSize();
+ }
+ }
+ };
+};
+
+// 应用字体大小到编辑器
+export const applyFontSize = (view: EditorView, fontSize: number) => {
+ if (!view) return;
+
+ // 更新编辑器的字体大小
+ const editorDOM = view.dom;
+ if (editorDOM) {
+ editorDOM.style.fontSize = `${fontSize}px`;
+ }
+};
\ No newline at end of file
diff --git a/frontend/src/editor/font/font.ts b/frontend/src/editor/font/font.ts
deleted file mode 100644
index 312174b..0000000
--- a/frontend/src/editor/font/font.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import {EditorView} from '@codemirror/view'
-
-export const fontTheme = EditorView.theme({
- '&': {
- fontFamily: '"Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", Arial, sans-serif',
- fontSize: '12px'
- }
-})
\ No newline at end of file
diff --git a/frontend/src/editor/index.vue b/frontend/src/editor/index.vue
index 23530bc..8e33632 100644
--- a/frontend/src/editor/index.vue
+++ b/frontend/src/editor/index.vue
@@ -1,34 +1,17 @@