From 42aa116d6742837fb32d2b5dfed9fa089c6e9fc5 Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Wed, 13 Aug 2025 16:33:32 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat=20(core):=20=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E4=B8=BA=20CodeMirror?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 9 + src/components/CodeEditor.vue | 123 +++++++------- src/utils/highlighter/index.ts | 37 ----- src/utils/highlighter/languages/go.ts | 176 -------------------- src/utils/highlighter/languages/nodejs.ts | 152 ----------------- src/utils/highlighter/languages/python2.ts | 94 ----------- src/utils/highlighter/languages/python3.ts | 111 ------------- src/utils/highlighter/manager.ts | 184 --------------------- src/utils/highlighter/types.ts | 50 ------ 9 files changed, 66 insertions(+), 870 deletions(-) delete mode 100644 src/utils/highlighter/index.ts delete mode 100644 src/utils/highlighter/languages/go.ts delete mode 100644 src/utils/highlighter/languages/nodejs.ts delete mode 100644 src/utils/highlighter/languages/python2.ts delete mode 100644 src/utils/highlighter/languages/python3.ts delete mode 100644 src/utils/highlighter/manager.ts delete mode 100644 src/utils/highlighter/types.ts diff --git a/package.json b/package.json index 419766bc..b94bdb21 100644 --- a/package.json +++ b/package.json @@ -10,14 +10,23 @@ "tauri": "tauri" }, "dependencies": { + "@babel/runtime": "^7.28.2", + "@codemirror/lang-go": "^6.0.1", + "@codemirror/lang-javascript": "^6.2.4", + "@codemirror/lang-python": "^6.2.1", + "@codemirror/state": "^6.5.2", + "@codemirror/view": "^6.38.1", "@tauri-apps/api": "^2", "@tauri-apps/plugin-dialog": "^2.3.2", "@tauri-apps/plugin-opener": "^2", "@tauri-apps/plugin-shell": "^2.3.0", + "@uiw/codemirror-themes-all": "^4.24.2", "@vueuse/core": "^13.6.0", + "codemirror": "^6.0.2", "lodash-es": "^4.17.21", "lucide-vue-next": "^0.539.0", "vue": "^3.5.13", + "vue-codemirror": "^6.1.1", "vue3-markdown-it": "^1.0.10" }, "devDependencies": { diff --git a/src/components/CodeEditor.vue b/src/components/CodeEditor.vue index 286ca252..07606d15 100644 --- a/src/components/CodeEditor.vue +++ b/src/components/CodeEditor.vue @@ -1,40 +1,20 @@ \ No newline at end of file + +// 监听语言变化 +watch(() => props.language, async () => { + isReady.value = false + await nextTick() + await updateExtensions() +}, { immediate: false }) + +// 组件挂载时初始化 +onMounted(async () => { + await updateExtensions() +}) + diff --git a/src/utils/highlighter/index.ts b/src/utils/highlighter/index.ts deleted file mode 100644 index de2c1730..00000000 --- a/src/utils/highlighter/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -export * from './types' -export * from './manager' -export { Python2Highlighter } from './languages/python2' -export { Python3Highlighter } from './languages/python3' - -// 导入并重新导出管理器实例 -import { HighlightManager } from './manager' - -// 创建单例实例 -export const highlightManager = new HighlightManager() - -/** - * 高亮代码的便捷函数 - * @param code 源代码 - * @param language 语言名称 - * @returns 高亮后的 HTML - */ -export function highlightCode(code: string, language: string): string -{ - return highlightManager.highlight(code, language) -} - -/** - * 获取支持的语言列表 - */ -export function getSupportedLanguages() -{ - return highlightManager.getSupportedLanguages() -} - -/** - * 注册自定义高亮器 - */ -export function registerHighlighter(highlighter: import('./types').LanguageHighlighter) -{ - highlightManager.register(highlighter) -} \ No newline at end of file diff --git a/src/utils/highlighter/languages/go.ts b/src/utils/highlighter/languages/go.ts deleted file mode 100644 index c1ebb6b6..00000000 --- a/src/utils/highlighter/languages/go.ts +++ /dev/null @@ -1,176 +0,0 @@ -import type { HighlightRule, LanguageHighlighter } from '../types' - -export class GoHighlighter - implements LanguageHighlighter -{ - getLanguageName(): string - { - return 'go' - } - - getDisplayName(): string - { - return 'Go' - } - - getOrder(): number - { - return 4 - } - - getRules(): HighlightRule[] - { - return [ - // 1. 注释 (最高优先级) - { - pattern: /\/\/.*$/gm, - className: 'text-gray-500 italic', - priority: 1 - }, - { - pattern: /\/\*[\s\S]*?\*\//g, - className: 'text-gray-500 italic', - priority: 1 - }, - - // 2. 字符串 (高优先级) - { - pattern: /`(?:[^`\\]|\\.)*`/g, - className: 'text-green-600', - priority: 2 - }, - { - pattern: /"(?:[^"\\]|\\.)*"/g, - className: 'text-green-600', - priority: 2 - }, - { - pattern: /'(?:[^'\\]|\\.)*'/g, - className: 'text-green-600', - priority: 2 - }, - - // 3. Go 关键字 - { - pattern: /\b(package|import|func|var|const|type|struct|interface|map|chan|select|go|defer|return|break|continue|fallthrough|if|else|switch|case|default|for|range|goto|true|false|nil|iota)\b/g, - className: 'text-purple-600 font-semibold', - priority: 3 - }, - - // 4. Go 内置类型 - { - pattern: /\b(bool|byte|complex64|complex128|error|float32|float64|int|int8|int16|int32|int64|rune|string|uint|uint8|uint16|uint32|uint64|uintptr)\b/g, - className: 'text-blue-600 font-semibold', - priority: 4 - }, - - // 5. 数字 - { - pattern: /\b\d+(?:\.\d+)?(?:[eE][+-]?\d+)?[fFlL]?\b/g, - className: 'text-blue-600', - priority: 5 - }, - - // 6. 十六进制、八进制、二进制数字 - { - pattern: /\b0[xX][0-9a-fA-F]+\b|\b0[0-7]+\b|\b0[bB][01]+\b/g, - className: 'text-blue-600', - priority: 5 - }, - - // 7. 函数定义 - { - pattern: /\bfunc\s+([a-zA-Z_]\w*)/g, - className: 'text-orange-600 font-semibold', - priority: 6 - }, - - // 8. 函数调用 - { - pattern: /\b([a-zA-Z_]\w*)(?=\s*\()/g, - className: 'text-orange-600', - priority: 7 - }, - - // 9. 类型定义 - { - pattern: /\btype\s+([A-Z]\w*)/g, - className: 'text-yellow-600 font-semibold', - priority: 8 - }, - - // 10. 结构体字段 - { - pattern: /\b([a-zA-Z_]\w*)\s*:/g, - className: 'text-cyan-600', - priority: 9 - }, - - // 11. 包名 - { - pattern: /\bpackage\s+([a-zA-Z_]\w*)/g, - className: 'text-indigo-600 font-semibold', - priority: 10 - }, - - // 12. import 语句 - { - pattern: /\bimport\s*\(\s*[\s\S]*?\)/g, - className: 'text-emerald-600', - priority: 11 - }, - { - pattern: /\bimport\s+"[^"]+"/g, - className: 'text-emerald-600', - priority: 11 - }, - - // 13. 常见的 Go 内置函数 - { - pattern: /\b(make|new|len|cap|append|copy|delete|close|panic|recover|print|println)\b/g, - className: 'text-pink-600 font-medium', - priority: 12 - }, - - // 14. 指针操作符 - { - pattern: /[*&]/g, - className: 'text-red-600 font-bold', - priority: 13 - }, - - // 15. 通道操作符 - { - pattern: /<-/g, - className: 'text-violet-600 font-bold', - priority: 14 - }, - - // 16. 结构体标签 - { - pattern: /`[^`]*`/g, - className: 'text-teal-600 bg-gray-100', - priority: 15 - }, - - // 17. 大写开头的导出标识符 - { - pattern: /\b[A-Z]\w*/g, - className: 'text-amber-600', - priority: 16 - } - ] - } - - preProcess(code: string): string - { - // Go 特定的预处理 - return code - } - - postProcess(highlighted: string): string - { - // Go 特定的后处理 - return highlighted - } -} diff --git a/src/utils/highlighter/languages/nodejs.ts b/src/utils/highlighter/languages/nodejs.ts deleted file mode 100644 index 22850696..00000000 --- a/src/utils/highlighter/languages/nodejs.ts +++ /dev/null @@ -1,152 +0,0 @@ -import type { HighlightRule, LanguageHighlighter } from '../types' - -export class NodeJSHighlighter - implements LanguageHighlighter -{ - getLanguageName(): string - { - return 'nodejs' - } - - getDisplayName(): string - { - return 'Node.js' - } - - getOrder(): number - { - return 3 - } - - getRules(): HighlightRule[] - { - return [ - // 1. 注释 (最高优先级) - { - pattern: /\/\/.*$/gm, - className: 'text-gray-500 italic', - priority: 1 - }, - { - pattern: /\/\*[\s\S]*?\*\//g, - className: 'text-gray-500 italic', - priority: 1 - }, - - // 2. 字符串 (高优先级) - { - pattern: /`(?:[^`\\]|\\.)*`/g, - className: 'text-green-600', - priority: 2 - }, - { - pattern: /"(?:[^"\\]|\\.)*"/g, - className: 'text-green-600', - priority: 2 - }, - { - pattern: /'(?:[^'\\]|\\.)*'/g, - className: 'text-green-600', - priority: 2 - }, - - // 3. JavaScript/Node.js 关键字 - { - pattern: /\b(const|let|var|function|class|if|else|for|while|do|switch|case|default|break|continue|return|try|catch|finally|throw|new|this|super|extends|import|export|from|as|async|await|yield|typeof|instanceof|in|of|delete|void|null|undefined|true|false)\b/g, - className: 'text-purple-600 font-semibold', - priority: 3 - }, - - // 4. Node.js 特定关键字和全局对象 - { - pattern: /\b(require|module|exports|process|global|__dirname|__filename|Buffer|console|setTimeout|setInterval|clearTimeout|clearInterval)\b/g, - className: 'text-indigo-600 font-semibold', - priority: 3 - }, - - // 5. 数字 - { - pattern: /\b\d+(?:\.\d+)?(?:[eE][+-]?\d+)?\b/g, - className: 'text-blue-600', - priority: 4 - }, - - // 6. 函数调用 - { - pattern: /\b([a-zA-Z_$]\w*)(?=\s*\()/g, - className: 'text-orange-600', - priority: 5 - }, - - // 7. 类名定义 - { - pattern: /\bclass\s+([A-Z]\w*)/g, - className: 'text-yellow-600 font-semibold', - priority: 6 - }, - - // 8. 对象属性 - { - pattern: /\b([a-zA-Z_$]\w*)\s*:/g, - className: 'text-cyan-600', - priority: 7 - }, - - // 9. 箭头函数 - { - pattern: /=>/g, - className: 'text-pink-600 font-bold', - priority: 8 - }, - - // 10. 模板字符串插值 - { - pattern: /\$\{[^}]*\}/g, - className: 'text-red-600 bg-yellow-100', - priority: 9 - }, - - // 11. require 路径 - { - pattern: /require\s*\(\s*(['"`])([^'"`]+)\1\s*\)/g, - className: 'text-emerald-600', - priority: 10 - }, - - // 12. 常见的 Node.js 模块名 - { - pattern: /\b(fs|path|http|https|url|crypto|util|events|stream|os|cluster|child_process|readline|querystring|zlib|assert|buffer|domain|punycode|string_decoder|tls|tty|dgram|dns|net|vm|repl)\b/g, - className: 'text-teal-600 font-medium', - priority: 11 - }, - - // 13. 正则表达式 - { - pattern: /\/(?:[^\/\\\r\n]|\\.)+\/[gimuy]*/g, - className: 'text-rose-600', - priority: 12 - }, - - // 14. 装饰器 (如果使用 TypeScript) - { - pattern: /@[a-zA-Z_$]\w*/g, - className: 'text-violet-600', - priority: 13 - } - ] - } - - preProcess(code: string): string - { - // Node.js 特定的预处理 - // 可以在这里处理一些特殊的语法转换 - return code - } - - postProcess(highlighted: string): string - { - // Node.js 特定的后处理 - // 可以在这里添加一些额外的样式处理 - return highlighted - } -} diff --git a/src/utils/highlighter/languages/python2.ts b/src/utils/highlighter/languages/python2.ts deleted file mode 100644 index a1cbf2ef..00000000 --- a/src/utils/highlighter/languages/python2.ts +++ /dev/null @@ -1,94 +0,0 @@ -import type { HighlightRule, LanguageHighlighter } from '../types' - -export class Python2Highlighter - implements LanguageHighlighter -{ - getLanguageName(): string - { - return 'python2' - } - - getDisplayName(): string - { - return 'Python 2' - } - - getOrder(): number - { - return 2 - } - - getRules(): HighlightRule[] - { - return [ - // 1. 注释 (最高优先级) - { - pattern: /#.*$/gm, - className: 'text-gray-500 italic', - priority: 1 - }, - - // 2. 字符串 (高优先级) - { - pattern: /"""[\s\S]*?"""/g, - className: 'text-green-600', - priority: 2 - }, - { - pattern: /'''[\s\S]*?'''/g, - className: 'text-green-600', - priority: 2 - }, - { - pattern: /"(?:[^"\\]|\\.)*"/g, - className: 'text-green-600', - priority: 2 - }, - { - pattern: /'(?:[^'\\]|\\.)*'/g, - className: 'text-green-600', - priority: 2 - }, - - // 3. Python 2 关键字 - { - pattern: /\b(def|class|if|elif|else|for|while|try|except|finally|with|as|import|from|return|yield|break|continue|pass|lambda|and|or|not|in|is|True|False|None|print|exec|raw_input)\b/g, - className: 'text-purple-600 font-semibold', - priority: 3 - }, - - // 4. 数字 - { - pattern: /\b\d+(?:\.\d+)?(?:[eE][+-]?\d+)?\b/g, - className: 'text-blue-600', - priority: 4 - }, - - // 5. 函数调用 - { - pattern: /\b([a-zA-Z_]\w*)(?=\s*\()/g, - className: 'text-orange-600', - priority: 5 - }, - - // 6. 类名定义 - { - pattern: /\bclass\s+([A-Z]\w*)/g, - className: 'text-yellow-600 font-semibold', - priority: 6 - } - ] - } - - preProcess(code: string): string - { - // Python 2 特定的预处理 - return code - } - - postProcess(highlighted: string): string - { - // Python 2 特定的后处理 - return highlighted - } -} \ No newline at end of file diff --git a/src/utils/highlighter/languages/python3.ts b/src/utils/highlighter/languages/python3.ts deleted file mode 100644 index d6f83edb..00000000 --- a/src/utils/highlighter/languages/python3.ts +++ /dev/null @@ -1,111 +0,0 @@ -import type { HighlightRule, LanguageHighlighter } from '../types' - -export class Python3Highlighter - implements LanguageHighlighter -{ - getLanguageName(): string - { - return 'python3' - } - - getDisplayName(): string - { - return 'Python 3' - } - - getOrder(): number - { - return 1 - } - - getRules(): HighlightRule[] - { - return [ - // 1. 注释 (最高优先级) - { - pattern: /#.*$/gm, - className: 'text-gray-500 italic', - priority: 1 - }, - - // 2. 字符串 (高优先级) - { - pattern: /"""[\s\S]*?"""/g, - className: 'text-green-600', - priority: 2 - }, - { - pattern: /'''[\s\S]*?'''/g, - className: 'text-green-600', - priority: 2 - }, - { - pattern: /f"(?:[^"\\]|\\.)*"/g, - className: 'text-emerald-600', - priority: 2 - }, // f-strings - { - pattern: /f'(?:[^'\\]|\\.)*'/g, - className: 'text-emerald-600', - priority: 2 - }, // f-strings - { - pattern: /"(?:[^"\\]|\\.)*"/g, - className: 'text-green-600', - priority: 2 - }, - { - pattern: /'(?:[^'\\]|\\.)*'/g, - className: 'text-green-600', - priority: 2 - }, - - // 3. Python 3 关键字 - { - pattern: /\b(def|class|if|elif|else|for|while|try|except|finally|with|as|import|from|return|yield|break|continue|pass|lambda|and|or|not|in|is|True|False|None|async|await|nonlocal)\b/g, - className: 'text-purple-600 font-semibold', - priority: 3 - }, - - // 4. 数字 - { - pattern: /\b\d+(?:\.\d+)?(?:[eE][+-]?\d+)?\b/g, - className: 'text-blue-600', - priority: 4 - }, - - // 5. 函数调用 - { - pattern: /\b([a-zA-Z_]\w*)(?=\s*\()/g, - className: 'text-orange-600', - priority: 5 - }, - - // 6. 装饰器 - { - pattern: /@[a-zA-Z_]\w*/g, - className: 'text-yellow-600', - priority: 6 - }, - - // 7. 类名定义 - { - pattern: /\bclass\s+([A-Z]\w*)/g, - className: 'text-yellow-600 font-semibold', - priority: 7 - } - ] - } - - preProcess(code: string): string - { - // Python 3 特定的预处理 - return code - } - - postProcess(highlighted: string): string - { - // Python 3 特定的后处理 - return highlighted - } -} \ No newline at end of file diff --git a/src/utils/highlighter/manager.ts b/src/utils/highlighter/manager.ts deleted file mode 100644 index 7a5a4589..00000000 --- a/src/utils/highlighter/manager.ts +++ /dev/null @@ -1,184 +0,0 @@ -import type { HighlightMatch, LanguageHighlighter } from './types' -import { Python2Highlighter } from './languages/python2' -import { Python3Highlighter } from './languages/python3' -import { NodeJSHighlighter } from './languages/nodejs.ts' -import { GoHighlighter } from './languages/go.ts' - -export class HighlightManager -{ - private highlighters = new Map() - - constructor() - { - this.registerDefaultHighlighters() - } - - /** - * 注册默认高亮器 - */ - private registerDefaultHighlighters(): void - { - this.register(new Python2Highlighter()) - this.register(new Python3Highlighter()) - this.register(new NodeJSHighlighter()) - this.register(new GoHighlighter()) - } - - /** - * 注册高亮器 - */ - register(highlighter: LanguageHighlighter): void - { - this.highlighters.set(highlighter.getLanguageName(), highlighter) - } - - /** - * 注销高亮器 - */ - unregister(languageName: string): boolean - { - return this.highlighters.delete(languageName) - } - - /** - * 获取高亮器 - */ - getHighlighter(languageName: string): LanguageHighlighter | undefined - { - return this.highlighters.get(languageName) - } - - /** - * 获取支持的语言列表 - */ - getSupportedLanguages(): Array<{ name: string; displayName: string; order: number }> - { - const languages = Array.from(this.highlighters.values()) - .map(highlighter => ({ - name: highlighter.getLanguageName(), - displayName: highlighter.getDisplayName(), - order: highlighter.getOrder() - })) - - // 按 order 排序 - return languages.sort((a, b) => a.order - b.order) - } - - /** - * 检查是否支持某种语言 - */ - isSupported(languageName: string): boolean - { - return this.highlighters.has(languageName) - } - - /** - * 对代码进行语法高亮 - */ - highlight(code: string, languageName: string): string - { - if (!code) { - return '' - } - - const highlighter = this.getHighlighter(languageName) - if (!highlighter) { - // 如果不支持该语言,返回转义后的原始代码 - return this.escapeHtml(code) - } - - // 预处理 - let processedCode = highlighter.preProcess ? highlighter.preProcess(code) : code - - // HTML 转义 - processedCode = this.escapeHtml(processedCode) - - // 应用高亮规则 - const highlighted = this.applyHighlightRules(processedCode, highlighter.getRules()) - - // 后处理 - return highlighter.postProcess ? highlighter.postProcess(highlighted) : highlighted - } - - /** - * 应用高亮规则 - */ - private applyHighlightRules(code: string, rules: Array<{ pattern: RegExp; className: string; priority?: number }>): string - { - // 收集所有匹配 - const matches: HighlightMatch[] = [] - - for (const rule of rules) { - const regex = new RegExp(rule.pattern.source, rule.pattern.flags) - let match - - while ((match = regex.exec(code)) !== null) { - matches.push({ - start: match.index, - end: match.index + match[0].length, - className: rule.className, - priority: rule.priority || 999 - }) - - // 防止无限循环 - if (!rule.pattern.global) { - break - } - } - } - - // 按优先级排序,优先级高的(数字小的)在前 - matches.sort((a, b) => a.priority - b.priority || a.start - b.start) - - // 移除重叠的匹配(保留高优先级的) - const filteredMatches = this.removeOverlappingMatches(matches) - - // 按开始位置倒序排序,从后往前插入标签 - filteredMatches.sort((a, b) => b.start - a.start) - - // 插入高亮标签 - let highlighted = code - for (const match of filteredMatches) { - const before = highlighted.substring(0, match.start) - const content = highlighted.substring(match.start, match.end) - const after = highlighted.substring(match.end) - - highlighted = before + `${ content }` + after - } - - return highlighted - } - - /** - * 移除重叠的匹配 - */ - private removeOverlappingMatches(matches: HighlightMatch[]): HighlightMatch[] - { - const filteredMatches: HighlightMatch[] = [] - - for (const match of matches) { - const hasOverlap = filteredMatches.some(existing => - (match.start < existing.end && match.end > existing.start) - ) - - if (!hasOverlap) { - filteredMatches.push(match) - } - } - - return filteredMatches - } - - /** - * HTML 转义 - */ - private escapeHtml(text: string): string - { - return text - // .replace(/&/g, '&') - .replace(//g, '>') - // .replace(/"/g, '"') - // .replace(/'/g, ''') - } -} diff --git a/src/utils/highlighter/types.ts b/src/utils/highlighter/types.ts deleted file mode 100644 index 41fe98d9..00000000 --- a/src/utils/highlighter/types.ts +++ /dev/null @@ -1,50 +0,0 @@ -// 语法高亮规则接口 -export interface HighlightRule -{ - pattern: RegExp - className: string - priority?: number -} - -// 匹配结果接口 -export interface HighlightMatch -{ - start: number - end: number - className: string - priority: number -} - -// 语言高亮插件接口 -export interface LanguageHighlighter -{ - /** - * 获取语言名称 - */ - getLanguageName(): string - - /** - * 获取显示名称 - */ - getDisplayName(): string - - /** - * 获取高亮规则 - */ - getRules(): HighlightRule[] - - /** - * 获取排序权重(数字越小越靠前) - */ - getOrder(): number - - /** - * 预处理代码(可选) - */ - preProcess?(code: string): string - - /** - * 后处理高亮结果(可选) - */ - postProcess?(highlighted: string): string -} \ No newline at end of file From 28cb0b473d716edefc5f650cfec0b5658c1365bb Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Wed, 13 Aug 2025 18:13:10 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat=20(core):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/config.rs | 29 +++ src/components/CodeEditor.vue | 64 +----- src/components/Settings.vue | 9 +- src/components/setting/Editor.vue | 62 ++++++ src/composables/useCodeMirrorEditor.ts | 294 +++++++++++++++++++++++++ src/composables/useEditorConfig.ts | 190 ++++++++++++++++ 6 files changed, 595 insertions(+), 53 deletions(-) create mode 100644 src/components/setting/Editor.vue create mode 100644 src/composables/useCodeMirrorEditor.ts create mode 100644 src/composables/useEditorConfig.ts diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs index 9fc1e39b..f40ac386 100644 --- a/src-tauri/src/config.rs +++ b/src-tauri/src/config.rs @@ -3,6 +3,7 @@ use crate::plugin::PluginManagerState; use crate::plugins::PluginConfig; use log::{info, warn}; use serde::{Deserialize, Serialize}; +use serde_json::Value::Bool; use std::fs; use std::path::PathBuf; use std::sync::Mutex; @@ -10,6 +11,13 @@ use tauri::{AppHandle, Manager, command}; static CONFIG_MANAGER: Mutex> = Mutex::new(None); +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct EditorConfig { + pub indent_with_tab: Option, // 是否使用 tab 缩进 + pub tab_size: Option, // tab 缩进, 空格数,默认为 2 + pub theme: Option, // 编辑器主题 +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AppConfig { pub log_directory: Option, @@ -17,6 +25,7 @@ pub struct AppConfig { pub keep_log_days: Option, pub theme: Option, pub plugins: Option>, + pub editor: Option, } impl Default for AppConfig { @@ -27,6 +36,11 @@ impl Default for AppConfig { keep_log_days: Some(30), theme: Some("system".to_string()), plugins: Some(vec![]), + editor: Some(EditorConfig { + indent_with_tab: Some(true), + tab_size: Some(2), + theme: Some("githubLight".to_string()), + }), } } } @@ -75,6 +89,16 @@ impl ConfigManager { // 合并插件配置(现有配置 + 默认配置中缺失的插件) config.plugins = Self::merge_plugins_config(config.plugins, app_handle); + // 检查并设置 editor 默认配置 + if config.editor.is_none() { + config.editor = Some(EditorConfig { + indent_with_tab: Some(true), + tab_size: Some(2), + theme: Some("githubLight".to_string()), + }); + println!("读取配置 -> 添加默认 editor 配置"); + } + Ok(config) } Err(e) => { @@ -170,6 +194,11 @@ impl ConfigManager { keep_log_days: Some(30), theme: Some("system".to_string()), plugins: Self::get_default_plugins_config(app_handle), + editor: Some(EditorConfig { + indent_with_tab: Some(true), + tab_size: Some(2), + theme: Some("githubLight".to_string()), + }), } } diff --git a/src/components/CodeEditor.vue b/src/components/CodeEditor.vue index 07606d15..25851c0a 100644 --- a/src/components/CodeEditor.vue +++ b/src/components/CodeEditor.vue @@ -4,17 +4,16 @@ style="width: 100%; height: 100%" :model-value="modelValue" :extensions="extensions" + :indent-with-tab="editorConfig?.indent_with_tab" + :tab-size="editorConfig?.tab_size" @change="handleInput"/> diff --git a/src/components/Settings.vue b/src/components/Settings.vue index eedc6a89..341634cc 100644 --- a/src/components/Settings.vue +++ b/src/components/Settings.vue @@ -11,6 +11,11 @@ + + +