diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b191c3a4..72eff5be 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,8 +1,8 @@ -name: Publish docs via GitHub Pages +name: Deploy docs to GitHub Pages on: - pull_request: - types: [ closed ] + push: + paths: [ 'docs/**', '.github/workflows/docs.yml' ] workflow_dispatch: permissions: @@ -10,32 +10,50 @@ permissions: pages: write id-token: write +# 同一时间只跑一个部署,新提交自动取消进行中的旧部署 +concurrency: + group: pages + cancel-in-progress: true + jobs: - deploy: + build: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [ 22.x ] - + defaults: + run: + working-directory: docs steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + with: + version: 10 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} + node-version: 22 + cache: pnpm + cache-dependency-path: docs/pnpm-lock.yaml - name: Install dependencies - run: npm install pageforge -g + run: pnpm install --frozen-lockfile - name: Build - run: | - cd docs - pageforge build - echo 'codeforge.devlive.org' > dist/CNAME + run: pnpm build - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 + - uses: actions/configure-pages@v5 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 with: - github_token: ${{ secrets.GH_TOKEN }} - publish_dir: docs/dist \ No newline at end of file + path: docs/dist + + deploy: + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..1cf7629d --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,4 @@ +node_modules +dist +.vite +*.local diff --git a/docs/content/download.md b/docs/content/download.md deleted file mode 100644 index ece402d1..00000000 --- a/docs/content/download.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: 下载 CodeForge - -config: - sidebar: false - toc: false ---- - -当前的 CodeForge 版本是 。有关详细信息,请参阅 [发行说明](/release/25.0.1.html)。 - -
- -::: grid -- 适配 Windows -- 适配 macOS -::: - -!btn[点我立即下载](https://github.com/devlive-community/codeforge/releases/){w-96 my-24 text-center text-white bg-green-500 hover:bg-green-600} diff --git a/docs/content/index.md b/docs/content/index.md deleted file mode 100644 index 3c0f5651..00000000 --- a/docs/content/index.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: 欢迎使用 CodeForge -template: home - -config: - sidebar: false - toc: false - -hero: - title: 轻量级桌面代码执行器 - description: 轻量级、高性能的桌面代码执行器,专为开发者、学生和编程爱好者设计。 - primaryCta: - url: /download.html - text: 立即下载 - secondaryCta: - url: https://github.com/devlive-community/codeforge - text: 了解更多 - -features: - subtitle: 核心优势 - title: 为什么选择我们 - description: 轻量级、高性能,专为开发者、学生和编程爱好者设计。 - items: - - icon: >- - - - - title: 高性能 - description: 可扩展的语言支持系统 - - - icon: >- - - - - title: 操作简洁 - description: 一键运行代码 - - - icon: >- - - + +declare module '*.vue' { + import type {DefineComponent} from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} + +// unplugin-vue-markdown:.md 作为 Vue 组件导入,并暴露 frontmatter +declare module '*.md' { + import type {DefineComponent} from 'vue' + const component: DefineComponent<{}, {}, any> + export default component + export const frontmatter: Record +} diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..94db638d --- /dev/null +++ b/docs/index.html @@ -0,0 +1,18 @@ + + + + + + + + + + CodeForge — 轻量级桌面代码执行器 + + + + +
+ + + diff --git a/docs/pageforge.yaml b/docs/pageforge.yaml deleted file mode 100644 index 34ab9e3a..00000000 --- a/docs/pageforge.yaml +++ /dev/null @@ -1,54 +0,0 @@ -site: - title: CodeForge - description: CodeForge 是一款轻量级、高性能的桌面代码执行器,专为开发者、学生和编程爱好者设计。 - hiddenTitle: true - keywords: CodeForge, Markdown, Python 2, Python 3, Rust - logo: /assets/logo.svg - favicon: assets/logo.svg - baseUrl: https://codeforge.devlive.org - -repo: - owner: devlive-community - name: codeforge - url: https://github.com/devlive-community/codeforge - branch: dev - -banner: - content: 💗 CodeForge 26.2.0 已经发布, 如果喜欢我们的软件,请点击这里支持我们 ❤️ - -feature: - lucide: - enable: true - grid: - enable: true - share: - enable: true - options: - qq: true - wechat: true - weibo: true - sitemap: - enable: true - fontSize: - enable: true - button: - enable: true - -footer: - copyright: © 2025 CodeForge All Rights Reserved. - social: - github: - title: GitHub - href: https://github.com/devlive-community/codeforge - -nav: - - 发布日志: - - /release/26.2.0.md - - /release/26.1.0.md - - /release/26.0.0.md - - /release/25.0.5.md - - /release/25.0.4.md - - /release/25.0.3.md - - /release/25.0.2.md - - /release/25.0.1.md - - /release/25.0.0.md \ No newline at end of file diff --git a/docs/postcss.config.js b/docs/postcss.config.js new file mode 100644 index 00000000..2b75bd8a --- /dev/null +++ b/docs/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +} diff --git a/docs/CNAME b/docs/public/CNAME similarity index 100% rename from docs/CNAME rename to docs/public/CNAME diff --git a/docs/assets/logo.svg b/docs/public/logo.svg similarity index 100% rename from docs/assets/logo.svg rename to docs/public/logo.svg diff --git a/docs/src/App.vue b/docs/src/App.vue new file mode 100644 index 00000000..233bc8c2 --- /dev/null +++ b/docs/src/App.vue @@ -0,0 +1,20 @@ + + + diff --git a/docs/src/components/CodeWindow.vue b/docs/src/components/CodeWindow.vue new file mode 100644 index 00000000..04da76f2 --- /dev/null +++ b/docs/src/components/CodeWindow.vue @@ -0,0 +1,45 @@ + + + diff --git a/docs/src/components/LangToggle.vue b/docs/src/components/LangToggle.vue new file mode 100644 index 00000000..37fb8f82 --- /dev/null +++ b/docs/src/components/LangToggle.vue @@ -0,0 +1,18 @@ + + + diff --git a/docs/src/components/SiteFooter.vue b/docs/src/components/SiteFooter.vue new file mode 100644 index 00000000..d8a00b60 --- /dev/null +++ b/docs/src/components/SiteFooter.vue @@ -0,0 +1,23 @@ + + + diff --git a/docs/src/components/SiteHeader.vue b/docs/src/components/SiteHeader.vue new file mode 100644 index 00000000..30109ac4 --- /dev/null +++ b/docs/src/components/SiteHeader.vue @@ -0,0 +1,39 @@ + + + diff --git a/docs/src/components/ThemeToggle.vue b/docs/src/components/ThemeToggle.vue new file mode 100644 index 00000000..7f669a4a --- /dev/null +++ b/docs/src/components/ThemeToggle.vue @@ -0,0 +1,35 @@ + + + diff --git a/docs/content/release/25.0.0.md b/docs/src/content/release/25.0.0.md similarity index 100% rename from docs/content/release/25.0.0.md rename to docs/src/content/release/25.0.0.md diff --git a/docs/content/release/25.0.1.md b/docs/src/content/release/25.0.1.md similarity index 100% rename from docs/content/release/25.0.1.md rename to docs/src/content/release/25.0.1.md diff --git a/docs/content/release/25.0.2.md b/docs/src/content/release/25.0.2.md similarity index 100% rename from docs/content/release/25.0.2.md rename to docs/src/content/release/25.0.2.md diff --git a/docs/content/release/25.0.3.md b/docs/src/content/release/25.0.3.md similarity index 100% rename from docs/content/release/25.0.3.md rename to docs/src/content/release/25.0.3.md diff --git a/docs/content/release/25.0.4.md b/docs/src/content/release/25.0.4.md similarity index 100% rename from docs/content/release/25.0.4.md rename to docs/src/content/release/25.0.4.md diff --git a/docs/content/release/25.0.5.md b/docs/src/content/release/25.0.5.md similarity index 100% rename from docs/content/release/25.0.5.md rename to docs/src/content/release/25.0.5.md diff --git a/docs/content/release/26.0.0.md b/docs/src/content/release/26.0.0.md similarity index 100% rename from docs/content/release/26.0.0.md rename to docs/src/content/release/26.0.0.md diff --git a/docs/content/release/26.1.0.md b/docs/src/content/release/26.1.0.md similarity index 100% rename from docs/content/release/26.1.0.md rename to docs/src/content/release/26.1.0.md diff --git a/docs/content/release/26.2.0.md b/docs/src/content/release/26.2.0.md similarity index 100% rename from docs/content/release/26.2.0.md rename to docs/src/content/release/26.2.0.md diff --git a/docs/src/content/releases.ts b/docs/src/content/releases.ts new file mode 100644 index 00000000..05179e12 --- /dev/null +++ b/docs/src/content/releases.ts @@ -0,0 +1,37 @@ +// 发布日志:扫描 release/*.md,自动生成版本列表与路由组件。 +// 新发版只需往 release/ 丢一个 md 文件,无需改其它代码。 + +// 懒加载的 Vue 组件(每个 md 经 unplugin-vue-markdown 转成组件) +const componentLoaders = import.meta.glob('./release/*.md') + +export interface ReleaseMeta { + version: string + title: string +} + +const versionFromPath = (p: string): string => (p.match(/([^/]+)\.md$/)?.[1]) ?? p + +// 形如 26.2.0 的版本号降序 +const compareVersionDesc = (a: string, b: string): number => { + const pa = a.split('.').map(Number) + const pb = b.split('.').map(Number) + for (let i = 0; i < Math.max(pa.length, pb.length); i++) { + const d = (pb[i] || 0) - (pa[i] || 0) + if (d !== 0) return d + } + return 0 +} + +const versions = Object.keys(componentLoaders) + .map(versionFromPath) + .sort(compareVersionDesc) + +export const releases: ReleaseMeta[] = versions.map(version => ({version, title: `v${version}`})) + +export const latestRelease = releases[0] + +// 路由:每个版本一个静态路由,便于 vite-ssg 全量预渲染 +export const releaseRoutes = Object.entries(componentLoaders).map(([path, loader]) => ({ + path: `/release/${versionFromPath(path)}`, + component: loader +})) diff --git a/docs/src/i18n.ts b/docs/src/i18n.ts new file mode 100644 index 00000000..1d2ab237 --- /dev/null +++ b/docs/src/i18n.ts @@ -0,0 +1,100 @@ +import {createI18n} from 'vue-i18n' + +export const SUPPORTED_LOCALES = ['zh', 'en'] as const +export type Locale = (typeof SUPPORTED_LOCALES)[number] + +const messages = { + zh: { + nav: {download: '下载', releases: '发布日志'}, + hero: { + badge: 'v{version} 已发布', + title1: '轻量级桌面', + title2: '代码执行器', + subtitle: '高性能、可扩展的桌面代码执行器,集编辑、运行、调试、数据库与 Git 工作台于一身,专为开发者、学生和编程爱好者打造。', + download: '立即下载', + github: '在 GitHub 查看', + langsPrefix: '支持', + langsSuffix: '等数十种语言' + }, + features: { + tag: '核心优势', + title: '一个应用,覆盖完整开发流', + items: { + run: {title: '极速运行', desc: '一键运行任意语言,可扩展的语言支持系统,启动与执行都很迅捷。'}, + edit: {title: '智能编辑', desc: 'LSP 补全、跳转、诊断,符号大纲、面包屑、多光标与代码片段一应俱全。'}, + debug: {title: '可视化调试', desc: '基于 DAP 的断点调试,变量、调用栈、监视与悬停求值,无需切到命令行。'}, + db: {title: '数据库工作台', desc: '多数据源连接、SQL 执行与结果导出、ER 图与交互式事务,数据开发更顺手。'}, + git: {title: 'Git 工作台', desc: '暂存、提交、分支、分支图、变基、cherry-pick、子模块与工作树,全部图形化。'}, + ai: {title: 'AI 辅助', desc: '代码预测、解释、生成测试与格式化,让常见任务交给 AI 一步完成。'} + } + }, + download: { + title: '下载 CodeForge', + latestPrefix: '当前最新版本', + latestSuffix: ',详见', + releaseNotes: '发布说明', + winNote: '.msi / .exe 安装包', + macNote: 'Apple Silicon 与 Intel', + allVersions: '查看全部历史版本与安装包' + }, + releaseList: {title: '发布日志', intro: '每个版本的更新内容如下,点击查看详情。'}, + footer: {download: '下载', releases: '发布日志'} + }, + en: { + nav: {download: 'Download', releases: 'Releases'}, + hero: { + badge: 'v{version} released', + title1: 'Lightweight desktop', + title2: 'code runner', + subtitle: 'A fast, extensible desktop code runner — editing, running, debugging, a database console and a full Git workbench in one app. Built for developers, students and coding enthusiasts.', + download: 'Download now', + github: 'View on GitHub', + langsPrefix: 'Supports', + langsSuffix: 'and dozens more' + }, + features: { + tag: 'Why CodeForge', + title: 'One app for your entire workflow', + items: { + run: {title: 'Blazing fast', desc: 'Run any language with one click. An extensible language system keeps startup and execution snappy.'}, + edit: {title: 'Smart editing', desc: 'LSP completion, go-to, diagnostics, symbol outline, breadcrumbs, multi-cursor and snippets.'}, + debug: {title: 'Visual debugging', desc: 'DAP-based breakpoint debugging with variables, call stack, watches and hover evaluation — no terminal needed.'}, + db: {title: 'Database console', desc: 'Multiple data sources, SQL execution and export, ER diagrams and interactive transactions.'}, + git: {title: 'Git workbench', desc: 'Staging, commits, branches, branch graph, rebase, cherry-pick, submodules and worktrees — all graphical.'}, + ai: {title: 'AI assistance', desc: 'Code prediction, explanation, test generation and formatting — common tasks in a single step.'} + } + }, + download: { + title: 'Download CodeForge', + latestPrefix: 'Latest version', + latestSuffix: '. See the', + releaseNotes: 'release notes', + winNote: '.msi / .exe installers', + macNote: 'Apple Silicon & Intel', + allVersions: 'Browse all releases and installers' + }, + releaseList: {title: 'Releases', intro: 'Update notes for each version. Click to view details.'}, + footer: {download: 'Download', releases: 'Releases'} + } +} + +const stored = (): Locale => { + if (typeof localStorage !== 'undefined') { + const v = localStorage.getItem('locale') + if (v === 'zh' || v === 'en') return v + } + return 'zh' +} + +export const i18n = createI18n({ + legacy: false, + locale: stored(), + fallbackLocale: 'zh', + messages +}) + +export const setLocale = (l: Locale) => { + i18n.global.locale.value = l + if (typeof localStorage !== 'undefined') localStorage.setItem('locale', l) + if (typeof document !== 'undefined') document.documentElement.lang = l === 'zh' ? 'zh-CN' : 'en' +} diff --git a/docs/src/layouts/DocLayout.vue b/docs/src/layouts/DocLayout.vue new file mode 100644 index 00000000..39e3ca76 --- /dev/null +++ b/docs/src/layouts/DocLayout.vue @@ -0,0 +1,25 @@ + + + diff --git a/docs/src/main.ts b/docs/src/main.ts new file mode 100644 index 00000000..29756c7f --- /dev/null +++ b/docs/src/main.ts @@ -0,0 +1,19 @@ +import {ViteSSG} from 'vite-ssg' +import App from './App.vue' +import {routes} from './router' +import {i18n} from './i18n' +import './styles/main.css' + +// vite-ssg:开发用 SPA,构建时把每个路由预渲染成静态 HTML +export const createApp = ViteSSG( + App, + {routes, scrollBehavior: () => ({top: 0})}, + ({app, router}) => { + app.use(i18n) + router.afterEach((to) => { + if (typeof document !== 'undefined' && to.meta?.title) { + document.title = String(to.meta.title) + } + }) + } +) diff --git a/docs/src/pages/Download.vue b/docs/src/pages/Download.vue new file mode 100644 index 00000000..e3152a39 --- /dev/null +++ b/docs/src/pages/Download.vue @@ -0,0 +1,52 @@ + + + diff --git a/docs/src/pages/Home.vue b/docs/src/pages/Home.vue new file mode 100644 index 00000000..9f6f139b --- /dev/null +++ b/docs/src/pages/Home.vue @@ -0,0 +1,94 @@ + + + diff --git a/docs/src/pages/ReleaseList.vue b/docs/src/pages/ReleaseList.vue new file mode 100644 index 00000000..a1dc3401 --- /dev/null +++ b/docs/src/pages/ReleaseList.vue @@ -0,0 +1,18 @@ + + + diff --git a/docs/src/router.ts b/docs/src/router.ts new file mode 100644 index 00000000..02739605 --- /dev/null +++ b/docs/src/router.ts @@ -0,0 +1,12 @@ +import type {RouteRecordRaw} from 'vue-router' +import Home from './pages/Home.vue' +import Download from './pages/Download.vue' +import ReleaseList from './pages/ReleaseList.vue' +import {releaseRoutes} from './content/releases' + +export const routes: RouteRecordRaw[] = [ + {path: '/', component: Home, meta: {title: 'CodeForge — 轻量级桌面代码执行器'}}, + {path: '/download', component: Download, meta: {title: '下载 CodeForge'}}, + {path: '/release', component: ReleaseList, meta: {title: '发布日志', doc: true}}, + ...releaseRoutes.map(r => ({...r, meta: {doc: true}})) +] diff --git a/docs/src/styles/main.css b/docs/src/styles/main.css new file mode 100644 index 00000000..afdb0614 --- /dev/null +++ b/docs/src/styles/main.css @@ -0,0 +1,143 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + color-scheme: light dark; +} + +html { + scroll-behavior: smooth; +} + +body { + @apply font-sans antialiased; +} + +/* ===== 科技感动效 ===== */ +@keyframes blob { + 0%, 100% { transform: translate(0, 0) scale(1); } + 33% { transform: translate(30px, -40px) scale(1.1); } + 66% { transform: translate(-20px, 20px) scale(0.95); } +} +.animate-blob { animation: blob 14s ease-in-out infinite; } + +@keyframes float { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-12px); } +} +.animate-float { animation: float 6s ease-in-out infinite; } + +@keyframes spin-slow { to { transform: rotate(360deg); } } +.animate-spin-slow { animation: spin-slow 6s linear infinite; } + +@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } } +.animate-marquee { animation: marquee 28s linear infinite; } + +@keyframes shimmer { 100% { transform: translateX(200%); } } +.shimmer { position: relative; overflow: hidden; } +.shimmer::after { + content: ''; + position: absolute; + inset: 0; + transform: translateX(-200%); + background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, .35) 50%, transparent 70%); + animation: shimmer 3.5s ease-in-out infinite; +} + +/* 渐变描边(旋转的 conic 光圈) */ +.glow-border { position: relative; } +.glow-border::before { + content: ''; + position: absolute; + inset: -1px; + border-radius: inherit; + padding: 1px; + background: conic-gradient(from var(--a, 0deg), #6366f1, #22d3ee, #a855f7, #6366f1); + -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; + animation: spin-border 8s linear infinite; + opacity: .7; +} +@property --a { syntax: ''; initial-value: 0deg; inherits: false; } +@keyframes spin-border { to { --a: 360deg; } } + +@media (prefers-reduced-motion: reduce) { + .animate-blob, .animate-float, .animate-spin-slow, .animate-marquee, .shimmer::after, .glow-border::before { + animation: none !important; + } +} + +/* 发布日志正文排版(Markdown 渲染结果) */ +.prose-doc { + @apply text-slate-700 dark:text-slate-300 leading-7 text-[15px]; +} +.prose-doc h1 { + @apply text-3xl font-bold tracking-tight text-slate-900 dark:text-white mt-2 mb-6 scroll-mt-24; +} +.prose-doc h2 { + @apply text-xl font-semibold text-slate-900 dark:text-white mt-12 mb-4 pb-2 border-b border-slate-200 dark:border-slate-800 scroll-mt-24; +} +.prose-doc h3 { + @apply text-lg font-semibold text-slate-900 dark:text-white mt-8 mb-3 scroll-mt-24; +} +.prose-doc p { + @apply my-4; +} +.prose-doc a { + @apply text-brand-600 dark:text-brand-400 font-medium hover:underline underline-offset-2; +} +.prose-doc strong { + @apply font-semibold text-slate-900 dark:text-slate-100; +} +.prose-doc ul { + @apply list-disc pl-5 my-4 space-y-2 marker:text-slate-300 dark:marker:text-slate-600; +} +.prose-doc ol { + @apply list-decimal pl-5 my-4 space-y-2 marker:text-slate-400; +} +.prose-doc li > ul, +.prose-doc li > ol { + @apply my-2; +} +.prose-doc code { + @apply px-1.5 py-0.5 rounded-md bg-slate-100 dark:bg-slate-800 text-brand-600 dark:text-brand-300 text-[0.85em] font-mono; +} +.prose-doc pre { + @apply p-4 rounded-xl bg-slate-900 dark:bg-slate-900 border border-slate-800 text-slate-100 overflow-x-auto my-5 text-sm leading-relaxed; +} +.prose-doc pre code { + @apply bg-transparent text-slate-100 p-0 text-[0.85em]; +} +.prose-doc blockquote { + @apply border-l-2 border-brand-400 dark:border-brand-600 pl-4 my-5 text-slate-500 dark:text-slate-400; +} +.prose-doc table { + @apply w-full my-6 text-sm border border-slate-200 dark:border-slate-800 rounded-lg overflow-hidden border-separate border-spacing-0; +} +.prose-doc thead { + @apply bg-slate-50 dark:bg-slate-800/60; +} +.prose-doc th, +.prose-doc td { + @apply border-b border-slate-200 dark:border-slate-800 px-3.5 py-2.5 text-left; +} +.prose-doc tbody tr:last-child td { + @apply border-b-0; +} +.prose-doc th { + @apply font-semibold text-slate-700 dark:text-slate-200; +} +.prose-doc hr { + @apply my-10 border-slate-200 dark:border-slate-800; +} +.prose-doc img { + @apply inline-block max-w-full align-middle; +} + +/* 锚点链接(markdown-it-anchor headerLink):去掉默认下划线 */ +.prose-doc :where(h1, h2, h3) a { + @apply no-underline text-inherit; + font-weight: inherit; +} diff --git a/docs/tailwind.config.js b/docs/tailwind.config.js new file mode 100644 index 00000000..c2f4de5e --- /dev/null +++ b/docs/tailwind.config.js @@ -0,0 +1,25 @@ +/** @type {import('tailwindcss').Config} */ +export default { + darkMode: 'class', + content: ['./index.html', './src/**/*.{vue,ts,md}'], + theme: { + extend: { + fontFamily: { + sans: ['Inter', 'system-ui', '-apple-system', 'Segoe UI', 'Roboto', '"PingFang SC"', '"Microsoft YaHei"', 'sans-serif'], + mono: ['"JetBrains Mono"', 'ui-monospace', 'SFMono-Regular', 'Menlo', 'monospace'] + }, + colors: { + brand: { + 50: '#eef2ff', 100: '#e0e7ff', 200: '#c7d2fe', 300: '#a5b4fc', + 400: '#818cf8', 500: '#6366f1', 600: '#4f46e5', 700: '#4338ca', + 800: '#3730a3', 900: '#312e81' + } + }, + boxShadow: { + soft: '0 1px 2px rgba(15,23,42,.04), 0 8px 24px rgba(15,23,42,.06)', + glow: '0 20px 60px -20px rgba(79,70,229,.35)' + } + } + }, + plugins: [] +} diff --git a/docs/vite.config.ts b/docs/vite.config.ts new file mode 100644 index 00000000..35daf5c3 --- /dev/null +++ b/docs/vite.config.ts @@ -0,0 +1,28 @@ +import {defineConfig} from 'vite' +import vue from '@vitejs/plugin-vue' +import Markdown from 'unplugin-vue-markdown/vite' +import anchor from 'markdown-it-anchor' +import {fileURLToPath, URL} from 'node:url' + +// 自建文档站:Vue 单文件组件 + Markdown(发布日志)渲染为 Vue 组件 +export default defineConfig({ + base: '/', + plugins: [ + // 注意:Markdown 必须在 vue 之前,先把 .md 转成 SFC 再交给 vue 编译 + Markdown({ + exposeFrontmatter: true, + markdownItOptions: {html: true, linkify: true}, + markdownItSetup(md) { + md.use(anchor, {permalink: anchor.permalink.headerLink()}) + } + }), + vue({include: [/\.vue$/, /\.md$/]}) + ], + resolve: { + alias: {'@': fileURLToPath(new URL('./src', import.meta.url))} + }, + // vite-ssg:把所有路由静态预渲染为 HTML + ssgOptions: { + formatting: 'minify' + } +}) diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs index 361f5f6b..e04a514e 100644 --- a/src-tauri/src/config.rs +++ b/src-tauri/src/config.rs @@ -22,6 +22,7 @@ pub struct EditorConfig { pub space_dot_omission: Option, // 是否显示空格省略 pub show_minimap: Option, // 是否显示代码缩略图 pub show_sticky_scroll: Option, // 是否启用粘性滚动 + pub word_wrap: Option, // 是否自动换行 pub layout: Option, // 编辑器/控制台布局: horizontal | vertical | editor pub last_direction: Option, // 仅编辑器模式下控制台弹出方向: horizontal | vertical pub max_open_file_size: Option, // 打开文件大小上限(MB),超过则拒绝打开 @@ -73,6 +74,7 @@ impl Default for AppConfig { space_dot_omission: Some(false), show_minimap: Some(false), show_sticky_scroll: Some(false), + word_wrap: Some(false), layout: Some("horizontal".to_string()), last_direction: Some("horizontal".to_string()), max_open_file_size: Some(5), @@ -145,6 +147,7 @@ impl ConfigManager { space_dot_omission: Some(false), show_minimap: Some(false), show_sticky_scroll: Some(false), + word_wrap: Some(false), layout: Some("horizontal".to_string()), last_direction: Some("horizontal".to_string()), max_open_file_size: Some(5), @@ -270,6 +273,7 @@ impl ConfigManager { space_dot_omission: Some(false), show_minimap: Some(false), show_sticky_scroll: Some(false), + word_wrap: Some(false), layout: Some("horizontal".to_string()), last_direction: Some("horizontal".to_string()), max_open_file_size: Some(5), diff --git a/src/App.vue b/src/App.vue index 69ad0a2e..022edf22 100644 --- a/src/App.vue +++ b/src/App.vue @@ -53,6 +53,8 @@