175 Commits

Author SHA1 Message Date
28072c7f90 📝 Update document 2025-11-18 18:46:27 +08:00
991a89147e 🎨 Optimize code 2025-11-17 23:14:58 +08:00
a08c0d8448 🎨 Modify code block logic 2025-11-17 22:11:16 +08:00
59db8dd177 Added Monocraft font 2025-11-16 22:04:02 +08:00
29693f1baf 💄 Modify some styles 2025-11-16 21:23:59 +08:00
5d6f157ae1 🎨 Update initial code block definition
Some checks failed
Build and Release Voidraft / prepare (push) Failing after 2s
Build and Release Voidraft / build (push) Has been cancelled
Build and Release Voidraft / release (push) Has been cancelled
2025-11-16 17:49:19 +08:00
afda3d5301 Merge remote-tracking branch 'github/dependabot/npm_and_yarn/frontend/js-yaml-4.1.1' 2025-11-16 15:44:58 +08:00
5d4ba757aa Optimize HTTP client 2025-11-16 15:41:16 +08:00
d12d58b15a 🐛 Fixed markdown preview issue 2025-11-16 15:22:49 +08:00
627c3dc71f 🐛 Fixed markdown preview issue 2025-11-16 15:16:49 +08:00
26c7a3241c 🐛 Fixed module path issues 2025-11-16 02:42:59 +08:00
46c5e3dd1a Added markdown and mermaid preview 2025-11-16 02:42:01 +08:00
dependabot[bot]
92a6c6bfdb ⬆️ Bump js-yaml from 4.1.0 to 4.1.1 in /frontend
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-15 18:38:56 +00:00
031aa49f9f Added markdown and mermaid preview 2025-11-16 02:37:30 +08:00
1d7aee4cea 🐛 Fixed data migration issues 2025-11-14 20:16:16 +08:00
dec3ef5ef4 Added cursor protection extension 2025-11-13 21:00:35 +08:00
d42f913250 Added editor cursor state persistence 2025-11-13 20:44:47 +08:00
bae4e663fb ⬆️ Upgrade dependencies 2025-11-13 20:02:22 +08:00
a17e060d16 ⬆️ Upgrade dependencies 2025-11-13 19:36:11 +08:00
71946965eb 🐛 Fixed database constraint issues 2025-11-08 17:35:29 +08:00
d4cd22d234 🚀 Update build and release workflows 2025-11-08 17:17:07 +08:00
05f2f7d46d 🚀 Update build and release workflows 2025-11-08 17:05:31 +08:00
9deb2744a9 🚀 Update build and release workflows 2025-11-08 16:24:22 +08:00
6fac7c42d6 🚀 Update build and release workflows 2025-11-08 16:03:26 +08:00
3393bc84e3 🚀 Add build and release workflows 2025-11-08 15:50:30 +08:00
286b0159d7 🎨 Optimize update services
Some checks failed
Deploy VitePress site to Pages / build (push) Has been cancelled
Deploy VitePress site to Pages / Deploy (push) Has been cancelled
2025-11-08 00:00:08 +08:00
cc98e556c6 ♻️ Optimize code
Some checks failed
Deploy VitePress site to Pages / build (push) Has been cancelled
Deploy VitePress site to Pages / Deploy (push) Has been cancelled
2025-11-07 22:34:12 +08:00
5902f482d9 ♻️ Refactor configuration change notification service 2025-11-07 00:35:11 +08:00
551e7e2cfd Optimize hotkey service 2025-11-06 22:42:44 +08:00
e0179b5838 🎨 Optimize hotkey service 2025-11-06 00:08:26 +08:00
df79267e16 Optimize multi-window services 2025-11-05 22:07:43 +08:00
1f0254822f 🎨 Optimize multi-window services 2025-11-05 00:10:26 +08:00
e9b6fef3cd Added mermaid language support 2025-11-04 22:58:36 +08:00
689b0d5d14 🚀 Fixed resource path issues 2025-11-04 01:21:10 +08:00
a058e62595 🚀 Fixed resource path issues 2025-11-04 01:07:28 +08:00
8571fc0f5c 🚀 Fixed resource path issues 2025-11-04 00:57:49 +08:00
4dad0a86b3 🚀 Improve deployment scripts 2025-11-04 00:36:32 +08:00
3168b7ff43 🚀 Modify deployment command 2025-11-04 00:27:34 +08:00
d002a5be5a 🚀 Adjust base path 2025-11-04 00:16:39 +08:00
24a550463c 🚀 Remove dead links 2025-11-03 23:58:27 +08:00
14ae3e80c4 Beautify style and add automatic deployment scripts 2025-11-03 23:38:15 +08:00
e4d3969e95 📝 Build document directory structure 2025-11-03 22:49:38 +08:00
0b16d1d4ac Merge branch 'master' into docs 2025-11-03 22:18:06 +08:00
300514531d Improve HTTP client function 2025-11-03 22:15:45 +08:00
6a4780b002 📝 Replace official website framework 2025-11-02 22:48:33 +08:00
5688304817 🎨 Add variable support for http client 2025-11-02 17:20:22 +08:00
4380ad010c 🎨 Supports file upload 2025-11-02 01:53:11 +08:00
4fa6bb42e3 ⬆️ Upgrade dependencies 2025-11-02 00:16:57 +08:00
7aa3a7e37f 🚧 Improve HTTP language parser 2025-11-02 00:01:16 +08:00
94306497a9 🚧 Improve HTTP language parser 2025-11-01 21:40:51 +08:00
93c85b800b 🚧 Optimized HTTP language parser 2025-11-01 17:42:22 +08:00
8ac78e39f1 🚧 Added HTTP language parser 2025-10-31 19:39:44 +08:00
61a23fe7f2 🐛 Fixed tab and multi-window issues 2025-10-23 19:07:11 +08:00
87fea58102 Merge pull request #6 from landaiqing/dependabot/npm_and_yarn/frontend/vite-7.1.11
⬆️ Bump vite from 7.1.10 to 7.1.11 in /frontend
2025-10-21 10:25:54 +08:00
dependabot[bot]
edeac01bee ⬆️ Bump vite from 7.1.10 to 7.1.11 in /frontend
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.1.10 to 7.1.11.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.1.11/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.1.11
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-21 01:50:20 +00:00
852424356a 🐛 Fixed startup failure issue 2025-10-20 23:07:29 +08:00
b704dd2438 🎨 Optimize code 2025-10-20 23:00:04 +08:00
aa8139884b 🎨 Optimize preset theme code 2025-10-20 21:58:37 +08:00
9a15df01ee Added preset theme 2025-10-19 23:57:03 +08:00
03780b5bc7 ⬆️ Upgrade dependencies 2025-10-10 23:40:23 +08:00
b5d90cc59a Added the ability to automatically scroll to active tabs 2025-10-05 18:53:49 +08:00
d49ffc20df 🎨 Refactor and optimize code 2025-10-05 00:58:27 +08:00
c22e349181 🐛 Fixed tab switch issue 2025-10-04 14:31:06 +08:00
45968cd353 Added tab functionality and optimized related configurations 2025-10-04 02:27:32 +08:00
2d02bf7f1f 🚧 Optimize 2025-10-01 22:32:57 +08:00
1216b0b67c 🚧 Optimize 2025-10-01 18:15:22 +08:00
cf8bf688bf 🚧 Optimize 2025-09-30 00:28:15 +08:00
4d6a4ff79f 🐛 Fixed SQLite time field issue 2025-09-29 00:59:59 +08:00
3077d5a7c5 ♻️ Refactor document selector and cache management logic 2025-09-29 00:26:05 +08:00
bc0569af93 🎨 Optimize code structure 2025-09-28 01:09:20 +08:00
0188b618f2 🐛 Fixed docker prettier plugin issue 2025-09-27 20:11:31 +08:00
08860e9a5c ⬆️ Update dependencies 2025-09-24 23:57:22 +08:00
a56d4ef379 Adds multiple code block language support 2025-09-24 23:05:21 +08:00
f5bfff80b7 🚨 Format code 2025-09-24 21:44:42 +08:00
1462d8a753 🐛 Fixed docker prettier plugin issue 2025-09-24 19:14:10 +08:00
39ee2d14f3 Optimize font size and add more fonts 2025-09-24 00:44:41 +08:00
e536cdd9ba 🐛 Fixed docker、shell prettier plugin issue 2025-09-23 19:43:26 +08:00
dc4b73406d 🐛 Fixed prettier plugin parser configuration issue 2025-09-21 23:23:43 +08:00
0012a5dc19 Added loading animation switch 2025-09-21 22:17:41 +08:00
3cda88371e 🐛 Fixed manual Chunks issue 2025-09-21 21:54:39 +08:00
0338351680 Improve app launch speed 2025-09-21 03:04:23 +08:00
e372a0dd7c 🎨 Modify the rendering logic of the checkbox 2025-09-21 01:14:33 +08:00
d597f379ff 🚚 Refactor directory structure 2025-09-21 00:11:40 +08:00
9222a52d91 Modified sql prettier plugin 2025-09-20 19:18:33 +08:00
c3670bb8cd Added dockerfile、lua prettier plugin 2025-09-20 01:30:16 +08:00
2ea3456ff7 Added dart prettier plugin 2025-09-19 19:41:48 +08:00
c9379f0edb Added python prettier plugin 2025-09-19 19:35:48 +08:00
f72010bd69 Added clang prettier plugin 2025-09-19 19:17:13 +08:00
cd027097f8 🐛 Fixed golang prettier plugin issue 2025-09-19 18:39:41 +08:00
9cbbf729c0 🔥 Remove powershell prettier plugin 2025-09-18 00:13:07 +08:00
landaiqing
c26c11e253 🐛 Fixed build issue 2025-09-17 09:54:43 +08:00
338ac358db 🚧 Modify toml,powershell prettier plugin(beta) 2025-09-17 00:12:39 +08:00
a83c7139c9 Added scala、powershell、groovy prettier plugin 2025-09-14 23:45:01 +08:00
42c7d11c09 📦 Optimized packaging 2025-09-13 20:25:19 +08:00
5ca5aa64c7 Added shell prettier plugin 2025-09-13 19:21:06 +08:00
eda7ef771e Added rust prettier plugin 2025-09-13 00:02:17 +08:00
593c4d7783 Added java prettier plugin 2025-09-12 23:01:19 +08:00
d24a522b32 Added php prettier plugin 2025-09-12 20:15:56 +08:00
41afb834ae Added sql prettier plugin 2025-09-12 00:52:19 +08:00
b745329e26 Added golang prettier plugin 2025-09-11 20:42:39 +08:00
1fb4f64cb3 Add update notifications 2025-09-06 01:21:02 +08:00
1f8e8981ce 🐛 Fixed version generation issues 2025-09-05 22:40:09 +08:00
a257d30dba 🎨 Modify configuration migration policy 2025-09-05 22:07:00 +08:00
97ee3b0667 🐛 Fixed configuration merge override issue 2025-09-05 00:36:33 +08:00
8e2bafba5f Optimize window snapping performance 2025-09-04 00:20:30 +08:00
6149bc133d 🐛 Fixed window pinning issue 2025-09-02 23:59:04 +08:00
5f22ee3b1f ♻️ Refactoring configuration migration service 2025-08-31 17:48:41 +08:00
fa72ff8061 Merge remote-tracking branch 'github/dependabot/go_modules/github.com/ulikunitz/xz-0.5.14' 2025-08-30 19:00:36 +08:00
65f24860e6 Added window snapping function toggle 2025-08-30 00:18:29 +08:00
dependabot[bot]
4881233211 ⬆️ Bump github.com/ulikunitz/xz from 0.5.12 to 0.5.14
Bumps [github.com/ulikunitz/xz](https://github.com/ulikunitz/xz) from 0.5.12 to 0.5.14.
- [Commits](https://github.com/ulikunitz/xz/compare/v0.5.12...v0.5.14)

---
updated-dependencies:
- dependency-name: github.com/ulikunitz/xz
  dependency-version: 0.5.14
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 19:44:41 +00:00
bc01fdf362 Added window snapping feature 2025-08-24 16:07:48 +08:00
709998ff9c 🐛 Fixed hotkey crashes 2025-08-19 22:26:55 +08:00
6adeadeed4 🐛 Fixed document deadlock issue 2025-08-19 00:24:51 +08:00
7b70a39b23 🐛 Fixed hotkey service issues 2025-08-19 00:08:50 +08:00
873a3c0e60 Modify the theme storage schema 2025-08-17 19:34:35 +08:00
5b88efcfbe 🐛 Fixed the window toggle maximise issue 2025-08-17 14:51:39 +08:00
f37c659c89 🐛 Adjusted error message and icon clearing logic 2025-07-17 11:03:42 +08:00
9fff7bcfca Added the backup feature 2025-07-17 00:12:00 +08:00
b4b0ad9bba 🎨 Optimize storage logic 2025-07-13 22:32:58 +08:00
6d8fdf62f1 💡 Update docs 2025-07-13 11:58:53 +08:00
9f53d7421d Merge remote-tracking branch 'github/master' 2025-07-12 23:56:43 +08:00
80c8ecb4cf 💡 Update docs 2025-07-12 23:56:04 +08:00
d10059a82d Create CNAME 2025-07-12 22:25:19 +08:00
737f83cd5f 💡 Add docs 2025-07-12 22:14:35 +08:00
a720a4cfb8 Complete the custom editor theme 2025-07-11 23:03:28 +08:00
b5510d605c Add multi-window document functionality 2025-07-10 18:45:51 +08:00
4d62da912a ⬆️ Upgrade wails v3 from Alpha 9 to Alpha 10 2025-07-10 10:01:52 +08:00
b52e067d50 🍎 Fix build issues 2025-07-08 17:36:45 +08:00
8dce06c30e 🐛 Fixed the reboot issue on different platforms 2025-07-08 12:41:30 +08:00
b404434b5b 🎨 Updated 2025-07-07 16:09:09 +08:00
685897e828 🎨 Updated 2025-07-07 15:55:48 +08:00
4f1d70135e 📝 README.md 2025-07-07 15:41:46 +08:00
4dc424781b 📄 Change the license 2025-07-07 13:39:54 +08:00
7fcfc5e992 🎨 Refactoring the extension service and the keybinding service 2025-07-07 13:19:59 +08:00
7c2318a13f Add translation features 2025-07-06 23:41:15 +08:00
a2a332e735 Added context menu 2025-07-04 14:37:35 +08:00
ebee33ea7c Add self-updating service 2025-07-03 15:21:01 +08:00
81eb2c94ac 🐛 Fixed some issues 2025-07-02 12:10:46 +08:00
25e1a98932 🐛 Fixed block formatting issue 2025-07-01 23:55:15 +08:00
1ccee779ae 🐛 Fixed extension management issues 2025-07-01 23:25:24 +08:00
3e45e6aa9b Performance optimization 2025-07-01 20:11:27 +08:00
1604564e63 Complete multi-document mode 2025-07-01 18:16:05 +08:00
70d88dabba Use SQLite instead of JSON storage 2025-06-29 23:42:06 +08:00
6f8775472d Add selection box extension 2025-06-25 23:50:57 +08:00
a9b967aba4 🐛 Fixed the issue of text highlighting expansion 2025-06-25 22:53:00 +08:00
69957a16cf 🎨 binding keymap and extension 2025-06-25 21:09:21 +08:00
650884cb85 Improve extension management 2025-06-25 17:50:50 +08:00
8e91e3cf7c Add extension management page 2025-06-24 19:18:30 +08:00
f3bcb87828 Add extension management service 2025-06-24 14:16:53 +08:00
ea025e3f5d Add update service 2025-06-23 19:42:48 +08:00
4f8272e290 Add configuration merge service 2025-06-23 12:03:56 +08:00
d6dd34db87 ♻️ Refactor and clean up the code 2025-06-22 21:30:45 +08:00
eb9b037f8e 🎨 Optimize code 2025-06-22 15:08:38 +08:00
35c89e086e 🎨 Updated 2025-06-22 12:08:50 +08:00
77287bccfa 🎨 Updated 2025-06-21 19:05:08 +08:00
a92e5486b2 🐛 Fixed theme and packaging issues 2025-06-21 15:33:50 +08:00
1153c0a652 🐛 Fixed bug 2025-06-21 15:04:04 +08:00
145b868a44 🐛 Fixed the issue of deleting blocks 2025-06-21 00:34:22 +08:00
6acab678d0 Unified management of keymap 2025-06-21 00:28:35 +08:00
cb3d369aef 🎨 Updated 2025-06-20 13:46:13 +08:00
85544ba1e4 Added key binding service 2025-06-20 13:37:48 +08:00
13072a00a1 Add formatting method 2025-06-19 20:23:20 +08:00
25858cb42b Use guesslang to detect the language 2025-06-19 16:55:02 +08:00
f2894b2a89 🐛 Fixed the issue of block creation 2025-06-19 13:40:25 +08:00
a62ea251cd Cancel use HTTP services and WebSockets 2025-06-19 10:44:27 +08:00
3c880199ae ♻️ Refactor code 2025-06-19 01:05:08 +08:00
9204315c7b Improve code block function 2025-06-18 21:19:19 +08:00
cce9cf7e92 Add code blocks and rainbow bracket extensions 2025-06-18 18:16:56 +08:00
87fe9d48b1 🎨 Update 2025-06-17 19:15:59 +08:00
1d6cf7cf68 Added text highlight and minimap 2025-06-17 17:31:01 +08:00
0927b921c3 🎨 Update 2025-06-12 00:58:35 +08:00
4844ccdf58 Added hyperlink extension 2025-06-10 21:28:50 +08:00
c79cba48c2 Added search and replace 2025-06-10 19:17:29 +08:00
ceb177114d 🐛 Fixed the bug of obtaining the operating system 2025-06-09 14:18:25 +08:00
5203784b63 Added window title bars for different operating systems 2025-06-09 03:02:07 +08:00
765 changed files with 92604 additions and 10688 deletions

325
.github/workflows/build-release.yml vendored Normal file
View File

@@ -0,0 +1,325 @@
name: Build and Release Voidraft
on:
# 推送标签时触发(用于正式发布)
push:
tags:
- 'v*' # 触发条件:推送 v 开头的标签,如 v1.0.0
branches:
- main # 仅当标签在 main 分支时触发
# 手动触发(用于测试)
workflow_dispatch:
inputs:
release:
description: '是否创建 Release测试时选 false'
required: true
type: boolean
default: false
platforms:
description: '要构建的平台用逗号分隔windows,linux,macos-intel,macos-arm'
required: true
type: string
default: 'windows,linux'
env:
NODE_OPTIONS: "--max-old-space-size=4096" # 防止 Node.js 内存溢出
jobs:
# 准备构建配置
prepare:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
should_release: ${{ steps.check-release.outputs.should_release }}
steps:
- name: 确定构建平台
id: set-matrix
run: |
# 如果是手动触发,根据输入决定平台
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
PLATFORMS="${{ github.event.inputs.platforms }}"
else
# 标签触发,构建所有平台
PLATFORMS="windows,linux,macos-intel,macos-arm"
fi
echo "构建平台: $PLATFORMS"
# 构建矩阵 JSON
MATRIX='{"include":[]}'
if [[ "$PLATFORMS" == *"windows"* ]]; then
MATRIX=$(echo "$MATRIX" | jq -c '.include += [{"platform":"windows-latest","os":"windows","arch":"amd64","platform_dir":"windows","id":"windows"}]')
fi
if [[ "$PLATFORMS" == *"linux"* ]]; then
MATRIX=$(echo "$MATRIX" | jq -c '.include += [{"platform":"ubuntu-22.04","os":"linux","arch":"amd64","platform_dir":"linux","id":"linux"}]')
fi
if [[ "$PLATFORMS" == *"macos-intel"* ]]; then
MATRIX=$(echo "$MATRIX" | jq -c '.include += [{"platform":"macos-latest","os":"darwin","arch":"amd64","platform_dir":"darwin","id":"macos-intel"}]')
fi
if [[ "$PLATFORMS" == *"macos-arm"* ]]; then
MATRIX=$(echo "$MATRIX" | jq -c '.include += [{"platform":"macos-latest","os":"darwin","arch":"arm64","platform_dir":"darwin","id":"macos-arm"}]')
fi
# 使用 -c 确保输出紧凑的单行 JSON符合 GitHub Actions 输出格式
echo "matrix=$(echo "$MATRIX" | jq -c .)" >> $GITHUB_OUTPUT
# 输出美化的 JSON 用于日志查看
echo "生成的矩阵:"
echo "$MATRIX" | jq .
- name: 检查是否创建 Release
id: check-release
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
# 手动触发,根据输入决定
echo "should_release=${{ github.event.inputs.release }}" >> $GITHUB_OUTPUT
else
# 标签触发,自动创建 Release
echo "should_release=true" >> $GITHUB_OUTPUT
fi
build:
needs: prepare
if: ${{ fromJson(needs.prepare.outputs.matrix).include[0] != null }}
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
runs-on: ${{ matrix.platform }}
steps:
- name: 检出代码
uses: actions/checkout@v4
with:
submodules: recursive
- name: 设置 Go 环境
uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: true
- name: 设置 Node.js 环境
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
# Linux 平台依赖
- name: 安装 Linux 依赖
if: matrix.os == 'linux'
run: |
sudo apt-get update
# Wails 3 + 项目特定依赖
sudo apt-get install -y \
build-essential \
pkg-config \
libgtk-3-dev \
libwebkit2gtk-4.1-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
patchelf \
libx11-dev \
rpm \
fuse \
file
# 依赖说明:
# - build-essential: C/C++ 编译工具链
# - pkg-config: 包配置工具
# - libgtk-3-dev: GTK3 GUI 框架
# - libwebkit2gtk-4.1-dev: WebKit2GTK 4.1 (Wails 3 要求)
# - libayatana-appindicator3-dev: 系统托盘支持
# - librsvg2-dev: SVG 图标支持
# - patchelf: 修改 ELF 二进制文件
# - libx11-dev: X11 库 (热键服务依赖)
# - rpm: RPM 打包工具
# - fuse: AppImage 运行依赖
# - file: 文件类型检测工具
# Windows 平台依赖
- name: 设置 Windows 构建环境
if: matrix.os == 'windows'
run: |
# 安装 NSIS (用于创建安装程序)
choco install nsis -y
# 将 NSIS 添加到 PATH
echo "C:\Program Files (x86)\NSIS" >> $GITHUB_PATH
shell: bash
# macOS 平台依赖
- name: 设置 macOS 构建环境
if: matrix.os == 'darwin'
run: |
# Xcode 命令行工具通常已安装
xcode-select --install 2>/dev/null || true
# 安装 Wails CLI
- name: 安装 Wails CLI
run: go install github.com/wailsapp/wails/v3/cmd/wails3@latest
# 安装前端依赖
- name: 安装前端依赖
working-directory: frontend
run: npm ci
# 构建前端
- name: 构建前端
working-directory: frontend
run: npm run build
# 使用 Wails Task 构建和打包应用
- name: 构建和打包 Wails 应用
run: wails3 task ${{ matrix.id }}:package PRODUCTION=true ARCH=${{ matrix.arch }}
env:
CGO_ENABLED: 1
APP_NAME: voidraft
BIN_DIR: bin
ROOT_DIR: .
shell: bash
# 整理构建产物
- name: 整理构建产物
id: organize_artifacts
run: |
echo "=== 构建产物列表 ==="
ls -lhR bin/ || echo "bin 目录不存在"
# 创建输出目录
mkdir -p artifacts
# 根据平台复制产物
if [ "${{ matrix.os }}" = "windows" ]; then
echo "Windows 平台:查找 NSIS 安装程序"
find . -name "*.exe" -type f
cp bin/*.exe artifacts/ 2>/dev/null || echo "未找到 .exe 文件"
elif [ "${{ matrix.os }}" = "linux" ]; then
echo "Linux 平台:查找 AppImage, deb, rpm, archlinux 包"
find bin -type f
cp bin/*.AppImage artifacts/ 2>/dev/null || echo "未找到 AppImage"
cp bin/*.deb artifacts/ 2>/dev/null || echo "未找到 deb"
cp bin/*.rpm artifacts/ 2>/dev/null || echo "未找到 rpm"
cp bin/*.pkg.tar.zst artifacts/ 2>/dev/null || echo "未找到 archlinux 包"
elif [ "${{ matrix.os }}" = "darwin" ]; then
echo "macOS 平台:查找 .app bundle"
find bin -name "*.app" -type d
# macOS: .app bundle打包成 zip
if [ -d "bin/voidraft.app" ]; then
cd bin
zip -r ../artifacts/voidraft-darwin-${{ matrix.arch }}.app.zip voidraft.app
cd ..
else
echo "未找到 .app bundle"
fi
fi
echo "=== 最终产物 ==="
ls -lh artifacts/ || echo "artifacts 目录为空"
shell: bash
# 上传构建产物到 Artifacts
- name: 上传构建产物
uses: actions/upload-artifact@v4
with:
name: voidraft-${{ matrix.id }}
path: artifacts/*
if-no-files-found: warn
# 创建 GitHub Release 并上传所有构建产物
release:
needs: [prepare, build]
if: ${{ needs.prepare.outputs.should_release == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 下载所有构建产物
uses: actions/download-artifact@v4
with:
path: artifacts
- name: 显示下载的文件
run: |
echo "下载的构建产物:"
ls -R artifacts/
- name: 准备 Release 文件
run: |
mkdir -p release
find artifacts -type f -exec cp {} release/ \;
ls -lh release/
- name: 生成 Release 说明
id: release_notes
run: |
# 获取版本号
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="${{ github.sha }}"
VERSION_NAME="测试构建 ${VERSION:0:7}"
else
VERSION="${{ github.ref_name }}"
VERSION_NAME="${VERSION}"
fi
cat > release_notes.md << EOF
## Voidraft ${VERSION_NAME}
### 📦 下载
根据你的操作系统选择对应的版本:
- **Windows (64位)**: \`voidraft-windows-amd64.exe\`
- **Linux (64位)**: \`voidraft-linux-amd64\`
- **macOS (Intel)**: \`voidraft-darwin-amd64.zip\`
- **macOS (Apple Silicon)**: \`voidraft-darwin-arm64.zip\`
### 📝 更新内容
请查看 [提交历史](../../commits/${{ github.ref_name }}) 了解本次更新的详细内容。
### 💡 使用说明
#### Windows
1. 下载 `voidraft-windows-amd64.exe`
2. 直接运行即可
#### Linux
1. 下载 `voidraft-linux-amd64`
2. 添加执行权限:`chmod +x voidraft-linux-amd64`
3. 运行:`./voidraft-linux-amd64`
#### macOS
1. 下载对应架构的 zip 文件
2. 解压后运行
3. 如果提示无法打开,请在 系统偏好设置 > 安全性与隐私 中允许运行
---
构建时间: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
EOF
- name: 创建 GitHub Release
uses: softprops/action-gh-release@v2
with:
files: release/*
body_path: release_notes.md
draft: false
prerelease: ${{ github.event_name == 'workflow_dispatch' }}
tag_name: ${{ github.event_name == 'workflow_dispatch' && format('test-{0}', github.sha) || github.ref_name }}
name: ${{ github.event_name == 'workflow_dispatch' && format('测试构建 {0}', github.sha) || github.ref_name }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

67
.github/workflows/deploy.yml vendored Normal file
View File

@@ -0,0 +1,67 @@
# 构建 VitePress 站点并将其部署到 GitHub Pages 的示例工作流程
#
name: Deploy VitePress site to Pages
on:
# 在针对 `main` 分支的推送上运行。如果你
# 使用 `master` 分支作为默认分支,请将其更改为 `master`
push:
branches: [master]
# 允许你从 Actions 选项卡手动运行此工作流程
workflow_dispatch:
# 设置 GITHUB_TOKEN 的权限,以允许部署到 GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# 只允许同时进行一次部署,跳过正在运行和最新队列之间的运行队列
# 但是,不要取消正在进行的运行,因为我们希望允许这些生产部署完成
concurrency:
group: pages
cancel-in-progress: false
jobs:
# 构建工作
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # 如果未启用 lastUpdated则不需要
# - uses: pnpm/action-setup@v3 # 如果使用 pnpm请取消此区域注释
# with:
# version: 9
# - uses: oven-sh/setup-bun@v1 # 如果使用 Bun请取消注释
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: frontend/package-lock.json
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Install dependencies
run: cd frontend && npm ci
- name: Build with VitePress
run: cd frontend && npm run docs:build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: frontend/docs/.vitepress/dist
# 部署工作
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
name: Deploy
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

4
.gitignore vendored
View File

@@ -4,4 +4,6 @@ frontend/dist
frontend/node_modules
build/linux/appimage/build
build/windows/nsis/MicrosoftEdgeWebview2Setup.exe
.idea
.idea
frontend/docs/.vitepress/cache/
frontend/docs/.vitepress/dist/

83
LICENSE
View File

@@ -1,73 +1,18 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
MIT License
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Copyright (c) 2025 landaiqing
1. Definitions.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
Copyright 2025 landaiqing
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.

174
README.md
View File

@@ -1,59 +1,163 @@
# Welcome to Your New Wails3 Project!
# <img src="./frontend/public/appicon.png" alt="voidraft Logo" width="32" height="32" style="vertical-align: middle;"> voidraft
Congratulations on generating your Wails3 application! This README will guide you through the next steps to get your project up and running.
[中文](README_ZH.md) | **English**
## Getting Started
> *An elegant text snippet recording tool designed for developers.*
1. Navigate to your project directory in the terminal.
voidraft is a modern developer-focused text editor that allows you to record, organize, and manage various text snippets anytime, anywhere. Whether it's temporary code snippets, API responses, meeting notes, or daily to-do lists, voidraft provides a smooth and elegant editing experience.
2. To run your application in development mode, use the following command:
## Core Features
```
wails3 dev
```
### Developer-Friendly
This will start your application and enable hot-reloading for both frontend and backend changes.
- Multi-language code block support - Syntax highlighting for 30+ programming languages
- Smart language detection - Automatically recognizes code block language types
- Code formatting - Built-in Prettier support for one-click code beautification
- Block editing mode - Split content into independent code blocks, each with different language settings
- Multi-window support - edit multiple documents at the same time
- Support for custom themes - Custom editor themes
3. To build your application for production, use:
### Modern Interface
```
wails3 build
```
- Clean and elegant design - Simple yet sophisticated user interface
- Dark/Light themes - Adapts to different usage scenarios
- Multi-language support - Built-in internationalization with multiple language switching
This will create a production-ready executable in the `build` directory.
### Extension System
## Exploring Wails3 Features
- Modular architecture - Extensible editor based on CodeMirror 6
- Rich extensions - Includes various practical editor extensions
- Rainbow bracket matching
- VSCode-style search and replace
- Color picker
- Built-in translation tool
- Text highlighting
- Code folding
- Hyperlink support
- Checkbox support
- Minimap
Now that you have your project set up, it's time to explore the features that Wails3 offers:
## Quick Start
1. **Check out the examples**: The best way to learn is by example. Visit the `examples` directory in the `v3/examples` directory to see various sample applications.
### Download and Use
2. **Run an example**: To run any of the examples, navigate to the example's directory and use:
1. Visit the releases page: https://github.com/landaiqing/voidraft/releases
2. Select and download the appropriate version
3. Run the installer and start using
```
go run .
```
### Development Environment
Note: Some examples may be under development during the alpha phase.
```bash
# Clone the project
git clone https://github.com/landaiqing/voidraft
cd voidraft
3. **Explore the documentation**: Visit the [Wails3 documentation](https://v3alpha.wails.io/) for in-depth guides and API references.
# Install frontend dependencies
cd frontend
npm install
npm run build
cd ..
4. **Join the community**: Have questions or want to share your progress? Join the [Wails Discord](https://discord.gg/JDdSxwjhGf) or visit the [Wails discussions on GitHub](https://github.com/wailsapp/wails/discussions).
# Start development server
wails3 dev
```
### Production Build
```bash
# Build application
wails3 package
```
After building, the executable will be generated in the `bin` directory.
## Technical Architecture
### Core Technologies
| Layer | Technology Stack |
|-------|------------------|
| Desktop Framework | Wails3 |
| Backend Language | Go 1.21+ |
| Frontend Framework | Vue 3 + TypeScript |
| Editor Core | CodeMirror 6 |
| Build Tool | Vite |
| Data Storage | SQLite |
## Project Structure
Take a moment to familiarize yourself with your project structure:
```
voidraft/
├── frontend/ # Vue 3 frontend application
│ ├── src/
│ │ ├── views/editor/ # Editor core views
│ │ │ ├── extensions/ # Editor extension system
│ │ │ │ ├── codeblock/ # Code block support
│ │ │ │ ├── translator/ # Translation tool
│ │ │ │ ├── minimap/ # Code minimap
│ │ │ │ ├── vscodeSearch/ # VSCode-style search
│ │ │ │ └── ... # More extensions
│ │ │ └── ...
│ │ ├── components/ # Reusable components
│ │ ├── stores/ # Pinia state management
│ │ └── utils/ # Utility functions
│ └── public/ # Static assets
├── internal/ # Go backend core
│ ├── services/ # Core business services
│ ├── models/ # Data model definitions
│ └── events/ # Event handling mechanisms
└── main.go # Application entry point
```
- `frontend/`: Contains your frontend code (HTML, CSS, JavaScript/TypeScript)
- `main.go`: The entry point of your Go backend
- `app.go`: Define your application structure and methods here
- `wails.json`: Configuration file for your Wails project
## Development Roadmap
## Next Steps
### Platform Extension Plans
1. Modify the frontend in the `frontend/` directory to create your desired UI.
2. Add backend functionality in `main.go`.
3. Use `wails3 dev` to see your changes in real-time.
4. When ready, build your application with `wails3 build`.
| Platform | Status | Expected Time |
|----------|--------|---------------|
| macOS | Planned | Future versions |
| Linux | Planned | Future versions |
Happy coding with Wails3! If you encounter any issues or have questions, don't hesitate to consult the documentation or reach out to the Wails community.
### Planned Features
- ✅ Custom themes - Customize editor themes
- ✅ Multi-window support - Support editing multiple documents simultaneously
- ✅ Data synchronization - Cloud backup for documents
- [ ] Enhanced clipboard - Monitor and manage clipboard history
- [ ] Extension system - Support for custom plugins
## Acknowledgments
> Standing on the shoulders of giants, paying tribute to the open source spirit
The birth of voidraft is inseparable from the following excellent open source projects:
### Special Thanks
- **[Heynote](https://github.com/heyman/heynote/)** - voidraft is a feature-enhanced version based on Heynote's concept
- Inherits Heynote's elegant block editing philosophy
- Adds more practical features on the original foundation
- Rebuilt with modern technology stack
- Provides richer extension system and customization options
- Thanks to the Heynote team for bringing innovative ideas to the developer community
### Core Technology Stack
| Technology | Purpose | Link |
|------------|---------|------|
| Wails3 | Cross-platform desktop application framework | [wails.io](https://v3alpha.wails.io/) |
| Vue.js | Progressive frontend framework | [vuejs.org](https://vuejs.org/) |
| CodeMirror 6 | Modern code editor | [codemirror.net](https://codemirror.net/) |
| Prettier | Code formatting tool | [prettier.io](https://prettier.io/) |
| TypeScript | Type-safe JavaScript | [typescriptlang.org](https://www.typescriptlang.org/) |
## License
This project is open source under the [MIT License](LICENSE).
Welcome to Fork, Star, and contribute code.
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![GitHub stars](https://img.shields.io/github/stars/landaiqing/voidraft.svg?style=social&label=Star)](https://github.com/yourusername/voidraft)
[![GitHub forks](https://img.shields.io/github/forks/landaiqing/voidraft.svg?style=social&label=Fork)](https://github.com/yourusername/voidraft)
*Made with ❤️ by landaiqing*

165
README_ZH.md Normal file
View File

@@ -0,0 +1,165 @@
# <img src="./frontend/public/appicon.png" alt="voidraft Logo" width="32" height="32" style="vertical-align: middle;"> voidraft
**中文** | [English](README.md)
> *一个专为开发者打造的优雅文本片段记录工具。*
voidraft 是一个现代化的开发者专用文本编辑器让你能够随时随地记录、整理和管理各种文本片段。无论是临时的代码片段、API 响应、会议笔记还是日常的待办事项voidraft 都能为你提供流畅而优雅的编辑体验。
## 核心特性
### 开发者友好
- 多语言代码块支持 - 支持 30+ 种编程语言的语法高亮
- 智能语言检测 - 自动识别代码块语言类型
- 代码格式化 - 内置 Prettier 支持,一键美化代码
- 块状编辑模式 - 将内容分割为独立的代码块,每个块可设置不同语言
- 支持多窗口 - 同时编辑多个文档
- 支持自定义主题 - 自定义编辑器主题
### 现代化界面
- 清新脱俗的设计 - 简洁而不失优雅的用户界面
- 深色/浅色主题 - 适应不同使用场景
- 多语言支持 - 内置国际化功能,支持多种语言切换
### 扩展系统
- 模块化架构 - 基于 CodeMirror 6 的可扩展编辑器
- 丰富的扩展 - 包含多种实用编辑器扩展
- 彩虹括号匹配
- VSCode 风格搜索替换
- 颜色选择器
- 内置翻译工具
- 文本高亮
- 代码折叠
- 超链接支持
- 复选框支持
- 小地图
## 快速开始
### 下载使用
1. 访问发布页面https://github.com/landaiqing/voidraft/releases
2. 选择适合的版本下载
3. 运行安装程序,开始使用
### 开发环境
```bash
# 克隆项目
git clone https://github.com/landaiqing/voidraft
cd voidraft
# 安装前端依赖
cd frontend
npm install
npm run build
cd ..
# 启动开发服务器
wails3 dev
```
### 生产构建
```bash
# 构建应用
wails3 package
```
构建完成后,可执行文件将生成在 `bin` 目录中。
## 技术架构
### 核心技术
| 层级 | 技术栈 |
|------|--------|
| 桌面框架 | Wails3 |
| 后端语言 | Go 1.21+ |
| 前端框架 | Vue 3 + TypeScript |
| 编辑器核心 | CodeMirror 6 |
| 构建工具 | Vite |
| 数据存储 | SQLite |
## 项目结构
```
voidraft/
├── frontend/ # Vue 3 前端应用
│ ├── src/
│ │ ├── views/editor/ # 编辑器核心视图
│ │ │ ├── extensions/ # 编辑器扩展系统
│ │ │ │ ├── codeblock/ # 代码块支持
│ │ │ │ ├── translator/ # 翻译工具
│ │ │ │ ├── minimap/ # 代码小地图
│ │ │ │ ├── vscodeSearch/ # VSCode风格搜索
│ │ │ │ └── ... # 更多扩展
│ │ │ └── ...
│ │ ├── components/ # 可复用组件
│ │ ├── stores/ # Pinia 状态管理
│ │ └── utils/ # 工具函数库
│ └── public/ # 静态资源文件
├── internal/ # Go 后端核心
│ ├── services/ # 核心业务服务
│ ├── models/ # 数据模型定义
│ └── events/ # 事件处理机制
└── main.go # 应用程序入口
```
## 开发路线图
### 平台扩展计划
| 平台 | 状态 | 预期时间 |
|------|------|----------|
| macOS | 计划中 | 后续版本 |
| Linux | 计划中 | 后续版本 |
### 计划添加的功能
- ✅ 自定义主题 - 自定义编辑器主题
- ✅ 多窗口支持 - 支持同时编辑多个文档
- ✅ 数据同步 - 文档云端备份
- [ ] 剪切板增强 - 监听和管理剪切板历史
- [ ] 扩展系统 - 支持自定义插件
## 致谢
> 站在巨人的肩膀上,致敬开源精神
voidraft 的诞生离不开以下优秀的开源项目:
### 特别感谢
- **[Heynote](https://github.com/heyman/heynote/)** - voidraft 是基于 Heynote 概念的功能增强版本
- 继承了 Heynote 优雅的块状编辑理念
- 在原有基础上增加了更多实用功能
- 采用现代化技术栈重新构建
- 提供更丰富的扩展系统和自定义选项
- 感谢 Heynote 团队为开发者社区带来的创新思路
### 核心技术栈
| 技术 | 用途 | 链接 |
|------|------|------------------------------------------------------|
| Wails3 | 跨平台桌面应用框架 | [wails.io](https://v3alpha.wails.io/) |
| Vue.js | 渐进式前端框架 | [vuejs.org](https://vuejs.org/) |
| CodeMirror 6 | 现代化代码编辑器 | [codemirror.net](https://codemirror.net/) |
| Prettier | 代码格式化工具 | [prettier.io](https://prettier.io/) |
| TypeScript | 类型安全的 JavaScript | [typescriptlang.org](https://www.typescriptlang.org/) |
## 许可证
本项目采用 [MIT 许可证](LICENSE) 开源。
欢迎 Fork、Star 和贡献代码。
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![GitHub stars](https://img.shields.io/github/stars/landaiqing/voidraft.svg?style=social&label=Star)](https://github.com/yourusername/voidraft)
[![GitHub forks](https://img.shields.io/github/forks/landaiqing/voidraft.svg?style=social&label=Fork)](https://github.com/yourusername/voidraft)
*Made with ❤️ by landaiqing*

293
build/COMMANDS.md Normal file
View File

@@ -0,0 +1,293 @@
# Wails 3 命令参考表
本文档列出了 Voidraft 项目中使用的所有 Wails 3 命令和参数。
## 📋 命令总览
| 类别 | 命令 | 用途 |
|------|------|------|
| 生成工具 | `wails3 generate` | 生成项目所需的各种资源文件 |
| 打包工具 | `wails3 tool package` | 使用 nfpm 打包应用程序 |
| 任务执行 | `wails3 task` | 执行 Taskfile.yml 中定义的任务 |
---
## 🔧 详细命令参数
### 1. `wails3 generate bindings`
**生成 TypeScript 绑定文件**
| 参数 | 说明 | 示例值 |
|------|------|--------|
| `-f` | 构建标志 | `''` (空字符串) |
| `-clean` | 清理旧绑定 | `true` |
| `-ts` | 生成 TypeScript | 无需值 |
**使用位置:** `build/Taskfile.yml:53`
**完整命令:**
```bash
wails3 generate bindings -f '' -clean=true -ts
```
---
### 2. `wails3 generate icons`
**从单个图片生成多平台图标**
| 参数 | 说明 | 示例值 |
|------|------|--------|
| `-input` | 输入图片路径 | `appicon.png` |
| `-macfilename` | macOS 图标输出路径 | `darwin/icons.icns` |
| `-windowsfilename` | Windows 图标输出路径 | `windows/icons.ico` |
**使用位置:** `build/Taskfile.yml:64`
**完整命令:**
```bash
wails3 generate icons \
-input appicon.png \
-macfilename darwin/icons.icns \
-windowsfilename windows/icons.ico
```
---
### 3. `wails3 generate syso`
**生成 Windows .syso 资源文件**
| 参数 | 说明 | 示例值 |
|------|------|--------|
| `-arch` | 目标架构 | `amd64` / `arm64` |
| `-icon` | 图标文件 | `windows/icon.ico` |
| `-manifest` | 清单文件 | `windows/wails.exe.manifest` |
| `-info` | 应用信息 JSON | `windows/info.json` |
| `-out` | 输出文件路径 | `../wails_windows_amd64.syso` |
**使用位置:** `build/windows/Taskfile.yml:42`
**完整命令:**
```bash
wails3 generate syso \
-arch amd64 \
-icon windows/icon.ico \
-manifest windows/wails.exe.manifest \
-info windows/info.json \
-out ../wails_windows_amd64.syso
```
---
### 4. `wails3 generate webview2bootstrapper`
**生成 Windows WebView2 引导程序**
| 参数 | 说明 | 示例值 |
|------|------|--------|
| `-dir` | 输出目录 | `build/windows/nsis` |
**使用位置:** `build/windows/Taskfile.yml:55`
**完整命令:**
```bash
wails3 generate webview2bootstrapper -dir "build/windows/nsis"
```
**说明:** 下载 Microsoft Edge WebView2 运行时安装程序,用于 NSIS 打包。
---
### 5. `wails3 generate .desktop`
**生成 Linux .desktop 桌面文件**
| 参数 | 说明 | 示例值 |
|------|------|--------|
| `-name` | 应用名称 | `voidraft` |
| `-exec` | 可执行文件名 | `voidraft` |
| `-icon` | 图标名称 | `appicon` |
| `-outputfile` | 输出文件路径 | `build/linux/voidraft.desktop` |
| `-categories` | 应用分类 | `Development;` |
**使用位置:** `build/linux/Taskfile.yml:107`
**完整命令:**
```bash
wails3 generate .desktop \
-name "voidraft" \
-exec "voidraft" \
-icon "appicon" \
-outputfile build/linux/voidraft.desktop \
-categories "Development;"
```
---
### 6. `wails3 generate appimage`
**生成 Linux AppImage 包**
| 参数 | 说明 | 示例值 |
|------|------|--------|
| `-binary` | 二进制文件名 | `voidraft` |
| `-icon` | 图标文件路径 | `../../appicon.png` |
| `-desktopfile` | .desktop 文件路径 | `../voidraft.desktop` |
| `-outputdir` | 输出目录 | `../../../bin` |
| `-builddir` | 构建临时目录 | `build/linux/appimage/build` |
**使用位置:** `build/linux/Taskfile.yml:49`
**完整命令:**
```bash
wails3 generate appimage \
-binary voidraft \
-icon ../../appicon.png \
-desktopfile ../voidraft.desktop \
-outputdir ../../../bin \
-builddir build/linux/appimage/build
```
**说明:** 自动下载 linuxdeploy 工具并创建 AppImage。
---
### 7. `wails3 tool package` (deb)
**创建 Debian/Ubuntu .deb 包**
| 参数 | 说明 | 示例值 |
|------|------|--------|
| `-name` | 包名称 | `voidraft` |
| `-format` | 包格式 | `deb` |
| `-config` | nfpm 配置文件 | `./build/linux/nfpm/nfpm.yaml` |
| `-out` | 输出目录 | `./bin` |
**使用位置:** `build/linux/Taskfile.yml:90`
**完整命令:**
```bash
wails3 tool package \
-name voidraft \
-format deb \
-config ./build/linux/nfpm/nfpm.yaml \
-out ./bin
```
---
### 8. `wails3 tool package` (rpm)
**创建 RedHat/CentOS/Fedora .rpm 包**
| 参数 | 说明 | 示例值 |
|------|------|--------|
| `-name` | 包名称 | `voidraft` |
| `-format` | 包格式 | `rpm` |
| `-config` | nfpm 配置文件 | `./build/linux/nfpm/nfpm.yaml` |
| `-out` | 输出目录 | `./bin` |
**使用位置:** `build/linux/Taskfile.yml:95`
**完整命令:**
```bash
wails3 tool package \
-name voidraft \
-format rpm \
-config ./build/linux/nfpm/nfpm.yaml \
-out ./bin
```
---
### 9. `wails3 tool package` (archlinux)
**创建 Arch Linux .pkg.tar.zst 包**
| 参数 | 说明 | 示例值 |
|------|------|--------|
| `-name` | 包名称 | `voidraft` |
| `-format` | 包格式 | `archlinux` |
| `-config` | nfpm 配置文件 | `./build/linux/nfpm/nfpm.yaml` |
| `-out` | 输出目录 | `./bin` |
**使用位置:** `build/linux/Taskfile.yml:100`
**完整命令:**
```bash
wails3 tool package \
-name voidraft \
-format archlinux \
-config ./build/linux/nfpm/nfpm.yaml \
-out ./bin
```
---
### 10. `wails3 task`
**执行 Taskfile.yml 中定义的任务**
| 参数 | 说明 | 示例值 |
|------|------|--------|
| `[taskname]` | 任务名称 | `build`, `package`, `run` |
| `[VAR=value]` | 变量赋值 | `PRODUCTION=true`, `ARCH=amd64` |
**常用任务:**
| 任务 | 说明 | 命令 |
|------|------|------|
| `build` | 构建应用 | `wails3 task build PRODUCTION=true` |
| `package` | 打包应用 | `wails3 task package` |
| `run` | 运行应用 | `wails3 task run` |
**使用位置:** `build/config.yml`
---
## 📊 平台对应命令表
| 平台 | 主要命令 | 产物 |
|------|----------|------|
| **Windows** | `generate syso`<br>`generate webview2bootstrapper` | `.syso` 资源文件<br>NSIS 安装程序 |
| **Linux** | `generate .desktop`<br>`generate appimage`<br>`tool package -format deb/rpm/archlinux` | `.desktop` 文件<br>`.AppImage`<br>`.deb` / `.rpm` / `.pkg.tar.zst` |
| **macOS** | `generate icons` | `.icns` 图标<br>`.app` 应用包 |
| **通用** | `generate bindings`<br>`generate icons` | TypeScript 绑定<br>多平台图标 |
---
## 🚀 快速参考
### 完整构建流程
```bash
# 1. 生成绑定和图标
wails3 task common:generate:bindings
wails3 task common:generate:icons
# 2. 构建前端
cd frontend
npm install
npm run build
cd ..
# 3. 构建应用(各平台)
cd build/windows && wails3 task build PRODUCTION=true # Windows
cd build/linux && wails3 task build PRODUCTION=true # Linux
cd build/darwin && wails3 task build PRODUCTION=true # macOS
# 4. 打包应用(各平台)
cd build/windows && wails3 task package # NSIS 安装程序
cd build/linux && wails3 task package # AppImage + deb + rpm + archlinux
cd build/darwin && wails3 task package # .app bundle
```
---
## 📝 注意事项
1. **变量传递:** Task 命令支持通过 `VAR=value` 格式传递变量
2. **路径问题:** 相对路径基于 Taskfile.yml 所在目录
3. **依赖顺序:** 某些任务有依赖关系(通过 `deps:` 定义)
4. **环境变量:** 使用 `env:` 定义的环境变量会自动设置
---
## 🔗 相关文档
- [Wails 3 官方文档](https://v3alpha.wails.io/)
- [Taskfile 语法](https://taskfile.dev/)
- [nfpm 打包工具](https://nfpm.goreleaser.com/)

View File

@@ -5,12 +5,12 @@ version: '3'
# This information is used to generate the build assets.
info:
companyName: "Voidraft" # The name of the company
productName: "Voidraft" # The name of the application
companyName: "voidraft" # The name of the company
productName: "voidraft" # The name of the application
productIdentifier: "landaiqing" # The unique product identifier
description: "Your Inspiration Catcher - Instant thought-capturing tool with minimalist design" # The application description
copyright: "© 2025 Voidraft. All rights reserved." # Copyright text
comments: "Effortlessly capture and organize fleeting ideas with minimal design" # Comments
description: "voidraft" # The application description
copyright: "© 2025 voidraft. All rights reserved." # Copyright text
comments: "voidraft" # Comments
version: "0.0.1.0" # The application version
# Dev mode configuration

View File

@@ -4,7 +4,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleName</key>
<string>Voidraft</string>
<string>voidraft</string>
<key>CFBundleExecutable</key>
<string>voidraft</string>
<key>CFBundleIdentifier</key>
@@ -12,7 +12,7 @@
<key>CFBundleVersion</key>
<string>0.0.1.0</string>
<key>CFBundleGetInfoString</key>
<string>Effortlessly capture and organize fleeting ideas with minimal design</string>
<string>voidraft</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1.0</string>
<key>CFBundleIconFile</key>
@@ -22,7 +22,7 @@
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSHumanReadableCopyright</key>
<string>© 2025 Voidraft. All rights reserved.</string>
<string>© 2025 voidraft. All rights reserved.</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>

View File

@@ -4,7 +4,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleName</key>
<string>Voidraft</string>
<string>voidraft</string>
<key>CFBundleExecutable</key>
<string>voidraft</string>
<key>CFBundleIdentifier</key>
@@ -12,7 +12,7 @@
<key>CFBundleVersion</key>
<string>0.0.1.0</string>
<key>CFBundleGetInfoString</key>
<string>Effortlessly capture and organize fleeting ideas with minimal design</string>
<string>voidraft</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1.0</string>
<key>CFBundleIconFile</key>
@@ -22,6 +22,6 @@
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSHumanReadableCopyright</key>
<string>© 2025 Voidraft. All rights reserved.</string>
<string>© 2025 voidraft. All rights reserved.</string>
</dict>
</plist>

View File

@@ -11,9 +11,12 @@ tasks:
- task: common:build:frontend
- task: common:generate:icons
cmds:
- go build {{.BUILD_FLAGS}} -o {{.OUTPUT}}
- go build {{.BUILD_FLAGS}} -ldflags="{{.LDFLAGS}} {{.VERSION_FLAGS}}" -o {{.OUTPUT}}
vars:
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
LDFLAGS: '{{if eq .PRODUCTION "true"}}-w -s{{else}}{{end}}'
VERSION_FLAGS:
sh: 'grep "VERSION=" version.txt | cut -d"=" -f2 | xargs -I {} echo "-X voidraft/internal/version.Version={}"'
DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}'
OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}'
env:

View File

@@ -11,9 +11,12 @@ tasks:
- task: common:build:frontend
- task: common:generate:icons
cmds:
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}
- go build {{.BUILD_FLAGS}} -ldflags="{{.LDFLAGS}} {{.VERSION_FLAGS}}" -o {{.BIN_DIR}}/{{.APP_NAME}}
vars:
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
LDFLAGS: '{{if eq .PRODUCTION "true"}}-w -s{{else}}{{end}}'
VERSION_FLAGS:
sh: 'grep "VERSION=" version.txt | cut -d"=" -f2 | xargs -I {} echo "-X voidraft/internal/version.Version={}"'
env:
GOOS: linux
CGO_ENABLED: 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -10,9 +10,9 @@ version: "0.0.1.0"
section: "default"
priority: "extra"
maintainer: ${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>
description: "Your Inspiration Catcher - Instant thought-capturing tool with minimalist design"
vendor: "Voidraft"
homepage: "https://wails.io"
description: "voidraft"
vendor: "voidraft"
homepage: "https://voidraft.landaiqing.cn"
license: "MIT"
release: "1"

View File

@@ -0,0 +1,10 @@
[Desktop Entry]
Type=Application
Name=voidraft
Exec=voidraft
Icon=appicon
Categories=Development;
Terminal=false
Keywords=wails
Version=1.0
StartupNotify=false

View File

@@ -14,13 +14,16 @@ tasks:
- task: common:generate:icons
cmds:
- task: generate:syso
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}.exe
- go build {{.BUILD_FLAGS}} -ldflags="{{.LDFLAGS}} {{.VERSION_FLAGS}}" -o {{.BIN_DIR}}/{{.APP_NAME}}.exe
- cmd: powershell Remove-item *.syso
platforms: [windows]
- cmd: rm -f *.syso
platforms: [linux, darwin]
vars:
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s -H windowsgui"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
LDFLAGS: '{{if eq .PRODUCTION "true"}}-w -s -H windowsgui{{else}}{{end}}'
VERSION_FLAGS:
sh: 'powershell -Command "(Get-Content version.txt) -replace ''VERSION='', ''-X voidraft/internal/version.Version=''"'
env:
GOOS: windows
CGO_ENABLED: 1

View File

@@ -5,11 +5,11 @@
"info": {
"0000": {
"ProductVersion": "0.0.1.0",
"CompanyName": "Voidraft",
"FileDescription": "Your Inspiration Catcher - Instant thought-capturing tool with minimalist design",
"LegalCopyright": "© 2025 Voidraft. All rights reserved.",
"ProductName": "Voidraft",
"Comments": "Effortlessly capture and organize fleeting ideas with minimal design"
"CompanyName": "voidraft",
"FileDescription": "voidraft",
"LegalCopyright": "© 2025 voidraft. All rights reserved.",
"ProductName": "voidraft",
"Comments": "voidraft"
}
}
}

View File

@@ -8,16 +8,16 @@
!define INFO_PROJECTNAME "voidraft"
!endif
!ifndef INFO_COMPANYNAME
!define INFO_COMPANYNAME "Voidraft"
!define INFO_COMPANYNAME "voidraft"
!endif
!ifndef INFO_PRODUCTNAME
!define INFO_PRODUCTNAME "Voidraft"
!define INFO_PRODUCTNAME "voidraft"
!endif
!ifndef INFO_PRODUCTVERSION
!define INFO_PRODUCTVERSION "0.0.1.0"
!endif
!ifndef INFO_COPYRIGHT
!define INFO_COPYRIGHT "© 2025 Voidraft. All rights reserved."
!define INFO_COPYRIGHT "© 2025 voidraft. All rights reserved."
!endif
!ifndef PRODUCT_EXECUTABLE
!define PRODUCT_EXECUTABLE "${INFO_PROJECTNAME}.exe"

View File

@@ -5,82 +5,61 @@
// @ts-ignore: Unused imports
import {Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as slog$0 from "../../../../../../log/slog/models.js";
export class App {
/**
* ServiceOptions provides optional parameters for calls to [NewService].
*/
export class ServiceOptions {
/**
* The main application menu
* Name can be set to override the name of the service
* for logging and debugging purposes.
*
* If empty, it will default
* either to the value obtained through the [ServiceName] interface,
* or to the type name.
*/
"ApplicationMenu": Menu | null;
"Logger": slog$0.Logger | null;
"Name": string;
/** Creates a new App instance. */
constructor($$source: Partial<App> = {}) {
if (!("ApplicationMenu" in $$source)) {
this["ApplicationMenu"] = null;
/**
* If the service instance implements [http.Handler],
* it will be mounted on the internal asset server
* at the prefix specified by Route.
*/
"Route": string;
/**
* MarshalError will be called if non-nil
* to marshal to JSON the error values returned by this service's methods.
*
* MarshalError is not allowed to fail,
* but it may return a nil slice to fall back
* to the globally configured error handler.
*
* If the returned slice is not nil, it must contain valid JSON.
*/
"MarshalError": any;
/** Creates a new ServiceOptions instance. */
constructor($$source: Partial<ServiceOptions> = {}) {
if (!("Name" in $$source)) {
this["Name"] = "";
}
if (!("Logger" in $$source)) {
this["Logger"] = null;
if (!("Route" in $$source)) {
this["Route"] = "";
}
if (!("MarshalError" in $$source)) {
this["MarshalError"] = null;
}
Object.assign(this, $$source);
}
/**
* Creates a new App instance from a string or object.
* Creates a new ServiceOptions instance from a string or object.
*/
static createFrom($$source: any = {}): App {
const $$createField0_0 = $$createType1;
const $$createField1_0 = $$createType3;
static createFrom($$source: any = {}): ServiceOptions {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("ApplicationMenu" in $$parsedSource) {
$$parsedSource["ApplicationMenu"] = $$createField0_0($$parsedSource["ApplicationMenu"]);
}
if ("Logger" in $$parsedSource) {
$$parsedSource["Logger"] = $$createField1_0($$parsedSource["Logger"]);
}
return new App($$parsedSource as Partial<App>);
return new ServiceOptions($$parsedSource as Partial<ServiceOptions>);
}
}
export class Menu {
/** Creates a new Menu instance. */
constructor($$source: Partial<Menu> = {}) {
Object.assign(this, $$source);
}
/**
* Creates a new Menu instance from a string or object.
*/
static createFrom($$source: any = {}): Menu {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
return new Menu($$parsedSource as Partial<Menu>);
}
}
export class WebviewWindow {
/** Creates a new WebviewWindow instance. */
constructor($$source: Partial<WebviewWindow> = {}) {
Object.assign(this, $$source);
}
/**
* Creates a new WebviewWindow instance from a string or object.
*/
static createFrom($$source: any = {}): WebviewWindow {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
return new WebviewWindow($$parsedSource as Partial<WebviewWindow>);
}
}
// Private type creation functions
const $$createType0 = Menu.createFrom;
const $$createType1 = $Create.Nullable($$createType0);
const $$createType2 = slog$0.Logger.createFrom;
const $$createType3 = $Create.Nullable($$createType2);
export type Window = any;

View File

@@ -0,0 +1,83 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* Service represents the dock service
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../application/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as $models from "./models.js";
/**
* HideAppIcon hides the app icon in the dock/taskbar.
*/
export function HideAppIcon(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3413658144) as any;
return $resultPromise;
}
/**
* RemoveBadge removes the badge label from the application icon.
*/
export function RemoveBadge(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2752757297) as any;
return $resultPromise;
}
/**
* ServiceName returns the name of the service.
*/
export function ServiceName(): Promise<string> & { cancel(): void } {
let $resultPromise = $Call.ByID(2949906614) as any;
return $resultPromise;
}
/**
* ServiceShutdown is called when the service is unloaded.
*/
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(307064411) as any;
return $resultPromise;
}
/**
* ServiceStartup is called when the service is loaded.
*/
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1350118426, options) as any;
return $resultPromise;
}
/**
* SetBadge sets the badge label on the application icon.
*/
export function SetBadge(label: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1717705661, label) as any;
return $resultPromise;
}
/**
* SetCustomBadge sets the badge label on the application icon with custom options.
*/
export function SetCustomBadge(label: string, options: $models.BadgeOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2730169760, label, options) as any;
return $resultPromise;
}
/**
* ShowAppIcon shows the app icon in the dock/taskbar.
*/
export function ShowAppIcon(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3409697379) as any;
return $resultPromise;
}

View File

@@ -0,0 +1,9 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import * as DockService from "./dockservice.js";
export {
DockService
};
export * from "./models.js";

View File

@@ -0,0 +1,61 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as color$0 from "../../../../../../../image/color/models.js";
/**
* BadgeOptions represents options for customizing badge appearance
*/
export class BadgeOptions {
"TextColour": color$0.RGBA;
"BackgroundColour": color$0.RGBA;
"FontName": string;
"FontSize": number;
"SmallFontSize": number;
/** Creates a new BadgeOptions instance. */
constructor($$source: Partial<BadgeOptions> = {}) {
if (!("TextColour" in $$source)) {
this["TextColour"] = (new color$0.RGBA());
}
if (!("BackgroundColour" in $$source)) {
this["BackgroundColour"] = (new color$0.RGBA());
}
if (!("FontName" in $$source)) {
this["FontName"] = "";
}
if (!("FontSize" in $$source)) {
this["FontSize"] = 0;
}
if (!("SmallFontSize" in $$source)) {
this["SmallFontSize"] = 0;
}
Object.assign(this, $$source);
}
/**
* Creates a new BadgeOptions instance from a string or object.
*/
static createFrom($$source: any = {}): BadgeOptions {
const $$createField0_0 = $$createType0;
const $$createField1_0 = $$createType0;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("TextColour" in $$parsedSource) {
$$parsedSource["TextColour"] = $$createField0_0($$parsedSource["TextColour"]);
}
if ("BackgroundColour" in $$parsedSource) {
$$parsedSource["BackgroundColour"] = $$createField1_0($$parsedSource["BackgroundColour"]);
}
return new BadgeOptions($$parsedSource as Partial<BadgeOptions>);
}
}
// Private type creation functions
const $$createType0 = color$0.RGBA.createFrom;

View File

@@ -0,0 +1,9 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import * as NotificationService from "./notificationservice.js";
export {
NotificationService
};
export * from "./models.js";

View File

@@ -0,0 +1,107 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Create as $Create} from "@wailsio/runtime";
/**
* NotificationAction represents an action button for a notification.
*/
export class NotificationAction {
"id"?: string;
"title"?: string;
/**
* (macOS-specific)
*/
"destructive"?: boolean;
/** Creates a new NotificationAction instance. */
constructor($$source: Partial<NotificationAction> = {}) {
Object.assign(this, $$source);
}
/**
* Creates a new NotificationAction instance from a string or object.
*/
static createFrom($$source: any = {}): NotificationAction {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
return new NotificationAction($$parsedSource as Partial<NotificationAction>);
}
}
/**
* NotificationCategory groups actions for notifications.
*/
export class NotificationCategory {
"id"?: string;
"actions"?: NotificationAction[];
"hasReplyField"?: boolean;
"replyPlaceholder"?: string;
"replyButtonTitle"?: string;
/** Creates a new NotificationCategory instance. */
constructor($$source: Partial<NotificationCategory> = {}) {
Object.assign(this, $$source);
}
/**
* Creates a new NotificationCategory instance from a string or object.
*/
static createFrom($$source: any = {}): NotificationCategory {
const $$createField1_0 = $$createType1;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("actions" in $$parsedSource) {
$$parsedSource["actions"] = $$createField1_0($$parsedSource["actions"]);
}
return new NotificationCategory($$parsedSource as Partial<NotificationCategory>);
}
}
/**
* NotificationOptions contains configuration for a notification
*/
export class NotificationOptions {
"id": string;
"title": string;
/**
* (macOS and Linux only)
*/
"subtitle"?: string;
"body"?: string;
"categoryId"?: string;
"data"?: { [_: string]: any };
/** Creates a new NotificationOptions instance. */
constructor($$source: Partial<NotificationOptions> = {}) {
if (!("id" in $$source)) {
this["id"] = "";
}
if (!("title" in $$source)) {
this["title"] = "";
}
Object.assign(this, $$source);
}
/**
* Creates a new NotificationOptions instance from a string or object.
*/
static createFrom($$source: any = {}): NotificationOptions {
const $$createField5_0 = $$createType2;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("data" in $$parsedSource) {
$$parsedSource["data"] = $$createField5_0($$parsedSource["data"]);
}
return new NotificationOptions($$parsedSource as Partial<NotificationOptions>);
}
}
// Private type creation functions
const $$createType0 = NotificationAction.createFrom;
const $$createType1 = $Create.Array($$createType0);
const $$createType2 = $Create.Map($Create.Any, $Create.Any);

View File

@@ -0,0 +1,110 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* Service represents the notifications service
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../application/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as $models from "./models.js";
export function CheckNotificationAuthorization(): Promise<boolean> & { cancel(): void } {
let $resultPromise = $Call.ByID(2216952893) as any;
return $resultPromise;
}
/**
* OnNotificationResponse registers a callback function that will be called when
* a notification response is received from the user.
*/
export function OnNotificationResponse(callback: any): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1642697808, callback) as any;
return $resultPromise;
}
export function RegisterNotificationCategory(category: $models.NotificationCategory): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2917562919, category) as any;
return $resultPromise;
}
export function RemoveAllDeliveredNotifications(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3956282340) as any;
return $resultPromise;
}
export function RemoveAllPendingNotifications(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(108821341) as any;
return $resultPromise;
}
export function RemoveDeliveredNotification(identifier: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(975691940, identifier) as any;
return $resultPromise;
}
export function RemoveNotification(identifier: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3966653866, identifier) as any;
return $resultPromise;
}
export function RemoveNotificationCategory(categoryID: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2032615554, categoryID) as any;
return $resultPromise;
}
export function RemovePendingNotification(identifier: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3729049703, identifier) as any;
return $resultPromise;
}
/**
* Public methods that delegate to the implementation.
*/
export function RequestNotificationAuthorization(): Promise<boolean> & { cancel(): void } {
let $resultPromise = $Call.ByID(3933442950) as any;
return $resultPromise;
}
export function SendNotification(options: $models.NotificationOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3968228732, options) as any;
return $resultPromise;
}
export function SendNotificationWithActions(options: $models.NotificationOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1886542847, options) as any;
return $resultPromise;
}
/**
* ServiceName returns the name of the service.
*/
export function ServiceName(): Promise<string> & { cancel(): void } {
let $resultPromise = $Call.ByID(2704532675) as any;
return $resultPromise;
}
/**
* ServiceShutdown is called when the service is unloaded.
*/
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2550195434) as any;
return $resultPromise;
}
/**
* ServiceStartup is called when the service is loaded.
*/
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(4047820929, options) as any;
return $resultPromise;
}

View File

@@ -0,0 +1,46 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Create as $Create} from "@wailsio/runtime";
/**
* RGBA represents a traditional 32-bit alpha-premultiplied color, having 8
* bits for each of red, green, blue and alpha.
*
* An alpha-premultiplied color component C has been scaled by alpha (A), so
* has valid values 0 <= C <= A.
*/
export class RGBA {
"R": number;
"G": number;
"B": number;
"A": number;
/** Creates a new RGBA instance. */
constructor($$source: Partial<RGBA> = {}) {
if (!("R" in $$source)) {
this["R"] = 0;
}
if (!("G" in $$source)) {
this["G"] = 0;
}
if (!("B" in $$source)) {
this["B"] = 0;
}
if (!("A" in $$source)) {
this["A"] = 0;
}
Object.assign(this, $$source);
}
/**
* Creates a new RGBA instance from a string or object.
*/
static createFrom($$source: any = {}): RGBA {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
return new RGBA($$parsedSource as Partial<RGBA>);
}
}

View File

@@ -1,31 +0,0 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Create as $Create} from "@wailsio/runtime";
/**
* A Logger records structured information about each call to its
* Log, Debug, Info, Warn, and Error methods.
* For each call, it creates a [Record] and passes it to a [Handler].
*
* To create a new Logger, call [New] or a Logger method
* that begins "With".
*/
export class Logger {
/** Creates a new Logger instance. */
constructor($$source: Partial<Logger> = {}) {
Object.assign(this, $$source);
}
/**
* Creates a new Logger instance from a string or object.
*/
static createFrom($$source: any = {}): Logger {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
return new Logger($$parsedSource as Partial<Logger>);
}
}

View File

@@ -0,0 +1,4 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
export * from "./models.js";

View File

@@ -0,0 +1,14 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Create as $Create} from "@wailsio/runtime";
/**
* A Header represents the key-value pairs in an HTTP header.
*
* The keys should be in canonical form, as returned by
* [CanonicalHeaderKey].
*/
export type Header = { [_: string]: string[] };

View File

@@ -0,0 +1,4 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
export * from "./models.js";

View File

@@ -0,0 +1,76 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Create as $Create} from "@wailsio/runtime";
/**
* LanguageInfo 语言信息结构体
*/
export class LanguageInfo {
/**
* 语言代码
*/
"Code": string;
/**
* 语言名称
*/
"Name": string;
/** Creates a new LanguageInfo instance. */
constructor($$source: Partial<LanguageInfo> = {}) {
if (!("Code" in $$source)) {
this["Code"] = "";
}
if (!("Name" in $$source)) {
this["Name"] = "";
}
Object.assign(this, $$source);
}
/**
* Creates a new LanguageInfo instance from a string or object.
*/
static createFrom($$source: any = {}): LanguageInfo {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
return new LanguageInfo($$parsedSource as Partial<LanguageInfo>);
}
}
/**
* TranslatorType 翻译器类型
*/
export enum TranslatorType {
/**
* The Go zero value for the underlying type of the enum.
*/
$zero = "",
/**
* GoogleTranslatorType 谷歌翻译器
*/
GoogleTranslatorType = "google",
/**
* BingTranslatorType 必应翻译器
*/
BingTranslatorType = "bing",
/**
* YoudaoTranslatorType 有道翻译器
*/
YoudaoTranslatorType = "youdao",
/**
* DeeplTranslatorType DeepL翻译器
*/
DeeplTranslatorType = "deepl",
/**
* TartuNLPTranslatorType TartuNLP翻译器
*/
TartuNLPTranslatorType = "tartunlp",
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* BackupService 提供基于Git的备份功能
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as models$0 from "../models/models.js";
/**
* HandleConfigChange 处理备份配置变更
*/
export function HandleConfigChange(config: models$0.GitBackupConfig | null): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(395287784, config) as any;
return $resultPromise;
}
/**
* Initialize 初始化备份服务
*/
export function Initialize(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1052437974) as any;
return $resultPromise;
}
/**
* PushToRemote 推送本地更改到远程仓库
*/
export function PushToRemote(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(262644139) as any;
return $resultPromise;
}
/**
* Reinitialize 重新初始化备份服务,用于响应配置变更
*/
export function Reinitialize(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(301562543) as any;
return $resultPromise;
}
/**
* ServiceShutdown 服务关闭时的清理工作
*/
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(422131801) as any;
return $resultPromise;
}
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2900331732, options) as any;
return $resultPromise;
}
/**
* StartAutoBackup 启动自动备份定时器
*/
export function StartAutoBackup(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3035755449) as any;
return $resultPromise;
}
/**
* StopAutoBackup 停止自动备份
*/
export function StopAutoBackup(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2641894021) as any;
return $resultPromise;
}

View File

@@ -2,7 +2,7 @@
// This file is automatically generated. DO NOT EDIT
/**
* ConfigService 提供基于 Viper 的配置管理功能
* ConfigService 应用配置服务
* @module
*/
@@ -10,10 +10,17 @@
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as models$0 from "../models/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as $models from "./models.js";
/**
* Get 获取配置项
*/
@@ -34,6 +41,14 @@ export function GetConfig(): Promise<models$0.AppConfig | null> & { cancel(): vo
return $typingPromise;
}
/**
* MigrateConfig 执行配置迁移
*/
export function MigrateConfig(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(434292783) as any;
return $resultPromise;
}
/**
* ResetConfig 强制重置所有配置为默认值
*/
@@ -42,6 +57,22 @@ export function ResetConfig(): Promise<void> & { cancel(): void } {
return $resultPromise;
}
/**
* ServiceShutdown 关闭服务
*/
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3963562361) as any;
return $resultPromise;
}
/**
* ServiceStartup initializes the service when the application starts
*/
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3311949428, options) as any;
return $resultPromise;
}
/**
* Set 设置配置项
*/
@@ -51,18 +82,18 @@ export function Set(key: string, value: any): Promise<void> & { cancel(): void }
}
/**
* SetDataPathChangeCallback 设置数据路径配置变更回调
* Watch 注册配置变更监听器
*/
export function SetDataPathChangeCallback(callback: any): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(393017412, callback) as any;
export function Watch(path: string, callback: $models.ObserverCallback): Promise<$models.CancelFunc> & { cancel(): void } {
let $resultPromise = $Call.ByID(1143583035, path, callback) as any;
return $resultPromise;
}
/**
* SetHotkeyChangeCallback 设置热键配置变更回调
* WatchWithContext 使用 Context 注册监听器
*/
export function SetHotkeyChangeCallback(callback: any): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(283872321, callback) as any;
export function WatchWithContext(path: string, callback: $models.ObserverCallback): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1454973098, path, callback) as any;
return $resultPromise;
}

View File

@@ -0,0 +1,39 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* DatabaseService provides shared database functionality
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
/**
* RegisterModel 注册模型与表的映射关系
*/
export function RegisterModel(tableName: string, model: any): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(175397515, tableName, model) as any;
return $resultPromise;
}
/**
* ServiceShutdown shuts down the service when the application closes
*/
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3907893632) as any;
return $resultPromise;
}
/**
* ServiceStartup initializes the service when the application starts
*/
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2067840771, options) as any;
return $resultPromise;
}

View File

@@ -10,10 +10,6 @@
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
/**
* SelectDirectory 打开目录选择对话框
*/
@@ -23,9 +19,9 @@ export function SelectDirectory(): Promise<string> & { cancel(): void } {
}
/**
* SetWindow 设置绑定的窗口
* SelectFile 打开文件选择对话框
*/
export function SetWindow(window: application$0.WebviewWindow | null): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(968177170, window) as any;
export function SelectFile(): Promise<string> & { cancel(): void } {
let $resultPromise = $Call.ByID(37302920) as any;
return $resultPromise;
}

View File

@@ -2,7 +2,7 @@
// This file is automatically generated. DO NOT EDIT
/**
* DocumentService 提供文档管理功能
* DocumentService provides document management functionality
* @module
*/
@@ -10,23 +10,18 @@
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as models$0 from "../models/models.js";
/**
* ForceSave 强制保存
* CreateDocument creates a new document and returns the created document with ID
*/
export function ForceSave(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2767091023) as any;
return $resultPromise;
}
/**
* GetActiveDocument 获取活动文档
*/
export function GetActiveDocument(): Promise<models$0.Document | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(1785823398) as any;
export function CreateDocument(title: string): Promise<models$0.Document | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(3360680842, title) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result);
}) as any;
@@ -35,45 +30,98 @@ export function GetActiveDocument(): Promise<models$0.Document | null> & { cance
}
/**
* Initialize 初始化服务
* DeleteDocument marks a document as deleted (default document with ID=1 cannot be deleted)
*/
export function Initialize(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3418008221) as any;
export function DeleteDocument(id: number): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(412287269, id) as any;
return $resultPromise;
}
/**
* OnDataPathChanged 处理数据路径变更
* GetDocumentByID gets a document by ID
*/
export function OnDataPathChanged(oldPath: string, newPath: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(269349439, oldPath, newPath) as any;
export function GetDocumentByID(id: number): Promise<models$0.Document | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(3468193232, id) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* ListAllDocumentsMeta lists all active (non-deleted) document metadata
*/
export function ListAllDocumentsMeta(): Promise<(models$0.Document | null)[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(3073950297) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType2($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* ListDeletedDocumentsMeta lists all deleted document metadata
*/
export function ListDeletedDocumentsMeta(): Promise<(models$0.Document | null)[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(490143787) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType2($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* LockDocument 锁定文档,防止删除
*/
export function LockDocument(id: number): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1889494473, id) as any;
return $resultPromise;
}
/**
* ReloadDocument 重新加载文档
* RestoreDocument restores a deleted document
*/
export function ReloadDocument(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3093415283) as any;
export function RestoreDocument(id: number): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(784200778, id) as any;
return $resultPromise;
}
/**
* ServiceShutdown 关闭服务
* ServiceStartup initializes the service when the application starts
*/
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(638578044) as any;
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1474135487, options) as any;
return $resultPromise;
}
/**
* UpdateActiveDocumentContent 更新文档内容
* UnlockDocument 解锁文档
*/
export function UpdateActiveDocumentContent(content: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1486276638, content) as any;
export function UnlockDocument(id: number): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(222307930, id) as any;
return $resultPromise;
}
/**
* UpdateDocumentContent updates the content of a document
*/
export function UpdateDocumentContent(id: number, content: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3251897116, id, content) as any;
return $resultPromise;
}
/**
* UpdateDocumentTitle updates the title of a document
*/
export function UpdateDocumentTitle(id: number, title: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2045530459, id, title) as any;
return $resultPromise;
}
// Private type creation functions
const $$createType0 = models$0.Document.createFrom;
const $$createType1 = $Create.Nullable($$createType0);
const $$createType2 = $Create.Array($$createType1);

View File

@@ -0,0 +1,74 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* ExtensionService 扩展管理服务
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as models$0 from "../models/models.js";
/**
* GetAllExtensions 获取所有扩展配置
*/
export function GetAllExtensions(): Promise<models$0.Extension[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(3094292124) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* ResetAllExtensionsToDefault 重置所有扩展到默认状态
*/
export function ResetAllExtensionsToDefault(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(270611949) as any;
return $resultPromise;
}
/**
* ResetExtensionToDefault 重置扩展到默认状态
*/
export function ResetExtensionToDefault(id: models$0.ExtensionID): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(868308101, id) as any;
return $resultPromise;
}
/**
* ServiceStartup 启动时调用
*/
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(40324057, options) as any;
return $resultPromise;
}
/**
* UpdateExtensionEnabled 更新扩展启用状态
*/
export function UpdateExtensionEnabled(id: models$0.ExtensionID, enabled: boolean): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1067300094, id, enabled) as any;
return $resultPromise;
}
/**
* UpdateExtensionState 更新扩展状态
*/
export function UpdateExtensionState(id: models$0.ExtensionID, enabled: boolean, config: models$0.ExtensionConfig): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2917946454, id, enabled, config) as any;
return $resultPromise;
}
// Private type creation functions
const $$createType0 = models$0.Extension.createFrom;
const $$createType1 = $Create.Array($$createType0);

View File

@@ -18,7 +18,7 @@ import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/applic
import * as models$0 from "../models/models.js";
/**
* GetCurrentHotkey 获取当前注册的热键
* GetCurrentHotkey 获取当前热键
*/
export function GetCurrentHotkey(): Promise<models$0.HotkeyCombo | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(2572811187) as any;
@@ -32,13 +32,13 @@ export function GetCurrentHotkey(): Promise<models$0.HotkeyCombo | null> & { can
/**
* Initialize 初始化热键服务
*/
export function Initialize(app: application$0.App | null): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3671360458, app) as any;
export function Initialize(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3671360458) as any;
return $resultPromise;
}
/**
* IsRegistered 检查是否已注册热键
* IsRegistered 检查是否已注册
*/
export function IsRegistered(): Promise<boolean> & { cancel(): void } {
let $resultPromise = $Call.ByID(106954156) as any;
@@ -48,13 +48,13 @@ export function IsRegistered(): Promise<boolean> & { cancel(): void } {
/**
* RegisterHotkey 注册全局热键
*/
export function RegisterHotkey(hotkey: models$0.HotkeyCombo | null): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1103945691, hotkey) as any;
export function RegisterHotkey(combo: models$0.HotkeyCombo | null): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1103945691, combo) as any;
return $resultPromise;
}
/**
* ServiceShutdown 关闭热键服务
* ServiceShutdown 关闭服务
*/
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(157291181) as any;
@@ -62,10 +62,10 @@ export function ServiceShutdown(): Promise<void> & { cancel(): void } {
}
/**
* ToggleWindow 切换窗口显示/隐藏 - 通过事件通知前端处理
* ServiceStartup 服务启动时初始化
*/
export function ToggleWindow(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1318185132) as any;
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3079990808, options) as any;
return $resultPromise;
}
@@ -80,8 +80,8 @@ export function UnregisterHotkey(): Promise<void> & { cancel(): void } {
/**
* UpdateHotkey 更新热键配置
*/
export function UpdateHotkey(enable: boolean, hotkey: models$0.HotkeyCombo | null): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(823285555, enable, hotkey) as any;
export function UpdateHotkey(enable: boolean, combo: models$0.HotkeyCombo | null): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(823285555, enable, combo) as any;
return $resultPromise;
}

View File

@@ -0,0 +1,31 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* HttpClientService HTTP客户端服务
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as $models from "./models.js";
/**
* ExecuteRequest 执行HTTP请求
*/
export function ExecuteRequest(request: $models.HttpRequest | null): Promise<$models.HttpResponse | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(3143343977, request) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
// Private type creation functions
const $$createType0 = $models.HttpResponse.createFrom;
const $$createType1 = $Create.Nullable($$createType0);

View File

@@ -1,21 +1,43 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import * as BackupService from "./backupservice.js";
import * as ConfigService from "./configservice.js";
import * as DatabaseService from "./databaseservice.js";
import * as DialogService from "./dialogservice.js";
import * as DocumentService from "./documentservice.js";
import * as ExtensionService from "./extensionservice.js";
import * as HotkeyService from "./hotkeyservice.js";
import * as HttpClientService from "./httpclientservice.js";
import * as KeyBindingService from "./keybindingservice.js";
import * as MigrationService from "./migrationservice.js";
import * as SelfUpdateService from "./selfupdateservice.js";
import * as StartupService from "./startupservice.js";
import * as SystemService from "./systemservice.js";
import * as TestService from "./testservice.js";
import * as ThemeService from "./themeservice.js";
import * as TranslationService from "./translationservice.js";
import * as TrayService from "./trayservice.js";
import * as WindowService from "./windowservice.js";
export {
BackupService,
ConfigService,
DatabaseService,
DialogService,
DocumentService,
ExtensionService,
HotkeyService,
HttpClientService,
KeyBindingService,
MigrationService,
SelfUpdateService,
StartupService,
SystemService,
TrayService
TestService,
ThemeService,
TranslationService,
TrayService,
WindowService
};
export * from "./models.js";

View File

@@ -0,0 +1,42 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* KeyBindingService 快捷键管理服务
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as models$0 from "../models/models.js";
/**
* GetAllKeyBindings 获取所有快捷键配置
*/
export function GetAllKeyBindings(): Promise<models$0.KeyBinding[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(1633502882) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* ServiceStartup 启动时调用
*/
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2057121990, options) as any;
return $resultPromise;
}
// Private type creation functions
const $$createType0 = models$0.KeyBinding.createFrom;
const $$createType1 = $Create.Array($$createType0);

View File

@@ -50,13 +50,5 @@ export function ServiceShutdown(): Promise<void> & { cancel(): void } {
return $resultPromise;
}
/**
* SetProgressBroadcaster 设置进度广播函数
*/
export function SetProgressBroadcaster(broadcaster: any): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3244071921, broadcaster) as any;
return $resultPromise;
}
// Private type creation functions
const $$createType0 = $models.MigrationProgress.createFrom;

View File

@@ -5,6 +5,121 @@
// @ts-ignore: Unused imports
import {Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as http$0 from "../../../net/http/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as time$0 from "../../../time/models.js";
/**
* CancelFunc 取消订阅函数
* 调用此函数可以取消对配置的监听
*/
export type CancelFunc = any;
/**
* HttpRequest HTTP请求结构
*/
export class HttpRequest {
"method": string;
"url": string;
"headers": { [_: string]: string };
/**
* json, formdata, urlencoded, text, params, xml, html, javascript, binary
*/
"bodyType"?: string;
"body"?: any;
/** Creates a new HttpRequest instance. */
constructor($$source: Partial<HttpRequest> = {}) {
if (!("method" in $$source)) {
this["method"] = "";
}
if (!("url" in $$source)) {
this["url"] = "";
}
if (!("headers" in $$source)) {
this["headers"] = {};
}
Object.assign(this, $$source);
}
/**
* Creates a new HttpRequest instance from a string or object.
*/
static createFrom($$source: any = {}): HttpRequest {
const $$createField2_0 = $$createType0;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("headers" in $$parsedSource) {
$$parsedSource["headers"] = $$createField2_0($$parsedSource["headers"]);
}
return new HttpRequest($$parsedSource as Partial<HttpRequest>);
}
}
/**
* HttpResponse HTTP响应结构
*/
export class HttpResponse {
/**
* 使用resp.Status()返回完整状态如"200 OK"
*/
"status": string;
/**
* 响应时间(毫秒)
*/
"time": number;
/**
* 请求大小
*/
"requestSize": string;
"body": any;
"headers": http$0.Header;
"timestamp": time$0.Time;
"error"?: any;
/** Creates a new HttpResponse instance. */
constructor($$source: Partial<HttpResponse> = {}) {
if (!("status" in $$source)) {
this["status"] = "";
}
if (!("time" in $$source)) {
this["time"] = 0;
}
if (!("requestSize" in $$source)) {
this["requestSize"] = "";
}
if (!("body" in $$source)) {
this["body"] = null;
}
if (!("headers" in $$source)) {
this["headers"] = ({} as http$0.Header);
}
if (!("timestamp" in $$source)) {
this["timestamp"] = null;
}
Object.assign(this, $$source);
}
/**
* Creates a new HttpResponse instance from a string or object.
*/
static createFrom($$source: any = {}): HttpResponse {
const $$createField4_0 = $$createType1;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("headers" in $$parsedSource) {
$$parsedSource["headers"] = $$createField4_0($$parsedSource["headers"]);
}
return new HttpResponse($$parsedSource as Partial<HttpResponse>);
}
}
/**
* MemoryStats 内存统计信息
*/
@@ -76,19 +191,8 @@ export class MemoryStats {
* MigrationProgress 迁移进度信息
*/
export class MigrationProgress {
/**
* 迁移状态
*/
"status": MigrationStatus;
/**
* 进度百分比 (0-100)
*/
"progress": number;
/**
* 错误信息
*/
"error"?: string;
/** Creates a new MigrationProgress instance. */
@@ -121,18 +225,193 @@ export enum MigrationStatus {
*/
$zero = "",
/**
* 迁移中
*/
MigrationStatusMigrating = "migrating",
/**
* 完成
*/
MigrationStatusCompleted = "completed",
/**
* 失败
*/
MigrationStatusFailed = "failed",
};
/**
* OSInfo 操作系统信息
*/
export class OSInfo {
"id": string;
"name": string;
"version": string;
"branding": string;
/** Creates a new OSInfo instance. */
constructor($$source: Partial<OSInfo> = {}) {
if (!("id" in $$source)) {
this["id"] = "";
}
if (!("name" in $$source)) {
this["name"] = "";
}
if (!("version" in $$source)) {
this["version"] = "";
}
if (!("branding" in $$source)) {
this["branding"] = "";
}
Object.assign(this, $$source);
}
/**
* Creates a new OSInfo instance from a string or object.
*/
static createFrom($$source: any = {}): OSInfo {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
return new OSInfo($$parsedSource as Partial<OSInfo>);
}
}
/**
* ObserverCallback 观察者回调函数
*/
export type ObserverCallback = any;
/**
* SelfUpdateResult 自我更新结果
*/
export class SelfUpdateResult {
/**
* 是否有更新
*/
"hasUpdate": boolean;
/**
* 当前版本
*/
"currentVersion": string;
/**
* 最新版本
*/
"latestVersion": string;
/**
* 是否已应用更新
*/
"updateApplied": boolean;
/**
* 下载链接
*/
"assetURL": string;
/**
* 发布说明
*/
"releaseNotes": string;
/**
* 错误信息
*/
"error": string;
/**
* 更新源github/gitea
*/
"source": string;
/** Creates a new SelfUpdateResult instance. */
constructor($$source: Partial<SelfUpdateResult> = {}) {
if (!("hasUpdate" in $$source)) {
this["hasUpdate"] = false;
}
if (!("currentVersion" in $$source)) {
this["currentVersion"] = "";
}
if (!("latestVersion" in $$source)) {
this["latestVersion"] = "";
}
if (!("updateApplied" in $$source)) {
this["updateApplied"] = false;
}
if (!("assetURL" in $$source)) {
this["assetURL"] = "";
}
if (!("releaseNotes" in $$source)) {
this["releaseNotes"] = "";
}
if (!("error" in $$source)) {
this["error"] = "";
}
if (!("source" in $$source)) {
this["source"] = "";
}
Object.assign(this, $$source);
}
/**
* Creates a new SelfUpdateResult instance from a string or object.
*/
static createFrom($$source: any = {}): SelfUpdateResult {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
return new SelfUpdateResult($$parsedSource as Partial<SelfUpdateResult>);
}
}
/**
* SystemInfo 系统信息
*/
export class SystemInfo {
"os": string;
"arch": string;
"debug": boolean;
"osInfo": OSInfo | null;
"platformInfo": { [_: string]: any };
/** Creates a new SystemInfo instance. */
constructor($$source: Partial<SystemInfo> = {}) {
if (!("os" in $$source)) {
this["os"] = "";
}
if (!("arch" in $$source)) {
this["arch"] = "";
}
if (!("debug" in $$source)) {
this["debug"] = false;
}
if (!("osInfo" in $$source)) {
this["osInfo"] = null;
}
if (!("platformInfo" in $$source)) {
this["platformInfo"] = {};
}
Object.assign(this, $$source);
}
/**
* Creates a new SystemInfo instance from a string or object.
*/
static createFrom($$source: any = {}): SystemInfo {
const $$createField3_0 = $$createType5;
const $$createField4_0 = $$createType6;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("osInfo" in $$parsedSource) {
$$parsedSource["osInfo"] = $$createField3_0($$parsedSource["osInfo"]);
}
if ("platformInfo" in $$parsedSource) {
$$parsedSource["platformInfo"] = $$createField4_0($$parsedSource["platformInfo"]);
}
return new SystemInfo($$parsedSource as Partial<SystemInfo>);
}
}
// Private type creation functions
const $$createType0 = $Create.Map($Create.Any, $Create.Any);
var $$createType1 = (function $$initCreateType1(...args): any {
if ($$createType1 === $$initCreateType1) {
$$createType1 = $$createType3;
}
return $$createType1(...args);
});
const $$createType2 = $Create.Array($Create.Any);
const $$createType3 = $Create.Map($Create.Any, $$createType2);
const $$createType4 = OSInfo.createFrom;
const $$createType5 = $Create.Nullable($$createType4);
const $$createType6 = $Create.Map($Create.Any, $Create.Any);

View File

@@ -0,0 +1,51 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* SelfUpdateService 自我更新服务
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as $models from "./models.js";
/**
* ApplyUpdate 应用更新
*/
export function ApplyUpdate(): Promise<$models.SelfUpdateResult | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(2009328394) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* CheckForUpdates 检查更新
*/
export function CheckForUpdates(): Promise<$models.SelfUpdateResult | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(438757208) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* RestartApplication 重启应用程序
*/
export function RestartApplication(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3341481538) as any;
return $resultPromise;
}
// Private type creation functions
const $$createType0 = $models.SelfUpdateResult.createFrom;
const $$createType1 = $Create.Nullable($$createType0);

View File

@@ -0,0 +1,19 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* StartupService 开机启动服务
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
/**
* SetEnabled 设置开机启动状态
*/
export function SetEnabled(enabled: boolean): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2911601468, enabled) as any;
return $resultPromise;
}

View File

@@ -34,6 +34,18 @@ export function GetMemoryStats(): Promise<$models.MemoryStats> & { cancel(): voi
return $typingPromise;
}
/**
* GetSystemInfo 获取系统环境信息
*/
export function GetSystemInfo(): Promise<$models.SystemInfo | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(2629436820) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType2($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* TriggerGC 手动触发垃圾回收
*/
@@ -44,3 +56,5 @@ export function TriggerGC(): Promise<void> & { cancel(): void } {
// Private type creation functions
const $$createType0 = $models.MemoryStats.createFrom;
const $$createType1 = $models.SystemInfo.createFrom;
const $$createType2 = $Create.Nullable($$createType1);

View File

@@ -0,0 +1,55 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* TestService 测试服务 - 仅在开发环境使用
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
/**
* ClearAll 清除所有测试状态
*/
export function ClearAll(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2179720854) as any;
return $resultPromise;
}
/**
* ServiceStartup 服务启动时调用
*/
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(617408198, options) as any;
return $resultPromise;
}
/**
* TestBadge 测试Badge功能
*/
export function TestBadge(text: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(4242952145, text) as any;
return $resultPromise;
}
/**
* TestNotification 测试通知功能
*/
export function TestNotification(title: string, subtitle: string, body: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1697553289, title, subtitle, body) as any;
return $resultPromise;
}
/**
* TestUpdateNotification 测试更新通知
*/
export function TestUpdateNotification(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3091730060) as any;
return $resultPromise;
}

View File

@@ -0,0 +1,80 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* ThemeService 主题服务
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as models$0 from "../models/models.js";
/**
* GetAllThemes 获取所有主题
*/
export function GetAllThemes(): Promise<(models$0.Theme | null)[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(2425053076) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType2($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* GetThemeByID 根据ID或名称获取主题
* 如果 id > 0按ID查询如果 id = 0按名称查询
*/
export function GetThemeByIdOrName(id: number, ...name: string[]): Promise<models$0.Theme | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(127385338, id, name) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* ResetTheme 重置主题为预设配置
*/
export function ResetTheme(id: number, ...name: string[]): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1806334457, id, name) as any;
return $resultPromise;
}
/**
* ServiceShutdown 服务关闭
*/
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1676749034) as any;
return $resultPromise;
}
/**
* ServiceStartup 服务启动时初始化
*/
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2915959937, options) as any;
return $resultPromise;
}
/**
* UpdateTheme 更新主题
*/
export function UpdateTheme(id: number, colors: models$0.ThemeColorConfig): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(70189749, id, colors) as any;
return $resultPromise;
}
// Private type creation functions
const $$createType0 = models$0.Theme.createFrom;
const $$createType1 = $Create.Nullable($$createType0);
const $$createType2 = $Create.Array($$createType1);

View File

@@ -0,0 +1,70 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* TranslationService 翻译服务
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as translator$0 from "../common/translator/models.js";
/**
* GetTranslatorLanguages 获取翻译器的语言列表
* @param {string} translatorType - 翻译器类型 ("google", "bing", "youdao", "deepl")
* @returns {map[string]string} 语言代码到名称的映射
* @returns {error} 可能的错误
*/
export function GetTranslatorLanguages(translatorType: translator$0.TranslatorType): Promise<{ [_: string]: translator$0.LanguageInfo }> & { cancel(): void } {
let $resultPromise = $Call.ByID(3976114458, translatorType) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* GetTranslators 获取所有可用翻译器类型
* @returns {[]string} 翻译器类型列表
*/
export function GetTranslators(): Promise<string[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(3720069432) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType2($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* IsLanguageSupported 检查指定的语言代码是否受支持
*/
export function IsLanguageSupported(translatorType: translator$0.TranslatorType, languageCode: string): Promise<boolean> & { cancel(): void } {
let $resultPromise = $Call.ByID(2819945417, translatorType, languageCode) as any;
return $resultPromise;
}
/**
* TranslateWith 使用指定翻译器进行翻译
* @param {string} text - 待翻译文本
* @param {string} from - 源语言代码 (如 "en", "zh", "auto")
* @param {string} to - 目标语言代码 (如 "en", "zh")
* @param {string} translatorType - 翻译器类型 ("google", "bing", "youdao", "deepl")
* @returns {string} 翻译后的文本
* @returns {error} 可能的错误
*/
export function TranslateWith(text: string, $from: string, to: string, translatorType: string): Promise<string> & { cancel(): void } {
let $resultPromise = $Call.ByID(3577923623, text, $from, to, translatorType) as any;
return $resultPromise;
}
// Private type creation functions
const $$createType0 = translator$0.LanguageInfo.createFrom;
const $$createType1 = $Create.Map($Create.Any, $$createType0);
const $$createType2 = $Create.Array($Create.Any);

View File

@@ -10,9 +10,13 @@
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
/**
* AutoShowHide 自动显示/隐藏主窗口
*/
export function AutoShowHide(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(4044219428) as any;
return $resultPromise;
}
/**
* HandleWindowClose 处理窗口关闭事件
@@ -38,14 +42,6 @@ export function MinimizeButtonClicked(): Promise<void> & { cancel(): void } {
return $resultPromise;
}
/**
* SetAppReferences 设置应用引用
*/
export function SetAppReferences(app: application$0.App | null, mainWindow: application$0.WebviewWindow | null): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3544515719, app, mainWindow) as any;
return $resultPromise;
}
/**
* ShouldMinimizeToTray 检查是否应该最小化到托盘
*/

View File

@@ -0,0 +1,62 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* WindowService 窗口管理服务
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
/**
* GetOpenWindows 获取所有打开的文档窗口
*/
export function GetOpenWindows(): Promise<application$0.Window[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(1464997251) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType0($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* IsDocumentWindowOpen 检查指定文档的窗口是否已打开
*/
export function IsDocumentWindowOpen(documentID: number): Promise<boolean> & { cancel(): void } {
let $resultPromise = $Call.ByID(1735611839, documentID) as any;
return $resultPromise;
}
/**
* OpenDocumentWindow 为指定文档ID打开新窗口
*/
export function OpenDocumentWindow(documentID: number): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(494716471, documentID) as any;
return $resultPromise;
}
/**
* ServiceShutdown 实现服务关闭接口
*/
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(202192783) as any;
return $resultPromise;
}
/**
* ServiceStartup 服务启动时初始化
*/
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2432987694, options) as any;
return $resultPromise;
}
// Private type creation functions
const $$createType0 = $Create.Array($Create.Any);

View File

@@ -1,17 +1,29 @@
/* eslint-disable */
// @ts-nocheck
// biome-ignore lint: disable
// oxlint-disable
// ------
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
// biome-ignore lint: disable
export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
BlockLanguageSelector: typeof import('./src/components/toolbar/BlockLanguageSelector.vue')['default']
DocumentSelector: typeof import('./src/components/toolbar/DocumentSelector.vue')['default']
LinuxTitleBar: typeof import('./src/components/titlebar/LinuxTitleBar.vue')['default']
LoadingScreen: typeof import('./src/components/loading/LoadingScreen.vue')['default']
MacOSTitleBar: typeof import('./src/components/titlebar/MacOSTitleBar.vue')['default']
MemoryMonitor: typeof import('./src/components/monitor/MemoryMonitor.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
TabContainer: typeof import('./src/components/tabs/TabContainer.vue')['default']
TabContextMenu: typeof import('./src/components/tabs/TabContextMenu.vue')['default']
TabItem: typeof import('./src/components/tabs/TabItem.vue')['default']
Toolbar: typeof import('./src/components/toolbar/Toolbar.vue')['default']
WindowsTitleBar: typeof import('./src/components/titlebar/WindowsTitleBar.vue')['default']
WindowTitleBar: typeof import('./src/components/titlebar/WindowTitleBar.vue')['default']
}
}

View File

@@ -0,0 +1,149 @@
import {defineConfig} from 'vitepress'
const base = '/'
// https://vitepress.dev/reference/site-config
export default defineConfig({
base: base,
title: "voidraft",
description: "An elegant text snippet recording tool designed for developers.",
srcDir: 'src',
assetsDir: 'assets',
cacheDir: './.vitepress/cache',
outDir: './.vitepress/dist',
srcExclude: [],
ignoreDeadLinks: false,
head: [
["link", {rel: "icon", type: "image/png", href: "/icon/favicon-96x96.png", sizes: "96x96"}],
["link", {rel: "icon", type: "image/svg+xml", href: "/icon/favicon.svg"}],
["link", {rel: "shortcut icon", href: "/icon/favicon.ico"}],
["link", {rel: "apple-touch-icon", sizes: "180x180", href: "/icon/apple-touch-icon.png"}],
["meta", {name: "apple-mobile-web-app-title", content: "voidraft"}],
["link", {rel: "manifest", href: "/icon/site.webmanifest"}],
['meta', {name: 'viewport', content: 'width=device-width,initial-scale=1'}]
],
// 国际化配置
locales: {
root: {
label: 'English',
lang: 'en-US',
description: 'An elegant text snippet recording tool designed for developers.',
themeConfig: {
logo: '/icon/logo.png',
siteTitle: 'voidraft',
nav: [
{text: 'Home', link: '/'},
{text: 'Guide', link: '/guide/introduction'}
],
sidebar: {
'/guide/': [
{
text: 'Getting Started',
items: [
{text: 'Introduction', link: '/guide/introduction'},
{text: 'Installation', link: '/guide/installation'},
{text: 'Quick Start', link: '/guide/getting-started'}
]
},
{
text: 'Features',
items: [
{text: 'Overview', link: '/guide/features'}
]
}
]
},
socialLinks: [
{icon: 'github', link: 'https://github.com/landaiqing/voidraft'}
],
outline: {
label: 'On this page'
},
lastUpdated: {
text: 'Last updated'
},
docFooter: {
prev: 'Previous',
next: 'Next'
},
darkModeSwitchLabel: 'Appearance',
sidebarMenuLabel: 'Menu',
returnToTopLabel: 'Return to top',
footer: {
message: 'Released under the MIT License.',
copyright: 'Copyright © 2025-present landaiqing'
}
}
},
zh: {
label: '简体中文',
lang: 'zh-CN',
link: '/zh/',
description: '一个为开发者设计的优雅文本片段记录工具',
themeConfig: {
logo: '/icon/logo.png',
siteTitle: 'voidraft',
nav: [
{text: '首页', link: '/zh/'},
{text: '指南', link: '/zh/guide/introduction'}
],
sidebar: {
'/zh/guide/': [
{
text: '开始使用',
items: [
{text: '简介', link: '/zh/guide/introduction'},
{text: '安装', link: '/zh/guide/installation'},
{text: '快速开始', link: '/zh/guide/getting-started'},
{text: '界面总览', link: '/zh/guide/ui-overview'},
{text: '块语法与结构', link: '/zh/guide/block-syntax'}
]
},
{
text: '编辑与效率',
items: [
{text: '键盘快捷键', link: '/zh/guide/keyboard-shortcuts'},
{text: '多窗口与标签页', link: '/zh/guide/multiwindow-tabs'},
{text: '扩展与插件', link: '/zh/guide/extensions'},
{text: 'HTTP 客户端', link: '/zh/guide/http-client'}
]
},
{
text: '个性化与数据',
items: [
{text: '设置与配置', link: '/zh/guide/settings'},
{text: '主题与外观', link: '/zh/guide/themes'},
{text: '备份与更新', link: '/zh/guide/backup-update'}
]
},
{
text: '问题处理',
items: [
{text: '常见问题与故障排查', link: '/zh/guide/troubleshooting'}
]
}
]
},
socialLinks: [
{icon: 'github', link: 'https://github.com/landaiqing/voidraft'}
],
outline: {
label: '本页目录'
},
lastUpdated: {
text: '最后更新'
},
docFooter: {
prev: '上一页',
next: '下一页'
},
darkModeSwitchLabel: '外观',
sidebarMenuLabel: '菜单',
returnToTopLabel: '返回顶部',
footer: {
message: 'Released under the MIT License.',
copyright: 'Copyright © 2025-present landaiqing'
}
}
}
}
})

View File

@@ -0,0 +1,6 @@
@import "style/var.css";
@import "style/blur.css";
@import "style/badge.css";
@import "style/grid.css";

View File

@@ -0,0 +1,17 @@
// https://vitepress.dev/guide/custom-theme
import { h } from 'vue'
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import './index.css'
export default {
extends: DefaultTheme,
Layout: () => {
return h(DefaultTheme.Layout, null, {
// https://vitepress.dev/guide/extending-default-theme#layout-slots
})
},
enhanceApp({ app, router, siteData }) {
// ...
}
} satisfies Theme

View File

@@ -0,0 +1,21 @@
/* 提示框背景颜色 */
:root {
--vp-custom-block-tip-bg: var(--vp-c-green-soft);
}
/* 提示框 */
.custom-block.tip {
border-color: var(--vp-c-green-2);
}
/* 警告框 */
.custom-block.warning {
/* border-color: #d97706; */
border-color: var(--vp-c-yellow-2);
}
/* 危险框 */
.custom-block.danger {
/* border-color: #f43f5e; */
border-color: var(--vp-c-red-2);
}

View File

@@ -0,0 +1,73 @@
/* .vitepress/theme/style/blur.css */
:root {
/* 首页导航 */
.VPNavBar {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
/* 文档页导航两侧 */
.VPNavBar:not(.home) {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
@media (min-width: 960px) {
/* 文档页导航两侧 */
.VPNavBar:not(.home) {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
/* 首页下滑后导航两侧 */
.VPNavBar:not(.has-sidebar):not(.home.top) {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
}
@media (min-width: 960px) {
/* 文档页导航中间 */
.VPNavBar:not(.home.top) .content-body {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
/* 首页下滑后导航中间 */
.VPNavBar:not(.has-sidebar):not(.home.top) .content-body {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
}
/* 分割线 */
@media (min-width: 960px) {
/* 文档页分割线 */
.VPNavBar:not(.home.top) .divider-line {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
/* 首页分割线 */
.VPNavBar:not(.has-sidebar):not(.home.top) .divider {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
}
/* 搜索框 VPNavBarSearchButton.vue */
.DocSearch-Button {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
/* 移动端大纲栏 */
.VPLocalNav {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
/* 隐藏分割线 */
/* border-bottom: 5px solid var(--vp-c-gutter); */
border-bottom: 0px;
}
}

View File

@@ -0,0 +1,40 @@
/**
* Grid Background
* 网格背景样式 - 为文档页面添加简约的网格背景
* -------------------------------------------------------------------------- */
.VPDoc,
.VPHome {
position: relative;
}
.VPDoc::before,
.VPHome::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
pointer-events: none;
}
/* 亮色模式网格 */
:root:not(.dark) .VPDoc::before,
:root:not(.dark) .VPHome::before {
background-image:
linear-gradient(rgba(0, 0, 0, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 0, 0, 0.05) 1px, transparent 1px);
background-size: 60px 60px;
}
/* 暗色模式网格 */
.dark .VPDoc::before,
.dark .VPHome::before {
background-image:
linear-gradient(rgba(255, 255, 255, 0.06) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 255, 255, 0.06) 1px, transparent 1px);
background-size: 60px 60px;
}

View File

@@ -0,0 +1,137 @@
/**
* Customize default theme styling by overriding CSS variables:
* https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
*/
/**
* Colors
*
* Each colors have exact same color scale system with 3 levels of solid
* colors with different brightness, and 1 soft color.
*
* - `XXX-1`: The most solid color used mainly for colored text. It must
* satisfy the contrast ratio against when used on top of `XXX-soft`.
*
* - `XXX-2`: The color used mainly for hover state of the button.
*
* - `XXX-3`: The color for solid background, such as bg color of the button.
* It must satisfy the contrast ratio with pure white (#ffffff) text on
* top of it.
*
* - `XXX-soft`: The color used for subtle background such as custom container
* or badges. It must satisfy the contrast ratio when putting `XXX-1` colors
* on top of it.
*
* The soft color must be semi transparent alpha channel. This is crucial
* because it allows adding multiple "soft" colors on top of each other
* to create an accent, such as when having inline code block inside
* custom containers.
*
* - `default`: The color used purely for subtle indication without any
* special meanings attached to it such as bg color for menu hover state.
*
* - `brand`: Used for primary brand colors, such as link text, button with
* brand theme, etc.
*
* - `tip`: Used to indicate useful information. The default theme uses the
* brand color for this by default.
*
* - `warning`: Used to indicate warning to the users. Used in custom
* container, badges, etc.
*
* - `danger`: Used to show error, or dangerous message to the users. Used
* in custom container, badges, etc.
* -------------------------------------------------------------------------- */
:root {
--vp-c-default-1: var(--vp-c-gray-1);
--vp-c-default-2: var(--vp-c-gray-2);
--vp-c-default-3: var(--vp-c-gray-3);
--vp-c-default-soft: var(--vp-c-gray-soft);
--vp-c-brand-1: var(--vp-c-indigo-1);
--vp-c-brand-2: var(--vp-c-indigo-2);
--vp-c-brand-3: var(--vp-c-indigo-3);
--vp-c-brand-soft: var(--vp-c-indigo-soft);
--vp-c-tip-1: var(--vp-c-brand-1);
--vp-c-tip-2: var(--vp-c-brand-2);
--vp-c-tip-3: var(--vp-c-brand-3);
--vp-c-tip-soft: var(--vp-c-brand-soft);
--vp-c-warning-1: var(--vp-c-yellow-1);
--vp-c-warning-2: var(--vp-c-yellow-2);
--vp-c-warning-3: var(--vp-c-yellow-3);
--vp-c-warning-soft: var(--vp-c-yellow-soft);
--vp-c-danger-1: var(--vp-c-red-1);
--vp-c-danger-2: var(--vp-c-red-2);
--vp-c-danger-3: var(--vp-c-red-3);
--vp-c-danger-soft: var(--vp-c-red-soft);
}
/**
* Component: Button
* -------------------------------------------------------------------------- */
:root {
--vp-button-brand-border: transparent;
--vp-button-brand-text: var(--vp-c-white);
--vp-button-brand-bg: var(--vp-c-brand-3);
--vp-button-brand-hover-border: transparent;
--vp-button-brand-hover-text: var(--vp-c-white);
--vp-button-brand-hover-bg: var(--vp-c-brand-2);
--vp-button-brand-active-border: transparent;
--vp-button-brand-active-text: var(--vp-c-white);
--vp-button-brand-active-bg: var(--vp-c-brand-1);
}
/**
* Component: Home
* -------------------------------------------------------------------------- */
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(
120deg,
#bd34fe 30%,
#41d1ff
);
--vp-home-hero-image-background-image: linear-gradient(
-45deg,
#bd34fe 50%,
#47caff 50%
);
--vp-home-hero-image-filter: blur(44px);
}
@media (min-width: 640px) {
:root {
--vp-home-hero-image-filter: blur(56px);
}
}
@media (min-width: 960px) {
:root {
--vp-home-hero-image-filter: blur(68px);
}
}
/**
* Component: Custom Block
* -------------------------------------------------------------------------- */
:root {
--vp-custom-block-tip-border: transparent;
--vp-custom-block-tip-text: var(--vp-c-text-1);
--vp-custom-block-tip-bg: var(--vp-c-brand-soft);
--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
}
/**
* Component: Algolia
* -------------------------------------------------------------------------- */
.DocSearch {
--docsearch-primary-color: var(--vp-c-brand-1) !important;
}

View File

@@ -0,0 +1,163 @@
# Features
Explore the powerful features that make voidraft a great tool for developers.
## Block-Based Editing
voidraft's core feature is its block-based editing system:
- Each block can have a different programming language
- Blocks are separated by delimiters (`∞∞∞language`)
- Navigate quickly between blocks
- Format each block independently
## Syntax Highlighting
Professional syntax highlighting for 30+ languages:
- Automatic language detection
- Customizable color schemes
- Support for nested languages
- Code folding support
## HTTP Client
Built-in HTTP client for API testing:
### Request Types
- GET, POST, PUT, DELETE, PATCH
- Custom headers
- Multiple body formats: JSON, FormData, URL-encoded, XML, Text
### Request Variables
Define and reuse variables:
```http
@var {
baseUrl: "https://api.example.com",
token: "your-api-token"
}
GET "{{baseUrl}}/users" {
authorization: "Bearer {{token}}"
}
```
### Response Handling
- View formatted JSON responses
- See response time and size
- Inspect headers
- Save responses for later
## Code Formatting
Integrated Prettier support:
- Format on save (optional)
- Format selection or entire block
- Supports JavaScript, TypeScript, CSS, HTML, JSON, and more
- Customizable formatting rules
## Editor Extensions
### VSCode-Style Search
- Find and replace with regex support
- Case-sensitive and whole word options
- Search across all blocks
### Minimap
- Bird's-eye view of your document
- Quick navigation
- Customizable size and position
### Rainbow Brackets
- Color-coded bracket pairs
- Easier to match brackets
- Customizable colors
### Color Picker
- Visual color selection
- Supports hex, RGB, HSL
- Live preview
### Translation Tool
- Translate selected text
- Multiple language support
- Quick keyboard access
### Text Highlighting
- Highlight important text
- Multiple highlight colors
- Persistent highlights
## Multi-Window Support
Work efficiently with multiple windows:
- Each window is independent
- Separate documents
- Synchronized settings
- Window state persistence
## Theme Customization
Full control over editor appearance:
### Built-in Themes
- Dark mode
- Light mode
- Auto-switch based on system
### Custom Themes
- Create your own themes
- Customize every color
- Save and share themes
- Import community themes
## Auto-Update System
Stay current with automatic updates:
- Background update checks
- Notification of new versions
- One-click update
- Update history
- Support for multiple update sources (GitHub, Gitea)
## Data Backup
Secure your data with Git-based backup:
- Automatic backups
- Manual backup triggers
- Support for GitHub and Gitea
- Multiple authentication methods (SSH, Token, Password)
- Configurable backup intervals
## Keyboard Shortcuts
Extensive keyboard support:
- Customizable shortcuts
- Vim/Emacs keybindings (planned)
- Quick command palette
- Context-aware shortcuts
## Performance
Built for speed:
- Fast startup time
- Smooth scrolling
- Efficient memory usage
- Large file support
## Privacy & Security
Your data is safe:
- Local-first storage
- Optional cloud backup
- No telemetry or tracking
- Open source codebase

View File

@@ -0,0 +1,107 @@
# Getting Started
Learn the basics of using voidraft and create your first document.
## The Editor Interface
When you open voidraft, you'll see:
- **Main Editor**: The central area where you write and edit
- **Toolbar**: Quick access to common actions
- **Status Bar**: Shows current block language and other info
## Creating Code Blocks
voidraft uses a block-based editing system. Each block can have a different language:
1. Press `Ctrl+Enter` to create a new block
2. Type `∞∞∞` followed by a language name (e.g., `∞∞∞javascript`)
3. Start coding in that block
### Supported Languages
voidraft supports 30+ programming languages including:
- JavaScript, TypeScript
- Python, Go, Rust
- HTML, CSS, Sass
- SQL, YAML, JSON
- And many more...
## Basic Operations
### Navigation
- `Ctrl+Up/Down`: Move between blocks
- `Ctrl+Home/End`: Jump to first/last block
- `Ctrl+F`: Search within document
### Editing
- `Ctrl+D`: Duplicate current line
- `Ctrl+/`: Toggle comment
- `Alt+Up/Down`: Move line up/down
- `Ctrl+Shift+F`: Format code (if language supports Prettier)
### Block Management
- `Ctrl+Enter`: Create new block
- `Ctrl+Shift+Enter`: Create block above
- `Alt+Delete`: Delete current block
## Using the HTTP Client
voidraft includes a built-in HTTP client for testing APIs:
1. Create a block with HTTP language
2. Write your HTTP request:
```http
POST "https://api.example.com/users" {
content-type: "application/json"
@json {
name: "John Doe",
email: "john@example.com"
}
}
```
3. Click the run button to execute the request
4. View the response inline
## Multi-Window Support
Work on multiple documents simultaneously:
1. Go to `File > New Window` (or `Ctrl+Shift+N`)
2. Each window is independent
3. Changes are saved automatically
## Customizing Themes
Personalize your editor:
1. Open Settings (`Ctrl+,`)
2. Go to Appearance
3. Choose a theme or create your own
4. Customize colors to your preference
## Keyboard Shortcuts
Learn essential shortcuts:
| Action | Shortcut |
|--------|----------|
| New Window | `Ctrl+Shift+N` |
| Search | `Ctrl+F` |
| Replace | `Ctrl+H` |
| Format Code | `Ctrl+Shift+F` |
| Toggle Theme | `Ctrl+Shift+T` |
| Command Palette | `Ctrl+Shift+P` |
## Next Steps
Now that you know the basics:
- Explore [Features](/guide/features) in detail

View File

@@ -0,0 +1,63 @@
# Installation
This guide will help you install voidraft on your system.
## System Requirements
- **Operating System**: Windows 10 or later (macOS and Linux support planned)
- **RAM**: 4GB minimum, 8GB recommended
- **Disk Space**: 200MB free space
## Download
Visit the [releases page](https://github.com/landaiqing/voidraft/releases) and download the latest version for your platform:
- **Windows**: `voidraft-windows-amd64-installer.exe`
## Installation Steps
### Windows
1. Download the installer from the releases page
2. Run the `voidraft-windows-amd64-installer.exe` file
3. Follow the installation wizard
4. Launch voidraft from the Start menu or desktop shortcut
## First Launch
When you first launch voidraft:
1. The application will create a data directory to store your documents
2. You'll see the main editor interface with a welcome block
3. Start typing or create your first code block!
## Configuration
voidraft stores its configuration and data in:
- **Windows**: `%APPDATA%/voidraft/`
You can customize various settings including:
- Editor theme (dark/light mode)
- Code formatting preferences
- Backup settings
- Keyboard shortcuts
## Updating
voidraft includes an auto-update feature that will notify you when new versions are available. You can:
- Check for updates manually from the settings
- Enable automatic updates
- Choose your preferred update source
## Troubleshooting
If you encounter any issues during installation:
1. Make sure you have administrator privileges
2. Check that your antivirus isn't blocking the installation
3. Visit our [GitHub issues](https://github.com/landaiqing/voidraft/issues) page for help
Next: [Getting Started →](/guide/getting-started)

View File

@@ -0,0 +1,50 @@
# Introduction
Welcome to voidraft - an elegant text snippet recording tool designed specifically for developers.
## What is voidraft?
voidraft is a modern desktop application that helps developers manage text snippets, code blocks, API responses, meeting notes, and daily to-do lists. It provides a smooth and elegant editing experience with powerful features tailored for development workflows.
## Key Features
### Block-Based Editing
voidraft uses a unique block-based editing system inspired by Heynote. You can split your content into independent code blocks, each with:
- Different programming language settings
- Syntax highlighting
- Independent formatting
- Easy navigation between blocks
### Developer Tools
- **HTTP Client**: Test APIs directly within the editor
- **Code Formatting**: Built-in Prettier support for multiple languages
- **Syntax Highlighting**: Support for 30+ programming languages
- **Auto Language Detection**: Automatically recognizes code block language types
### Customization
- **Custom Themes**: Create and save your own editor themes
- **Extensions**: Rich set of editor extensions including minimap, rainbow brackets, color picker, and more
- **Multi-Window**: Work on multiple documents simultaneously
### Data Management
- **Git-Based Backup**: Automatic backup using Git repositories
- **Cloud Sync**: Sync your data across devices
- **Auto-Update**: Stay up-to-date with the latest features
## Why voidraft?
- **Developer-Focused**: Built with developers' needs in mind
- **Modern Stack**: Uses cutting-edge technologies (Wails3, Vue 3, CodeMirror 6)
- **Cross-Platform**: Works on Windows (macOS and Linux support planned)
- **Open Source**: MIT licensed, community-driven development
## Getting Started
Ready to start? Download the latest version from our [releases page](https://github.com/landaiqing/voidraft/releases) or continue reading the documentation to learn more.
Next: [Installation →](/guide/installation)

View File

@@ -0,0 +1,56 @@
---
layout: home
hero:
name: "voidraft"
text: "An elegant text snippet recording tool"
tagline: Designed for developers, built with modern technology
image:
src: /img/hero.png
alt: "voidraft"
actions:
- theme: brand
text: Get Started
link: https://github.com/landaiqing/voidraft/releases
- theme: alt
text: Documentation
link: /guide/introduction
features:
- icon: 📝
title: Block-Based Editing
details: Split your content into independent code blocks, each with different language settings. Inspired by Heynote's innovative design philosophy.
- icon: 🎨
title: Syntax Highlighting
details: Built-in support for 30+ programming languages with automatic language detection and Prettier integration for code formatting.
- icon: 🌐
title: HTTP Client
details: Integrated HTTP client with support for multiple request formats including JSON, FormData, XML, and more. Test APIs directly within the editor.
- icon: 🎯
title: Multi-Window Support
details: Work on multiple documents simultaneously with independent windows. Each window maintains its own state and configuration.
- icon: 🎭
title: Customizable Themes
details: Full theme customization support with dark/light modes. Create and save your own editor themes to match your preferences.
- icon: 🔧
title: Rich Extensions
details: VSCode-style search and replace, rainbow brackets, minimap, color picker, translation tool, text highlighting, and more.
- icon: 🔄
title: Auto-Update System
details: Built-in self-update mechanism with support for multiple update sources. Stay up-to-date with the latest features and improvements.
- icon: ☁️
title: Git-Based Backup
details: Automatic data backup using Git repositories. Supports GitHub, Gitea, with multiple authentication methods including SSH and tokens.
- icon: ⚡
title: Modern Architecture
details: Built with Wails3, Vue 3, and CodeMirror 6. Cross-platform desktop application with native performance and modern UI.
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,21 @@
{
"name": "voidraft",
"short_name": "voidraft",
"icons": [
{
"src": "/img/web-app-manifest-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/img/web-app-manifest-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,60 @@
# 备份与更新
![备份更新占位](/img/placeholder-backup.png)
> 替换为备份设置、推送状态、更新提示的截图。
## Git 备份
`BackupService``dataPath` 转化为 Git 仓库,并提供自动/手动推送。
### 初始化
1. 在设置 > 备份中开启「启用备份」。
2. 填写远程仓库 URLHTTPS 或 SSH
3. 选择认证方式:
- **Token**:适用于 GitHub/Gitea https 仓库。
- **SSH Key**:指定私钥路径和 passphrase。
- **用户名/密码**:适合自建 HTTP 仓库。
4. 点击“测试连接”(按钮在计划中,可先在终端测试)。
### 自动备份
- 勾选 “自动备份” + 设置 `BackupInterval`(分钟)。
- 服务会创建 ticker 定时 `git add -> commit -> push`
- Commit 消息形如 `Auto backup <timestamp>`,包含 `voidraft.db`, `extensions.json`, `config.json`, `voidraft_data.bin`
### 手动推送
- 打开工具栏消息中心或设置页点击“立即推送”。
- `backupStore.pushToRemote` 会显示状态气泡(成功/失败提示 3~5 秒)。
### 常见问题
| 提示 | 解决 |
| --- | --- |
| `repository not found` | 检查 Repo URL 与权限,必要时创建空仓库 |
| `authentication required` | 选择正确认证方式,确认 token scope需 repo 权限) |
| `auto backup stopped` | 查看日志,可能是网络不通或凭据失效;修改配置后服务会自动重启 |
## 自动更新
`SelfUpdateService` 负责检测、下载、应用新版。
### 检查更新
- 启动时若勾选 “自动更新” 会自动检查。
- 也可在设置 > 更新点击 “检查更新” 或在工具栏更新图标处触发。
- 服务优先访问 `primarySource`,失败时回退 `backupSource`
### 下载与应用
1. 检测到更新后,界面提示版本号与变更信息(从 Release Notes 获取)。
2. 点击 “下载并安装” 后,后台执行下载,完成后提示“准备重启”。
3. 选择 “立即重启” 将调用 `RestartApplication`,自动重新打开上次的文档。
4. 若启用了 “更新前备份”,在下载前会触发一次 Git push。
### 失败处理
| 场景 | 建议 |
| --- | --- |
| 下载失败 | 检查网络/代理,切换至备用源 |
| 校验失败 | 删除 `%LOCALAPPDATA%/voidraft/update-cache` 再重试 |
| 应用后无法启动 | 从 Git 备份回滚数据,下载旧版本安装包覆盖 |
## 发布渠道
- 官方 GitHub Releases`https://github.com/landaiqing/voidraft/releases`
- 自建 Gitea`https://git.landaiqing.cn/landaiqing/voidraft`
- 可在设置中替换 Owner/Repo/BaseURL以指向企业私有镜像。
> 建议将备份仓库设为私有,并在更新前后验证数据完整性。若要接入 S3/OSS 等备份方式,可关注 roadmap 或自行扩展。

View File

@@ -0,0 +1,78 @@
# 块语法与结构
![块语法占位](/img/placeholder-block-flow.png)
> 替换为展示分隔符(`∞∞∞language`)、块内容、语言标签的截图。
## 结构定义
每个块都由 **分隔符 + 内容** 组成:
```
∞∞∞language[-a]\n
<内容>
```
- `language``lang-parser/languages.ts` 中的 token例如 `text``javascript``python``md``http``math``sql`
- `-a`:可选自动检测后缀,表示忽略显式语言,由 `lang-detect/autodetect.ts` 根据内容猜测。
- 内容允许空行;块之间无需额外空格。
`parser.ts` 会将块解析为:
```ts
{
language: { name: "javascript", auto: false },
delimiter: { from, to },
content: { from, to },
range: { from, to }
}
```
这些字段供格式化、HTTP 运行、块操作等扩展示例使用。
## 快捷命令
| 命令 | 默认快捷键 | 说明 |
| --- | --- | --- |
| blockAddAfterCurrent | `Ctrl+Enter` | 插入新块(下方) |
| blockAddBeforeCurrent | `Ctrl+Shift+Enter` | 插入新块(上方) |
| blockGotoPrevious/Next | `Alt+↑ / Alt+↓` | 在块之间跳转 |
| blockSelectAll | `Ctrl+Shift+A` | 选中当前块(含分隔符) |
| blockDelete | `Alt+Delete` | 删除整个块 |
| blockMoveUp/Down | `Ctrl+Shift+↑ / Ctrl+Shift+↓` | 重排块顺序 |
| blockFormat | `Ctrl+Shift+F` | 针对当前块执行 Prettier |
## 语言与能力矩阵
| 语言 | 适配特性 |
| --- | --- |
| `text`/`note` | 基础文本,没有特殊扩展 |
| `md` | Markdown 预览、checkbox、高亮 |
| `javascript`/`typescript`/`json` | Prettier 格式化、彩虹括号、折叠、颜色选择 |
| `go`/`rust`/`python`/`java` | 高亮、折叠、自动缩进、语法跳转 |
| `http` | HTTP DSL、变量、响应插入详见 [HTTP 客户端](/zh/guide/http-client)|
| `math` | `mathBlock` 运行器,支持 `prev` 引用上一次结果 |
| `sql`/`yaml`/`toml` | 语法高亮、格式化(由 Prettier/插件支持) |
> 若需要不在列表中的语言,可先使用 `text` 块输入,再在工具栏搜索语言名;也可以在 `lang-parser/languages.ts` 中添加条目。
## 自动检测策略
- 当分隔符以 `∞∞∞text-a` 写成时,`AUTO_DETECT_SUFFIX` 生效,`lang-detect` 会基于内容统计 + Levenshtein 距离预测语言。
- 自动结果会写入块状态,但不会覆盖分隔符原文,因此可通过工具栏明确指定。
## 特殊块
### HTTP 块
- 语法位于 `extensions/httpclient/language`,支持 `@var/@json/@form/@multipart` 等指令。
- 运行器会在块尾生成 `### Response`包含状态码、耗时、headers、body。
### 数学块
- 语言设为 `math`,逐行计算。
- `prev` 变量表示上一行结果,可完成链式运算。
- 结果挂件可点击复制,或显示格式化/定点值。
### Markdown 块
- 工具栏中的 Preview 按钮会调用 `toggleMarkdownPreview`,右侧打开面板。
- 预览状态按文档隔离,不会影响其他文档。
## 分隔符校验
- `parser.ts` 暴露 `isValidDelimiter` 方法,格式错误时分隔符会以红色底纹标记。
- 复制/剪切操作会自动扩选到整个块,确保分隔符完整。
## 维护建议
- 保持每个逻辑主题占用一个块,并用 `md` 块写标题。
- 大量多语言内容时,可用 `text` + 自动检测,待语言确定后再改分隔符。
- 若文档出现“无法解析块”提示,可运行 `格式化文档` 或在命令面板触发“重建语法树”。

View File

@@ -0,0 +1,42 @@
# 扩展与插件
![扩展占位](/img/placeholder-extensions.png)
> 替换为展示扩展设置面板或功能合集(小地图、搜索、翻译)的截图。
voidraft 的扩展系统由 `internal/models/extensions.go` + 前端 `ExtensionManager` 驱动。扩展配置存储在 `%USERPROFILE%/.voidraft/data/extensions.json`,可在设置页面勾选启用或调整参数。
## 核心扩展
| 扩展 ID | 功能 | 关键文件 |
| --- | --- | --- |
| `editor` | 基础 CodeMirror 行为、光标保护、滚轮缩放 | `frontend/src/views/editor/basic/*` |
| `codeblock` | 块解析、拖拽、复制、格式化、数学、HTTP DSL | `extensions/codeblock` |
| `vscodeSearch` | VSCode 风格搜索替换面板 | `extensions/vscodeSearch` |
| `markdownPreview` | Markdown 实时预览 | `extensions/markdownPreview` |
## 编辑增强
- **Rainbow Brackets (`rainbowBrackets`)**:彩虹色括号匹配。
- **Fold (`fold`)**:代码折叠/展开,支持 `Ctrl+Alt+[`/`]`
- **Hyperlink (`hyperlink`)**:识别 URL/邮箱,`Ctrl+Click` 打开。
- **Color Selector (`colorSelector`)**:悬浮配色器,支持 HEX/RGB/HSL。
- **Checkbox (`checkbox`)**Markdown 任务列表交互式勾选。
- **Text Highlight (`textHighlight`)**`Mod+Shift+H` 快速标记重点,可自定义颜色/透明度。
## 工具扩展
- **Translator (`translator`)**:选区翻译;配置项包括默认翻译器、最短/最长字符数。后端集成 Bing/Google/Youdao/DeepL/TartuNLP。
- **Minimap (`minimap`)**:右侧迷你地图,支持悬浮/常驻、显示字符/块,突出当前选区。
- **Search (`search`)**:补充 VSCode 风格搜索,暴露命令给快捷键系统。
- **HTTP Client (`httpclient`)**DSL + 运行器,详见 [HTTP 客户端](/zh/guide/http-client)。
## 未来扩展(欢迎参与)
- Vim / Emacs 键位层(正在计划)。
- 自定义命令面板Command Palette
- 代码片段/模板库扩展。
- AI 助手(文生代码/注释)。
## 开发者指南概述
1. **注册扩展**:在 `extensionManager.registerFactory` 中添加自定义扩展工厂。
2. **配置项**:在 `extensions.json` 中声明默认配置,并在设置面板暴露 UIVue 组件)。
3. **热更新**:调用 `manager.updateExtensionImmediate(id, enabled, config)` 实时切换,无需刷新窗口。
4. **后端交互**:通过 `ExtensionService.UpdateExtensionState` 将配置写入 SQLite。
> 如果需要编写自用扩展,可 fork 项目在 `frontend/src/views/editor/extensions` 中添加文件,再通过 PR 贡献给社区。

View File

@@ -0,0 +1,86 @@
# 功能特性
![扩展能力占位](/img/placeholder-extensions.png)
> 替换为展示彩虹括号、小地图、搜索工具条等扩展组合的截图。
## 1. 编辑体验
### 块状编辑全流程
- `∞∞∞language[-a]` 语法由 `codeblock/lang-parser` 解析,支持自动检测、分隔符校验、块范围缓存。
- `blockState` 暴露 API`getActiveBlock/getFirstBlock/getLastBlock`供格式化、重排、复制、HTTP 执行等插件共享。
- `mathBlock` 可在块尾展示计算结果,点击可复制;`CURRENCIES_LOADED` 注解在汇率更新时刷新缓存。
### 语言支持
- 内建 30+ 语言模版(`lang-parser/languages.ts`),覆盖 JS/TS/HTML/CSS/Go/Rust/Python/SQL/YAML/HTTP/Markdown/Plain/Text/Math。
- 语言切换下拉实时更新分隔符;支持自定义别名(例如 `∞∞∞shell`)。
### 语法高亮与主题
- `rainbowBracket``fold``hyperlink``colorSelector` 等扩展组合提供接近 VSCode 的体验。
- `ThemeService` 预置 12+ 暗/亮主题,可在设置中克隆、修改 JSON 色板,并立即生效。
### 文本统计与滚轮缩放
- `statsExtension` 实时统计行数、字符数和选区,展示在状态栏。
- `wheelZoomExtension``Ctrl + 鼠标滚轮` 调整字体大小,同时同步 `configStore`
## 2. 高效工具箱
### VSCode 式搜索替换
- `extensions/vscodeSearch` 提供悬浮面板,支持大小写/整词/正则、向上/向下跳转、批量替换。
- 对应快捷键:`Ctrl+F``Ctrl+H``Alt+Enter`(替换全部)。
### Markdown 预览
- `panelStore` 为每个文档维护预览状态,保证不同文档互不影响。
- 选中 Markdown 块后点击工具栏预览按钮即可在右侧展开实时渲染面板。
### HTTP 客户端
- Request DSL + 运行器在 [专章](/zh/guide/http-client) 详细说明。
- 支持变量、响应插入、多种请求体、定制 header、复制 cURL。
### 翻译助手
- `translator` 扩展监听选区,符合长度阈值后显示按钮;由 `TranslationService` 调用 Bing/Google/Youdao/DeepL/TartuNLP。
- 支持语种缓存、复制译文、切换译文方向。
### 颜色与高亮
- `colorSelector` 识别 `#fff/rgba/hsl`、打开取色器;`textHighlight``Mod+Shift+H` 标记重要行。
## 3. 复杂布局能力
### 多窗口
- `WindowService` 允许为任意文档创建独立 WebViewURL 自动携带 `?documentId=`
- `WindowSnapService` 根据主窗口位置吸附子窗口(上下左右+四角),并缓存尺寸、位置。
- 支持全局热键(默认 `Alt+X`)一键显示或隐藏所有窗口。
### 标签页
- `tabStore` 通过 `enableTabs` 控制;支持拖拽排序、关闭其他/左侧/右侧标签。
- 与多窗口互斥:当文档被新窗口接管后会从标签栏移除,避免重复。
### 系统托盘与置顶
- `TrayService` 控制关闭时隐藏到托盘或直接退出。
- 工具栏提供图钉按钮,可即时切换 `AlwaysOnTop`(支持临时置顶和永久置顶)。
## 4. 数据守护
### SQLite + 自动迁移
- `DatabaseService` 启动时执行 PRAGMA + 表结构校验,缺失字段自动 `ALTER TABLE`
- 默认生成 `documents/extensions/key_bindings/themes` 等表,支持软删除与锁定。
### Git 备份
- `BackupService``dataPath` 初始化为 Git 仓库,支持 Token/SSHKey/用户名密码三种方式。
- 自动任务按分钟运行(`BackupInterval`),包括 add/commit/push也可从 UI 触发一次性 push。
### 配置快照
- 所有设置存于 `config.json`,包含 `metadata.version/lastUpdated`,方便手工回滚。
- `ConfigService.Watch` 为窗口吸附、托盘、热键等服务提供实时响应。
### 自动更新
- `SelfUpdateService` 先检查主源Gitea失败再回退到 GitHub下载完成后可一键「重启并更新」。
- 更新前可选自动触发 Git 备份(`backupBeforeUpdate`)。
## 5. 自动化与集成
- **启动时动作**:可开启开机自启(`StartupService`)、默认最小化至托盘。
- **HTTP 运行挂钩**`response-inserter` 可在响应块尾部插入 `// @timestamp` 等自定义标记。
- **Math/汇率**`mathBlock` 可引用上一次结果 (`prev`),配合 `CURRENCIES_LOADED` 注解支撑货币换算。
- **系统信息**`SystemService` 暴露内存、GC、Goroutine 数量,可在调试面板查看。
## 6. 可配置的快捷键
- 详见 [键盘快捷键](/zh/guide/keyboard-shortcuts)。默认绑定定义在 `internal/models/key_bindings.go`,前端设置页可逐项修改、禁用。
## 7. 文档 & 帮助
- 文档站以 VitePress 构建(`frontend/docs`),内置中英双语导航,可一键部署到 GitHub Pages。
- `README` 与本文档同步介绍核心功能;建议将常用工作流截图补充到每个「图片占位」中。

View File

@@ -0,0 +1,82 @@
# 快速开始
![块结构流程占位](/img/placeholder-block-flow.png)
> 替换为展示块分隔符、语言标签、内容的截图,帮助读者直观理解 `∞∞∞language` 结构。
## 5 分钟上手流程
1. **启动应用**:等待加载动画结束,默认会打开 `default` 文档。
2. **新建文档**:点击工具栏的文档列表按钮,输入标题后创建;也可在设置里开启标签页,以便同时挂载多个文档。
3. **创建首个块**
- 在空白处输入 `∞∞∞javascript` 并回车。
- 输入代码或文本,`CodeBlockExtension` 会自动匹配语法高亮。
4. **格式化与预览**
- 选中块后点击工具栏的「Format」或使用 `Ctrl+Shift+F`
- 如果块语言是 `md`可点击「Preview」按钮开启 Markdown 侧栏。
5. **运行 HTTP 请求**:创建 `∞∞∞http` 块,填写请求,再点击行号旁的 Run 按钮即可获取响应。
6. **打开第二窗口**:在文档列表中右键文档 -> “在新窗口中打开”。`WindowService` 会创建无边框窗口并自动贴靠主窗口。
## 界面导览
- **主编辑区**CodeMirror 视图,支持鼠标滚轮 + `Ctrl` 缩放(`wheelZoomExtension`)。
- **右侧小地图**`extensions/minimap` 提供鸟瞰和选区同步。
- **底部状态**`editorStore.documentStats` 实时展示行数/字符/选区。
- **工具栏**`Toolbar.vue`包含文档切换、块语言下拉、窗口置顶、格式化、Markdown 预览、更新提示、进入设置等。
## 块的基本操作
| 操作 | 快捷键 | 说明 |
| --- | --- | --- |
| 新建块(下方) | `Ctrl+Enter` | 在当前块后插入 `∞∞∞text-a` 分隔符 |
| 新建块(上方) | `Ctrl+Shift+Enter` | 在当前块前插入 |
| 跳到上/下一个块 | `Alt+Up / Alt+Down` | 通过 `blockGotoPrevious/Next` 命令 |
| 删除块 | `Alt+Delete` | 仅删除块内容,不影响其他块 |
| 块排序 | `Ctrl+Shift+↑/↓` | `moveLines` 结合块范围移动 |
| 复制块 | `Ctrl+C`(光标在块上即可) | `copyPaste.ts` 自动扩展选区至整个块 |
## 自动语言与格式化
- 当分隔符写成 `∞∞∞text-a` 时,会触发语言自动检测(`lang-detect/autodetect.ts`),常用于粘贴未知代码。
- `formatCode.ts` 调用 Prettier自动选择 parser若语言不支持会提示不可格式化。
- 块语言可在工具栏下拉中修改,列表由 `lang-parser/languages.ts` 提供。
## Markdown / 待办
1. 使用 `∞∞∞md` 分隔符。
2. 在块内写 Markdown点击工具栏预览按钮。
3. 勾选/取消 Checkbox`extensions/checkbox`)即可同步更新文本。
## 翻译与文本标注
- 选中文本后会浮现翻译入口(`translator` 扩展),点击即可在块内查看结果、复制、切换目标语言。
- `textHighlight` 扩展提供 `Mod+Shift+H` 高亮当前选区,颜色可在扩展设置中调整。
## HTTP 客户端概览
```http
http
@var {
baseUrl: "https://api.example.com",
token: "{{secrets.token}}"
}
POST "{{baseUrl}}/users" {
authorization: "Bearer {{token}}"
content-type: "application/json"
@json {
name: "voidraft",
role: "developer"
}
}
```
- `parser/request-parser.ts` 会将变量与请求体解析为结构化对象。
- 点击 gutter Run 获取响应,`response-inserter.ts` 会将结果写入 `### Response` 区块。
## 自动保存与版本安全
- `editorStore` 为每个文档维护 `autoSaveTimer`,默认 2000 ms可在设置 > 编辑 调整。
- `documentStates` 记录每个文档的光标位置,切换文档或重启应用都会恢复。
- 若开启 Git 备份,可在工具栏或设置中查看最近一次 `push` 是否成功。
## 最佳实践
- 使用 Markdown 块为每组代码加标题/注释,便于导航。
- 重要文档启用“锁定”以避免被删除(文档右键菜单)。
- 多窗口 + 吸附用于常驻参考资料,标签页用于在一个窗口内快速切换。
- 善用「窗口置顶」图钉,让 voidraft 叠放在 VSCode/浏览器之上。
接下来:
- [界面总览](/zh/guide/ui-overview)
- [块语法与结构](/zh/guide/block-syntax)

View File

@@ -0,0 +1,72 @@
# HTTP 客户端
![HTTP 客户端占位](/img/placeholder-http.png)
> 替换为 HTTP 块 + 响应卡片的截图。
voidraft 将 HTTP 测试写成块(`∞∞∞http`),语法与 JetBrains Http Client 类似。解析与执行由 `frontend/src/views/editor/extensions/httpclient` 完成。
## 基本语法
```http
http
GET "https://api.example.com/users" {
accept: "application/json"
}
```
- 方法 + URL 必须用双引号包裹。
- Header 以 `key: "value"` 格式编写。
- 请求体使用内联指令(见下文)。
## 变量与环境
```http
@var {
baseUrl: "https://api.example.com",
token: "{{secrets.token}}"
}
GET "{{baseUrl}}/users" {
authorization: "Bearer {{token}}"
}
```
- `@var` 块使用 JSON 语法。
- 变量在任意请求中以 `{{name}}` 引用。
- `variable-resolver.ts` 支持嵌套、默认值、外部 secrets 映射。
## 请求体助手
| 指令 | 示例 | 说明 |
| --- | --- | --- |
| `@json` | `@json { "name": "voidraft" }` | 自动 `content-type: application/json` 并格式化 |
| `@form` | `@form { username: "demo" }` | 转为 `application/x-www-form-urlencoded` |
| `@multipart` | `@multipart { file: @"C:\tmp\a.txt" }` | 读取文件、多段表单 |
| `@text` | `@text <raw body>` | 自由文本 |
## 运行与响应
1. 将光标置于 HTTP 块内。
2. 点击行号左侧的 Run三角形图标或按下自定义快捷键。
3. 运行结果会插入到块尾的 `### Response` 中,包含:
- 状态行 + 响应时间 + 体积。
- Headers可折叠
- 响应体(自动格式化 JSON / XML / HTML / Text
- 复制、另存为、再次发送等快捷按钮。
## 多请求文档
- 每个 `∞∞∞http` 块被视为独立请求。
- `request-parser.ts` 会解析同一块内的多个请求(以 `###` 分隔)。
- 使用 Markdown 块写注释或分组标题。
## 变量注入顺序
1. 块内 `@var`
2. 文档级变量(计划中)。
3. 环境变量(`EnvironmentService` 预留)。
## 调试技巧
- 运行器会在控制台打印完整请求信息,可通过 `wails3 dev` 查看。
- 如果响应过大,可右键响应块选择“折叠正文”或“导出到文件”。
- 网络错误会在响应卡片顶部以红条展示,内容来自 `HttpClientService`
- 需要代理时确保系统代理已设置voidraft 会自动继承。
## 与其他功能配合
- 运行结果可直接与 Markdown/代码块混排,形成 API 使用手册。
- 配合 Git 备份可版本化 API 调试记录。
- 可将响应复制到其他块(例如 JSON → Prettier 之后用于 mock
> 欢迎在 Issue 中提交你希望支持的额外 DSL 指令(例如 GraphQL、WebSocket、gRPC

View File

@@ -0,0 +1,77 @@
# 安装
![安装流程占位](/img/placeholder-settings.png)
> 替换为安装向导或设置页截图,展示关键开关(置顶、数据目录、自动更新等)。
## 系统要求2025.11
| 项目 | 最低配置 | 推荐配置 |
| --- | --- | --- |
| 操作系统 | Windows 10 19045 / Windows 11 21H2 | Windows 11 23H2macOS/Linux 版本开发中) |
| CPU | x86_64 双核 | 4 核以上 |
| 内存 | 4 GB | ≥ 8 GB |
| 磁盘空间 | 200 MB含 SQLite 数据) | 1 GB 以上以保存附件/备份 |
| 运行环境 | Go 1.21+, Node.js 18+(仅开发者编译时需要) | 同左 + pnpm 8 用于前端 |
## 获取发行版
1. 打开 [GitHub Releases](https://github.com/landaiqing/voidraft/releases) 或自建 Gitea 镜像。
2. 下载 `voidraft-windows-amd64-installer.exe`(安装版)或 `voidraft-portable.zip`(绿色版)。
3. (可选)验证 SHA256
```powershell
Get-FileHash .\voidraft-windows-amd64-installer.exe -Algorithm SHA256
```
4. 双击安装包,按向导完成安装;或解压绿色版至任意目录并创建快捷方式。
## 首次启动流程
1. 启动后将创建数据目录:`%USERPROFILE%\.voidraft\data`(含 `voidraft.db`、`config.json`、`extensions.json`)。
2. 默认会生成 `default` 文档和一段示例块 `∞∞∞text-a`。
3. 若检测到旧版本数据,`ConfigMigrationService` 会自动迁移字段;`DataMigrationService` 确保表结构一致。
4. 首次运行建议立刻打开「设置 > 备份」配置远程 Git 仓库。
## 开发者手动构建
```bash
# 克隆项目
git clone https://github.com/landaiqing/voidraft.git
cd voidraft
# 安装前端依赖
cd frontend
npm install
npm run build
cd ..
# 构建/运行桌面应用
wails3 dev # 启动调试
wails3 package # 生成安装包(输出位于 bin/
```
> 若遇到 `wails3` 未找到,请先执行 `go install github.com/wailsapp/wails/v3/cmd/wails3@latest`。
## 数据目录与可执行文件
| 类型 | 默认位置 | 说明 |
| --- | --- | --- |
| 安装目录 | `C:\Program Files\voidraft` | 包含主程序与嵌入式前端资源 |
| 数据目录 | `C:\Users\<you>\.voidraft\data` | 可在设置 > 通用修改 `dataPath`,修改后需重启 |
| 备份仓库 | `dataPath/.git` | `BackupService` 初始化或使用现有仓库 |
| 日志 | `%LOCALAPPDATA%/voidraft/logs/*.log` | 通过 Wails `application.Log` 输出 |
## 常用 CLI 检查
```powershell
# 查看版本
& "C:\Program Files\voidraft\voidraft.exe" --version
# 清理缓存(若前端异常)
Remove-Item "$env:APPDATA\voidraft\Cache" -Recurse -Force
```
## 防火墙与代理
- voidraft 仅在使用 HTTP 客户端、更新检测、REST 翻译器时发起网络请求。
- 若处于企业代理,请在系统代理中放行 `voidraft.exe` 或设置环境变量 `HTTP(S)_PROXY`HTTP 客户端会继承系统代理。
## 常见安装问题
| 症状 | 处理方案 |
| --- | --- |
| 安装向导被安全策略阻止 | 使用签名哈希进行白名单设置或改用便携版 |
| 启动后白屏 | 删除 `%APPDATA%/voidraft/Cache`,确保显卡驱动支持 WebView2 |
| `wails3 dev` 报错缺少 WebView2 | 安装 [WebView2 Runtime](https://developer.microsoft.com/en-us/microsoft-edge/webview2/) |
| 便携版无法写入 | 检查解压目录是否具有写权限,或在设置内切换 `dataPath` 至可写分区 |
> 继续阅读:[快速开始](/zh/guide/getting-started)

View File

@@ -0,0 +1,73 @@
# 简介
> voidraft 是一款面向开发者的「块式工作台」,用 CodeMirror 6 打造 Heynote 风格的体验,并结合 Wails3 + Go 后端提供系统托盘、全局热键、自动备份等桌面级能力。
![主界面总览占位](/img/placeholder-main-ui.png)
> 将 `/img/placeholder-main-ui.png` 替换为真实的应用主界面截图,演示数据面板、工具栏和右侧小地图。
## 产品定位
- **核心诉求**:在一处快速记录代码/配置/API 响应/待办清单,并能随时重排、格式化、运行或搜索。
- **目标用户**需要跨项目管理零碎文本的开发者、DevOps、测试或产品技术写作者。
- **设计理念**:所有内容都拆成可重排的块(`∞∞∞language`);每个块拥有独立语言、格式化器与扩展;多窗口/多标签保证同一份数据的不同视角。
## 面向场景
1. **临时代码/脚本草稿**:支持 30+ 语言高亮、Prettier 格式化、彩虹括号、文本高亮。
2. **API 调试台**HTTP 块内置运行器、变量解析、响应插入;请求和响应始终和文档共存。
3. **会议 & 需求记录**Markdown 块 + Checkbox 扩展 + 颜色标注快速整理想法。
4. **翻译与研究**:选中文本即可调 Bing/Google/DeepL/TartuNLP/有道翻译,结果内联呈现。
5. **多窗口资料墙**重要文档可弹出独立无边框窗口依附Snap在主窗口侧边。
## 核心概念
### 块式编辑器
- 解析器位于 `frontend/src/views/editor/extensions/codeblock`,依赖自研 Lezer 语法树确保 `∞∞∞` 分隔符稳定。
- 块结构(语言、是否自动检测、正文范围)存入 `blockState`供格式化、移动、复制、HTTP 执行等扩展复用。
- `math` 块使用 `math.js` 运行器,`http` 块调用 request parser + gutter run widget。
### 扩展驱动
- 后端通过 `internal/models/extensions.go` 定义扩展 ID/配置,`ExtensionService` 负责持久化。
- 前端 `ExtensionManager` 根据扩展配置动态拼装 CodeMirror Extension pipeline小地图、VSCode Search、Translator、Color Picker 等)。
- 所有扩展都可在设置页热切换,立即同步到当前与所有已打开的编辑器实例。
### 数据与安全
- SQLite 数据保存在 `%USERPROFILE%/.voidraft/data/voidraft.db`(可在设置中自定义 dataPath
- `DatabaseService` 自动迁移表结构,`DocumentService` 提供软删除/锁定机制避免误删默认草稿。
- `BackupService` 基于 go-gitSSH/Token/用户名密码)把 dataPath git 化,可按分钟全量提交、推送到 GitHub/Gitea 等。
- `SelfUpdateService` 同时轮询 GitHub/Gitea Release支持自动下载 + 一键重启。
## 系统架构概览
| 层级 | 说明 | 关键路径 |
| --- | --- | --- |
| 桌面容器 | Wails3 + Go 1.21,负责窗口、托盘、热键、服务注入 | `main.go`, `internal/services` |
| 后端服务 | Config/Document/Extension/Theme/Backup/Window/Hotkey/Translation 等 | `internal/services/*.go` |
| 数据模型 | Document、Theme、KeyBinding、GitBackup、Config | `internal/models` |
| 前端应用 | Vue 3 + Vite + Pinia + vue-router | `frontend/src` |
| 编辑器内核 | CodeMirror 6 扩展及自研块解析、HTTP DSL、Markdown 预览 | `frontend/src/views/editor` |
| 文档站点 | VitePress多语言导航 | `frontend/docs` |
## 模块速览
- **文档存储**`DocumentService` 支持创建/重命名/软删除/恢复、多窗口并发打开同一文档。
- **编辑器实例管理**`editorStore` 使用 LRU 缓存 + 自动保存计时器,确保在多文档切换时保留光标位置、未保存内容。
- **HTTP 客户端**`extensions/httpclient` 包括 Lezer 语法、变量解析、响应插入与运行 gutter支持 JSON/FormData/GraphQL 等多体格式。
- **Markdown 预览**`panelStore` 管理逐文档的预览状态,可随块实时刷新。
- **多窗口/吸附**`WindowService` + `WindowSnapService` 根据主窗口位置智能吸附子窗口、自动记忆尺寸。
- **全局热键**`HotkeyService` 监听系统级组合键,切换窗口显隐(默认 Alt+X可配置
- **系统托盘**`systray.SetupSystemTray` 注入显示/隐藏、退出、开机启动等操作。
- **翻译生态**`TranslationService` 聚合 Bing/Google/Youdao/DeepL/TartuNLP前端 `translator` 扩展提供 Tooltip + 复制。
- **主题与外观**`ThemeService` 预置 12+ 主题,可重置/克隆;前端 `createThemeExtension` 即时应用。
## 数据流(从键盘到持久化)
1. 用户按键 -> CodeMirror extensions 更新文档。
2. `contentChangeExtension` 记录脏状态并刷新 `documentStats`(行数、字符数、选区字符数)。
3. 触发自动保存计时器(默认 2s -> `DocumentService.UpdateDocumentContent` 写入 SQLite。
4. 若开启 Git 自动备份,每次 Commit 会序列化数据库 + 附带 `voidraft_data.bin`
5. 配置变更Pinia store通过 `ConfigService.Set` 传回 Go并触发观察者如 WindowSnap/Hotkey/Backup
## 版本节奏与路线图
- ✅ 当前实现多窗口、标签页、HTTP 客户端、Markdown Preview、数学块、彩虹括号、翻译、Git 备份、自动更新。
- 🚧 进行中自定义扩展导入、键位模版、Linux/macOS 原生打包。
- 🗺️ 规划中:剪贴板历史、团队同步、云端模板市场。
## 下一步
- [安装 voidraft](/zh/guide/installation)
- [界面总览](/zh/guide/ui-overview)
- [快速开始](/zh/guide/getting-started)

View File

@@ -0,0 +1,74 @@
# 键盘快捷键
![快捷键占位](/img/placeholder-shortcuts.png)
> 替换为展示快捷键设置界面或常用快捷键速查表的截图。
快捷键定义源自 `internal/models/key_bindings.go`,在设置 > 键位 中可以启用/禁用或改写。下表列出常用组合:
## 块管理
| 功能 | 默认快捷键 | 备注 |
| --- | --- | --- |
| 新建块(下方) | `Ctrl+Enter` | `blockAddAfterCurrent` |
| 新建块(上方) | `Ctrl+Shift+Enter` | `blockAddBeforeCurrent` |
| 跳到上/下一个块 | `Alt+↑ / Alt+↓` | `blockGotoPrevious/Next` |
| 选择当前块 | `Ctrl+Shift+A` | `blockSelectAll` |
| 删除块 | `Alt+Delete` | `blockDelete` |
| 块上移/下移 | `Ctrl+Shift+↑ / Ctrl+Shift+↓` | `blockMoveUp/Down` |
| 复制块 | `Ctrl+C`(块获得焦点) | `blockCopy` |
| 剪切块 | `Ctrl+X` | `blockCut` |
| 粘贴块 | `Ctrl+V` | `blockPaste` |
## 行与文本编辑
| 功能 | 快捷键 |
| --- | --- |
| 行复制(上/下) | `Shift+Alt+↑ / Shift+Alt+↓` |
| 行移动(上/下) | `Alt+↑ / Alt+↓`(在块内部) |
| 插入空行 | `Ctrl+Enter`(块尾后仍可插入) |
| 选择整行 | `Alt+L` |
| 语法级跳转 | `Ctrl+Alt+Left / Ctrl+Alt+Right` |
| 匹配括号 | `Shift+Ctrl+\` |
| 注释/块注释 | `Ctrl+/` / `Shift+Alt+A` |
| Tab 缩进/反向缩进 | `Ctrl+]` / `Ctrl+[` |
| 删除单词(向前/向后) | `Ctrl+Backspace` / `Ctrl+Delete` |
## 搜索与替换
| 功能 | 快捷键 | 描述 |
| --- | --- | --- |
| 打开搜索 | `Ctrl+F` | `showSearch` |
| 打开替换 | `Ctrl+H` | `searchShowReplace` |
| 切换大小写/整词/正则 | `Alt+C / Alt+W / Alt+R` | `searchToggleCase/Word/Regex` |
| 替换全部 | `Alt+Enter` | `searchReplaceAll` |
## Markdown/预览/格式化
| 功能 | 快捷键 |
| --- | --- |
| 格式化块 | `Ctrl+Shift+F` |
| 打开 Markdown 预览 | 工具栏按钮(建议映射到 `Ctrl+Shift+M` |
| 高亮文本 | `Mod+Shift+H` |
## 窗口与系统
| 功能 | 快捷键 |
| --- | --- |
| 新建窗口 | `Ctrl+Shift+N`(命令面板) |
| 全局显示/隐藏所有窗口 | 默认 `Alt+X`(可在设置 > 通用 > 全局热键中修改) |
| 打开设置 | `Ctrl+,` |
| 切换主题 | `Ctrl+Shift+T`(可自定义) |
## HTTP 客户端
| 功能 | 快捷键 |
| --- | --- |
| 运行请求 | 点击行号旁 Run 或自定义 `Ctrl+Alt+R` |
| 复制响应正文 | `Ctrl+Alt+C`(响应块聚焦时) |
## 翻译工具
| 功能 | 快捷键 |
| --- | --- |
| 显示翻译浮层 | 选中 ≥ `minSelectionLength` 的文本后按 `Ctrl+'`(可自定义) |
| 复制译文 | 在浮层中按 `Ctrl+C` |
## 自定义与导出
1. 打开设置 > 键位,列表会加载来自 `ExtensionService.GetAllKeyBindings()` 的数据。
2. 可单独禁用某个绑定或录入新组合;存储在 `%USERPROFILE%/.voidraft/data/key_bindings.json`
3. 需要与系统级快捷键冲突时,可勾选“忽略系统修饰键”。
> 建议将以上表格打印贴在工作区,或在文档中保留常用组合,方便新同事查阅。

View File

@@ -0,0 +1,67 @@
# 多窗口与标签页
![多窗口占位](/img/placeholder-multiwindow.png)
> 替换为展示主窗口 + 侧边浮窗(子窗口)或标签页齐开的截图。
## 多窗口工作流
- `WindowService.OpenDocumentWindow` 会根据文档 ID 创建新 WebView 窗口URL 自动附加 `?documentId=<id>`
- `windowStore` 通过查询字符串判断当前是否为子窗口(非主窗口)。
- 子窗口具备:
- 独立的 CodeMirror 实例与扩展栈。
- 与主窗口共享的 Document/Config Store因此编辑内容实时同步SQLite 数据库为唯一来源)。
- `WindowSnapService` 提供吸附:拖动靠近主窗口边缘时自动贴靠;支持上下左右以及四个角。
- 关闭时自动注销吸附状态,避免悬挂引用。
### 操作步骤
1. 打开文档列表(工具栏图标或 `Ctrl+Shift+O`)。
2. 右键目标文档 → 选择 “在新窗口中打开”。
3. 若文档已在标签页打开,会自动从标签栏移除,防止重复。
4. 关闭窗口:
- 点击自定义标题栏关闭按钮。
- 系统托盘菜单选择退出。
### 使用建议
- 将参考资料或检查清单放在子窗口中,配合“窗口置顶”保持常驻。
- 通过 Windows Snap + voidraft Snap 组合,可快速排版 2-4 个窗口。
- 若想在多窗口之间同步滚动,可尝试启用“共享视图状态”扩展(计划中)。
## 标签页模式
- 在设置 > 通用中开启“启用标签页”(`config.general.enableTabs`)。
- `tabStore` 维护 `tabsMap` + `tabOrder`,支持:
- 拖拽排序(拖动标签即可)。
- 关闭单个/其他/左侧/右侧标签。
- 检测当前文档是否已存在标签。
- 标签栏位于主窗口顶部,紧贴工具栏下方。
### 常用操作
| 操作 | 方法 |
| --- | --- |
| 关闭标签 | 点击标签上的叉号或中键 |
| 关闭其他 | 右键标签 → “关闭其他标签” |
| 关闭右侧/左侧 | 右键标签 → 选择对应菜单 |
| 固定标签(计划中) | 将在后续版本中提供 pin 功能 |
### Tabs vs 窗口
| 项目 | 标签页 | 新窗口 |
| --- | --- | --- |
| UI 占用 | 集成在一个窗口中 | 独立操作系统窗口 |
| 跨屏 | 不方便 | 可拖到其他显示器 |
| 独立置顶 | 不可单独置顶 | 每个窗口可单独置顶 |
| 推荐场景 | 同一背景的多个文档 | 跨项目/跨显示器对比 |
## 系统托盘与热键
- 勾选 “启用系统托盘” 后,关闭窗口默认隐藏至托盘。
- 全局热键(默认 `Alt+X`)由 `HotkeyService` 控制:
- 若 main window 可见 → 隐藏所有 voidraft 窗口。
- 若 main window 隐藏 → Show + Restore + Focus。
- `TrayService` 还提供“最小化到托盘”“显示主窗口”等菜单项。
## 常见问题
| 问题 | 原因 | 解决 |
| --- | --- | --- |
| 新窗口无法打开 | 文档 ID 不存在或被锁定 | 在文档列表确认状态,必要时解锁 |
| 子窗口未吸附 | WindowSnap 未启用 | 设置 > 通用 → 勾选“窗口吸附” |
| 关闭窗口直接退出应用 | 未启用托盘模式 | 设置 > 通用 → 启用系统托盘 |
| 标签页切换慢 | 同时开启标签 + 多窗口导致资源占用 | 关闭暂不需要的窗口或减少标签 |
> 如果需要更复杂的布局(如平铺窗口、快捷布局),欢迎在 Issue 中提出建议。

View File

@@ -0,0 +1,71 @@
# 设置与配置
![设置占位](/img/placeholder-settings.png)
> 替换为设置页截图,突出通用/编辑/外观/更新/备份等分栏。
所有设置都映射到 `internal/models/config.go`,持久化文件位于 `%USERPROFILE%/.voidraft/data/config.json`。前端 `configStore` 负责与后端 `ConfigService` 同步。
## 通用General
| 选项 | 说明 | 后端键 |
| --- | --- | --- |
| 窗口置顶 (`alwaysOnTop`) | 永久置顶主窗口 | `general.alwaysOnTop` |
| 数据目录 (`dataPath`) | SQLite + 备份所在目录,修改后需重启 | `general.dataPath` |
| 系统托盘 (`enableSystemTray`) | 关闭窗口后隐藏到托盘而非退出 | `general.enableSystemTray` |
| 开机自启 (`startAtLogin`) | 调用 `StartupService` 注册 | `general.startAtLogin` |
| 窗口吸附 (`enableWindowSnap`) | `WindowSnapService` 是否启用 | `general.enableWindowSnap` |
| 全局热键 (`enableGlobalHotkey` + `globalHotkey`) | 默认 Alt+X控制显隐 | `general.globalHotkey` |
| 标签页 (`enableTabs`) | 启用多标签界面 | `general.enableTabs` |
| 加载动画 (`enableLoadingAnimation`) | 切换文档时显示动画 | `general.enableLoadingAnimation` |
## 编辑Editing
| 选项 | 说明 |
| --- | --- |
| Font Size/Family/Weight/Line Height | 立即作用于所有编辑器实例 |
| Tab Size/Tab Type/Enable Tab Indent | 映射 `tabExtension` 行为 |
| Auto Save Delay | ms影响 `editorStore` 自动保存周期 |
## 外观Appearance
| 选项 | 说明 |
| --- | --- |
| Language | UI 语言(`zh-CN`/`en-US` |
| System Theme | 深色/浅色/跟随系统 |
| Current Theme | 选择预设或自定义主题(详见 [主题与外观](/zh/guide/themes) |
## 更新Updates
| 选项 | 说明 |
| --- | --- |
| Auto Update | 启动时自动检查更新 |
| Primary/Backup Source | `github``gitea`,对应 `UpdatesConfig` |
| Backup Before Update | 下载更新前执行 Git 备份 |
| Update Timeout | HTTP 请求超时 |
| GitHub/Gitea 仓库 | owner/repo/baseURL可指向自建镜像 |
## 备份Backup
| 选项 | 说明 |
| --- | --- |
| Enabled | 开关 Git 备份 |
| Repo URL | 远程仓库地址HTTPS 或 SSH |
| Auth Method | `token` / `ssh_key` / `user_pass` |
| Username/Password/Token/SSH Key Path | 根据认证方式填写 |
| Backup Interval | 自动备份间隔(分钟) |
| Auto Backup | 是否按间隔自动推送 |
## 键位Key Bindings
- 列表由 `ExtensionService.GetAllKeyBindings()` 提供。可搜索命令 ID 或组合。
- 允许将命令禁用(关闭开关)或录入新组合。
- 更改立即影响所有编辑器实例。
## 扩展Extensions
- 显示 `ExtensionSettings` 中的所有扩展。
- 每项可开关并展示 JSON 配置(背景色、最小选区、最小化提示等)。
- 修改后调用 `ExtensionService.UpdateExtensionState` 并通知 `ExtensionManager` 热更新。
## 配置文件备份
- 每次修改配置都会更新 `metadata.lastUpdated`,可用 Git 备份追踪历史。
- 若出现配置损坏,可删除 `config.json`,应用会写入 `NewDefaultAppConfig`
## 导入/导出(建议)
- 目前可手动复制 `config.json`/`extensions.json`/`key_bindings.json`
- 计划提供 UI 层面的导入导出按钮,便于跨设备同步。
> 修改高级选项(如 dataPath后建议重启以确保后台服务数据库、备份、窗口吸附等读取到最新配置。

View File

@@ -0,0 +1,44 @@
# 主题与外观
![主题占位](/img/placeholder-themes.png)
> 替换为主题切换界面或自定义主题编辑器的截图。
voidraft 的主题由后端 `ThemeService` 管理,存储在 `themes` 表。前端通过 `themeStore` + `createThemeExtension` 应用色板。
## 预设主题
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| default-dark | Dark | 默认暗色,适合低光环境 |
| default-light | Light | 默认亮色 |
| dracula | Dark | 高对比度紫色系 |
| aura | Dark | 柔和霓虹风 |
| github-dark / github-light | Dark/Light | 与 GitHub 主题接近 |
| material-dark / light | Dark/Light | Material Design 色板 |
| one-dark | Dark | VSCode 经典主题 |
| solarized-dark / light | Dark/Light | Solarized 配色 |
| tokyo-night / storm / day | Dark/Light | Tokyo Night 三件套 |
## 自定义主题
1. 打开设置 > 外观,选择「创建主题」。
2. 颜色字段对应 `ThemeColorConfig`,包含 `editor.background`, `editor.foreground`, `gutter`, `selection`, `bracket`, `keyword`, `string`, `comment`, `accent` 等。
3. 保存后立即写入数据库,可通过 `Reset` 按钮恢复为预设值。
4. 前端 `themeExtension` 会向 CodeMirror 注入新的 `EditorView.theme`
## 动态切换
- 切换主题会立即影响所有已打开的编辑器实例;`updateEditorTheme` 逐个更新 `EditorView`
- `SystemTheme` 设为 `auto`voidraft 会监听操作系统深浅模式并自动切换到 `default-dark``default-light`
## 字体与行高
- 字体配置来自设置 > 编辑,`createFontExtensionFromBackend` 会同步 `fontFamily/fontSize/fontWeight/lineHeight`
- 可在通用设置中的“滚轮缩放”手势下临时调整字号。
## 小地图/装饰色
- `minimap` 扩展读取主题中的 `accent` 颜色,用于高亮当前视区。
- `textHighlight` 扩展的默认背景色可在扩展设置中配置。
## 截图建议
- 展示暗/亮主题对比。
- 展示主题编辑对话框,标出关键字段。
- 展示自定义主题应用后的编辑器界面。
> 如果希望导入 VSCode `.json` 主题,可将颜色映射到 `ThemeColorConfig` 后写入数据库,或等待官方导入工具上线。

View File

@@ -0,0 +1,53 @@
# 常见问题与故障排查
![故障排查占位](/img/placeholder-troubleshooting.png)
> 替换为错误提示或日志查看界面的截图。
## 安装与启动
| 问题 | 可能原因 | 解决步骤 |
| --- | --- | --- |
| 启动白屏 | WebView2 缺失或缓存损坏 | 安装 WebView2 Runtime删除 `%APPDATA%/voidraft/Cache` 后重启 |
| 双击无反应 | 被安全策略拦截 | 以管理员运行或使用便携版;验证 SHA256 后加入白名单 |
| `wails3 dev` 报错 | Go/Node 版本不符或缺少 WebView2 | 确保 Go 1.21+、Node 18+,安装 WebView2 |
## 编辑器
| 问题 | 原因 | 解决 |
| --- | --- | --- |
| 格式化按钮灰色 | 当前块语言无对应 Prettier parser | 更换语言或安装支持的语言扩展(未来版本) |
| 块解析错误 | 分隔符格式不正确 | 确认 `∞∞∞language` 后跟换行;可用自动重建语法树命令 |
| 翻译浮层不出现 | 选区过短或超过最大长度 | 在设置 > 扩展 > translator 中调整阈值 |
| 小地图不同步 | 编辑器实例未刷新 | 切换文档或重开应用,检查扩展是否被禁用 |
## 窗口与多实例
| 问题 | 原因 | 解决 |
| --- | --- | --- |
| 子窗口未吸附 | WindowSnap 未启用 | 设置 > 通用 → 勾选“窗口吸附” |
| 全局热键无效 | 与系统/其他软件冲突 | 在设置 > 通用改用非系统占用组合,比如 `Ctrl+Alt+Space` |
| 关闭窗口直接退出 | 未启用托盘模式 | 设置 > 通用 → 启用系统托盘 |
## HTTP 客户端
| 问题 | 可能原因 | 解决 |
| --- | --- | --- |
| 发送失败,提示 `proxy` | 系统代理配置异常 | 在系统代理或环境变量中设置 HTTP(S)_PROXY或关闭代理再试 |
| 响应乱码 | 服务器未声明编码 | 手动在请求头中加 `accept-charset: utf-8`,或在响应视图切换编码(计划) |
| 变量未替换 | 变量名拼写或作用域错误 | 确认 `@var` 定义位置,使用 `{{name}}` 语法 |
## 数据与备份
| 问题 | 可能原因 | 解决 |
| --- | --- | --- |
| 自动备份停在 “未初始化” | Repo URL/认证缺失 | 补全备份配置或关闭自动备份 |
| Push 失败 | Token 权限不足或网络问题 | 为 Token 开启 `repo` scope检查代理稍后再试 |
| 数据目录迁移后文件缺失 | 未重启或权限不足 | 修改 `dataPath` 后重启应用;确保目标目录可写 |
## 更新
| 问题 | 原因 | 解决 |
| --- | --- | --- |
| 检查更新超时 | 主源不可达 | 切换到备用源或关闭代理重试 |
| 下载完成但未重启 | 权限或文件被占用 | 以管理员运行,关闭杀毒软件后重试 |
## 收集日志
- Wails 日志:`%LOCALAPPDATA%/voidraft/logs/*.log`
- 终端调试:运行 `wails3 dev` 并观察控制台输出。
- 若提交 Issue请附上系统版本、voidraft 版本、日志片段、复现步骤。
> 仍未解决?请到 GitHub Issues 提交反馈,并尽可能附上截图和日志。

View File

@@ -0,0 +1,46 @@
# 界面总览
![界面截图占位](/img/placeholder-main-ui.png)
> 替换为包含顶部工具栏、块区域、右侧小地图、底部状态栏的完整截图。
voidraft 的主窗口由四个区域组成:
| 区域 | 位置 | 作用 | 相关代码 |
| --- | --- | --- | --- |
| 工具栏 | 顶部浮层 | 文档切换、块语言选择、格式化、Markdown 预览、窗口置顶、更新提示、进入设置 | `frontend/src/components/toolbar/Toolbar.vue` |
| 编辑器主体 | 中央 | CodeMirror 6 视图承载块编辑、HTTP 运行器、翻译按钮等 | `frontend/src/views/editor/Editor.vue` + `extensions` |
| 导航辅助 | 右侧 | 小地图、滚动条、块徽标、HTTP 运行按钮 | `extensions/minimap`, `codeblock/decorations.ts` |
| 底部状态 | 左下角 | 行数、字符数、选区统计、文档脏状态 | `editorStore.documentStats` |
## 工具栏详解
| 项 | 说明 | 快捷入口 |
| --- | --- | --- |
| 文档切换器 | 展开后列出全部文档,支持搜索、创建、在新窗口打开 | 同步 `DocumentService.ListAllDocumentsMeta` |
| 块语言下拉 | 当前块语言,列表取自 `lang-parser/languages.ts`,支持搜索 | 鼠标选择或输入语言 token |
| Pin窗口置顶 | 临时 / 永久置顶切换,调用 `SystemService.SetWindowOnTop``config.general.alwaysOnTop` | Alt+Space自定义 |
| Format / Preview | 对当前块执行 Prettier 或打开 Markdown 预览 | `Ctrl+Shift+F` / 工具栏按钮 |
| 更新提示 | 轮询 `SelfUpdateService`,有更新时显示小点,可直接“检查/下载/重启” | 设置 > 更新 |
| 设置入口 | 跳转到 Vue Router 的 `/settings` 页面 | `Ctrl+,` |
## 多文档视图
- **标签页(可选)**:在设置 > 通用中启用“标签页模式”,`tabStore` 将当前文档加入 tab bar支持拖拽、批量关闭。
- **多窗口**:以文档列表右键「在新窗口中打开」或命令面板为入口。`WindowService` 会根据文档 ID 命名窗口,`WindowSnapService` 自动吸附。
- **系统托盘**:关闭窗口时默认最小化到托盘,可在托盘图标中重新唤醒或彻底退出。
## 面板与浮层
- **Markdown 预览**:针对选中的 Markdown 块,面板会贴在右侧,支持实时滚动同步、关闭动画。
- **HTTP 响应**:运行后在块底部自动插入 `### Response`,可展开查看头部/体/耗时。
- **翻译浮层**:选中文本后自动出现按钮,点击后显示结果卡片,附带复制、语种切换。
## 快捷状态
- **底部统计**
- `Ln`:当前块内行号。
- `Ch`:字符数。
- `Sel`:选区字符数。
- **右上角加载动画**:当编辑器实例加载或切换文档时显示,遵循 `enableLoadingAnimation` 设置。
## 建议截图
1. 默认深色主题 + 多块示例。
2. 打开 Markdown 预览 + 小地图。
3. 展示 HTTP 块运行按钮与响应卡片。
4. 展示标签页或多窗口。

View File

@@ -0,0 +1,56 @@
---
layout: home
hero:
name: "voidraft"
text: "优雅的文本片段记录工具"
tagline: 为开发者设计,用现代技术打造
image:
src: /img/hero.png
alt: "voidraft"
actions:
- theme: brand
text: 开始使用
link: https://github.com/landaiqing/voidraft/releases
- theme: alt
text: 使用文档
link: /zh/guide/introduction
features:
- icon: 📝
title: 块状编辑模式
details: 将内容分割为独立的代码块,每个块可设置不同语言。继承了 Heynote 优雅的块状编辑理念。
- icon: 🎨
title: 语法高亮
details: 内置支持 30+ 种编程语言的语法高亮,自动语言检测,集成 Prettier 代码格式化工具。
- icon: 🌐
title: HTTP 客户端
details: 集成 HTTP 客户端,支持 JSON、FormData、XML 等多种请求格式。直接在编辑器中测试 API。
- icon: 🎯
title: 多窗口支持
details: 同时编辑多个文档,每个窗口独立维护自己的状态和配置。
- icon: 🎭
title: 主题自定义
details: 完整的主题自定义支持,支持深色/浅色模式。创建并保存你自己的编辑器主题。
- icon: 🔧
title: 丰富的扩展
details: VSCode 风格搜索替换、彩虹括号、小地图、颜色选择器、翻译工具、文本高亮等实用扩展。
- icon: 🔄
title: 自动更新系统
details: 内置自我更新机制,支持多个更新源。及时获取最新功能和改进。
- icon: ☁️
title: Git 备份
details: 基于 Git 的自动数据备份。支持 GitHub、Gitea提供 SSH、Token 等多种认证方式。
- icon: ⚡
title: 现代化架构
details: 采用 Wails3、Vue 3 和 CodeMirror 6 构建。跨平台桌面应用,原生性能,现代化界面。
---

Some files were not shown because too many files have changed in this diff Show More