功能说明
本文档按使用场景整理 Markdown Editor 当前已经支持的功能。
- 界面中带说明的控件显示统一样式的 tooltip:
- 默认仅在鼠标悬停 300ms 后显示,聚焦不触发提示,鼠标移出后聚焦也不会保留提示。
- 开启隐藏功能后,设置中可勾选“聚焦时显示 tooltip”,聚焦时立即显示。
- 默认关闭,仅保存在本机,各窗口即时生效,重启后保留,不参与账号同步。
- 关闭隐藏功能后立即停用聚焦显示并隐藏设置项,保留配置;再次开启隐藏功能后恢复。
- 设置中取消修改不会保存;隐藏状态下保存普通设置不会提交该项草稿。
- 提示会自动避开窗口边缘。
- 快捷键提示按当前平台显示实际修饰键:macOS 显示 Command/Cmd,Windows 和 Linux 显示 Control/Ctrl,不使用跨平台占位写法。
- 所有按钮文案保持单行显示,不因按钮所在区域变窄而在文字中间换行。
- 表单中的单行输入和下拉选项默认采用同一行左标签、右控件的紧凑布局。
- 数字输入保持较窄宽度,文本输入随可用空间伸缩;设置、快捷键、语音与片段配置沿用相同规则。
- 多行输入保留标签在上方的布局,帮助说明独立显示在字段或分组下方。
- 校验按字段用途设置;搜索、笔记正文和转写编辑仍允许空内容,不新增统一必填或长度限制。
1. 菜单索引
主菜单分类
- 顶部依次为:文件、笔记库、编辑、插入、视图、转到、工具、窗口、帮助。
- 文件:新建、打开、快速打开、最近文件、保存、另存为、导出当前笔记、关闭及退出。
- “导出当前笔记”子菜单包含 PDF、Word。
- 笔记库:打开、最近笔记库、批量导出、同步中心、用 VS Code 打开当前仓库。
- “批量导出”子菜单包含原有批量导出及 PDF、Word 批量导出。
- 编辑:撤销、重做、剪切、复制、粘贴、全选、在文件中查找、在文件中替换、修改错别字、切换列表及整体调整大纲级别。
- 插入:本地图片、剪贴板图片、录音、fenced code 和代码片段注释标示。
- 视图:编辑与预览布局、侧边栏、大纲、命令历史工具条、自动换行、差异显示、缩放和全屏。
- 转到:后退、前进、聚焦笔记库、聚焦查找、聚焦收藏、聚焦文件树、聚焦编辑器、聚焦大纲、上一处及下一处差异。
- 工具:命令面板、Quick Cmd Form、剪贴板收集器、P2P 文件传输、拼音搜索、设置。
- 代码片段:片段管理器、当前项目作为数据源,以及检查、整理、比较和转换老格式代码片段。
- 语音识别:单次识别、批量识别和语音识别设置。
- 鼠标微调:左右和上下微调;沿用隐藏功能开关,同时控制子菜单与条目显隐。
- 开发调试:重新加载、强制重新加载和开发者工具。
- 窗口:新建、切换、设为主窗口,以及平台原生窗口操作。
- 帮助:菜单索引、检查应用更新、重启并安装更新、关于。
- 常用操作直接展示,同类操作用分隔线分组;功能子菜单不继续嵌套分类。
- macOS 保留最左侧原生应用菜单、系统服务和平台窗口操作。
- 现有命令 ID、快捷键、勾选状态和最近记录保持不变,子菜单中的快捷键也随用户配置刷新或移除。
- 没有应用命令的原生操作通过
menu.native.<菜单项 ID 或原生角色>注册到命令面板。- 包括新建窗口、粘贴、全选、重新加载、开发者工具、全屏及原生窗口操作等。
- 执行时重新检查当前菜单的显隐和可用状态,并在发起请求的窗口调用同一原生菜单操作。
- macOS 的系统角色沿用原生菜单对应的 first-responder selector;系统服务标题不作为独立操作注册。
菜单索引行为
- 从“帮助 → 菜单索引”打开类似文件查找结果的只读标签页,无需先打开笔记库。
- 命令面板支持搜索“菜单索引”或
help.menuIndex执行同一操作;默认不绑定快捷键,可在快捷键设置中自行配置。 - 按当前应用主菜单的顺序列出所有可见菜单及中文功能说明,每级使用两个空格缩进。
- 当前笔记及仓库批量导出的 PDF、Word 菜单项分别说明导出范围和格式,不使用快捷键设置提示代替功能说明。
- 包含系统菜单、“打开最近文件”和“打开最近笔记库”入口;过滤这些入口下的最近打开列表及空列表提示,隐藏项与分隔线也不列出。
- 有对应命令的菜单项在说明后输出
[命令: <命令 ID>],可复制到命令面板中搜索。- 应用操作使用原有命令 ID,原生操作使用
menu.native.<菜单项 ID 或原生角色>。 - 禁用操作仍显示命令 ID;没有对应命令的分类标题不添加命令 ID。
- 应用操作使用原有命令 ID,原生操作使用
- 禁用菜单保留在索引中并标记“不可用”;勾选项标记当前勾选状态。
- 再次点击会刷新并复用同一个索引标签页,反映最新菜单及快捷键标签。
- 快捷键按当前平台合并默认规则与用户配置后输出,包含自定义快捷键、多段组合键及同一命令的多组绑定,并去除重复项。
- 已被用户删除或在当前平台禁用的绑定不显示,不回退到旧的默认快捷键。
- 原生菜单独立处理的快捷键按实际菜单绑定显示;macOS 使用
Cmd,Windows/Linux 使用Ctrl。
- 索引内容可以选择、复制和使用当前页面查找;不会保存为笔记,也不参与仓库搜索替换。
2. 命令面板
- 默认命令
- 使用
Ctrl+Shift+P(macOS 为Cmd+Shift+P)、F1或工具栏“命令”按钮打开。 - 复用 Quick Open 的匹配算法,支持中文原文、无声调全拼、拼音首字母和命令 ID 搜索。
- 搜索支持空格分隔多个关键词和可选的
>前缀。 - 命令面板输入框中的
>可编辑;删除它或清空输入会切回文件快速打开,保留其余文字。 - 在快速打开中输入或粘贴以
>开头的查询可切换到命令面板;中文输入法组合输入结束后才切换。 - 两套面板共用位置和尺寸,水平居中,顶部间距随窗口高度调整,宽度最多 680px、高度最多 520px。
- 遮罩统一使用不透明度 42% 的黑色,切换时背景明暗保持一致。
- 拼音按钮独立放在搜索输入框右侧,间距为 6px,与输入框等高;两种模式的搜索行布局一致。
- 窄窗口自动缩小,底部提示可换行,结果区内部滚动;空结果或切换模式不会改变面板边界。
- 面板打开时,快速打开和命令面板的快捷键(含用户自定义绑定)可相互切换,并保留搜索正文。
- 转入命令模式时移除
@、@!或@@模式前缀;转回快速打开时移除>。 - 再次按下当前面板的快捷键会切换到另一面板,默认键位和用户自定义绑定均生效。
- 新增自定义绑定(如
Ctrl+Shift+I)时,默认的!modalOpen条件不会阻止面板输入框内的切换。- 其他自定义条件仍须满足;设置等其他模态对话框不会因此放行切换命令。
- 快捷键切换后选中搜索正文,命令模式不选中
>。 - 通过编辑前缀切换时,光标放在查询末尾,便于继续输入。
- 转入命令模式时移除
- 切换面板不记录查询历史;两套查询历史继续独立保存,命令查询历史只保存正文,恢复时补上
>。 - 跨面板切换后取消或执行,仍恢复最初输入位置的焦点、光标和选区;其他对话框打开时阻止面板启动。
- 命令面板继续按需加载;加载失败保留快速打开并显示错误,取消或修改查询后不会被过期加载重新打开。
- 使用上下方向键循环选择,按 Enter 执行;也可以点击命令执行。
- 点击命令或按 Enter 执行时保存非空查询;最近 50 条去重保存在本机 Local Storage。
- 历史上一条和下一条默认使用当前平台的
Ctrl或Cmd+↑↓,可在快捷键设置中分别修改。 - 输入框提示当前历史快捷键绑定,并可返回未提交的输入。
- 按 Esc 或点击面板外部关闭后,恢复原先 CodeMirror 编辑器或普通 input/textarea 的焦点、光标位置和选区方向。
- 鼠标点击“命令”按钮也保留原先的输入焦点;中文输入法确认不会执行命令。
- 执行命令前先恢复原先的焦点和选区,让命令使用原来的输入位置;命令自身仍可按其功能转移焦点。
- 显示注册命令,包括未分配快捷键的命令和已加载插件命令;不可用命令以较灰的颜色显示,选择时在面板底部提示原因。
- 顶部搜索行中,“隐藏不可用命令”眼睛图标按钮位于“拼音”左侧,使用一致的开关按钮样式,默认关闭。
- 悬停提示和无障碍名称均为“隐藏不可用命令”,图标本身不重复朗读。
- 启用后高亮并只显示当前上下文可用的命令;输入框使用按钮左侧的剩余空间。
- 不显示仅适用于系统全局热键或按住 Ctrl 切换标签的命令。
- 显示当前平台和用户配置的快捷键;当前不可用的命令仍显示已配置的快捷键,便于查看和进入快捷键设置。
- 命令可用条件独立于快捷键绑定。
- 每个命令最右侧提供设置图标;点击图标或按
Ctrl+Enter(macOS 为Cmd+Enter)后打开快捷键设置,并筛选定位到当前命令的全部绑定。 - 命令面板从 AppData 恢复已记录的命令历史,重启后仍优先显示历史命令;所有历史命令按最近执行顺序排列,忽略工具条中的固定状态。
- 历史记录与命令历史工具条共享,并同步到已打开的其他窗口。
- 工具条的固定排列不影响命令面板的历史排序。
- 隐藏工具条不影响面板恢复历史。
- 搜索结果仍以匹配程度排序。
- 命令面板模块在首次打开时加载;执行失败通过应用通知反馈。
- 执行所选命令时直接检查注册状态和当前上下文,不受搜索结果数量上限影响。
2.1 命令历史工具条
- 从命令面板执行命令时,按命令 ID 记录历史;再次执行同一命令会将其移到最前,不产生重复记录。菜单、普通快捷键和工具条重执行不增加历史。
- 历史、固定状态、自定义 emoji 和工具条显隐状态保存在应用 AppData 目录的
command-history-v1.json,并同步到已打开的其他窗口。 - 固定记录排在左侧,且只在固定区与普通历史之间显示分隔线;普通记录保留最近 50 条。命令卸载或当前不可用时记录仍保留,工具条显示不可用原因。
- 每个命令自动显示不同的默认 emoji;工具条中的「⋯」按钮可改为单个自定义 emoji,留空保存即可恢复默认图标。
- 每条历史记录的 PIN 和 emoji 按钮浮在命令按钮下方,仅在鼠标悬停或键盘聚焦该记录时显示;鼠标移向下方按钮时保持显示,不改变主工具条高度。
- 工具条默认固定在窗口顶部正中,始终显示且不随鼠标移动;可拖动把手调整位置。关闭按钮旁的 PIN 按钮可取消固定。
- 取消固定后,鼠标移出工具条上下各一个工具条高度后隐藏;停止一秒后在鼠标上方居中出现。悬停工具条时保持可操作,靠近窗口上缘时在鼠标下方显示。
- 点击关闭按钮后保持隐藏,并在需要手动确认的对话框中提示“主菜单 视图 → 显示命令历史工具条”的恢复方式。勾选“不再提示”并确认后,本应用以后不再显示这条提示;也可从命令面板执行“显示命令历史工具条”恢复。
- 视图菜单的“显示命令历史工具条”以勾选标记显示当前显隐状态,点击可切换状态;工具条关闭按钮和命令面板恢复操作会同步更新菜单标记。
- 按
Alt+Shift+H,再按1–9,执行工具条从左到右对应的前九条记录;固定记录也计入序号。
2.1 关于与隐藏功能
- 从“帮助 → 关于”或命令面板搜索“关于”/
app.about打开同一自定义对话框。 - 展示应用名称、运行中的版本、构建号、Git 提交、UTC 构建时间及操作系统。
- 构建号来自构建时的
MYNOTE_BUILD_NUMBER;未提供的字段明确显示“未提供”。 - Git 提交与构建时间固化在构建产物中,安装后无需 Git;有未提交改动的构建会标注。
- Git 提交在关于界面和复制文本中统一显示为 8 位短 hash,保留未提交改动标记。
- 构建号来自构建时的
- “复制”复制全部展示信息;“确定”或 Esc 关闭。文字支持选择,长信息与错误栈会换行和滚动。
- 连续点击标题或信息正文 10 次切换隐藏功能,并显示“隐藏功能已启用”或“隐藏功能已禁用”。
- 相邻有效点击间隔超过 2 秒、选择正文或关闭对话框都会重置计数。
- 正文单击等待 300ms 后计数,避免双击选词或拖动选字误触。
- 保存期间不重复提交;保存失败保留原状态,并显示完整错误诊断,允许重试。
- 隐藏功能默认关闭;开关仅保存在本机,所有笔记窗口即时同步,不参与账号设置同步。
- 控制“聚焦时显示 tooltip”设置项及其生效状态,关闭时保留已保存的配置。
- 鼠标微调的控制规则:
- 关闭时隐藏相关菜单、命令面板、命令历史、快捷键与热键设置条目及微调设置分组。
- 即使命令面板选择显示不可用命令,隐藏条目仍不显示。
- 主进程拒绝关闭状态下的微调请求,并注销相关全局热键、停止后台鼠标监听。
- 关闭会中止正在搜索的微调并恢复原位;后台锁释放。
- 已有微调参数、命令 ID、快捷键和热键配置保留,再次启用后按原配置恢复。
- 关闭状态下保存普通设置不会提交隐藏分组中的草稿,也不会被该分组的无效草稿阻止。
- 独立的“启用热键”总开关继续生效;隐藏功能启用不会绕过热键总开关。
- 安装此功能后需重启桌面应用;之后切换隐藏功能无需重启。
- 升级前已经使用鼠标微调的用户,也需要先在 About 中启用隐藏功能。
3. 鼠标微调
-
本功能属于隐藏功能,先按“关于与隐藏功能”说明启用后使用。
-
工具 → 鼠标微调提供“鼠标左右微调”和“鼠标上下微调”,命令面板也可搜索并执行。
-
默认全局热键:左右微调
Ctrl+Alt+H,上下微调Ctrl+Alt+V,在其他应用中也可触发。- 可在“设置 → 快捷键 → 热键”修改或删除,受热键总开关控制。
- 菜单和命令面板命令也可单独配置应用内快捷键。
-
触发时先读取系统光标;已经是对应方向的双向调整大小形状时保持原位。
-
默认每步移动 3 像素,并等待 50ms 后检查光标形状;遇到对应形状或该方向配置的额外 handle 即停止搜索。
- 左右微调先向左搜索,再向右搜索;上下微调先向上搜索,再向下搜索,每侧默认最多 10 步。
- 第一侧未命中时先回到原位,再搜索另一侧。
- 命中后停在目标位置;两侧搜索完毕仍未命中或中途出错时,尝试把鼠标恢复到最初位置,恢复失败会报错。
- 搜索期间重复触发会被忽略,不并行移动鼠标;不模拟按下鼠标按钮。
-
支持 Windows、macOS 和 Linux X11,识别系统标准调整大小光标。
- Windows 使用系统光标句柄,macOS 比较系统光标图像,Linux X11 使用标准 Xcursor 名称。
- 在本应用的前台窗口内,也读取鼠标所指元素的实际 CSS 光标,兼容 Chromium 的
col-resize/row-resize分隔条光标和页面缩放。 - 自定义图像或未命名光标可能无法识别;macOS 无法读取全局光标时会报错并停止。
- macOS 需在“系统设置 → 隐私与安全性 → 辅助功能”授权应用发送鼠标事件。
- Linux 需要 X11 和 XFixes 2.0 或更新版本;Wayland 暂不支持,触发时提示切换到 X11。
-
原生接口按需加载;菜单和命令面板执行错误通过应用通知反馈,全局热键执行错误写入应用日志。
-
每次触发微调时仅输出一次
[mynote:mouse-adjust] 初始位置鼠标形状日志,包括方向、初始坐标、系统光标名称或描述、原生标识、应用内 CSS 光标及初始位置是否命中。- 移动后及回到初始位置后的检查不记录;日志同时输出到控制台和应用统一日志文件。
3.1 第二种方案:按住修饰键锁定
- 当前先支持 Windows;按住
Ctrl+Alt时开始监听全局鼠标移动,即使本应用没有焦点也生效。 - 鼠标命中系统标准左右或上下调整大小光标,或任一方向配置的额外 handle 时,锁定当前位置;本应用的 CSS 分隔条光标也参与识别。
- 每次按住 Ctrl+Alt 时读取水平、垂直 handle 的配置快照;保存修改后,下次按住即使用新值。
- 复用第一种方案的分号列表、十六进制规范化及 64 位精确匹配规则。
- 锁定后即使光标形状改变也保持位置,直到松开 Ctrl 或 Alt;退出应用或发生监听错误也解除锁定。
- 使用 Koffi 调用
GetAsyncKeyState检查修饰键,按住期间安装WH_MOUSE_LL全局鼠标钩子。- 每 10ms 复查按键和光标,处理鼠标事件之后才发生的光标变化,以及没有鼠标移动时的按键释放。
- 命中时通过
ClipCursor将鼠标限制在一个像素的位置,解除时恢复原先的活动范围。 - 单元测试覆盖两轴命中、松键、异步读取、移动、退出及错误清理;Windows 原生冒烟测试验证全局修饰键和锁定/解除,光标命中条件在该后台用例中注入。
- 第二种方案独立于第一种方案的搜索命令及全局热键开关,不模拟鼠标按键或拖动。
3.2 配置
- 在“设置 → 鼠标微调”保存以下选项,菜单、命令面板和全局热键共用。
- 步长(
mouseAdjustStepPixels):每一步移动的像素值,默认 3。 - 每侧搜索步数(
mouseAdjustSteps):每个方向最多搜索多少步,默认 10,两侧合计最多 20 个搜索步。 - 水平额外停止 handle(
mouseAdjustHorizontalHandles):用于左右微调,也参与第二种方案的锁定判断。 - 垂直额外停止 handle(
mouseAdjustVerticalHandles):用于上下微调,也参与第二种方案的锁定判断。
- 步长(
- 默认步长仅用于未配置或无效配置;已保存的自定义步长保持不变。
- 步长和步数均接受 1–1000 的整数;换侧及结束时恢复原位不计入搜索步数。
- handle 以分号分隔,留空不添加额外停止条件。
- 可复制初始形状日志中的
cursorHandle,支持十进制或0x十六进制,例如77;0x58。 - 保存时将有效值转换为十进制、去重;使用 BigInt 避免 64 位标识精度丢失。
- 配置的 handle 与原生
cursorHandle精确匹配,匹配即停止搜索;预定光标及应用内 CSS 判断仍然保留。 - handle 是平台原生标识,可能随应用或系统重启变化;Linux 对应 XFixes 光标序列标识,应以当前日志为准。
- 可复制初始形状日志中的
- 选项保存在本机
workspace-state.json的settings中,不加入云端偏好同步。- 保存后下一次触发即生效,不必再次重启;运行中的搜索使用触发时的参数快照。
- 无效输入阻止保存;从磁盘读取到无效值时,该字段回退默认值。
3.3 实现原理
入口与共享执行逻辑
- 核心实现位于
src/main/mouse-adjust.ts,由主进程创建一个共享的createMouseAdjuster实例。 - 菜单和命令面板使用
mouse.adjustHorizontal/mouse.adjustVertical命令。- 菜单通过现有应用命令通道交给渲染进程执行。
- 渲染进程调用 preload 暴露的
adjustMouse(axis),经mouse:adjustIPC 请求进入主进程。
- 全局热键使用独立的
mouse.adjustHorizontalGlobal/mouse.adjustVerticalGlobal命令。- 复用现有快捷键配置解析和 Electron
globalShortcut注册机制,直接调用同一个微调实例。 - 全局热键命令不出现在命令面板中,避免与普通命令重复显示或重复触发。
- 复用现有快捷键配置解析和 Electron
axis只接受horizontal或vertical;共享的running标记防止多个入口同时操作鼠标。- 已有搜索运行时直接返回
{ busy: true }。 - 结束或出错时在
finally中清理资源并释放标记,后续触发可继续执行。
- 已有搜索运行时直接返回
- 每次触发通过
getSettings从共享设置存储读取并校验参数,以快照形式用于此次搜索。
系统光标与应用内光标识别
- 使用已安装的 Koffi 按需调用各平台原生接口,不通过截屏或图像识别模型判断形状。
- Windows:
GetCursorInfo读取全局光标句柄、可见状态和屏幕坐标。LoadCursorW加载IDC_SIZEWE(32644)或IDC_SIZENS(32645);光标可见且句柄相同即命中。SetCursorPos执行鼠标移动;常见标准光标句柄同时映射为日志中的形状名称。
- macOS:
- 经 Objective-C 接口取得
NSCursor.currentSystemCursor,读取当前光标图像。 - 使用
CFEqual比较当前光标与resizeLeftRightCursor/resizeUpDownCursor的 TIFF 数据,避免仅按对象身份比较。 CGEventGetLocation读取坐标;创建并发布鼠标移动事件,让悬停应用更新光标。- 执行前检查发送事件的权限;创建的 CoreGraphics 事件在使用后释放。
- 经 Objective-C 接口取得
- Linux X11:
- 连接 X11 显示服务并检查 XFixes 版本,通过
XFixesGetCursorImage读取位置和光标名称。 - 将光标名称与对应方向的标准名称、别名比较,例如
col-resize/sb_h_double_arrow和row-resize/sb_v_double_arrow。 - 使用
XWarpPointer移动,再用XFlush提交;读取的光标数据及时释放,搜索结束关闭连接。
- 连接 X11 显示服务并检查 XFixes 版本,通过
- 原生预定光标和当前方向额外 handle 均未命中时,
createAppCursorMatcher补充检查本应用当前聚焦且可见的窗口。- Windows 屏幕坐标先转换为 DIP,再减去内容区域的位置,并除以页面缩放倍率,得到 DOM 坐标。
- 使用
document.elementFromPoint找到悬停元素,再读取getComputedStyle(element).cursor。 - 左右方向接受
col-resize、ew-resize、e-resize、w-resize;上下方向接受row-resize、ns-resize、n-resize、s-resize。 - 这是针对 Chromium 自带分隔条光标的补充;其他应用仍依赖原生识别,不读取其 DOM。
搜索循环与停止条件
- 首次读取保存原始位置,并判断该位置是否已命中;已命中则不移动。
- 未命中时先按负方向搜索,左右对应向左,上下对应向上。
- 第
step步的目标坐标为原始坐标加上direction × step × mouseAdjustStepPixels,另一轴保持原值。 - 每步移动后等待 50ms,再读取实际位置和形状,为目标应用处理悬停事件留出时间。
- 第
- 负方向完成配置的每侧步数仍未命中时,回到原始位置,等待并再次检查,然后按正方向搜索同样的步数。
- 两侧目标坐标都以原始位置计算,避免第一轮偏移累计到第二轮。
- 恢复原位也会检查,若此时命中则直接停止。
- 任意检查命中返回
{ found: true };两侧完成仍未命中返回{ found: false }。- 已经尝试移动且未命中目标时,在
finally中恢复起点,并等待 50ms 让异步鼠标事件生效;命中则保留当前位置,随后释放资源和运行标记。 - 初始位置已经命中时不移动;搜索中读取失败也会执行原位恢复。
- 已经尝试移动且未命中目标时,在
- 搜索只移动鼠标并寻找可调整的位置,不按下鼠标按钮,也不执行拖动或改变控件尺寸。
初始日志与验证
- 成功完成初始读取后、决定是否移动前,只记录一次初始位置日志。
- 字段为
axis、x、y、cursorShape、cursorHandle、cssCursor、matches。 cursorShape是原生名称或描述;无法命名时保留原生标识供排查,CSS 补充结果单独放在cssCursor。- 原生检查或额外 handle 已经命中时不再查询 CSS,因此
cssCursor可能为空。 - 移动后继续读取并判断形状,但不输出形状日志;被忽略的重复触发或初始读取失败也不产生初始形状日志。
- 字段为
console.log复用主进程已有的控制台镜像机制,写入应用统一日志。test/mouse-adjust.test.ts验证搜索顺序、命中后的目标位置保留、未命中及异常后的原位恢复、可配置步长与步数、分轴 handle 匹配、并发保护、入口配置、坐标转换及一次初始日志。test/mouse-adjust-smoke.ts在 Windows 上验证真实col-resize/row-resize悬停光标和停止行为。- 可运行
node scripts/run.mts node --test test/mouse-adjust.test.js和node scripts/run.mts node scripts/smoke.js --run mouse-adjust test/mouse-adjust-smoke.js。 - Windows 已通过原生冒烟验证;macOS 和 Linux X11 的原生路径仍需对应平台实机验证。
- 可运行
4. 片段管理器
4.1 入口
- 从工具 → 代码片段 → 片段管理器或命令面板打开独立片段窗口。
- 默认系统级热键为
Ctrl+Alt+N,可在“设置 → 快捷键 → 热键”修改。 - 从工具 → 代码片段或命令面板执行“将当前项目作为片段管理器的数据源”。
- 首次以仓库名在应用数据目录的
snippet-projects下建立.cfg集合,递归读取其中的 Markdown 文件。 - 再次执行时复用该集合。同名文件已存在时追加短哈希以避免覆盖;旧版哈希命名的集合继续复用原文件。
- 集合以项目名称显示、移到首位并选中,片段窗口打开后保持置顶。
- 首次以仓库名在应用数据目录的
4.2 窗口管理
- 关闭窗口时隐藏,并让系统焦点回到先前窗口;重新打开后继续使用。
- 按
Esc隐藏片段窗口;编辑集合配置时,Esc只关闭配置对话框。 - macOS 隐藏片段窗口时直接隐藏,避免异步最小化动画重新显示窗口。
- “窗口 → 切换窗口”和命令面板中的“切换窗口”只在笔记主窗口之间轮换,不切换到片段窗口。
- 可从“窗口 → 设为主窗口”或命令面板固定系统级窗口切换命令的目标;未设置时仍以最近聚焦的笔记窗口为目标,固定窗口关闭后恢复此默认算法。
- macOS 的原生 Window 菜单也不显示片段窗口。
- 首次加载集合和刷新片段结果时显示加载动画;读取完成或失败后自动隐藏,切换到已缓存集合时直接显示结果。
- 查询尚未完成时不显示“没有匹配的片段”;仅在查询完成且结果为空时显示。
4.3 集合操作
- 集合管理:
- “新建”和“打开”共用的对话框起始路径可在“编辑配置”中填写现有文件夹的绝对路径,设置保存在
snippets.json。 - 起始路径可留空;留空或配置的目录后来不可用时,不指定对话框起始路径,由系统决定打开位置。
- 没有打开集合时,“编辑配置”仍可修改全局选项。
- “打开”可一次选择多个现有
.cfg文件并加入标签页,不复制配置文件。可切换或关闭集合,并在窗口中编辑配置、刷新结果。 - 编辑期间配置被外部修改时,保存会提示冲突。
- “新建”和“打开”共用的对话框起始路径可在“编辑配置”中填写现有文件夹的绝对路径,设置保存在
- 片段窗口中按
F5刷新当前集合;按Ctrl+N、Ctrl+O、Ctrl+E分别新建集合、打开集合、编辑当前配置,macOS 使用Cmd代替Ctrl。
4.4 Tab 管理
- 每个集合占用与主窗口一致的标签;切换标签时保留各自的查询条件、结果、选中项和滚动位置,刷新只更新当前集合。
- 拖动集合标签可调整顺序,拖到目标标签左半边或右半边分别插入其前方或后方;拖到标签栏空白处移到末尾。
- 拖动时显示插入位置;关闭按钮只用于点击,不启动拖动。
- 排序立即保存在
snippets.json,重启后恢复;当前集合、查询、结果选中项和滚动位置保持不变。
- 按
Ctrl/Cmd+PageUp、Ctrl/Cmd+PageDown按 Tab 顺序切换集合。 - 按
Ctrl/Cmd+Tab(Shift反向)从最近使用的集合中选择。列表打开时,↑、↓继续选择且不会导航搜索历史,松开修饰键切换。 - 按
Ctrl/Cmd+W关闭当前集合。 - 右键集合 Tab 可关闭当前、其他、左侧、右侧或全部集合,也可在文件管理器中显示对应
.cfg文件。 - 默认快捷键
Shift+Alt+R显示当前集合。菜单打开时显示菜单所指集合,按键提示随快捷键设置更新。 - 已打开集合和当前集合保存在应用数据目录的
snippets.json中,不随笔记库切换。
4.5 数据源与刷新
- 监测已加载集合的配置文件和来源文件或文件夹;有变化时标记集合待更新,下次刷新或修改查询条件时先重读集合再查询。
.cfg可用relay:=其他集合.cfg引用另一个 Tab 当前查询的全部命中项。- 路径可相对当前配置文件或为绝对路径,并可与普通来源混用。
- 未打开的上游集合会在后台打开,不切换当前 Tab。
- 按配置顺序合并后,以来源路径和行号去重,再执行当前查询。
- 上游查询或文件变化后,下游在下次查询或切回 Tab 时更新。
- 上游配置若仍含
relay:=,该引用显示诊断且不递归。
.cfg每行指定一个文件、目录或文件名通配符;目录及通配符递归读取,相对路径以配置文件所在目录为基准。空行和#注释行跳过。.cfg、.cfg.ignore和片段来源文件先按 BOM 识别 UTF-8、UTF-16 LE/BE;无 BOM 时优先严格按 UTF-8 解码,失败则按 GBK 解码。- 每个非空文本行形成一条片段,保留来源路径和原文件行号;首个不以
@@开头的内容行在展示及复制时加上@@。
4.6 配置
- 配置编辑器:
- 在数据源下方单独显示文件过滤配置。
- 两个文本框最小显示 6 行,对话框高度随内容自动调整并受窗口高度限制。
- 文本框支持系统标准的剪切、复制、粘贴、撤销和重做快捷键。
- 数据源保存到
.cfg,文件过滤配置独立保存到同名.cfg.ignore;过滤区的注释和空行不会混入数据源。 .cfg.ignore每行可用ignore:=过滤文件路径引用一个或多个过滤文件,相对路径以.cfg所在目录为基准。- 过滤文件沿用
.mynoteignore的 Gitignore 语义,命中的文件和目录不加载。 - 将仓库作为数据源时,新建的集合默认引用仓库根目录的
.mynoteignore。
- 编辑器保存配置时写入 UTF-8。
- 单个来源文件大小上限默认 2 MiB,片段结果上限默认 20000 条。
- 两者都可在“编辑配置”中调整,适用于所有集合。
- 读取错误、超限及不支持的配置行显示在诊断区。
- 点击任一上限提示可直接打开配置界面并聚焦对应字段,保存后刷新当前集合。
4.7 搜索
- 按片段文本和来源路径搜索,复用 Quick Open 的子串、跳字模糊、多关键词、无声调拼音全拼与首字母匹配及排序;拼音匹配遵循应用的全局开关。
- 在片段窗口按
Ctrl+F(macOS 为Cmd+F)聚焦搜索框。 - 片段文本和来源路径中的命中字符复用 Quick Open 的高亮规则;拼音全拼、首字母、跳字模糊及
f:、p:筛选命中也会高亮对应原文。 - 成功使用片段时保存非空搜索词,最近 50 条去重历史保存在本机 Local Storage。
- 搜索框用面板历史快捷键回看查询,默认
Ctrl+↑/↓(macOS 为Cmd+↑/↓),并跟随快捷键设置更新。
- 搜索框用面板历史快捷键回看查询,默认
- 搜索框旁的“拼音”按钮可切换全局拼音搜索并立即更新结果;在“设置 → 快捷键”中为“切换拼音搜索”设置的快捷键也可在片段搜索框内使用,改动即时生效。
- 使用
f:限定片段文本、p:限定来源路径。空查询保留来源顺序;显示匹配总数,列表展示前 500 条结果。- 空格表示“与”,非引用的
|表示“或”,无需在竖线两侧加空格。 苹果 红色|香蕉 黄色表示满足任意一组,组内关键词必须全部满足。p:、f:是独立于分组的全局条件,多个字段条件必须全部满足,无论写在哪一组。p:资料 苹果|香蕉 f:成熟表示来源包含“资料”、正文包含“成熟”,并匹配“苹果”或“香蕉”。s:限定片段正文的开头,全局作用于所有或分组;多个s:以及其他字段条件必须全部满足。红色|黄色 s:苹果只匹配以“苹果”开头且匹配“红色”或“黄色”的片段。- 前缀匹配不区分大小写,不使用拼音或跳字匹配,命中的前缀会高亮。
- 支持引号中的空格和竖线,例如
s:"a | b";未闭合引号沿用字段规则,空值沿用普通关键词处理。 - 对加载后的片段正文判断前缀,包含已有的
@@标记;例如标题可用s:@@筛选。
- 字面竖线使用字段引用,例如
f:"a|b"或p:"a|b";未闭合的字段引号将剩余输入作为字段内容。 - 空分组被忽略,
苹果|、|苹果、苹果||香蕉均可搜索;仅有分隔符时返回零条,仅有字段条件时按字段筛选。 - 同一片段命中多组只显示一次,取最高组分数排序,同分保留来源顺序;高亮全局字段和完整命中组中的字符。
- 搜索总数、集合接力和导出沿用相同匹配结果;历史查询中的非引用竖线也采用新语义。
- 本次未增加
e:、括号或否定语法;其他窗口的搜索规则不变。
- 空格表示“与”,非引用的
4.8 片段调用与导出
- “查询结果另存为”将当前查询命中的全部片段正文按结果顺序保存。
- 默认文件名为
查询结果.md,也可在系统对话框中指定其他文件名或扩展名。 - 没有查询结果时不可用。
- 默认文件名为
- “ctrl for paste”默认勾选,选择保存在本机。勾选时,双击、按 Enter 或按 Alt+数字键打开来源,按住 Ctrl 则粘贴;取消勾选时,普通操作粘贴,按住 Ctrl 则打开来源。
- 粘贴会把片段写入剪贴板、隐藏片段窗口,并向之前使用的外部应用发送
Ctrl+V(macOS 为Cmd+V);不会拉起笔记编辑窗口。- Windows 会记住片段窗口打开或失焦时的外部窗口,未找到外部窗口时提示先切换到目标应用。
Alt+1–Alt+9、Alt+0分别执行当前结果前十项的双击动作,也受“ctrl for paste”和 Ctrl 修饰键控制;单独输入数字可继续搜索。- 跨应用粘贴在 macOS 需要授权系统辅助功能;Linux X11 需要
xdotool,Wayland 需要已运行的ydotool服务。系统工具不可用时显示错误并重新打开片段窗口。 - 行内“插入”按钮执行同样的跨应用粘贴,不要求当前笔记可编辑。
- “打开来源”将 Markdown 文件在应用内打开并跳转到对应行,其他文件交由系统默认程序打开;包含 HTTP/HTTPS 网址的片段还可选择“打开链接”。
4.9 未迁移功能
- 当前不支持
filter_path=:、sql_配置行、tnd、SQLite 和.zrtf内部跳转。
5. 文档与标签管理
5.1 新建、打开与保存
- 新建 Markdown 文档,并自动填充欢迎内容。
- 通过文件选择器一次打开一个或多个 Markdown 文件。
- 再次打开已经位于标签页中的文件时,直接切换到对应标签,不创建重复标签。
- 保存当前文档。
- 新建文档首次保存时,可以选择文件名和位置;保存到当前笔记库后会立即加入目录树管理和大纲索引,无需重开笔记库。
- 使用“另存为”按钮将当前内容保存到新文件。
- “另存为”也可从文件菜单执行,默认快捷键为
Ctrl/Cmd+Shift+S。 - 打开、保存、另存为和图片选择对话框绑定当前窗口显示,不会被主窗口遮挡。
手动导出 PDF 与 Word
- 文件 → 导出当前笔记提供“当前笔记导出 PDF…”和“当前笔记导出 Word…”。
- 笔记库 → 批量导出提供“批量导出仓库 PDF…”和“批量导出仓库 Word…”。
- 四个命令均可在快捷键设置中绑定按键,默认不占用快捷键。
- 仅手动触发,不依赖
.mynote/config,也不跟随保存自动生成。
- 当前笔记按点击导出时的编辑内容生成文件,包含尚未保存的修改。
- 未命名笔记也可导出;不会保存源文件、修改标签页内容或清除未保存状态。
- 在保存文件对话框中选择输出位置,默认使用笔记名称及
.pdf或.docx后缀。
- 批量导出会重新扫描当前仓库,沿用仓库忽略规则,并固定本次仓库及 Markdown 文件列表。
- 仅导出磁盘内容,不包含编辑器中尚未保存的修改。
- 选择输出目录后,在其中创建唯一的
mynote-pdf-…或mynote-docx-…子目录。 - 每篇生成独立文件,保留仓库子目录结构;同名不同 Markdown 后缀的输出追加编号,避免覆盖。
- 单篇失败后继续其余文档,完成提示包含成功数、失败数、失败原因及输出位置。
- 导出期间显示进度,同一窗口不能重复触发文档导出。
- 取消文件或目录选择不创建导出文件。
- 文件通过原子写入完成,生成失败不会留下半成品或破坏已有单篇输出。
- PDF 使用 A4 纵向、白底深色正文及四边 20 mm 页边距,不添加封面或页眉页脚。
- 长代码自动换行,图片和表格限制在正文宽度内。
- 中文、链接、代码及已渲染的 Mermaid 图表保留在输出中。
- Word 输出为可编辑的
.docx,保留标题、段落、列表、表格、引用、代码及链接的基础结构和格式。- 空笔记、仅空白内容或渲染后没有正文的笔记会生成包含空段落的 Word 文件;单篇与批量导出均支持。
- 正文不是整页截图;Mermaid 图表作为 PNG 图片嵌入。
- 代码按独立可编辑行保留换行、空行及缩进,使用等宽字体;不保留语法高亮配色。
- Word 的排版不承诺与应用预览逐像素一致,不提供旧版
.doc格式。
- 图片嵌入导出文件,不依赖旁边的资源目录。
- Electron 原生解码器无法读取的 WebP、GIF、BMP 等已识别图片格式由隐藏页面解码为 PNG;PDF 与 Word 导出共用此转换。
- 已保存笔记的本地图片限制在所在仓库范围内;仓库外单独打开的笔记限制在笔记所在目录内,并检查真实路径以阻止符号链接越界。
- 未命名笔记的本地图片无法定位,会显示替代文本;网络及 data 图片仍可导出。
- 网络图片沿用下载超时、10 MB 上限及格式校验;本地图片同样限制为普通文件且不超过 10 MB。
- 无法读取、解码或转换的图片和图表保留替代文本,并在完成提示中列出警告。
- 音频保留文字链接,不嵌入播放器。
- PDF、Word 和现有 HTML/TXT 导出共用串行渲染队列,防止多个窗口同时导出时串页。
src/main/publish-handlers.ts统一注册发布与文档导出入口,共享一个按需创建隐藏页面的渲染服务。- 发布警告只发送给打开对应笔记库的存活窗口;无法送达时写入主进程日志。
- 主进程入口负责装配依赖,并在原有退出阶段调用注册模块返回的关闭方法。
- 开发时更新此功能后需要重启客户端。
保存时导出 HTML 与纯文本
-
可在笔记库
.mynote/config的[export]分区配置保存时导出:[export] html_root = .published/html txt_root = .published/txt css_root = .published/css publish_root = https://example.com/notes extra_css = /notes/theme.css;https://cdn.example.com/print.css extra_js = /notes/interactions.js;https://cdn.example.com/addon.js -
html_root、txt_root和css_root可使用绝对路径;相对路径以笔记库根目录为基准。 -
文件路径上有嵌套的
.mynote目录但未配置导出目标时,会继续查找父目录中最近的导出配置;导出目录结构相对于找到配置的目录。 -
extra_css和extra_js可配置多个样式表或脚本链接,以;分隔。- 链接按配置原值写入 HTML,不复制对应文件,也不添加
publish_root。 - 额外样式表排在生成的预览样式之后,额外脚本放在正文末尾;仅导出 HTML 时使用。
- 链接按配置原值写入 HTML,不复制对应文件,也不添加
-
导出文件保留笔记库目录结构,并把 Markdown 后缀替换为
.html或.txt。 -
HTML 使用与应用预览相同的安全 Markdown、代码高亮和 Mermaid 渲染链路,并生成可独立打开的完整页面。
-
配置
css_root后,共享预览样式写入<css_root>/mynote.css,HTML 改为引用该文件。- 每次 Markdown 保存触发导出时都会原子覆盖
mynote.css;只配置css_root也会更新 CSS,不需要同时配置html_root。 - CSS 由应用内置的基础预览样式和代码高亮样式生成,并在当前应用进程首次导出时读取一次;升级应用或开发时修改内置样式后,需要重启应用并再次保存任意 Markdown 才会导出新样式。
- 修改
css_root后,下次保存 Markdown 会写入新位置;旧位置的mynote.css不会自动删除。 - 配置
publish_root且css_root位于html_root内时,样式链接包含 CSS 子目录,例如/client/__css/mynote.css。 css_root位于html_root外时,样式链接沿用${publish_root}/mynote.css;发布时需把该文件放到对应位置。- 未配置
publish_root时使用从当前 HTML 文件到 CSS 文件的相对链接。
- 每次 Markdown 保存触发导出时都会原子覆盖
-
HTML 引用的库内本地图片会按笔记库相对路径复制到
html_root。- 远程图片和
data:图片保持原链接。 - 库外图片不会复制,并会显示导出提示。
- 不再引用的图片副本不会自动删除,以免影响共享资源。
- 远程图片和
-
配置
publish_root后,库内页面与图片链接会添加该发布前缀,Markdown 页面链接同时改为.html。- 支持 HTTP/HTTPS 地址和以
/开头的站点路径。 - 外部链接、邮件、Codex 深链接、
data:和页内锚点保持不变。 - 未配置时使用从当前 HTML 出发的相对链接。
- 支持 HTTP/HTTPS 地址和以
-
TXT 内容来自渲染正文的
innerText,不是 Markdown 源码。 -
笔记库 → 批量导出中的“批量导出当前仓库”会重新扫描当前笔记库,并按现有忽略规则导出磁盘上的全部 Markdown 文档。
- 至少需要配置
html_root或txt_root;缺少时会显示可复制的完整示例配置和各配置项说明。 - 批量导出沿用现有目录结构、链接、图片、CSS 和安全渲染规则,不会保存或导出编辑器中尚未落盘的修改。
- 至少需要配置
-
编辑器保存、批量替换、新建、复制、移动、重命名、同步落盘和版本恢复都会更新导出文件。
- Markdown 被移动、重命名或删除时,对应 HTML/TXT 会同步迁移或清理。
- 图片副本保留。
- Markdown 已成功写盘但导出失败时,源文件仍视为保存成功,并显示导出错误。
-
每次写入都会重新读取配置,修改
.mynote/config后不需要重启应用。
5.2 写盘与文件格式
- 保存使用同目录临时文件和原子替换,写盘失败时不会先截断原文件。
- 文件树和“打开文件”均可打开有效 UTF-8 文本,包括源码、配置、无扩展名文件和 HTML。
- 图片、PDF、压缩包等非文本文件只能在文件树中显示,不能编辑或比较。
- 打开时还会检查实际内容,拒绝二进制控制字符、无效 UTF-8 和超过 20 MB 的文件。
- 文本编辑复用保存、另存为、撤销重做、外部修改检测与会话恢复,另存为保留用户选择的扩展名。
- 非 Markdown 文本使用纯文本编辑,不启用 Markdown 解析、图片插入、大纲或 HTML 转 Markdown 粘贴。
- Markdown 保持原有预览;
.html、.htm支持随编辑更新的静态预览。- HTML 在隔离 iframe 中展示,保留内容、内联样式及允许的资源引用。
- 禁止脚本、表单提交、弹窗、页面链接和自动跳转,不授予应用上下文访问权限。
- 其他文本禁用分栏和预览,保持编辑视图;切回 Markdown 或 HTML 后恢复对应文档的视图。
- 保存时保留原文件的 BOM 与 LF/CRLF 风格。
5.3 标签与未保存状态
- 使用多标签页同时编辑多个文档,并在标签间切换。
- 在文件树中单击文件会使用斜体的预览标签打开;同一窗口只保留一个预览标签,继续单击其他文件会在原位置替换它。
- 从文件树单击、双击或按 Enter 切换文件后,键盘焦点留在文件树,便于继续浏览;预览标签与普通标签行为一致。
- 双击文件、从 Quick Open 确认、使用系统打开文件或重新明确打开预览文件时,会保留为普通标签。
- 双击预览标签、从右键菜单选择“保留打开”、拖动预览标签或开始编辑时,会把预览标签转为普通标签。
- 已经打开的普通或固定标签不会因文件树单击或搜索结果单击而降级为预览标签。
- 标签右键菜单可固定或取消固定标签;直接固定预览标签时会先将其保留为普通标签。
- 命令面板提供
editor.keepOpen、editor.pin、editor.unpin、批量关闭和强制全部关闭命令。- Preview、Pinned 与 Dirty 上下文条件可供快捷键使用。
- 固定标签显示图钉,集中排列在标签栏最左侧,并在关闭其他、关闭左侧、关闭右侧和全部关闭操作中受到保护。
- 显式关闭固定标签时,第一次操作会提示保护状态;需在 5 秒提示期内再次按关闭快捷键或点击关闭按钮才会关闭。“强制全部关闭”仍可一次关闭包括固定标签在内的所有标签。
- 每个标签保留独立的原生编辑页,切换标签时不会重写正文。
- Markdown 源码使用适配深色背景的高对比语法配色,标题和列表符号、链接文字及链接目标均保持清晰可辨。
- 标签切换后保留横向与纵向滚动位置。
- 标签切换后保留光标选区。
- 标签切换后保留当前应用会话内的撤销与重做记录。
- 支持拖动标签进行排序;固定与未固定标签各自在所属区域内排序,跨区域拖动不会改变固定状态。
- 标签排序结果随当前笔记库会话保存。
- 标签右键菜单支持保留、固定、取消固定,复制已保存文件的绝对路径或笔记库相对路径,查找文件或当前标题引用,以及关闭当前、其他、左侧、右侧、全部未固定标签或强制全部关闭。
- 按下
Ctrl+Tab时显示按最近查看顺序排列的标签列表。 - 最近标签列表打开时,
↑、↓只切换列表选项,不会滚动编辑器或预览。 - 松开
Ctrl后切换到列表中的选中项。 - 修改后的文档会在标签名称前显示圆点标记。
- 关闭存在未保存修改的标签时会先进行确认。
- 最后一个标签可以直接关闭。
- 无文档时,保存、另存为和图片插入操作不可用。
5.4 会话恢复
- 每个笔记库独立保存已打开标签、活动标签和未保存内容。
- 预览与固定状态随笔记库会话保存和恢复。
- 每个已恢复 Markdown 标签会保存并恢复光标、选区、编辑区/预览区滚动位置及上次聚焦窗格。
- 切换笔记库时同步切换标签。
- 关闭窗口前刷新当前笔记库的恢复稿。
- 文件 → 退出 和命令面板中的
file.exit共用退出操作。- 默认快捷键为 Windows/Linux 的
Ctrl+Q、macOS 的Command+Q。 - 等待各窗口完成恢复稿保存,再停止后台服务并写完日志,最后结束应用进程。
- 多窗口同时返回关闭确认时,退出收尾只执行一次,避免重复进入退出流程后残留进程。
- 多窗口与标签恢复规则见笔记库。
- 默认快捷键为 Windows/Linux 的
- 未打开笔记库时,临时标签不会写入恢复记录。
- 启动或切换到没有已保存会话的笔记库时保持无文档状态,不自动创建新文档。
5.5 外部文件变更
- 外部程序修改未在本地编辑的文档时自动重载。
- 外部程序与本地同时修改文档时显示双版本冲突对比。
- 外部删除文件时保留编辑器内容并以中划线标记标签,不弹出提示;可继续编辑,保存时直接在原路径重建文件。正文相对最初加载内容未变化时关闭不要求保存,已有修改时仍执行未保存确认。应用内部移入回收站会先停止对应文件监听并关闭对应标签。
VSCode 主进程调试
- 先安装依赖,并使用 Node.js 24 LTS 打开项目根目录。
- 在 VS Code“运行和调试”中选择
Debug Main Process,按 F5 启动。- 启动前自动执行
npm run build:dev,更新编译产物、编辑器依赖和静态资源。 - macOS 构建任务使用交互式登录 zsh,加载
.zshrc中的 nvm 和 PATH,避免使用系统旧版 Node。- 任务使用 nvm 当前默认版本;如需调整,先安装所需版本并更新
nvm alias default,再重新运行任务。
- 任务使用 nvm 当前默认版本;如需调整,先安装所需版本并更新
- Electron 从
.build/加载应用,与npm start使用相同的工作目录。 - 在
src/bootstrap.ts、src/main.ts或src/main/下的 TypeScript 源文件设置断点。 - 调试器通过 Source Map 映射源码;主进程输出显示在集成终端。
- 启动前自动执行
- 此入口加载静态构建产物;修改源码后停止调试,再按 F5 重新构建并启动。
- 构建缓存会额外检查编辑器和文件筛选依赖模块;即使旧缓存漏记这些文件,也会重建缺失产物, 避免窗口能显示但页面初始化失败、“打开笔记库”等命令无响应。
- 调试前正常退出已运行的客户端,避免构建目录占用或已有窗口干扰调试。
- 配置参考 Electron 的 VS Code 调试说明。
VSCode 热键设置单元测试调试
- 先在项目根目录运行
npm run build,生成包含测试的.build/产物。 - 在 VS Code“运行和调试”中选择
Debug Hotkey Settings Test,按 F5 启动。- 工作目录为
.build/,运行test/hotkey-settings.test.js。 - 通过
--test-name-pattern仅运行以下匹配用例:hotkey reads, toggles and list writes retain invalid entries and apply valid rules
- 自动附加 Node 测试子进程,可在
test/hotkey-settings.test.ts和相关源码中设置断点。 - 使用 Source Map 映射源码,输出显示在集成终端。
- 工作目录为
- 此配置直接运行已有编译产物;修改源码后先重新运行
npm run build,再启动调试。 - 查看被测试捕获的控制台日志时,在调试配置的
env中加入"MYNOTE_TEST_DIAGNOSTICS": "1"。
6. 笔记库与文件管理
6.1 笔记库
- 将普通本地文件夹作为笔记库打开,无需导入或转换。
- 通过系统文件夹对话框选择笔记库。
- 打开笔记库也可从笔记库菜单执行,默认快捷键为
Ctrl/Cmd+K Ctrl/Cmd+O。 - 通过“文件 → 新建窗口”或
Ctrl+Shift+N(macOS 为Cmd+Shift+N)打开空白窗口,可在多个窗口中同时打开不同笔记库。 - Windows 上通过
npm start启动时,主窗口在首次绘制后显示并激活;若系统仍让启动终端保持前台,会再次请求激活。启动期间用户切换到其他程序后不会抢回焦点。- 开发启动
npm start复用上次成功构建,不自动检查源码是否更新;构建标记或记录的产物缺失时自动完整构建。 npm run dev检查独立开发缓存并启动 Vite;输入和产物未变时跳过 TypeScript 编译。- renderer 由 Vite 按需转译;主进程、preload 和共享代码变化时更新开发目标,WSH 辅助脚本单独判断。
- 普通开发启动不编译测试目标、不打包编辑器;发布与导出页面也加载 Vite 中的当前源码。
- 缓存失效或切换完整/开发构建时重建相应产物,构建失败不能复用;更新启动器后重新运行
npm run dev。 - 也可先执行
npm run build:dev再用npm start启动静态产物。
- 增量构建保留四组独立的 TypeScript 缓存,继续执行类型检查;编辑器输入与锁文件未变时复用编辑器 bundle 和许可证。
- 根
tsconfig.json引用四组 TypeScript 项目,使 VS Code 打开源码时自动选择对应配置并加载全局类型声明。- 若编辑器仍保留旧的类型报错,执行 VS Code 命令“TypeScript: Restart TS Server”重新加载项目配置。
- 删除、重命名输入文件,或修改编译配置、包清单、锁文件后,增量构建自动回退到完整清理构建,避免残留旧模块。
npm run build、测试、基准、同步管理及发布构建仍完整清理重建;构建失败后不能复用不完整产物。- 完整清理保留
.build根目录,只删除其内容,避免 Windows 因应用或终端以该目录为工作目录而报EBUSY。 - 若子目录或文件仍被独占锁定,需正常退出占用进程后重试;静态产物中的代码修改生效需要重启桌面应用。
- 耗时诊断和开发构建规则见 TS 迁移启动性能。
- 主窗口、片段窗口、Quick Cmd Form 和发布渲染页统一使用 ESM;运行时通过显式导入共享工具、类型和窗口状态,初始化按原有顺序执行。
runtime/state.mts只保存跨模块使用的窗口状态;组件独占的 DOM 引用、计时器、缓存和交互标记由所属模块私有管理。- 原先集中在
core等模块中的组件局部初始化移到所属模块的初始化入口,仍在绑定事件和使用控件前完成。 - 笔记库相关控件的启用状态由
runtime/workspace.mts统一更新,供仓库切换与窗口启动流程调用。 - 待同步刷新按钮由同步概览模块私有管理,包含控件查询、点击绑定和扫描状态恢复,不通过共享状态暴露。
- 同步概览的账户 ID 复制按钮及自动同步表单控件同样由模块私有管理和绑定事件。
- 立即同步按钮由同步窗口模块私有管理;账户和笔记库状态变化时同步更新其可用状态。
- 测试通过 DOM、现有操作入口和隔离 fixture 验证局部状态,不向生产模块新增测试专用导出。
- Vite 开发模式支持 CSS 热更新、无状态 ESM 函数模块 HMR 和 runtime ESM 业务函数体热替换。
- 安全热替换保留编辑器实例、未保存内容、选区、滚动位置和撤销历史,不重复注册事件监听器。
- runtime 导入、函数签名、初始化、变量声明、状态类、无状态工具的回调工厂或导出结构变化时,先保存恢复稿和窗口快照,再刷新并恢复打开的标签、未保存内容和选区。
- 刷新会重建编辑器,不能保留撤销历史;打开的对话框关闭后才执行待处理的刷新。保存失败或快照超出存储配额时取消刷新并保留当前编辑器。
- 开发页面仍使用
file://,继续加载本地媒体;开发服务只监听127.0.0.1,保留沙箱、上下文隔离及主帧校验。 - 编辑器适配器源码也由 Vite 加载,状态类修改时安全刷新;主进程、preload、开发工具配置及依赖修改后,需要退出开发应用并重新运行
npm run dev。 - 具体范围和独立测试命令见 Vite renderer 开发。
- 开发启动
- 所有平台均可按
Ctrl+Shift+Alt+S在当前已打开的应用窗口间循环切换。 - 新打开窗口、切换到已有窗口或从“最近笔记库”切换笔记库后,如果当前标签是编辑器且编辑区可见,会自动聚焦当前编辑器;应用内对话框打开时不会抢走对话框焦点。
- 每个窗口独立保有当前笔记库、目录索引和标签恢复上下文;最近笔记库、偏好和同步账号仍在应用内共享。
- 同一笔记库只能由一个窗口独占打开,覆盖本机多个新版 MyNote 实例。
- 同一实例重复打开时,还原并激活已有窗口;请求窗口保留当前笔记库和标签。
- 跨实例重复打开时提示已被占用;启动恢复遇到占用时保留空窗口和最近记录。
.mynote/workspace.lock是持续保留的空锁文件;文件存在不代表仓库已被占用。- 操作系统文件锁在正常关闭或进程崩溃后释放,无需删除锁文件。渲染进程崩溃但窗口仍存活时继续持锁。
- 仅在打开仓库时取得锁,关闭仓库并完成索引清理后释放;切换成功后释放旧仓库锁,打开失败时保留旧仓库。
- 普通 IPC、保存、刷新及后台同步不额外加锁;远端克隆完成后,进入打开流程时才取得锁。
- 关闭流程不通过统一锁层等待全部 IPC 或同步请求完成;未打开仓库的后台同步和克隆不受独占锁保护。
- 请勿在仓库使用期间手动删除、替换
.mynote或锁文件。 - 升级后需退出所有旧版实例并重启应用;旧版不参与独占协议,不保证跨电脑共享目录的互斥。
npm run test:smoke:workspace-exclusive验证真实 Electron 窗口激活、跨进程占用及渲染进程崩溃后的持锁行为。
- 窗口标题显示当前笔记库名称,方便在系统任务切换器中区分多个窗口。
- 自动恢复上次使用的笔记库。
- 退出时保存各窗口仍打开的仓库;下次启动并行重建窗口,并从各仓库恢复稿还原标签。恢复时以稳定的最近仓库记录校验路径,不会因其他窗口先完成而中断;手动新建的空窗口不会自动打开最近仓库。
- 窗口会话由
src/main/window-session.ts统一管理;主进程入口负责服务装配和应用退出事件。- 控制器默认使用现有窗口创建函数,窗口外链默认使用 Electron 的
shell;测试仍可显式注入替身。 - 控制器维护窗口与笔记库映射、最近聚焦窗口及菜单固定的主窗口。
- 管理器工厂接收当前会话,并通过构造参数传入
WorkspaceManager。 - 普通打开和克隆打开在管理器内统一激活同进程占用窗口;IPC 仅传递占用及激活结果。
- 两种打开入口均在返回值顶层提供
workspaceOccupied、rootPath和activated;占用时不返回成功快照。 - 克隆 IPC 原样返回管理器结果,不再自行捕获并转换占用异常。
- 非占用类错误继续抛出;打开目标被占用时保留请求窗口原有的仓库、索引和锁。
- 两种打开入口均在返回值顶层提供
- 独立使用管理器时可省略会话;跨进程占用或无法定位有效窗口时不激活,沿用占用提示。
- 快捷键和快速命令优先使用固定主窗口;片段窗口使用最近聚焦的笔记窗口。
- 会话快照按请求顺序串行保存,单次保存失败不阻断后续保存。
- 关闭部分窗口时保存剩余笔记库;最后窗口关闭后保留已有快照,避免下次启动丢失恢复目标。
- 退出时捕获仍打开的窗口快照;窗口已全部关闭时只等待已有保存任务,不写入空列表。
- 退出前等待窗口所属笔记库的异步清理完成,再释放进程级笔记库锁并完成日志落盘。
- 控制器默认使用现有窗口创建函数,窗口外链默认使用 Electron 的
- 各笔记库分别保存打开标签和活动标签;切换笔记库时恢复该库的标签,没有打开笔记库时不持久化标签。
- 最近笔记库不限制条目数;侧边栏选择器、原生“文件 → 打开最近笔记库”菜单和快捷选择面板共享同一列表,并随打开、重命名和移除操作即时更新。
- 所有平台统一使用
Ctrl+R打开类似 Quick Open 的最近笔记库面板。- 可按仓库名称或完整路径模糊筛选,并使用方向键、Enter 或鼠标切换。
- macOS 的
Cmd+R仍用于重新加载。
- “打开最近笔记库”也注册为
workspace.openRecent命令,可从命令面板执行。 - 所选目录被移动或删除后,清除失效选择及其最近文件和收藏状态,并从最近列表移除。
- 根目录失效时也会清除当前内存索引;其他扫描错误仍按原错误报告,不会误删最近记录。
6.2 目录树与侧边栏
- 侧边栏目录树默认展示文件夹和所有符合路径规则的普通文件。
- Markdown 支持
.md、.markdown、.mdown和.mkd。 - 开启“查看所有的文件”时显示
.mynote及其内容;关闭后隐藏整个分支,包括其中的 Markdown 文件和空文件夹。.mynote中的文本文件可以只读打开;打开、切回标签或恢复会话时提示只读。- 状态栏在文件路径前持续显示“只读”,避免长路径遮住提示;回车等原生按键同样禁止修改。
- 禁止编辑、保存和另存为;从文件选择器打开、切换标签或恢复会话后仍保持只读。
- 内部文件保留管理操作限制,不加入正文索引、全文搜索、打包、发布或同步清单。
.git、符号链接和名称以.app结尾的 macOS 应用包不会进入目录树或递归扫描。- 工具栏使用“编辑 / 并排 / 预览”三段式控件选择唯一的文档视图,避免同时隐藏编辑区和预览区。
- 视图菜单的“仅显示编辑区”“同时显示编辑区和预览”“仅显示预览”互斥,始终只有当前模式带 √。
- 菜单与命令面板共用
view.editor、view.split、view.preview命令。 - 工具栏、循环切换快捷键、页面恢复和切换窗口会同步勾选;重复选择当前模式不会取消勾选。
- 菜单与命令面板共用
- 连续切换视图后重新显示编辑区时,会保留 caret 和选区并恢复文本焦点,可立即继续输入。
- 每个文档页面独立记住编辑、并排或预览模式,切换页面互不影响;视图模式随笔记库会话保存在本机,重启后随页面恢复。
- 搜索页和差异模式的临时布局不会覆盖文档页面保存的视图模式。
- 侧栏与大纲仍使用独立开关。所有选择按笔记库保存在本机。
- 视图菜单的“仅显示编辑区”“同时显示编辑区和预览”“仅显示预览”互斥,始终只有当前模式带 √。
- 侧栏中的笔记库信息、查找、收藏和文件分区可折叠或展开,默认使用手风琴模式。
- 展开状态按笔记库保存在本机;各分区标题使用统一的加大字号。
- 详细交互见侧栏分区与手风琴模式。
- 拖动侧栏与编辑区、编辑区与预览区之间的分隔条调整大小;侧栏宽度和编辑/预览比例按笔记库自动保存在本机,重启后恢复。
- 分隔条支持 Tab 聚焦后用方向键调整,Shift 加方向键加大步长;窄窗口上下排列时可调整编辑与预览高度比例。
- 目录树使用背景色标示当前选中项;未由当前标签关联时,选中项和滚动位置按笔记库恢复。
- 文件树标题栏的设置菜单依次提供“关联当前页面”“显示空文件夹”和“查看所有的文件”,均按笔记库保存在本机。
- “查看所有的文件”默认选中;关闭后仅显示受支持的 Markdown 文件,已打开的其他文本标签不会关闭。
- 与路径、时间和空文件夹筛选共同生效,保留现有忽略规则。
- 设置菜单与命令面板共用
workspace.toggleShowAllFiles命令,支持键盘操作。 - 全文搜索、大纲索引、发布和远程同步的文件类型范围保持不变;新建笔记仍使用 Markdown。
- 切换笔记库后,旧笔记库的文件树设置保存响应不会修改新笔记库的界面。
- “关联当前页面”默认开启;原全局设置字段不迁移,新版本直接使用各笔记库自己的默认值或已保存值。
- 开启时,切换标签页会展开对应文件的父目录并高亮节点;节点不在可视区域时,文件树会滚动到该节点;目录展开状态按笔记库恢复。
- 文件树存在多选时,关联当前页面暂不替换整组选区;恢复单选后继续按上述规则定位当前文件。
- 关闭时,切换标签页不改变文件树的选择、展开状态和滚动位置;重新开启后立即定位当前页面。
- 未保存页面、搜索页及笔记库外的文件没有对应节点,关联开启时会清除树中的高亮。
- 目录树支持鼠标右键菜单及
Shift+F10键盘菜单。 - 上下文菜单支持方向键、
Home/End、Enter/Space和Esc操作。 - 目录树使用单一 Tab 停靠点。
- 目录树支持方向键、
Home/End、Enter和空格键导航、展开与打开条目;后台刷新、过滤变化或目录重绘后按路径恢复原焦点,避免方向键意外变成滚动文件树。
文件树刷新机制
重新扫描与界面重绘
- 左侧文件树使用最近一次扫描得到的工作区快照,不持续监听整个笔记库目录,也没有独立的定时目录刷新。
- 重新扫描会读取磁盘目录、受支持的 Markdown 文件、文件大小、文件修改时间及同步冲突标记,再更新文件树。
- 扫描仍遵守下文的路径边界、文件数量上限和
.mynoteignore准入规则。 - 扫描后仍应用当前文件筛选和“显示空文件夹”设置,因此磁盘上存在的文件不一定显示。
- 界面重绘只重新展示已有快照,不重新枚举磁盘目录。
- 展开或折叠、修改文件筛选、切换“显示空文件夹”、关联当前标签及选择变化可能改变树的显示,但不能据此判断已读取外部目录变化。
- 重绘时按路径恢复树内键盘焦点;同一笔记库刷新时沿用展开状态和仍有效的选择,移除已不存在或被筛选隐藏的选区条目。
会重新扫描的入口
- 打开、切换或启动时恢复笔记库。
- 点击文件树标题栏“刷新笔记库”,或执行同名命令。
- 默认快捷键为 Windows/Linux 的
Ctrl+K R、macOS 的Cmd+K R,也可在快捷键设置中修改。 - 手动刷新先保存会话恢复信息,再扫描磁盘;它不会把未保存正文写入笔记文件,也不会强制重新加载所有已打开文档。
- 按钮显示加载状态,完成后短暂显示成功或失败反馈;扫描失败会提示原因。
- 默认快捷键为 Windows/Linux 的
- 在应用内新建文件或文件夹、重命名、移动、复制、粘贴、移入回收站,以及撤销或重做这些操作后,使用返回的新快照更新树。
- 在当前窗口保存设置且改变 Markdown 文件扫描上限后。
- 手动同步正常完成后;同步抛出错误时也会尝试刷新,以展示可能已经写入的冲突文件。
- 同步因冲突或未保存文件等原因直接暂缓时,不能依赖该手动同步入口刷新树。
- 自动同步取得非空结果后,主进程为打开该笔记库的各窗口重新扫描并发送快照。
- 此刷新不要求实际拉取到新文件;返回“暂缓”结果时也会发送快照。
- 未登录等情况未取得结果,或同步过程抛出错误时,不会通过该回调刷新树。
- 因此自动同步可能顺带显示此前的本地外部目录变化;它不是文件树独立的定时刷新机制。
- 恢复文件历史版本、部分仓库恢复或冲突处理流程,以及打包界面的“刷新笔记库”等入口,也会扫描并更新主窗口文件树。
- 每次应用文件筛选、筛选预设或文件树差异比较前都会重新扫描,刷新候选文件和时间信息;因此外部新建的文件会参与本次筛选。
不会直接重新扫描的情况
- 在资源管理器、终端或其他编辑器中新增、删除、移动、重命名文件或文件夹,以及修改
.mynoteignore,不会单独触发整棵文件树刷新。 - 普通“保存”和“另存为”更新文档状态及相关大纲索引,不直接重新扫描左侧文件树。
- 未命名文档首次保存到笔记库后,文件可能要等下一次扫描才出现在树中。
- 外部文件监听针对已登记监听的具体文档路径,不是整个笔记库的递归监听。
- 监听父目录事件时按文件名过滤,并等待约 120 毫秒合并事件;应用自身保存会按内容签名抑制对应通知。
- 外部修改主要更新已打开文档、冲突提示和相关大纲索引;外部删除会保留编辑器内容并标记标签缺失,不直接从树快照中移除节点。
- 同目录中其他未监听文件的变化通常被忽略;监听错误也不会自动回退为整库扫描。
- 切回应用窗口、切换标签或刷新编辑器 Git HEAD 差异,不会重新扫描目录树。
- 同一笔记库由一个窗口独占打开;普通文件操作的树快照只更新持有窗口。
外部变化后的使用方式
- “有时自动刷新,有时不刷新”通常取决于外部变化之后是否又发生了上述扫描入口;单纯的界面重绘或文档监听不足以发现目录变化。
- 需要立即确认外部文件或目录变化时,执行“刷新笔记库”;若仍不可见,检查扩展名、准入规则、当前筛选和空文件夹显示设置。
路径映射与扫描边界
-
可在笔记库
.mynote/config中按 Git config 风格配置[mirror]下的host:[mirror] host = https://react.dev/learn -
HTTP/HTTPS 链接位于该前缀内,且映射的 Markdown 文件存在时,编辑区和预览区默认打开本地文件。
- 按住 Shift 点击始终打开原链接。
- 未配置、配置无效、链接越界或文件不存在时仍按外链处理。
-
例如
https://react.dev/learn/creating-a-react-app映射到仓库根目录的creating-a-react-app.md。 -
单个笔记库默认最多扫描 10000 个 Markdown 文件和 20000 个目录项;可在设置中调整文件上限,保存后当前窗口自动刷新,目录项上限保持为文件上限的两倍,超限时明确报错。
-
所有工作区 IPC 都校验真实路径,拒绝
..越界和通过符号链接访问库外文件。
.mynoteignore 准入规则
- 根目录可创建 UTF-8 编码的
.mynoteignore,按.gitignore语义支持:- 空行、
#注释、!反选、*、?和**。 - 以
/锚定根目录,以及以/结尾的目录规则。
- 空行、
Gitignore 基本规则
- 空行用于分隔规则,以
#开头的行是注释;需要匹配字面量#或!时在前面加反斜杠。 - 同一个规则文件内按从上到下的顺序匹配,后出现的匹配规则覆盖先前结果。
!pattern反选先前排除的路径,但不能单独反选已被排除目录内的文件:test/排除整个目录后,!test/1.md不会生效。- 若要只保留该文件,可写成
test/*和!test/1.md,让父目录本身保持可遍历。
- 不含
/的模式可匹配任意层级中的名称;开头的/把模式锚定到规则文件的根目录;结尾的/只匹配目录。 *匹配除/外的任意内容,?匹配除/外的单个字符,[abc]和[a-z]匹配字符集合或范围,**可跨越目录层级。- 行尾空格默认忽略;需要保留字面量空格时使用反斜杠转义。
- 完整语法和更多示例见 Git 官方 gitignore 文档。
# 构建产物与临时文件
build/
*.tmp
/private.md
!important.tmp
- 规则只限制尚未加入管理的新路径:
- 已进入管理清单或同步基线的 Markdown 文件继续显示、搜索和同步。
- 新增的非 Markdown 显示与编辑能力不扩展管理清单;这些文件每次扫描仍按忽略规则决定是否显示。
- 命中规则的新文件保持隐藏且不加入同步。
- 保存和文件变更通知触发的大纲更新也遵守准入规则;删除并退出管理后,同名文件重新创建不会绕过过滤。
- 准入结果保存在
.mynote/managed-paths.json,重启后仍有效。
.mynoteignore最大 256 KB,必须是普通文件,不显示在只展示 Markdown 的目录树中。- 它参与托管同步,也不能被自身规则排除。
.app应用包和.mynote是不可反选的内置排除项。
- 多设备并发修改规则时,远端版本生效;本地并发版本保存在
.mynote/sync-conflicts/mynoteignore-<设备>-r<revision>.txt,不会生效或再次同步。 .mynoteignore同步要求所有设备使用支持“只限制新路径”的客户端,并重启已升级的同步服务;旧客户端可能停止跟踪命中规则的已有文件。
Ignore 逻辑使用范围与一致性
- 仓库级
.mynoteignore用于以下流程:- 工作区扫描:决定文件树、全文搜索和大纲索引可见的 Markdown 文件。
- 工作区递归操作:重命名、移动、复制、删除和批量导出枚举 Markdown 文件时跳过未准入路径。
- 托管同步:本地变更预览、冲突检查、上传与删除推断使用同一份准入结果。
.mynoteignore自身仍作为同步文件处理;远端应用规则文件后,下一次本地扫描使用新规则。
- 片段集合的
.cfg.ignore只保存ignore:=过滤文件路径引用:- 每个被引用的过滤文件都复用仓库级规则解析与路径判断。
- 规则以各过滤文件所在目录为根;一个来源路径命中任意过滤文件就不加载。
- 片段过滤不读取仓库的已管理路径记录,因此规则始终直接作用于片段来源。
- 文件树和打包界面的“排除规则”使用同一个 Gitignore 匹配库,但只匹配已经进入工作区树的 Markdown 文件:
- 它与文件名、相对目录、扩展名和修改时间条件共同决定当前显示或打包范围。
- 它不参与仓库准入、文件操作或同步,也不读写
.mynoteignore。
- 算法统一情况:
- 规则语法统一。三处都使用项目固定版本的
ignore库,遵循 Gitignore 的规则顺序、通配符、注释、转义和反选语义。 - 仓库扫描、工作区递归操作、同步和片段集合共用
MyNoteIgnorePolicy;它统一规范化路径分隔符,并集中处理.mynoteignore、.mynote和.app的固定规则。 - 最终策略不完全相同,这是使用场景的必要差异:仓库规则只阻止新路径准入,已管理路径继续可见和同步;片段规则没有“已管理”例外;界面排除规则只是已有文件树上的临时筛选。
- 目录遍历也按内容范围分别实现:工作区只收集支持的 Markdown,托管同步收集协议支持的 Markdown、图片和
.mynoteignore,片段集合读取配置指定的普通文件。工作区与同步扫描另行跳过符号链接,这不属于 Gitignore 匹配算法。
- 规则语法统一。三处都使用项目固定版本的
6.3 文件操作
新建与文件树工具
- 支持新建文件和文件夹。
- 新建文件、文件夹及重命名共用弹窗字段校验;按钮与 Enter 提交行为一致。
- 名称的纯文本规则由渲染器在调用 IPC 前检查,与主进程复用同一实现。
- 非法字符、路径分隔符、名称结尾或补全扩展名后超长时直接显示字段提示,不发起远程调用。
- 必填名称去除首尾空白后须非空;文件名保持 255 字符限制,不接受路径分隔符。
- 非法名称、目标占用、符号链接或操作失败时,在字段下方提示并保留原输入,便于修正重试。
- 提交期间防止重复执行,操作成功后才关闭弹窗;重命名为原名称保持无操作行为。
- 写入前检查文件、目录及断开的符号链接占用;源路径和目标父目录各层均拒绝符号链接。
- 保留底层路径边界与防覆盖检查,以及普通文本文件的重命名规则。
- 在当前文件夹新建文件时,没有受支持的 Markdown 扩展名就自动补充
.md;已有.md、.markdown、.mdown或.mkd时保持不变。 - 文件树标题栏集中提供新建文件、新建文件夹、刷新、全部展开、全部折叠和文件树设置图标按钮。
- 文件树标题栏从“刷新笔记库”开始的刷新、全部展开、全部折叠、修改时间过滤和文件树设置操作均可从命令面板执行;
- 这些入口共用
workspace.*命令,仅在已打开笔记库且没有模态窗口时生效。 - 默认快捷键依次为
Ctrl/Cmd+K R、Ctrl/Cmd+K E、Ctrl/Cmd+K C、Ctrl/Cmd+K T和Ctrl/Cmd+K ,。- 也可在快捷键设置中修改。
- 5 个按钮的 tooltip 显示当前平台实际生效的快捷键,并随用户配置即时更新。
- 这些入口共用
- 文件树设置菜单可切换是否显示不包含当前可见文件的空文件夹,并按笔记库记住该选项。
- 修改时间、文件名、目录、扩展名或排除规则等过滤启用时仍遵循“显示空文件夹”设置;关闭该设置时只保留匹配文件及其父目录。
- 隐藏空文件夹时会递归隐藏仅包含空目录的父目录;该选项默认显示空文件夹。
文件筛选与打包
打包文件
- 打包保持原有 Markdown 范围;“查看所有的文件”不会把附件或其他文本自动加入打包内容。
- 文件树时间过滤按钮旁提供“打包文件”按钮,首次沿用文件树筛选,随后恢复独立的上次选择,并显示已选、匹配和总文件数。
- 打包入口由文件树控件模块
src/renderer/runtime/tree-controls.mts注册,首次打开时按需加载打包界面。 - 首次打开默认全部勾选;同一笔记库重新打开时保留上次勾选。
- 切换文件夹复选框会递归切换自身及所有子孙节点,混合选择显示半选状态。
- 树上方的操作行依次显示“应用筛选”“清除筛选”“全选”“取消全选”“全部折叠”“全部展开”和“刷新”。
- 刷新按钮旁的“统计文件大小”默认勾选,展示文件的磁盘字节大小及文件夹内当前筛选范围的文件大小总和;取消勾选隐藏大小。
- 复选框后显示当前已勾选文件的总大小;取消勾选时一并隐藏。
- 操作行中的按钮、复选框和总大小垂直居中对齐。
- 文件、文件夹和总大小统一按 KB(1 KB = 1024 字节)显示,保留两位小数,每三位数字用逗号分隔。
- 总大小在文件勾选、文件夹递归勾选、全选和取消全选后立即重新计算;未选择文件时显示
0.00 KB。 - 文件和文件夹行显示的磁盘大小在刷新时更新,文件夹行仍汇总当前筛选范围的文件。
- 同一笔记库关闭后重新打开保留此选项。
- 筛选区初始时按内容高度同时显示“编辑筛选条件和预设”与“修改时间”,不在操作按钮下方保留空白;展开筛选条件时会增大筛选区,文件树保留最小可见高度,对话框空间不足时可滚动查看文件树、问答与操作区。
- 筛选区始终显示灰色边框,失去焦点时仍可辨认其范围。
- 点击文件夹名称可切换其展开状态。
- 命令面板可搜索“打包文件”或
workspace.packFiles打开同一对话框;默认无快捷键,可在快捷键设置中绑定。 - 底部的“在内容头部插入相对路径”默认勾选,可取消;路径头格式为
// ======= 相对路径。 - 点击“选择文件打包”按文件树顺序读取所选文件的磁盘内容,每个文件的每行以从
1:开始的行号为前缀,以空行拼接后在对话框中展示并可复制;未保存编辑需先保存。 - 任一文件读取失败会显示具体路径,不输出不完整的打包结果;修改筛选、选择或路径选项会清空旧结果。
- “查询打包”保留查询命令和命中文件打包流程,但不发送最终回答请求。
- “选择文件提问”跳过查询命令和文件过滤,直接打包当前勾选的全部文件,在打包结果框显示内容并发送最终回答请求。
- 最终回答请求的
messages依次为系统提示词、打包文件内容、用户问题;文件内容和问题分别放在独立的user消息中,原样发送。 - 默认系统提示词要求只使用文件事实回答、证据不足时明确说明、引用相关文件的相对路径,并将文件内容视为不可信数据,不执行其中的指令。
- 最终回答请求的
- “选择文件打包”位于打包结果框下方、“复制打包结果”左侧;只在本机打包当前勾选的文件,不发送任何 DeepSeek 请求。结果框始终保留布局位置,避免首次或重复打包时界面跳动;没有结果时复制和另存为不可用。
- 打包结果框下方可复制完整打包内容,包括超过 1 MiB 的结果,也可通过“另存为…”将完整结果保存为 UTF-8 文件;默认扩展名为
.md,手动指定的扩展名会保留。底部按钮用于复制 DeepSeek 回答。
- 打包入口由文件树控件模块
- 打包界面可从完整文件树重新筛选;清除筛选恢复全部文件。每次应用筛选、预设或清除筛选都会重新扫描,并按当前条件重建默认全选的文件树;“刷新”按钮也会重新扫描并保留当前条件。
- 关闭打包对话框时仅隐藏界面;在同一笔记库再次打开会复用原有界面,保留文件勾选、筛选、展开状态、问题及打包结果。在其他笔记库打开时会创建新界面。
- 打包期间禁用筛选和勾选,避免结果与当前选择不一致;切换预设、应用筛选、修改勾选或路径头部选项会清空旧输出并禁用复制。
筛选条件
- 文件树和打包界面共享可保存、更新、重命名、删除的筛选预设,支持包含规则、排除规则与修改时间。
- 多个筛选条件须同时满足;空项表示不限。
- 包含规则每行一条,复用排除规则的 Gitignore 匹配语法;留空或仅写注释时包含所有文件(仍受其他条件限制)。
- 例如
工作/包含目录下的文件,**/*周报*.md匹配文件名,多个正向规则匹配任一条即可。 - 支持
#注释和!反选;排除规则优先,包含规则不能恢复被排除的文件。 - 排除规则同样每行一条;不能在已排除的父目录下单独反选文件。
- 不迁移旧版文件名、目录和扩展名条件;扩展名可改用
*.md等包含规则。
- 例如
- 包含规则和排除规则输入框至少显示 120px 高度,内容较多时仍可手动拉高。
- 筛选仅控制显示和打包范围,不修改
.mynoteignore、文件或同步规则。文件树显示匹配数量,重置后显示全部文件并恢复默认差异选项。
文件筛选预设与打包
- 预设包括不可修改的“全部文件”“最近七天”和每个笔记库最多 100 个用户预设。选择预设立即应用;填写名称后可另存、更新、重命名或删除,成功与失败均以不改变布局的 toast 反馈。
- 预设保存筛选条件与时间规则,不保存独立的编辑器差异选项;相对时间在应用或恢复时重新计算,指定日期保持不变。
- 用户预设、文件树当前条件及时间范围、打包界面上次使用的条件及时间范围,按笔记库分别保存在应用用户数据目录的
repository-ui-state-v1.json;重启后各自恢复。 - “文件筛选与差异”和“打包文件”使用同一套过滤器,以打包界面为模板,共用预设编辑、修改时间字段、校验、日历入口和布局代码。
- 界面入口分别为
file-filter-diff.mts中的createFileFilterDiff和按需加载的file-pack.mts。 - 公共组件集中在
file-filter-ui.mts,包括预设编辑、时间范围字段、筛选区域模板和输入交互。 - 公共业务集中在
file-filter.mts,包括筛选匹配、时间解析、预设身份判定及预设操作校验和列表变换;界面通过回调完成保存和应用。 - 两处共享预设列表,但分别保存当前选择。
- 预设下拉框与预设操作栏在筛选区域滚动时保持可见。
- “编辑筛选条件和预设”与“修改时间”默认折叠,展开后使用相同的平面缩进布局。
- 单行字段的标签与输入控件同排显示;包含和排除规则使用整行多行输入,预设名称位于条件编辑首行。
- 预设操作栏统一显示“另存为预设”“更新”“重命名”“删除”;“应用筛选”“清除筛选”位于各自的外部操作行。
- 两处统一通过同一入口解析时间条件;切换到自定义时间或指定日期时,自动聚焦对应输入框。
- 清除筛选共用完整草稿重置逻辑:清空包含、排除和时间输入,恢复“全部文件”预设,并清除自定义校验;随后重新扫描笔记库并应用不限条件。
- 文件树专有的差异选项和“比较整个文件树”操作继续保留;文件树清除筛选成功后仍恢复默认差异选项。
- 重新打开缓存的打包窗口时刷新共享预设列表,使文件树中新建、重命名或删除的预设立即反映到下拉框;保留当前筛选、打包输出和提问草稿。
- 界面入口分别为
- 内置预设不能更新、重命名或删除,尝试操作时会提示先另存为用户预设;用户预设操作按钮提供提示,校验或保存失败时显示原因。
修改时间过滤
- 文件树标题栏提供修改时间过滤:默认展示全部文件,可选择最近一天、七天、一个月、两个月、三个月、半年,也可输入自定义时间表达式。
- 纯数值仍以天为单位(如
0.5表示半天);- 根据当前时刻减去 n 个固定 24 小时生成截止时间。见 file-time-filter.mts
- “一个月”实际按 30 天计算,半年按 180 天计算,不是日历月。
- 固定时间间隔支持可组合的
ms、s、m、h、d、w单位(如1d 12h,其中m表示分钟);- 也支持 ISO 8601 周/日/时间间隔(如
PT1H30M)。
- 也支持 ISO 8601 周/日/时间间隔(如
2025-3-1 12:0形式的时间点按当前系统时区转换为时间戳。- 也可通过日期输入与独立的“日历”按钮指定起始日期,并可一键重置。
- 日期选择器导致窗口暂时失焦时,过滤面板仍保持打开,以便结果写回输入框。
- 文件修改时间统一取 mynote 仓库最近历史时间与磁盘
mtime中较早的一个,不依赖 Git; - 文件首次加入时会在新增历史中记录当时的磁盘
mtime,只有新增历史时使用该记录,旧历史没有该字段时兼容回退到新增版本时间,尚无历史时使用当前磁盘mtime。 - 应用启用时间条件的筛选或预设时会先重新扫描笔记库,刷新候选文件及其时间,再应用筛选。
- 文件过滤和文件差异的选择均按笔记库保存,切换笔记库或重启后恢复。
- 旧版数值天数配置继续兼容;重置文件时间后恢复全部文件及默认的 Git HEAD 差异选项。
- 退出差异模式恢复普通布局时会重新生成当前文档的大纲,避免保留进入差异模式前的文档大纲。
- 纯数值仍以天为单位(如
文件差异
当前文件差异
- 时间过滤面板的“文件差异”默认选择排在首位的 Git HEAD;
- 还可关闭差异、“同上”使用文件过滤时间,或通过“其他”独立选择时间预设、自定义时间表达式和日历日期。
- 选择框旁的“切换”按钮会按下拉框顺序循环选择并立即应用,
workspace.cycleFileDifferenceMode命令也可从命令面板触发并在快捷键设置中绑定; - 从面板外执行时不会打开面板,而是直接切换、保存并刷新编辑器差异视图。
- 状态栏常驻显示当前生效选项,并为“同上”和“其他”显示完整时间,如“当前差异模式:同上-自定义时间-3天”和“当前差异模式:其他-自定义时间-3天”。
- 文件时间为“不限时间”时会跳过无法产生基线的“同上”。
- 切换离开“其他”后仍会按笔记库保留最近使用的预设、自定义表达式或日期,再次切回时自动恢复。
- 选择 Git HEAD 时,当前文件与笔记库所在 Git 仓库的 HEAD 对应版本比较;
- 仓库可位于笔记库的上级目录,并兼容 Git 2.23 等不支持
rev-parse --path-format的旧版本。 - 应用可见期间自动跟踪 commit、分支切换和 reset 等 HEAD 变化;窗口重新获得焦点时也会立即检查。
- 未初始化 Git 或 HEAD 尚无提交时会提示版本不可用;HEAD 未跟踪的新增文件使用空基线,当前内容全部标为新增。
- 独立差异时间与修改时间、整个文件树比较基线共用时间字段生成函数;保留各自的字段标签、控件 ID 和时间选项。
- 展开独立差异时间字段时,面板会重新定位在窗口可见范围内,并在窗口高度不足时提供内部滚动。
- 启用后,编辑器以淡绿色标出当前内容相对所选基线新增或修改的行,并随未保存编辑即时更新;
- 删除行因当前编辑器没有对应行而不着色;两种基线复用同步中心的逐行差异计算。
- 时间基线使用目标时间或更早的最近 mynote 历史版本,不依赖 Git,且截止时间早于首个历史版本时以空内容为基线,将当前正文整篇视为新增。
- 相邻差异行合并为一处。
- 从 转到菜单或按
Alt+N/Alt+P可跳过当前整处差异,定位到下一处 / 上一处的首行。 - 到达首尾后不循环折返。两个命令的绑定可在快捷键设置中修改。
- 从 转到菜单或按
- 两个导航命令分别为
editor.nextDifference和editor.previousDifference。 - 只有一处差异时,两个快捷键仍能重新选中并滚动到该处;按住
Ctrl(macOS 为Command)双击差异行会返回编辑页并将对应行定位到顶部,纯删除行定位到当前正文中紧邻的行。 - 同一路径删除后重新创建时,历史查询优先使用当前有效文件身份;若有多个有效身份,选 revision 最新者。只有不存在有效身份时才回退到最新删除墓碑。
- macOS 的 转到菜单仅展示这些快捷键,由应用快捷键系统处理
Option组合,避免原生菜单截获按键; - 即使系统将
Option+N/P报告为重音组合输入,快捷键仍会执行并抑制后续字符提交。
文件树差异
- 面板底部的“比较整个文件树”沿用当前“文件差异”基线,并像“应用”一样立即应用及按笔记库保存面板中的文件时间与文件差异选择;
- 选择 Git HEAD 时,先固定当前 HEAD 提交,再将当前未过滤 Markdown 文件树中的每个文件与该提交中的版本比较。
- 选择“同上”或独立差异时间时,读取对应截止时间或更早的最近 mynote 历史版本。
- “文件差异”关闭时继续使用当前文件时间条件;
- “同上”或关闭差异且文件时间为“不限时间”时,比较按钮保持禁用,避免用不存在的截止时间启动比较。
- 结果在占满应用窗口宽度和高度的独立对话框中按文件相对路径列出实际正文变化,文件列表弹性占据顶部控件与底部按钮之间的剩余高度并独立滚动,默认全部展开;
- 每个标题栏可直接跳转并打开对应文件,顶部可全部折叠或全部展开,也可切换精简差异和自动换行。
- 对话框提供 Git HEAD 和时间范围选项、表达式、日期及日历控件,修改后可直接重新比较。
- 视图菜单的“文件树差异”、
view.fileTreeDifference命令或Ctrl/Cmd+Alt+D可直接打开该对话框; - 关闭或跳转只隐藏对话框,同一笔记库再次打开时会保留上次的比较基线、摘要、差异内容和展开状态,跳转按钮会恢复为可再次使用的状态。
- 比较会统一基线正文与磁盘正文的换行符,并沿用逐行差异对文件末尾换行的处理,避免把正文相同的 CRLF 文件或仅末尾换行表示不同的文件误报为变化。
- Git HEAD 未跟踪的新增文件使用空基线并显示为整篇新增;没有可靠同步历史身份的文件会跳过并显示数量。
- Git HEAD 比较支持非 Markdown 文本,包括编辑器中未保存的正文;HEAD 更新后会刷新比较基线。
- 整树 Git HEAD 比较覆盖当前扫描到的文本文件,非文本、编码无效或过大的文件会跳过,不中断其他文件的比较。
- 时间历史比较仍沿用原有 Markdown 范围。
- Git blob 与磁盘文件使用同一 UTF-8 解码规则去除 BOM,并统一 CRLF、CR 和 LF。
- 文件筛选与逐行渲染还会再次规范化,避免正文相同的 Windows 文件被误报为整篇变化。
- 每个文件的展开或折叠图标使用独立的左侧槽位,与文件名保持间距。
- 获取差异时,主进程终端与渲染器开发者工具会输出带
[mynote:file-diff:*]前缀的结构化详细日志。- 日志包括目标时间、历史版本、基线来源、缓存命中、差异行/块数量和耗时,不输出笔记正文。
文件整理与导航
- 支持重命名、移动和复制文件或文件夹;文件树条目可拖到目标文件夹,或拖到文件并以其父文件夹作为目标,默认移动,拖拽时按 Ctrl(macOS 为 Cmd)则复制。
- 文件树支持文件与文件夹混选:普通点击保持打开文件或展开文件夹的行为;Ctrl(macOS 为 Cmd)点击增减选区,Shift 点击按当前可见节点顺序选择范围。右键已选项保留整组选区,右键未选项改为单选;拖动已选项操作整组,拖动未选项只操作该项。
- 文件树右键菜单提供“比较文件”,仅在恰好选中两个文件且没有正在执行的文件树操作时可用;选中文件夹、单个文件或更多条目时禁用。
- 命令面板也提供“比较文件”(
workspace.compareFiles),沿用相同的选区与可用性规则;无默认快捷键,可在快捷键设置中自定义。 - 使用 VS Code 的
--diff打开磁盘上的两个文件,按文件树顺序排列左右两侧;未保存的编辑内容不参与比较。 - macOS 通过系统应用启动服务查找 VS Code;Windows 查找标准安装目录和 PATH 中的安装位置;Linux 需要
code命令位于 PATH。 - 未安装 VS Code、路径失效或启动失败时,使用应用内提示框显示错误。
- 命令面板也提供“比较文件”(
- 筛选隐藏或刷新后已不存在的条目从选区移除;折叠目录中的已选子项保留。多选仅在当前笔记库会话中有效,切换笔记库或重启应用后恢复现有的单选路径。
- 侧栏底部不再显示收藏、重命名、剪切、复制、粘贴和回收站按钮;这些操作继续通过文件树右键菜单执行。
- 文件树聚焦时支持 VS Code 风格的操作快捷键:Windows/Linux 按
F2重命名、Delete移入回收站,macOS 按Enter重命名、Cmd+Backspace移入回收站(也支持Delete);Ctrl/Cmd+X剪切,Ctrl/Cmd+C复制,Ctrl/Cmd+V粘贴。 - 文件树聚焦时,
Ctrl/Cmd+Z和Ctrl/Cmd+Shift+Z分别撤销、重做新建、重命名、移动、复制、粘贴和移入系统回收站;多选操作作为一步处理。多选删除及其撤销、重做并发处理各项目的系统回收站操作,统一更新工作区状态并刷新文件树。编辑器聚焦时仍撤销、重做正文修改。文件树历史只在当前窗口和当前笔记库会话内保留。 - 点击文件树空白处会将焦点移入文件树。重命名、新建文件夹、移动、复制、粘贴及撤销、重做完成后,焦点留在文件树;原节点消失时聚焦操作结果或其他可见节点,空树则聚焦文件树容器。新建文件继续聚焦新文档以便输入正文。
- 删除及撤销新建、复制时仍使用系统回收站,不另存文件副本;恢复会沿用删除时记录的系统回收站类型。回收站项目已被 Explorer 恢复或移走时,对应历史记录失效并从文件树撤销历史中移除,提示中列出失效项目的相对路径;项目仍在回收站但原路径被占用,或相关文档有未保存修改时,历史操作会停止并提示原因,保留可重试的记录。
- 文件树撤销或重做某项失败时,弹窗显示失败项目的相对路径和原因,并提供取消、重试、跳过。默认聚焦取消;取消保留当前进度,重试只重试该项,跳过只移除该项的历史记录并继续同组的其余项目。
- Windows 通过系统 Shell 回收站接口定位和恢复项目,不依赖 PowerShell;回收站记录中的中文路径经 URI 编码传递,并将原目录规范化后匹配。定位时还核对删除前后的卷与文件 ID,避免将其他进程删除的同名项目记入撤销历史;无法确认身份时不创建撤销记录。中文名称和短路径目录中的项目也可获得撤销所需的回收站记录。
- 删除、撤销和重做会输出
[mynote:tree:renderer]与[mynote:tree:main]诊断日志,记录操作路径、各阶段耗时stageMs和累计耗时elapsedMs。主进程日志细分系统回收站、工作区扫描、大纲索引和快照;Windows 还细分删除后的回收站查询、系统删除与恢复。可分别在开发者工具控制台和启动应用的终端查看。 - 复制不会立即改变文件树;剪切条目以半透明显示,粘贴完成后恢复。可在任意文件或文件夹节点粘贴:文件以其父文件夹为目标,文件夹以自身为目标。
- 混选时剪切、复制、粘贴、拖动和回收站操作处理整组选项;同时选中父文件夹与子项时只操作父文件夹。粘贴目标由当前焦点项决定。重命名、收藏等单项操作仅在选中一项时可用。
- 选中文件夹表示操作整个磁盘目录,包括界面筛选隐藏的文件、隐藏文件和非 Markdown 文件;复制目录仍沿用跳过符号链接的规则。批量操作逐项执行,失败后停止并报告完成数量,已完成结果保留;剪切粘贴失败时可重试尚未移动的项目。
- 条目也可拖到文件树根部;拖拽目标用不同强调色显示移动或复制,并在鼠标释放时以窗口级主修饰键状态决定操作。
- 新建和重命名使用应用内输入对话框,避免依赖 Electron 不可靠的浏览器提示框。
- 目标同名、移动到自身内部、符号链接操作或路径越界时拒绝操作。移动和重命名会保留已打开标签中的未保存修改,并同步迁移标签标题、路径、正文基线和文件监听,不触发外部删除恢复提示。
- 移动或复制文档时,调整常见 Markdown 图片相对路径。
- 文件树右键菜单支持从当前选中文件循环遍历上一个或下一个文件,默认快捷键为
Alt+PageUp/Alt+PageDown;- 遍历顺序与文件树一致,首尾折返,修改时间过滤隐藏的文件不参与,并在启用预览编辑器时通过预览方式打开目标文件。
- Windows 会阻止关闭 NumLock 后的小键盘 PageUp/PageDown 被系统同时解释为 Alt 数字码,连续遍历不会向编辑器插入字符。
- 文件树条目和已保存文档的 Tab 上下文菜单支持“在文件管理器中显示”;默认快捷键为
Shift+Alt+R,也可从命令面板执行。
路径与引用
- 文件树右键菜单支持复制文件或文件夹的系统绝对路径与笔记库相对路径,并显示当前生效的可配置快捷键。
- 默认按
Shift+Alt+C复制路径;按Ctrl+K Ctrl+Shift+C(macOS 为Cmd+K Cmd+Shift+C)复制相对路径。 - 已保存的仓库内 Markdown 标签及文件树 Markdown 文件支持“复制引用”和“复制引用(大纲)”;后者默认按
Ctrl+Alt+C(macOS 为Cmd+Alt+C)触发。 - “复制引用”始终生成指向文件顶部的 Markdown 链接。
- “复制引用(大纲)”对已打开文件使用其保留的 caret,并在片段中保留中文等非 ASCII 字母与数字,以便直接阅读。
- 文件未打开、caret 位于首个标题之前或没有标题时,退化为文件引用。
- 文件引用格式为
[文件名](/仓库路径.md),大纲引用格式为[大纲标题](/仓库路径.md#标题锚点);两者使用仓库根相对地址,可粘贴到仓库任意目录。库外文件的标签页只提供绝对路径。
删除与未保存保护
- 支持将文件或文件夹移入系统回收站。
- 批量移入回收站先统一确认一次;确认后检查所选目录,只有发现文件树未显示的文件(含非 Markdown 文件等)时才二次确认。取消任一确认都不会删除项目。
- 文件树获得焦点时,按
Delete可将所选文件或文件夹移入系统回收站;取消确认后即使文件树期间发生重绘也会恢复原条目焦点,确认删除后焦点仍留在文件树,并同时关闭对应的已打开标签。 - 有未保存文档时,仍阻止删除对应文件和父文件夹;移动和重命名会保留未保存正文并更新标签路径。
npm run test:smoke:tree-multiselect验证混选、整组操作、隐藏内容与符号链接范围,以及批量失败后的剩余项目。
6.4 查找、最近文件与收藏
全文搜索与替换
- 支持按文件名和正文搜索。
- 查找框前不显示文字标签;最左侧的
▸/▾箭头展开或收起替换,输入框保留无障碍名称。 - 大小写和全字匹配按钮位于“查找”标题行,沿用文件树标题操作按钮的样式。
- 输入区域下方显示命中文件数、结果数和“在编辑器中打开”入口。
- 正文按每处命中计数;仅路径命中的文件计一个结果。
- 无匹配时显示零个文件、零个结果;清空查询或切换笔记库时隐藏旧统计。
- 侧栏搜索结果按文件分组,显示文件名、相对目录和正文命中次数,默认展开,可通过文件标题或独立箭头折叠。
- 折叠箭头沿用文件树的
▾/▸图标,与文件标题垂直居中对齐。 - 文件标题使用独立底色、分隔线和蓝色加粗文件名,目录保持弱化,命中次数显示为徽标;文件分组之间留出间距。
- 折叠箭头沿用文件树的
- 文件下按源码顺序显示全部命中行及行号,不显示上下文;同一行只显示一次,全部命中关键字高亮。
- 点击命中行定位并选中该行首处命中;点击具体高亮定位对应命中,均使用预览标签。
- 点击文件标题切换展开或折叠,不打开文件,也不改变当前遍历位置;点击命中行打开并定位。
- 仅路径匹配时只显示文件标题,正文命中次数为零,仍可通过 F4 / Shift+F4 打开文件。
- 长行按实际可用宽度保留尽可能多的命中前文,仅省略容纳首处命中所必需的前缀。
- 加宽侧栏或重新展开文件时重新测量,恢复更多前文;能放下时显示完整前缀。
- 保持高亮文字可见,不横向滚动省略文本;源码行号与跳转位置不受截断影响。
- 悬停可查看完整行;新查询完成后文件分组重新展开。
- “编辑 → 在文件中查找”和“编辑 → 在文件中替换”分别复用命令
search.findInFiles、search.replaceInFiles。- 命令面板可搜索并执行同名操作;均要求已打开笔记库且没有模态窗口。
- 菜单快捷键随用户配置更新或移除;菜单入口位于“全选”之后,前后以分隔线分组。
- 使用
Ctrl+Shift+F(macOS 为Cmd+Shift+F)显示侧边栏并聚焦全文查找。 - 使用
Ctrl+Shift+R(macOS 为Cmd+Shift+R)展开全文替换并聚焦替换输入框。 - 使用
Ctrl+H(macOS 为Cmd+Option+F)在编辑区展开当前文件替换;可替换当前匹配或一次替换全部匹配,并沿用大小写和全字匹配选项。 - 当前文件替换展开时,Tab 从查找内容依次进入替换内容、查找选项和替换操作;Shift+Tab 按相反顺序移动。
- 焦点位于替换内容输入框时,按 Enter 替换当前匹配并保持输入焦点,可连续按 Enter 逐个替换。
- 焦点位于替换内容输入框时,Windows/Linux 按
Ctrl+Alt+Enter、macOS 按Cmd+Enter可替换当前文件中的全部匹配。 - 全文替换与查找共享大小写和全字匹配选项,仅修改 Markdown 正文,不更改文件名。
- 全部替换前显示影响文件数和替换数并要求确认;命中文件存在未保存修改时会阻止写盘。
- 全部替换使用原子写盘,保留 UTF-8 BOM 和 LF/CRLF 换行格式,并同步刷新已打开文件、搜索标签页和大纲索引。
- 单击侧栏搜索结果时使用预览标签打开,后续结果会复用同一个预览位置。
- 侧栏搜索结果可通过结果统计旁的“在编辑器中打开”按钮生成只读搜索标签页。
- 全库搜索内容、大小写和全字选项按笔记库保存;切换笔记库时清除旧结果并恢复目标笔记库的搜索状态。
- 侧栏搜索读取磁盘正文;保存库内文档、收到外部文件变更或删除通知、刷新笔记库及切回窗口时自动重查。
- 刷新会更新命中行号、跳转位置、统计和遍历指示,避免文件增删行后仍显示旧位置。
- 保存和文件通知引发的刷新合并等待 200 毫秒;同一查询的较早响应不会覆盖更新后的结果。
- 未保存的编辑缓冲区不参与磁盘搜索;独立搜索标签页仍保留原有快照行为。
- 搜索标签页按文件列出全部匹配行,默认显示每个匹配前后各一行上下文,并可随时隐藏或恢复上下文行。
- 搜索标签页高亮所有源码匹配位置,包括同一行的多次命中;查询或上下文状态改变后更新高亮,滚动时保持对齐,且不妨碍文本选择和页内查找。
- 搜索标签页顶部可直接修改查询,输入停止 200 毫秒后动态刷新当前标签页的结果和标题,并保留上下文显示状态。
- 搜索标签页支持编辑区内查找;双击文件标题、匹配行或上下文行可打开源文件并定位。
- “聚焦下一个搜索结果”命令(
search.action.focusNextSearchResult)默认绑定F4,可在快捷键设置中自定义。- “聚焦上一个搜索结果”(
search.action.focusPreviousSearchResult)默认绑定Shift+F4,同样支持自定义快捷键,并沿用相同来源与位置指示。 - 侧栏“查找”分区标题栏在大小写选项左侧提供“上一个搜索结果”(↑)和“下一个搜索结果”(↓)按钮。
- 按钮复用上述命令和导航规则,悬停提示显示当前自定义快捷键。
- 最近一次侧栏结果单击或搜索结果页双击决定导航来源;跳转源文件后继续沿用该来源。
- 两种来源都按每一处正文匹配遍历,同一文件的多行匹配和同一行的多次匹配均逐项访问。
- 侧栏仅路径匹配的文件算一条;结果页跳过文件标题和上下文行。
- F4 从记录的位置前进,末尾循环到首条;Shift+F4 后退,首条循环到末条;打开源文件预览,两种来源都会定位并选中命中内容。
- 侧栏突出当前文件和命中行,在结果统计下方显示当前结果序号、总数及源文件行列。
- 遍历指示固定在输入区域,不再重复占用命中行;长路径省略显示,悬停可查看完整位置。
- 结果页工具栏显示相同位置信息,并突出当前匹配。
- 导航到已折叠的侧栏文件时自动展开并显示当前命中行。
- 指示保留在原来源中,返回结果页时可查看当前项;刷新后清除失效位置。
- 首次使用优先取当前结果页,否则取侧栏结果;没有可用侧栏结果时可使用其他打开的搜索结果页。
- 刷新后按文件路径、行号和列号重新定位;原位置消失或首次使用时,前进从首条开始,后退从末条开始。
- 来源关闭或无结果时依次退回当前结果页、侧栏和其他打开的结果页;全部为空时不执行。
- 保留现有单击、双击行为;双击标题或上下文后的下一步仍只遍历正文匹配。
- “聚焦上一个搜索结果”(
- 搜索标签页是当前会话内的静态快照,不会作为 Markdown 文件保存,也不会在重启后恢复。
搜索边界与结果页
- 全文搜索匹配仓库相对路径和 Markdown 正文,不区分大小写。
- 超过 2 MB 的文件仍可打开,但跳过正文搜索。
- 每次最多返回 100 个文件,返回文件内列出全部正文命中行。
- 文件内容按修改时间和大小缓存。
- 搜索结果区域在零条或单条结果时仍保持可用高度;长路径和片段省略显示,不产生横向滚动。搜索框在窄侧栏中收缩到可用宽度。
- “在编辑器中打开”每次创建独立的只读搜索快照。
.code-search文本显示查询、结果和文件统计、文件分组及源码行号。- 匹配行用
:、上下文行用-;相邻命中的重叠上下文只显示一次。
- 从全文搜索打开结果页时继承大小写和全字匹配选项;结果页可独立调整。全文搜索的选项同时作用于路径与正文,结果页改动查询时会同步更新源码跳转映射。
- 搜索结果页最多覆盖 100 个文件和 10,000 个匹配行;达到限制时显示截断提示。仅路径匹配或正文因体积跳过的文件仍可列出并打开。
- 结果页双击匹配行时,会在源码中选择仍位于记录位置的首个匹配。
- CodeMirror 报告页通过外部正文替换更新查询,匹配范围使用 decorations。
- 键盘、粘贴、图片插入和替换命令不能修改报告正文。
- 迁移记录见 CodeMirror 迁移。
- 搜索栏、搜索结果页、编辑区和预览区的当前文件查找栏均提供
Aa(区分大小写)与Ab(全字匹配)开关。 - 编辑区页内查找条件变化后,当前匹配已完整显示在视图中时保留滚动位置;匹配在视图外时滚动定位。
- 也可按
Alt+C、Alt+W切换,只更新当前栏的选项和结果。 - 全字匹配要求查询前后不紧邻 Unicode 字母、组合标记、数字或下划线。
- 例如
cat不匹配scatter、cat2或cat_。
- 例如
- 也可按
- 聚焦全文搜索输入框时按
Alt+Enter可在编辑器打开结果;查询为空或正在打开结果时不会重复执行。通过快捷键重新聚焦页内或全文查找时,不超过 200 字符的单行选区会带入查询框。 - 页内和全文查找各自保存最近 50 条去重历史;输入停止 300 毫秒后记录,
↑和↓可回看。- 历史位于 Electron
userData/Local Storage。 - 键名分别为
mynote.page-find-history.v1和mynote.workspace-search-history.v1。
- 历史位于 Electron
npm run test:smoke:workspace-search覆盖真实渲染器中的全文查找与替换、结果页、写盘、打开文件刷新和恢复原文。- 同时覆盖 F4 与 Shift+F4 的两种来源、连续前进、后退与循环、结果刷新、来源关闭与空结果回退,以及自定义快捷键。
- 验证两种来源的当前位置指示,以及同一文件多行和同一行多次匹配的逐项遍历。
侧栏分区与手风琴模式
- 侧栏包含笔记库信息、查找、收藏和文件四个可折叠分区;最近文件通过“文件 → 打开最近文件”访问。
- 相邻分区在后一个分区的标题上沿显示清晰的水平分隔线,展开或折叠时均保持可见,且不占用额外高度。
- 默认启用“侧栏手风琴模式”,也允许手动将全部分区收起。
- 展开固定高度分区时,只收起其他固定高度分区,动态高度分区保持原有展开状态。
- 展开动态高度分区时,自动收起其他分区。
- 首次使用默认展开文件分区;恢复旧状态时,单个展开分区保持不变。
- 固定高度分区与动态高度分区可同时恢复展开;多个动态分区展开时优先保留文件分区, 否则保留侧栏顺序中的第一个动态分区。
- 历史最近文件分区的展开状态不再参与显示,最近文件记录保持不变。
- 设置中的“侧栏手风琴模式”可关闭互斥折叠,允许多个分区同时展开。
- 关闭后保留当前展开状态;重新开启时保留固定分区,并优先保留最近展开的动态分区。
- 保存设置后立即应用到各窗口,模式选择参与账号用户设置云同步。
- 各分区的实际展开状态仍按笔记库保存在本机,不随账号同步。
- 查找分区包含查询、替换和搜索结果;折叠不会清空输入或结果。
- 执行查找或替换命令时自动显示侧栏、展开查找并聚焦输入框。
- 执行文件定位时自动展开文件分区。
- 笔记库信息保持自身内容高度;查找、收藏和文件为动态高度分区。
- 手风琴模式下,展开的动态分区填满剩余高度,不显示高度分隔条。
- 非手风琴模式初始沿用原有高度分配;相邻已展开的动态分区之间显示水平分隔条。
- 拖动分隔条时,上下两个分区等量增减,其他分区高度保持不变,整体不超出侧栏可用高度。
- 拖动方式与侧栏宽度、编辑与预览比例的分隔条一致;按下时记录实际尺寸,再按指针位移计算。
- 分隔条支持 Tab 聚焦,向上或向下方向键每次调整 10px,配合 Shift 每次调整 40px。
- 标题保持可见,动态内容区正常至少保留 48px;内容超出后内部滚动,查找输入区域保留在顶部。
- 调整后的内容区首选高度按笔记库保存在本机,切库和重启后恢复,不参与账号同步。
- 折叠释放空间但保留记忆高度;重新展开后在可用空间内恢复。
- 窗口缩小时临时压缩,放大后恢复,不覆盖记忆高度;极小窗口允许内容区低于 48px。
- 切换手风琴模式不覆盖非手风琴模式的高度记录。
最近文件与收藏
- 支持最近文件、文件收藏和大纲收藏;大纲面板中每个标题右侧的星标及大纲右键菜单可收藏或取消收藏该标题。
- “文件 → 打开最近文件”按最近打开顺序显示当前笔记库的相对路径,重复打开会移至首位。
- 列表为空或当前窗口没有笔记库时显示不可用的“暂无最近文件”。
- 文件打开、重命名、删除、恢复和笔记库切换会更新列表;多窗口菜单使用当前焦点窗口的记录。
- 每项对应稳定命令
file.openRecent.<encodeURIComponent(相对路径)>,命令面板可搜索“打开最近文件”及路径。 - 原生菜单与命令面板使用同一打开流程和可用性检查;文件无法读取时沿用现有错误提示。
- 长中文路径对应的命令也可正常保存在命令历史中。
- 每个笔记库最多保存 20 个最近文件和 100 个文件或大纲收藏,收藏记录包含类型、路径、定位信息及毫秒时间戳。
outline.toggleFavorite命令可从命令面板执行,默认按Alt+F切换光标或大纲焦点所属标题的收藏状态;光标位于首个标题之前时不执行收藏。- 收藏记录类型、所属文件、大纲身份、收藏时的位置和收藏时间。
- 打开收藏时,先按最新正文中的标题、层级和同名序号动态计算大纲行号。
- 精确身份失效时,直接跳转到收藏时记录的源码行,不会猜测附近标题。
- 收藏目标会覆盖标签页原有阅读位置;预览渲染完成后不会跳回旧位置。
- 默认按文件组织;同一文件的大纲收藏按文档顺序缩进展示在文件下。
- 每次打开收藏区“整理”都会先把所有精确匹配大纲的最新行号自动写回收藏,再列出无法精确匹配的失效收藏;
- 已打开文档使用包含未保存修改的最新正文,其他文档读取磁盘内容。
- 大纲使用与编辑器章节高亮相同的归属规则:记录行不是标题时取其前方最后一个、也就是当前最深层的所属标题;
- 记录行位于首个标题之前或文件无法读取时只能取消收藏。
- 可逐项或勾选、全选后批量更新,更新会写入重新计算的 title、层级和同名序号并保留原收藏时间;
- 更新到已有收藏身份时自动移除失效的重复项。
- 整理列表支持双击详情跳转,跳转前关闭面板且不让焦点恢复覆盖目标位置;
outline.organizeFavorites命令仅在当前笔记库有大纲收藏且没有模态窗口时可用,可自定义快捷键。 - 收藏区“时间”按钮按“时间降序 → 时间升序 → 按文件组织”循环切换,首次点击优先显示最新收藏;时间方向和文件组织状态统一写入仓库 UI 数据并按笔记库恢复。
- 按时间展示收藏时,首行显示文件名或大纲标题,第二行统一显示仓库相对路径和收藏时间;大纲收藏前显示不受样式表字符集影响的箭头标记。
文件快速打开
Ctrl/Command+P打开文件快速打开面板;普通查询按文件名或相对路径模糊、多词匹配,空查询优先显示最近文件。标题查询与限定语法见大纲快速打开。- 输入
>切换到命令面板;两套面板支持通过各自快捷键切换并保留搜索正文,详见命令面板。 - 按 Esc 或点击面板外部关闭并恢复原先的焦点和选区;外部点击只关闭面板,不执行底层操作。
- 输入中未闭合的限定值引号按当前内容即时匹配;文件名、标题和路径中的匹配字符以亮蓝色粗体标出,全拼和拼音首字母命中时高亮对应汉字。
- 面板支持方向键、
Enter和Escape;确认打开时保存非空查询,最近 50 条去重历史保存在本机 Local Storage。历史快捷键可配置,普通↑↓仍选择结果。 - 关闭 Quick Open 会恢复原 CodeMirror 或输入框的焦点、光标、选区方向和编辑器滚动位置。
- 确认结果时,先恢复输入位置,再由目标打开或跳转设置新位置。
- 输入法组合期间,
Enter与方向键仍交由输入法处理。
- 使用方向键切换结果不会带动编辑器或预览滚动。
- 工作区状态保存在 Electron
userData/workspace-state.json,使用原子写入;笔记正文和附件仍在用户选择的普通文件夹中。 - 顶层
localSettings保存仅本机使用的配置,其中所有值均不参与账号偏好同步。- 热键总开关使用
localSettings.hotkeysEnabled,默认启用。 - 不读取或迁移旧位置的开关值。
- 设置层统一负责本地配置的加载、保存及窗口间广播;快捷键文件模块只读取开关并应用热键注册。
- 初始化、对话框修改和其他窗口的本地设置广播,均通过
applySettings更新 runtime store。 - 热键对话框与 Quick Cmd Form 的
h命令直接调用WorkspaceStateStore.updateLocalSettings,复用现有设置队列及save();保存失败时保留开关及热键注册状态。 - IPC 只订阅已提交的本地设置变更并广播,不维护额外保存函数或队列。
- 热键总开关使用
6.5 失效链接检查
- 侧边栏“检查链接”可批量扫描当前仓库中已保存的全部 Markdown 文件;同一功能也作为
workspace.checkBrokenLinks命令显示在命令面板和快捷键设置中。 - 检查普通 Markdown 链接、图片、引用式链接以及原始 HTML 的
href/src,并忽略代码围栏和行内代码中的示例文本。 - 检查相对路径、仓库根相对路径、URI 编码路径、Markdown 标题锚点和原始 HTML 的
id/name锚点。 - 报告区分目标不存在、目标无法读取、标题不存在、路径越界和符号链接逃逸,并高亮失效目标;双击文件标题或问题行可打开源文件并定位到对应行。
- 报告使用只读临时标签页,同一窗口内再次检查会刷新原报告,不创建重复标签;报告不会进入会话恢复记录。
- 检查以磁盘中已保存的正文为准;存在未保存编辑时,应先保存再运行以获得最新结果。
- HTTP、HTTPS、邮件和其他带协议的链接不会发起网络请求,统一计入报告中的“已跳过外部链接”。
- 单次最多显示 10,000 个失效链接;达到上限时报告会明确标记结果已截断。
引用查找
- 标签、文件树 Markdown 项和命令面板提供“查找文件引用”“查找当前标题引用”。
Shift+F12查找光标所属标题;光标位于首个标题之前、没有标题或文件未打开时回退为文件查找。- 未保存新文档、库外文件、文件夹和搜索报告不提供此命令。
- 扫描当前仓库文件清单中的 Markdown;文件查找包含指向任意标题的链接,标题查找只统计解析到该标题的链接,包括同文件锚点、中文与编码地址、重复标题的唯一锚点。
- 支持 Markdown 行内链接、引用式链接和 HTML
href;不统计图片、外部 URL 或代码中的链接。已打开文件使用未保存正文,其余文件读取磁盘,不强制保存。 - 复用独立只读的“引用查找”标签,按文件展示引用次数、行号和源码片段,同一行的多个引用分别计数。单击不跳转,双击跳到来源行并支持前进、后退;“刷新引用”重新读取内容,结果不会随输入自动更新。
- 最多返回 10,000 处引用并在超限时提示截断;单文件读取失败后继续扫描并标明结果不完整。关闭报告、切换仓库或开始新查询后,旧请求不会覆盖当前报告。
- 引用查找结果页支持
F4下一处、Shift+F4上一处,首尾循环;文件标题不参与遍历,同一行的多个引用逐项访问。- 双击引用行后继续从该引用遍历;跳到源文件后保留引用页作为导航来源,已有未保存内容保持不变。
- 工具栏显示当前序号、总数和来源位置,并高亮当前引用;刷新、关闭或空结果沿用搜索结果页的定位与回退规则。
- 引用跳转保持定位到来源行,不选择链接文本。
npm run test:smoke:references验证引用查找及失效链接报告流程,并覆盖引用结果的双向遍历、循环、重复引用及刷新。
6.6 仓库详情
- 笔记库菜单的“用 VS Code 打开当前仓库”会新建 VS Code 窗口打开当前仓库根目录,不沿用现有窗口;切换仓库后使用新的仓库路径。
- “用 VS Code 打开当前仓库”作为
workspace.openInVSCode命令显示在命令面板和快捷键设置中。- 默认快捷键为
Alt+Shift+V,可修改或添加多个自定义快捷键。
- 默认快捷键为
- 此功能需要安装 VS Code 并注册
vscode://协议,无需配置code命令的 PATH;未打开仓库或系统报告启动失败时显示错误提示。 - 侧边栏“刷新”旁提供“仓库详情”入口。
- “仓库详情”后提供当前仓库的同步快捷按钮;同步期间按钮显示加载状态并禁止重复操作,完成后通过非阻塞通知反馈结果。
- “切换仓库后仍自动同步”和“安全的自动同步”两个独立仓库级开关位于侧边栏仓库操作区,无需打开同步中心即可配置。
- 仓库详情显示以下信息:
- 当前仓库的本地名称与路径;
- 同步身份与账号;
- 本地和远端 Markdown 数量;
- revision 与 cursor;
- 同步状态和时间。
- 可为本地仓库设置独立的显示名称;侧边栏、最近仓库和仓库详情统一使用该名称,磁盘上的根目录文件夹名与路径保持不变。
- 本地及远端仓库改名保留 80 字符限制;空白或保存失败显示字段提示并保留弹窗输入。
- 修改仓库名称时保留以下数据:
.mynote元数据;- 最近文件;
- 收藏;
- 后台同步设置;
- 已打开标签。
- 可在应用内二次确认后,将当前仓库从最近仓库列表中移除。
- 移除仓库时删除
.mynote中除workspace.lock外的元数据,但不删除 Markdown 等笔记文件。- 保留
.mynote目录及空锁文件,防止删除期间其他实例绕过独占锁;完成后释放占用。
- 保留
- 若元数据删除失败,仓库保留在列表中以便重试。
- 大纲索引保存在
.mynote/outline-index-v1.json,记录文件修改时间、大小、标题层级和源码行号。 - 笔记库 IPC 按请求来源窗口选择对应的笔记库管理器;没有对应管理器时请求会报错。
- 大纲索引状态由各窗口的笔记库管理器通知所属窗口,避免其他窗口收到该仓库的进度。
- 页面或主渲染帧销毁、主帧脱离页面树时跳过进度通知;窗口关闭后解除监听,避免向已释放的帧发送消息。
- 启动或切换仓库后在后台按修改时间增量校验大纲索引;侧栏“重建索引”可强制重新解析全部受管理 Markdown。
- 普通刷新也会按文件修改时间和大小增量校验索引;后台变化会原位刷新已打开的全库大纲查询并尽量保留选中项。损坏或未知版本的索引会保留诊断副本后重建;该缓存可删除、可重建,不参与同步。
- 本地目录不存在时通过非阻塞通知明确提示。
- 本地目录不存在时移除对应的最近仓库记录。
- 不继续读取失效仓库的同步状态。
- 失效仓库处理不会影响 Windows 仓库下拉框继续操作。
- 仓库 ID 不属于当前账号与服务地址时明确提示,不继续读取失效身份的同步状态。
6.7 仓库切换与同步缓存
- 成功克隆仓库后,同步中心自动关闭。
- 克隆完成后,以非阻塞通知显示克隆位置。
- 克隆完成后,将焦点移到仓库下拉框,避免 Windows 原生对话框阻止仓库选择器展开。
- 同步客户端缓存按路径、账号或服务、设备和仓库 ID 隔离。
- 同步客户端在创建时启动一次初始化;读取同步状态前等待该次初始化完成,后续操作复用同一状态。
- 仓库身份变更后,不会把旧仓库的 cursor 或状态显示到新身份上。
- 读取仓库详情期间身份发生变更时,明确报告错误。
6.8 基础设置
- 设置编辑器字号。
- 字号范围为 12–24 px;笔记库 Markdown 文件上限也可在设置中调整。
- 设置单击文件时是否启用预览标签;关闭后文件树与搜索结果单击均直接打开普通标签。
- 搜索标签页的临时面板布局不会覆盖按笔记库保存的侧栏、大纲和按文档页面保存的视图选择。
- 可设置外部冲突工具的可执行文件绝对路径和参数模板;模板支持
%local、%remote、%base、%merged,替换后作为独立参数直接启动,不经过 shell。 - macOS 上的 Beyond Compare 应使用
/Applications/Beyond Compare.app/Contents/MacOS/bcomp。- 已有配置指向同目录
BCompare时会自动改用bcomp。
- 已有配置指向同目录
- 普通设置跨窗口共享并在保存后立即应用;点击“取消”丢弃未保存的表单修改。
- 按
Escape时,有未保存修改会先确认如何处理;可选择“保存修改”“放弃修改”或“继续编辑”。 - 选择“继续编辑”或再次按
Escape保留修改。 - 设置窗口保持打开时,后台刷新或其他窗口保存不会覆盖当前表单。
7. Markdown 编辑与预览
7.1 编辑与渲染
选区与编辑命令
- 在可编辑 Markdown 文档中选中文字后,编辑区选区旁显示悬浮格式工具条;取消选区、切换标签、隐藏编辑区或进入只读状态时关闭。
- 工具条优先显示在文字上方;靠近编辑区顶部、上方空间不足时显示在文字下方,避免遮挡标签栏。
- 编辑器聚焦且有文字选区时,按
Esc取消选择,光标保留在选区的活动端,编辑器保持聚焦;只读文档也支持。
- 工具条提供正文及 1–6 级标题、引用、列表、粗体、斜体、删除线、链接、行内代码和代码块。标题只处理单行;引用和列表处理选中的完整逻辑行;行内格式再次点击可移除标记。
- 链接通过应用内对话框填写链接文本和地址,打开时默认聚焦并选中链接文本。
- 普通选区自动回填文本;选中 URL 时也回填地址。
- 选中完整 Markdown 行内链接、其文字或地址时,自动回填原有文本与地址并替换原链接。
- 选区附带的空白和换行留在链接之外。
- 格式修改参与文档撤销、未保存状态和实时预览更新。
- 选区格式操作也可从命令面板执行,并在快捷键设置中自行绑定。
- 列表和代码块沿用已有命令,其余操作提供独立命令。
- “插入链接”在可编辑 Markdown 文档中始终显示;无选区时可手动输入文本和地址并在光标处插入。
- 链接文字和地址去除首尾空白后均须非空;字段错误保留原输入,按钮与 Enter 行为一致。
- 地址继续支持相对路径与页内锚点;不要求为绝对 URL。
- 其他新增格式命令需有选区;已有的列表命令仍可处理光标所在行。
- “修改错别字”命令
editor.proofreadSelection可从编辑菜单或命令面板执行。- 命令将当前选中文本发送给 DeepSeek,修改错别字并补充必要的标点符号。
- 返回结果有变化时,应用逐行和行内差异高亮的确认弹窗;用户确认后才替换原选区。
- 返回结果没有变化时只显示通知,不打开弹窗。
- DeepSeek 响应前原文已发生变化时不会覆盖新内容。
- “切换列表”命令
editor.selectionToList有选区时处理选中的完整逻辑行,无选区时处理光标当前行。- 目标行全部带
-时统一移除,否则为未带标记的行补上-。 - 默认快捷键为
Alt+Shift+L,编辑菜单同步展示,可在快捷键设置中修改。
- 目标行全部带
- “插入 fenced code”命令
editor.wrapFencedCode可从插入菜单或命令面板执行,默认无快捷键。- 只包裹选中文字,必要时补齐围栏前后的换行;内容含反引号时自动使用更长的围栏。
- 无选区时在光标处插入空代码块,并将光标置于围栏内。
- 操作后保留原文选区,支持一次撤销;只读文档不可执行。
- “整体提升大纲级别”和“整体降低大纲级别”命令可从编辑菜单或命令面板执行:
- 命令 ID 分别为
editor.promoteHeadingLevels、editor.demoteHeadingLevels。 - 两者处理选区触及的完整逻辑行,将其中每个 Markdown 标题整体升降一级。
- 选区内存在一级标题时不执行整体提升,存在六级标题时不执行整体降低,避免部分修改标题层级关系。
- 命令 ID 分别为
路径代码片段
- Quick Cmd Form 的
Code Snippet Paste可将来源选区直接采集为此格式,随后使用同一组检查、整理和比较命令。 - 从工具 → 代码片段、命令面板执行以下命令;默认无快捷键,可在快捷键设置中绑定。
editor.checkCodeSnippets:检查代码片段。editor.collateCodeSnippets:整理代码片段。editor.compareCodeSnippets:比较代码片段。editor.convertCodeSnippets:转换老格式代码片段。- 仅在可编辑的 Markdown 笔记有选区且没有打开对话框时可执行。
- 将完整位于选区内的
<--cs_begin、下一行路径、代码正文、--cs_end>转为路径围栏代码块。 - 标记须独占一行;保留代码缩进、内部分隔符、注释标记及片段之间的文字,正文换行统一为 LF。
- 正文含反引号时自动加长围栏;不读取或修改对应源文件,也不要求先保存笔记。
- 选区外及选区边缘不完整的片段保持原样;无完整片段时提示,完整片段路径无效时不应用转换。
- 一次撤销可恢复整个转换操作;不会自动转换全文。
- 插入菜单提供“插入代码片段注释标示”,命令面板使用同名命令
editor.insertCodeSnippetComment。- 默认快捷键为
Alt+I,可在快捷键设置中修改。 - 在当前光标位置依次插入
//.,,、一个空格和一个换行符,光标移到换行之后;有选区时在选区的光标端插入,保留选中文字。 - 仅在可编辑的 Markdown 笔记且没有打开对话框时可执行;一次撤销可恢复插入前的内容。
- 默认快捷键为
- 使用反引号围栏,路径紧接在开始围栏后,正文从下一行开始。
- 示例:开始行为
```C:\Users\Administrator\AppData\Local\Temp\file-sizes.txt,结束行为```。 - 路径可以包含空格、中文;支持绝对路径,以及
./、../或含目录分隔符的相对路径。 - 相对路径以当前笔记目录为基准,未保存笔记需要先保存才能使用相对路径。
- 无目录的相对文件名请写成
./file.txt,避免与普通代码块语言标签混淆。 - 仅处理顶层路径代码块;列表、引用中的围栏和普通语言代码块不参与操作。
- 检查、整理、比较不识别旧的
<--cs_begin/--cs_end>外层格式,需先选中并执行转换命令。
- 示例:开始行为
- 内部标记沿用 FindHelper 的规则。
- 单独一行
<===cs_sep===>分隔同一文件的多个片段。 - 包含
//.,,的整行不参与源码匹配或比较,整理时保留并随所属片段移动。 - 其他行仍按源码处理,注释标记不会让后续整段内容变成注释。
- 单独一行
- 检查和整理在有选区时只处理完整位于选区内的代码块;无选区时处理全文。
- 源文件按 UTF-8 读取,匹配前统一换行并去除各片段首尾空白。
- 每段必须在源文件中完整出现;失败时选中并滚动到对应片段,显示原因。
- 文件缺失、读取失败、路径代码块未闭合或没有可处理代码块时显示提示。
- 整理先完成全部检查,再按解析后的路径合并同文件片段。
- Windows 路径分组不区分大小写;其他平台按大小写区分。
- 按源码首次匹配位置稳定排序,使用内部分隔符连接;同组沿用首个代码块的路径写法。
- 整理结果放在第一个被处理代码块的位置,其他笔记文字保持原样。
- 正文含反引号时自动加长围栏,避免截断代码。
- 一次撤销可恢复整个整理操作;只读文档不可整理。
- 等待期间切换文档、变更路径或正文后,放弃过期结果并提示重试。
- 比较处理光标所在的路径代码块,不要求片段与源文件一致。
- 排除内部标记后将片段正文写入保留源文件扩展名的 UTF-8 临时文件,复用 VS Code 文件比较能力。
- 不修改源文件;VS Code 不可用时显示错误。
- 临时文件保存在应用用户数据目录的
code-snippet-diffs子目录,下次应用启动时清理。
- 预览标题显示完整文件路径,保留代码显示和复制按钮;预览本身不会读取源文件。
编辑器右键菜单
- 正文编辑器支持鼠标右键菜单,也可在编辑器聚焦时按
ContextMenu或Shift+F10打开。- 鼠标打开时菜单显示在点击位置附近。
- 键盘打开时菜单显示在当前光标附近。
- 菜单位置自动限制在窗口可视范围内。
- 标准编辑操作包括撤销、重做、剪切、复制、粘贴、粘贴为纯文本和全选。
- 撤销与重做使用当前标签独立的 CodeMirror 历史。
- 有选区时,剪切和复制处理选中文字。
- 无选区时,剪切和复制沿用快捷键行为,处理光标所在的完整逻辑行。
- 空文档禁用剪切、复制和全选;没有对应历史时禁用撤销或重做。
- “粘贴为纯文本”只读取剪贴板文本,在菜单打开时的选区插入,不转换 HTML,也不下载图片。
- Markdown 操作包括粗体、斜体、删除线、链接、行内代码、引用、列表和代码块。
- 粗体、斜体、删除线、行内代码和引用需要选区。
- 链接、列表和代码块可在没有选区时使用;链接打开应用内链接对话框,列表处理当前行,代码块在光标处插入空围栏。
- 操作复用选区工具栏的转换规则,并保留菜单打开时的选区;正文在执行前发生变化时不会套用过期操作。
- “下载外部图片”处理选区内的 HTTP/HTTPS Markdown 图片;没有选区时处理当前文档的全部外部图片。
- 重复地址只下载一次,成功的图片保存到文档同级
assets/并替换对应地址;失败的地址保持原样。 - 进度显示已处理、总数、成功和失败数量。“终止”会停止当前请求及后续下载,保留已完成的结果。
- 结束时提示成功、失败和未处理数量。任务期间文档变化时,不覆盖新正文。
- 重复地址只下载一次,成功的图片保存到文档同级
- 编辑器右键菜单提供“清理资源”,仅对已保存到当前笔记库的可编辑 Markdown 笔记可用。
- 有正文选区时,只清理引用语法完整位于选区内的资源;无选区时,清理当前文档引用的全部资源,不扫描未引用附件。
- 使用当前编辑器内容,包含尚未保存的修改;引用式链接可使用选区外的全文定义。
- 支持图片、音频、视频、普通附件链接和 HTML 媒体引用;代码中的伪引用不会作为资源处理。
- 仅处理笔记库内现存的非 Markdown 附件文件,跳过网络地址、库外路径、目录、保留目录和符号链接附件。
- 同一资源的重复引用只处理一次;清理前通过应用确认弹窗列出数量和相对路径,取消不会删除资源。
- 资源移入系统回收站,正文引用保持不变;共享资源也会删除,其他笔记中的引用将失效,确认弹窗会说明这一点。
- 确认期间正文、文档路径或笔记库变化时取消操作,需重新执行;没有可清理资源时显示提示。
- 一次清理作为一组文件树撤销/重做历史,编辑器撤销仍仅处理正文修改。无法定位系统回收站记录的资源不能通过文件树撤销恢复。
- 部分失败时列出完成数量、失败路径和原因,成功项仍可撤销。
- 只读编辑器仍可打开菜单,并保留焦点、选区、复制和全选。
- 只读时关闭编辑区的原生输入能力,避免中文输入法候选工具条随按键反复闪现。
- 恢复可编辑状态后重新启用原生输入,不切换系统输入法或影响其他输入框。
- 撤销、重做、剪切、粘贴、粘贴为纯文本及全部 Markdown 操作均禁用。
- 菜单中的粘贴调用 Electron 原生编辑命令,并继续进入现有编辑器粘贴事件链。
- 剪贴板含 HTML 时,按标题、段落、强调、链接、列表、引用、代码块、表格和图片等规则转换为 Markdown;纯文本中的 HTML 标签保持原样。
- 每次粘贴检查“不转换 HTML 的剪贴板类型”列表,匹配任一类型且有非空纯文本时,优先粘贴原始纯文本,保留代码缩进、换行及 Markdown 语法,不转换高亮 HTML 或导入图片。
- 所有用户默认包含
vscode-editor-data,未配置此列表的现有用户也使用该默认值。 - 设置页支持每行填写一个类型,可添加、删除或清空列表;清空后取消过滤。
- 来源标记存在但没有非空纯文本时,仍沿用 HTML 与图片粘贴流程。
- 无法识别来源的 IDE 可使用右键菜单中的“粘贴为纯文本”。
- 所有用户默认包含
- HTML 同时含正文和图片数据时优先保留完整正文;没有有效 HTML 时沿用单图粘贴。应用内跨目录 Markdown 图片路径调整保持原有行为。
- HTML 中的 HTTP/HTTPS 图片与
data:image图片会尝试保存到当前文档同级的assets/,重复地址只保存一次;相对地址保持原值。 - 每次粘贴最多导入 20 张图片,单张图片上限为 10 MB,网络请求 15 秒超时。
- 图片下载失败时仍粘贴正文,保留失败图片的原地址并提示数量。未保存文档取消选择保存位置时,也会粘贴正文并保留图片原地址。
- 默认在每次 HTML 粘贴转换时显示 Toast:“检测到 HTML 格式内容,正在尝试转换为 Markdown。”
- 每次粘贴都检查当前用户配置;普通文本、IDE 原文及应用内 Markdown 粘贴不显示此提示。
- 点击 Toast 或其下方的“查看更多”按钮,打开自定义确认对话框,选择“不再提示”“继续提示”或“转到设置”。
- “禁用转换”关闭 HTML 自动转换,从下次粘贴起优先保留纯文本,不再显示转换提示。
- 设置页提供默认启用的“启用 HTML 转 Markdown”,可重新开启自动转换;该开关与提示开关独立。
- 取消勾选时,下方的转换提示开关和类型过滤列表立即禁用并变灰;重新勾选后恢复可编辑。
- 禁用不会清空提示偏好或类型列表,取消设置修改后恢复已保存的状态。
- 禁用转换后不导入 HTML 内嵌图片;纯图片剪贴板仍沿用图片插入流程。
- “转到设置”打开设置页并聚焦“粘贴 HTML 时显示转换提示”,该选项默认启用,可重新开启或关闭。
- 提示偏好保存在本机应用配置中,跨窗口生效,重启后保留;不影响 HTML 自动转换与图片处理。
- 对话框为当前剪贴板中除
text/plain、text/html外的每个附加类型分别显示“该类型不转换”按钮;浏览器的Files条目指示器不作为类型选项。 - 点击类型按钮将其追加到过滤配置中,不关闭转换提示;从下次粘贴起生效,多个窗口同时追加也保留各自的选择。
- 图片下载失败仍显示独立的失败提示,并保留原地址。
- HTML 粘贴作为一次编辑,可用标准撤销与重做快捷键恢复。
- 实现调用链与边界见 HTML 粘贴与图片本地化实现。
- 菜单打开后自动聚焦第一个可用操作。
↑、↓在可用操作间循环移动。Home、End分别移动到第一个和最后一个可用操作。Enter或空格执行当前操作。Escape或Tab关闭菜单并恢复编辑器焦点和选区。
- 点击菜单外部、滚动编辑器、切换标签、调整窗口大小或窗口失焦时关闭菜单。
Markdown 渲染
- 在编辑区输入 Markdown 时实时刷新预览。
- 支持 GitHub Flavored Markdown。
- 源码中的换行会显示为预览换行。
- 支持标题、列表、引用、代码块、表格、链接和图片等常用 Markdown 内容。
- 带语言标识的预览代码块使用 Highlight.js 完整内置语言及别名目录进行语法高亮;未标识语言时自动识别,无法识别或显式语言未知时安全显示为纯文本。
- 路径代码块优先用文件扩展名匹配语言及别名,例如围栏后的
E:\uninote\mynote-client\src\main\quick-cmd-form.ts识别为ts,正文只有...时也适用。 - 预览顶部同时显示识别出的类型和完整路径;无法匹配扩展名时保留正文自动识别及路径显示。
- 路径代码块优先用文件扩展名匹配语言及别名,例如围栏后的
- 预览中的 fenced code block 顶部展示语言类型,并提供复制纯代码文本的按钮;按钮会就地反馈复制成功或失败。
- 仅主窗口预览页 fenced code 正文使用字体序列
Menlo, Monaco, Consolas, "Courier New", monospace;代码块工具栏、行内代码、缩进代码块、HTML 发布及文档导出沿用原有字体。 - 英文、空格使用等宽字体;中文和框线字符的宽度取决于系统实际字体及回退字体,图示需按该字体的字符宽度排版。
- 仅主窗口预览页 fenced code 正文使用字体序列
- 单个预览代码块超过 102,400 个 UTF-16 单元时跳过语法分析并保留代码展示,避免实时预览被超大代码块阻塞。
- 支持 Mermaid 流程图等图表。
- 使用
```mermaid围栏书写图表定义,预览区会实时渲染。 - 流程图节点使用原生 SVG 文字,并按完整行宽度排版。
- 窄预览区中的流程图支持横向滚动。
- 长中文与无空格文件路径不会被截断或缩小。
- Mermaid 语法错误会在图表位置显示提示。
- Mermaid 会自动恢复由
display:none隐藏路由节点引发的连线定位错误,并保持这些节点不可见。 - 预览面板隐藏时会延后 Mermaid 的几何布局,重新显示后再渲染,避免应用重启恢复隐藏布局时出现连线定位错误。
- 已完成的标签页预览会保留其 DOM;切换回未修改的标签时直接恢复原预览,避免 Mermaid 重绘造成闪烁和晃动。
7.2 链接
- 编辑器源码中的链接支持使用
Ctrl+单击(macOS 为Command+单击)激活。 - 预览中的链接支持普通单击激活。
- 跨文档标题链接在目标预览已缓存时仍会定位到对应标题。
- 当前文档标题链接会跳到对应标题。
- 相对 Markdown 链接会打开库内或当前文档旁的目标文件,并支持继续定位标题。
- 源码链接会将目标行稳定定位到编辑区顶部,且不会被目标标签尚未完成的旧视图恢复覆盖。
- Markdown 文件及标题链接跳转会加入编辑器导航历史。
Alt+Left返回来源位置,Alt+Right前进到最终文件与标题,不产生文件顶部的中间历史位置。- Windows 上完成上述导航后松开
Alt,焦点仍留在编辑区域,不会转移到原生菜单。 - 历史位置通过正文行及相邻行锚点动态解析,目标前方发生编辑后仍能恢复正确位置。
- HTTP、HTTPS、邮件和 Codex 链接在系统外部目标中打开,并使用安全的链接关系属性;其他协议不会执行。
Codex 深层链接
- 编辑区和预览区都可激活 Markdown 链接或裸露的
codex://地址。 - 链接经校验后交由系统协议处理器打开 Codex;在 Windows 上等同于在“运行”中输入并执行该地址。
- 选中
codex://地址插入链接时,对话框会自动回填链接地址。
7.3 编辑器显示
- 正文编辑器使用 CodeMirror 6,提供 Markdown 源码语法高亮、虚拟化渲染和每个标签独立的编辑历史。
- 正文编辑器、行号、查找高亮层、链接定位层和差异视图沿用
"Cascadia Code", Consolas, monospace字体序列。 - 1–6 级标题使用分别配色且加粗的可区分标题样式,同时保持源码行高一致。
- 带语言标识的围栏代码块按对应语言高亮。
- 支持 JavaScript、TypeScript、Python、Java、C/C++、Go、Rust、HTML、CSS、JSON、SQL、Shell 等常用语言及其别名。
- 路径围栏也可按文件名识别语言,例如
E:\uninote\mynote-client\src\main\quick-cmd-form.ts使用 TypeScript 高亮,并按需加载语言模块。
- 正文编辑器、行号、查找高亮层、链接定位层和差异视图沿用
- 大文件正文超过 524,288 个 UTF-16 单元时暂停源码语法配色,缩小后恢复;正文与预览仍可使用。
- 正文仍为普通 Markdown;预览仍走既有 Markdown 渲染链路。
- 编辑命令通过 transaction 提交,外部整体重载清空历史,保存和切换标签保留历史。
- 编辑区查找、报告命中、标题区间和差异行使用编辑器装饰层。
- 中文等输入法组合输入期间更新高亮时,保持各源码行完整显示,避免编辑区后续内容消失。
@codemirror/view使用包含输入法组合输入 DOM 复用修复的6.43.14补丁版本。
- 编辑区左侧显示源码行号。
- 输入、切换文档和纵向滚动时实时同步行号。
- 长行保持为单行并可横向滚动,确保行号与源码行准确对齐。
- 编辑区正文使用文本插入光标,横向和纵向滚动条及其交角使用常规箭头光标。
- 使用清晰的蓝色背景和左侧强调线高亮光标当前行,行号区域同步高亮;当前行位于所属章节底色内时仍优先显示,并在移动光标、滚动和切换文档时保持准确定位。
7.4 页面内查找
- 编辑区和预览区均支持类似 VS Code 的页面内查找。
Ctrl/Command+F在最近使用的内容区打开浮动查找栏。- 聚焦查找框时保留当前阅读位置。
- 每次重新聚焦编辑区查找框,都会按编辑器当前 caret 重新计算当前匹配序号,不移动 caret 或滚动位置。
- 编辑区查找框文本变化时,也会按当前 caret 重新计算匹配序号。
F3/Shift+F3每次从最新 caret 或选区重新计算目标匹配。- 查找栏显示当前匹配序号和总匹配数,并支持循环定位;编辑区切换到已完整显示在当前视图中的上一个或下一个匹配时保持滚动位置不变。
- 预览查找框保持打开且存在结果时,继续编辑会刷新结果高亮,同时保留编辑区和预览区的当前滚动位置。
- 编辑区与预览区均以深色文字高亮全部搜索结果,并以独立颜色突出当前匹配;焦点离开查找框后继续保留高亮。
- 编辑器使用醒目标记持续显示当前结果,并准确跟随中英文混排内容。
- 导航结果或缩放页面时,自动横向和纵向滚动以露出完整命中词。
- 使用
Enter、Shift+Enter或F3前后导航。 - 使用
Alt+C切换是否区分大小写。 - 使用
Escape关闭查找栏。
7.5 编辑与预览面板
编辑与预览布局
- 通过工具栏的“编辑”和“预览”按钮分别显示或隐藏编辑区与预览区。
- 文档视图可按
Ctrl/Cmd+Shift+V在编辑、并排和预览之间循环切换。 - 仅显示编辑区或预览区时,可见界面自动占满两者的可用空间;窄窗口上下排列时同样填满可用高度。
- 恢复同时显示编辑区和预览区时,沿用此前保存的分栏比例。
侧栏分区聚焦
- “转到”菜单在“聚焦编辑器”前按侧栏顺序提供四个聚焦入口,命令面板和快捷键设置同样可用。
- 聚焦笔记库:
sidebar.focusRepository,无默认快捷键。 - 聚焦查找:
sidebar.findInFiles,无默认快捷键。 - 聚焦收藏:
sidebar.focusFavorites,Windows/Linux 默认Ctrl+Shift+Alt+F,macOS 默认Cmd+Shift+Alt+F。 - 聚焦文件树:
sidebar.focusFiles,Windows/Linux 默认Ctrl+Shift+E,macOS 默认Cmd+Shift+E。
- 聚焦笔记库:
- 四个命令显示侧栏、展开目标分区,并恢复该分区上次离开时的控件,包括标题、工具按钮、输入框和列表条目。
- 记忆按当前窗口及各笔记库分别保存在内存,切换笔记库后返回仍可恢复,关闭窗口后清空。
- 列表重绘后按条目身份恢复;目标已删除、隐藏或禁用时使用默认入口。
- 笔记库默认聚焦最近笔记库选择框;查找默认聚焦查询输入框;收藏默认聚焦首个可见条目。
- 文件树默认聚焦当前选中且可见的条目,否则聚焦首个可见条目;没有可用入口时聚焦分区标题。
- 遵循现有手风琴及布局保存规则。对话框打开时不可执行,除笔记库外的三个命令要求已打开笔记库。
- 聚焦只移动焦点,不打开条目、不改查询或替换区显隐、不带入编辑器选区,也不主动全选输入内容。
search.findInFiles保留独立的全文查找语义和原有Ctrl+Shift+F(macOS 为Cmd+Shift+F)快捷键。
编辑器聚焦
- 使用转到菜单、命令面板的“聚焦编辑器”或
Shift+Alt+E聚焦当前编辑区。- 编辑区隐藏时自动显示,并保留已显示的预览和大纲、原光标及选区。
- 快捷键可在设置中修改;应用内对话框打开时不会抢走焦点。
差异模式
- 工具栏和视图菜单提供“切换差异模式”,默认快捷键为
Alt+Shift+D。- 差异模式只作用于当前 Markdown 标签。进入后临时关闭预览与大纲,让编辑区占满文档区域并禁止编辑。
- 切换到其他标签时沿用各标签自己的模式;后台设置或工作区状态刷新不会重新打开预览。
- 退出后恢复该笔记库原有的面板显隐设置。
- 当前标签的差异模式随恢复会话持久化。
- 默认比较当前正文与最近保存正文;文件树已启用历史时间差异时,改用该历史版本作为旧版本。
- 修改行按“旧行、新行”紧邻显示;纯删除行仅显示旧行,纯新增行仅显示新行。
- 在差异模式内使用
Alt+N/Alt+P会以当前滚动视图为起点,直接滚动到下一处 / 上一处可见变化并标出当前变化;手动滚动后不会沿用之前记住的差异索引。 - 退出模式后,编辑光标保留在该变化对应的正文位置。
7.6 大纲面板
大纲显示与过滤
- 通过“预览”旁的“大纲”按钮显示标题大纲。
- 当前文件名显示为大纲根节点;即使文档没有 Markdown 标题,根节点仍可见。根节点不作为标题参与复制或收藏。
- 大纲顶部使用与文件树一致的图标按钮执行全部折叠、全部展开和复制。
- 逐个标题的展开箭头与标题按层级一起缩进,也可用左右方向键切换;上下方向键只经过可见标题。
- 双击根节点或标题文字可切换该节点的折叠状态,同时将焦点留在大纲。
- 右键根节点或标题可递归折叠、展开该节点及其子标题;根节点递归折叠时只显示文件名。
- 手动折叠状态在本次应用会话内随编辑和标签切换保留。
- 折叠或展开节点后,不会为了追踪编辑器当前标题而自动滚动大纲。
- 大纲过滤支持标题原文、全拼和拼音首字母,默认显示完整匹配路径。
- “仅命中”图标按钮高亮时仅显示命中标题;取消高亮后显示命中标题及其祖先节点,提示为“显示完整匹配路径”。
- 父标题命中不会自动显示未命中的子标题。手动折叠优先于过滤。
- 过滤文本与“仅命中/完整匹配路径”模式按页面独立保存,切换页面互不影响,重启后随页面会话恢复。
- 新页面默认不设过滤并显示完整匹配路径;未命名页面也随会话保存过滤设置。
- 过滤历史独立保存在本机,最多 50 条去重记录,可用上下方向键回看。
- 焦点位于大纲面板时,
Ctrl/Cmd+F聚焦并选中大纲过滤框中的查询;在编辑器或预览区仍打开页内查找。 - 大纲顶部可将当前可见标题复制为 Markdown 标题或按原始级别缩进的纯文本。全部折叠、全部展开、聚焦过滤框、切换过滤模式和两种复制操作也可从命令面板执行。
- 命令面板提供
outline.collapseBranch和outline.expandBranch,分别递归折叠、展开当前大纲节点。- 大纲节点获得焦点时操作该节点;从编辑器执行时优先操作大纲中当前高亮的标题,没有可见的高亮标题时操作文件名根节点。
大纲尺寸与导航
- 拖动大纲左侧分隔条调整宽度并按笔记库自动保存,重启后恢复;窄窗口上下排列时拖动上方分隔条调整高度,宽度与高度分别记录。
- 大纲分隔条支持 Tab 聚焦后用方向键调整,Shift 加方向键加大步长;隐藏大纲或切换到搜索标签页时同步隐藏分隔条。
- 激活大纲节点时,将对应源码定位到编辑区顶部。
- 大纲高亮跟随当前聚焦的内容窗格:编辑器聚焦时跟随光标行,预览聚焦时跟随预览滚动位置;高亮节点超出大纲视图时自动滚入可视范围。
- 编辑区隐藏时,激活大纲节点会直接定位可见的预览内容,并将焦点留在大纲。
- 双击大纲节点切换折叠状态时,焦点仍留在大纲。
- 使用转到菜单的“聚焦大纲”或
Shift+Alt+O直接打开并聚焦面板;Ctrl/Command+Shift+O用于切换大纲显隐。
大纲收藏
- 最近文件与收藏
- 大纲标题右侧星标、右键菜单和命令面板中的“切换当前大纲收藏”共享同一操作;默认快捷键为
Alt+F。 - 切换大纲收藏只原位更新星标,不重建大纲列表,保留大纲栏的滚动位置、焦点和当前高亮。
大纲快速打开
Ctrl/Command+P的 Quick Open 中,@搜索全库持久大纲,@!仅搜索已收藏的大纲,@@搜索当前编辑内容的大纲;- 选中文件或大纲结果后,按
Ctrl+Enter(macOS 为Cmd+Enter)可在当前可编辑的笔记库 Markdown 文档中替换选区并插入对应引用,不切换文件;普通Enter仍打开结果。 @!会按已打开标签的最新正文动态计算收藏大纲行号。- 结果按标题级别缩进,一级标题不缩进,之后每增加一级添加两个空格;
- 结果可直接打开文件并跳转到标题。
- 索引更新状态显示在底部固定提示栏,不会挤压或推动结果列表;
- 后台索引刷新时保留当前选择项。
- 选中文件或大纲结果后,按
- 文件、标题和路径搜索支持中文原文、无声调全拼、拼音首字母以及空格分隔的混合关键词。
- 可通过“工具 → 拼音搜索”或命令面板中的“切换拼音搜索”全局启用或禁用拼音匹配,默认启用;状态栏显示当前状态。该设置适用于快速打开、命令面板、快捷键设置和大纲过滤,并在重启后保留。
- 上述四处搜索框旁的“拼音”按钮也可切换同一设置;切换后当前搜索结果立即更新。
- 文件、笔记库、编辑、插入、视图、转到、工具等原生菜单中对应应用命令的快捷键跟随快捷键配置更新或移除。
- Windows 和 Linux 的单段快捷键显示在菜单右侧。
- 双段快捷键及 macOS 上的快捷键显示在菜单名称后。
- 搜索框按钮也显示当前拼音搜索快捷键,聚焦搜索框时可直接切换并更新结果。
- 文件及
@、@!、@@大纲 Quick Open 均支持限定搜索:p:按笔记库相对路径,f:按所属文件名。- 限定值为不区分大小写的连续子串;含空格时可用双引号包裹,例如
@p:"abc efg" f:plan 发布。 - 限定项可重复,与普通关键词共同组成“与”关系;只有限定项时最近文件优先。
- 全拼仅支持精确、前缀和连续子串匹配,不再按分散在多个音节中的字母进行跳字匹配,避免短关键词误命中无关结果。
- 中文原文和拼音首字母仍支持按字符顺序跳字的模糊匹配;纯英文名称也保留这一行为。
- 上述中文、拼音和模糊匹配规则同时适用于普通文件快速打开、
@全库大纲和@@当前文件大纲。
大纲导航设置
- 设置中可控制单击或按
Enter/Space激活大纲节点后,是否把键盘焦点转移到编辑器。 - 关闭焦点转移后仍定位源码,但焦点留在大纲中。
- “导航大纲时即时跳转”默认开启。
- 即时跳转开启时,使用方向键或
Home/End移动大纲焦点会同步定位源码。 - 即时跳转关闭时,需要按
Enter/Space才跳转。 - 大纲跳转按照未自动换行的源码行精确定位。
- 标题前的长行不会产生额外的纵向偏移。
7.7 滚动同步与源码高亮
- 编辑区和预览区拥有独立滚动条。
- 程序定位、预览重建和导航恢复产生的延迟滚动事件不会覆盖另一窗格的显式位置。
- 导航恢复期间忽略编辑器测量布局产生的中间位置;恢复完成后继续双向同步。
- 并排编辑时,每次预览重建后重新对齐编辑器的当前阅读位置,避免连续输入使编辑器发生滚动漂移。
- Mermaid 异步重绘产生的中间滚动不会反向移动编辑器。
- 两个区域按照 Markdown 源码块锚点双向同步,避免标题、列表、图片及换行造成长文档定位偏差。
- 编辑区滚动到底部时,预览仍对齐编辑区视口顶部对应的源码位置,不会强制滚到预览底部。
- 底部附近的源码块保留实际坐标;目标位置超出可滚动范围时,由目标窗格限制到可达位置。
- 预览区从隐藏状态首次打开时,会立即对齐编辑区的当前阅读位置,无需再次滚动或编辑。
- 移动编辑器光标时,预览区以浅蓝背景高亮对应的源码内容。
- 列表中的每个列表项独立匹配源码范围,只高亮光标所在的列表项。
7.8 设置窗口
- 设置可从原生菜单打开,默认快捷键为
Ctrl/Cmd+Shift+,。 - 普通设置在所有应用窗口间共享;任一窗口保存后,其他窗口立即应用最新设置,并在下次打开设置窗口时显示最新值。
- 点击“取消”关闭设置并丢弃未保存修改。
- 按
Escape时,如果表单与打开时不同,先显示“设置尚未保存”确认弹窗。- 选择“保存修改”复用“保存设置”的校验和保存流程,成功后关闭设置;保存失败时显示错误并保留草稿。
- 选择“放弃修改”关闭设置并丢弃修改;选择“继续编辑”或在确认弹窗中按
Escape返回设置并保留修改和焦点。 - 未修改,或所有字段均已改回打开时的值,直接关闭设置。
- 检查包括文本、数字、复选框、多行输入,以及被禁用但仍保留草稿的字段。
- 窗口保持打开期间,后台同步刷新或其他窗口保存设置都不会覆盖这些修改。
- 编辑快捷键时,按键录制/手动输入模式同时作用于通用键位和全部平台覆盖;录制内容写入当前聚焦的键位输入框。
- 通用快捷键可留空,只设置特定平台;至少需要一个有效键位。
- 输入模式按钮旁提供平台转换:Windows 将 Control 转为 Command 填入 macOS,macOS 将 Command 转为 Control 填入 Windows;优先读取当前平台覆盖,留空时读取通用键位,保存后生效。
7.9 剪贴板收集器
操作入口与共享状态
- 从主菜单 工具 → 剪贴板收集器,或命令面板中的“剪贴板收集器”打开控制面板。
- 菜单与命令面板统一执行
clipboardCollector.show,可在快捷键设置中绑定快捷键。 - 不再支持旧命令 ID
collector.show;已有自定义快捷键需手动更新,旧命令历史条目不能再执行。
- 菜单与命令面板统一执行
- 面板采用单行紧凑布局,目标显示笔记文件名;悬停可查看完整路径。
- 状态和错误在同一行显示,过长文本省略;悬停可查看完整内容。
- 错误提示按内容宽度使用剩余空间,仅在空间不足时省略。
- 极窄窗口仅在面板内部横向滚动,不让整个窗口横向溢出。
- 每个主窗口可以显示自己的面板。
- 全应用只有一个收集器和一个固定目标笔记。
- 任一窗口的目标、状态和成功收集数量都会同步到其他窗口。
- 后打开的窗口读取当前共享状态。
- 停止时可以选择当前窗口笔记库内已有的 Markdown 文件。
- 通过“选择笔记”选定目标后自动开启新一轮收集;取消选择不会开启。
- “使用当前笔记”选取当前已保存的笔记,不能使用搜索页或未保存的新建笔记。
- 收集或暂停期间,“使用当前笔记”仍可点击。
- 切换到不同笔记时,先停止收集,再设置新目标并自动开启新一轮收集。
- 已停止时选取当前目标笔记,也会自动开启收集。
- 收集或暂停期间,当前笔记已经是目标时,显示提示并保留原来的状态和数量。
- 当前笔记尚未保存为文件或是搜索页时,显示错误,不停止现有收集。
- 通过“选择笔记”打开文件选择器前,仍需先停止收集。
- 点击“开启”开始新一轮收集,成功数量清零。
- 未选择目标时,“开启”仍可点击,并提示“请先选择目标笔记。”。
- 因编辑或错误暂停后,处理问题并点击“恢复”;恢复保留本轮成功数量。
- 关闭面板不停止收集。
- 切换笔记、切换笔记库、失去焦点或最小化不会改变目标或停止收集。
- 关闭选择目标的窗口后,只要还有主窗口,收集继续。
- 关闭最后一个主窗口或退出应用会停止收集。
- 状态和目标仅保留在本次应用运行期间。
- 重启后默认关闭,重新选择目标后自动开启。
内容与追加格式
- 开启和恢复时,以当前剪贴板内容为基准,只收集之后的新内容。
- 退出应用时停止收集,并等待正在执行的写入结束,再完成日志落盘和退出。
- 暂停或停止期间不缓存内容,也不在恢复时补收。
- 收集纯文本和图片,不转换网页 HTML。
- 文本保留原始缩进和换行,沿用笔记的换行编码设置保存。
- 同一快照同时有图片和文本时,优先保存图片,避免收集附带的地址或文件名。
- 图片保存为目标笔记同目录
assets/下的 PNG,并追加相对路径 Markdown 图片引用。
- 面板提供“分隔符”和“日期时间”两个独立开关,默认都开启。
- 各窗口共享配置;运行或暂停时也可以修改,对之后采集的条目生效,不改写已有内容。
- 停止、恢复或更换目标不会重置配置;应用重启后恢复上次选择,首次使用默认都开启。
- 两项配置保存在本机
workspace-state.json的localSettings中,不参与云同步。
- 每条内容按“分隔线、当地时间、正文”的顺序追加到笔记末尾,各部分之间留空行。
- 关闭对应开关时省略分隔线或日期时间;两个都关闭时只追加正文,条目之间仍留空行。
- 时间格式为
YYYY-MM-DD HH:mm:ss,使用电脑当地时间。
- 忽略空内容和连续重复内容。
A → A只收集一次。A → B → A保留三条。
- 成功数量只在笔记写入成功后增加。
- 主进程使用唯一的 500 毫秒轮询,并串行追加。
- 两次轮询之间出现后又消失的剪贴板内容无法保证捕获。
- 第一版不提供剪贴板历史、来源应用识别、全局快捷键或重启后自动收集。
编辑保护与错误处理
- 开启、恢复和每次追加前检查所有主窗口中的目标笔记。
- 任一窗口有未保存编辑、缺失文件状态或正在输入法组字时,暂停收集。
- 提示“目标笔记有未保存编辑,保存后将自动恢复收集。”,不会自动保存或覆盖用户编辑。
- 所有窗口中的目标笔记保存后自动恢复,保留收集数量,并重新校验目标和编辑状态。
- 自动恢复也以当前剪贴板为基准,不补收暂停期间的内容;其他错误仍需手动恢复。
- 窗口未响应时也暂停,避免仅根据延迟的恢复会话判断是否可以写入。
- 确认目标干净后,写入期间短暂锁定目标编辑页;文件更新广播后解除锁定。
- 收集追加与普通笔记保存共用按路径串行的写入队列。
- 每次追加重新读取磁盘内容,并检查写入前的版本变化。
- 无法安全追加时暂停,并显示原因。
- 文件删除、移动、不可写,或图片/笔记保存失败时暂停。
- 不自动重建丢失的目标文件;需要先停止并重新选择目标。
- 成功写入沿用原子保存及发布流程,并通知所有打开目标笔记的窗口刷新标签和预览。
8. 图片管理
8.1 插入图片
- 通过工具栏或快捷键选择并插入本地图片。
- 通过工具栏读取剪贴板图片。
- 在编辑器中直接粘贴复制的图片。
- 插入图片前,如果当前文档尚未保存,会先提示选择文档保存位置。
8.2 图片存储与路径
- 图片复制到 Markdown 文件同级的
assets/目录。 - 图片使用避免重名的文件名。
- 文档中插入相对于 Markdown 文件的图片路径,便于连同
assets/目录一起迁移。 - 预览区按照当前 Markdown 文件的位置解析相对图片路径。
8.3 跨目录粘贴
-
在应用内跨目录复制或剪切含图片的 Markdown 文本时,粘贴会自动换算图片相对路径。
 -
可通过标准撤销与重做快捷键恢复这次粘贴。
-
移动或重命名单个 Markdown 文件时,图片引用仍指向原附件;整体移动或复制文件夹时,文件夹内部的附件引用跟随新位置。
-
HTTP、HTTPS、仓库根路径和锚点引用保持不变;无法无损识别的复杂或未转义地址不作猜测性修改。
-
同目录粘贴和外部剪贴板文本保持原样;该能力仅处理 Markdown 图片语法,不改写普通链接或 HTML 标签路径。
-
自定义剪切写入 CodeMirror 所属页面的撤销历史,可用
Ctrl/Command+Z撤销并重做。
8.4 支持格式
- 支持插入 PNG、JPEG、GIF、WebP 和 BMP 格式的本地图片。
- 剪贴板图片保存为 PNG。
8.5 复制图片
- 编辑器没有文字选区且光标位于 Markdown 图片语法内部时,右键菜单显示“复制图片”。
- 此时使用 Windows/Linux 的
Ctrl+C或 macOS 的Cmd+C也会复制图片本身。 - 在预览区的图片上右键,也可以通过“复制图片”复制所点击的图片,不依赖编辑器光标位置。
- 支持 Markdown 与 HTML 渲染的图片,沿用预览中已经解析的图片地址。
- 点击菜单外部、按
Esc、滚动预览、切换文档或重新渲染预览时关闭菜单。
- 支持行内和引用式 Markdown 图片,本地相对路径按当前文档位置解析。
- 相对路径图片需要文档已有保存位置。
- HTTP/HTTPS 和
data:image图片沿用图片导入的格式检查、10 MB 上限与网络请求 15 秒超时。
- 复制写入系统剪贴板的图片数据,可粘贴到其他支持图片的应用;不会修改文档、光标或选区。
- 有文字选区时继续复制 Markdown 文本;光标不在图片内部时继续复制当前整行。剪切行为保持不变。
- 图片不存在、下载失败或无法解码时显示通知,并保留原剪贴板内容。
8.6 录音与豆包语音转文字
录音、暂停与文件命名
- “插入图片”左侧的麦克风按钮、工具栏“操作 → 录音”和命令面板“录音插入附件”(
editor.recordVoice)共用应用内录音窗口。- 不绑定默认快捷键;可在快捷键设置中自定义。旧
voice.record命令保留已有绑定。 - 仅可编辑的 Markdown 页面允许启动;预览、差异、搜索页面及打开其他对话框时不可用。
- 录音期间锁定目标笔记与选区,禁止编辑、关闭和切换;全应用只允许同时处理一个录音任务。
- 未保存的笔记先选择保存位置;取消保存不会启动录音。
- 仅授权应用自身窗口的音频请求;拒绝远端页面、子框架和摄像头请求。macOS 打包包含麦克风用途说明。
- 请求麦克风权限后使用原生 MediaRecorder 录制 AAC-LC/M4A,单声道、目标 64 kbps,支持“暂停”和“继续录音”。
- 暂停会暂停编码写入并禁用麦克风音轨,计时不包含暂停时长。
- “完成并插入”先校验录音可播放、非空且不超过上限,再保存到当前文档同级的
assets/,插入普通 Markdown 链接,例如[录音 00:12](assets/voice-20260909-170901.m4a)。 - 替换开始录音时的选区,光标移至引用末尾,笔记保持未保存;插入支持一次撤销,撤销不删除附件。
- 文件名使用录音开始时的本机日期与时分秒,例如
voice-20260909-170901.m4a。恢复和重试沿用已选择的路径。 - 同名文件存在时依次追加
-2、-3,使用排他创建避免覆盖已有文件。 - 已有录音不改名,单个附件不能超过 20 MiB。
- 不设固定时长上限;分段数据或码率估算达到 19 MiB 时自动完成,为封装保留空间。暂停时间不计入大小估算。
- 仅前台录音;切到后台、锁屏、设备中断时停止并保留内容,恢复后选择插入或放弃。权限请求造成的临时失焦不触发中断。
- 取消录音会释放麦克风并丢弃本次录音;保存失败时可以播放录音并重试保存。
- 不绑定默认快捷键;可在快捷键设置中自定义。旧
- 录音分段写入本机
userData/voice-recordings/,临时文件不进入同步目录。- 恢复记录包含目标笔记、原始正文、选区、开始时间和固定附件路径。
- 保存或正文插入失败后可重试;重启并打开原笔记时提示恢复,点击录音入口选择插入或放弃。
- 已导入附件与已插入的恢复稿不会重复创建或插入。异常退出留下的文件必须通过可播放校验。
- 独立打开的笔记没有仓库会话恢复稿,录音恢复记录会保留到插入后的正文落盘,再清理临时文件。
- 正常取消清理临时数据;已导入的附件保留,与图片附件的撤销规则一致。
- Markdown 预览中的 M4A 链接下方显示完整语音条和“转文字”按钮。
- 当前平台必须支持 M4A/AAC 编码;不支持时显示应用内错误,不自动切换音频格式。
完整语音条与全局倍速
- 语音条包含播放/暂停、倍速选择、当前时间、总时长和可拖动进度;编辑区打开本地 M4A 链接显示同样的应用内播放器。
- 拖动期间显示目标时间,松手后定位;播放时继续播放,暂停时保持暂停。
- 未加载录音可按链接中的时长定位,加载后按实际时长校正;旧链接没有时长时加载媒体时长。
- 倍速支持 0.5、0.6、0.7、0.8、0.9、1、1.25、1.5、2 倍,默认 1 倍。
- 倍速使用本机应用级设置
voicePlaybackRate,所有录音、笔记、仓库与窗口共享,重启恢复;不参与账号设置云同步。- 保存失败显示提示并保留原倍速;无效设置恢复为 1 倍。
- 全应用同一时间只播放一段录音。开始录音、切换笔记/仓库/模式、进入后台或关闭播放面板时停止播放。
- 预览重绘和缓存切换会清理旧播放器和媒体 URL,隐藏节点不会继续播放。
- 本地附件通过授权 IPC 读取,拒绝越界、私有目录和符号链接;缺失或损坏附件显示错误。远端链接仍按原规则处理。
- 录音相对引用在笔记移动、目录复制和内部 Markdown 粘贴时采用与图片相同的路径调整规则。
- M4A 附件沿用现有云同步、忽略规则、二进制哈希、配额及历史恢复,不新增协议字段。
本机配置与单段转写
- 在“操作 → 语音识别设置”填写 AppID 与 Access Token,可修改或清除配置。
- 使用豆包录音文件识别模型 2.0 标准版,资源为
volc.seedasr.auc。 - 该接口不使用 Secret Key。官方鉴权说明。
- 凭据通过 Electron
safeStorage加密保存到本机userData/voice-transcription/,不写入笔记、同步数据或日志。 - 系统安全存储不可用时拒绝保存凭据。
- 使用豆包录音文件识别模型 2.0 标准版,资源为
- 点击预览录音旁的“转文字”,或将光标放在录音链接上后执行“操作 → 语音转文字”。
- 文档只有一个录音链接时可以直接执行。
- 上传本地 M4A,提交异步任务后每 5 秒查询结果;上传超时为 90 秒,查询超时为 30 秒。
- 结果允许编辑,点击“插入文字”写入录音链接所在行的下方,保留录音附件并支持撤销。
- 单段录音链接出现多次时保留结果供复制,不自动选择插入位置;可使用批量转换统一插入各个位置。
- 关闭或终止窗口后停止查询,已提交任务仍由服务端继续处理。
- 本机按附件真实路径、内容摘要和 AppID 保留请求编号与结果,重新打开后继续查询或显示已有结果。
- 提交前先保存任务编号,网络失败后“重试查询”沿用该编号,避免自动重复上传;“重新识别”明确提交新任务。
- 只允许读取已授权笔记所在笔记库内的 M4A;单独打开的库外笔记使用其所在目录作为附件范围。
当前文件批量转写
- “操作 → 批量语音转文字”按文档顺序处理当前文件的全部 M4A 链接。
- 排除代码围栏、缩进代码、行内代码、图片与远程链接。
- 重复链接只调用一次服务,结果插入各个对应链接所在行的下方。
- 再次批量转换时,跳过链接下方已经存在的相同转写结果,避免重复插入。
- 单段转换插入的相同结果也会跳过;新增的链接位置和此前失败的结果仍可插入。
- 判断依据是当前正文,重新打开笔记后仍然有效;撤销或删除结果后可以再次批量插入。
- 手动修改过的文字与本次转写结果不相同时,仍会插入本次结果;单段手动插入保持原有行为。
- 转换期间显示进度窗口并锁定编辑区,禁止修改正文。
- 单段失败后继续处理其他录音,结束时显示成功与失败数量及错误详情。
- 完成后统一插入成功识别的非空文字;关闭进度窗口后恢复编辑,可以一次撤销本次插入。
- 终止操作停止后续查询与转换,不插入尚未统一插入的结果;已完成结果保留在本机任务记录中。
- 笔记在转换过程中被外部更新或切换时,不覆盖变化后的正文,保留结果供手动复制。
- 录音也可以从插入菜单执行;单段转写、批量转写和设置位于工具 → 语音识别。
- 这些操作也可以从命令面板或自定义快捷键执行。
9. 界面与状态显示
9.1 布局
- 原生文件、编辑、插入、视图等菜单与工具栏操作复用可配置命令;各功能的行为和默认快捷键在对应章节说明。
- 侧栏可从视图菜单切换,默认快捷键为
Ctrl/Cmd+B。 - 界面中的完整本地日期时间统一显示为
YYYY-MM-DD HH:mm:ss,日期与时间字段均补零并使用 24 小时制。- 仅日期和仅时间场景分别使用
YYYY-MM-DD与HH:mm:ss。
- 仅日期和仅时间场景分别使用
- 默认使用左右分栏布局,同时显示编辑区和预览区。
- 窗口宽度较小时自动切换为上下分栏布局。
- 编辑区、预览区和大纲直接展示内容,不占用空间显示重复的面板标题条。
- 工具栏仍可独立切换编辑区、预览区和大纲的显隐。
- 工具栏、标签栏和状态栏固定在窗口内,不随文档内容滚动。
- 主窗口工具栏右侧的“×”按钮可关闭工具栏,并释放其占用的高度。
- 从 视图 → 工具栏,或命令面板的“工具栏”(
view.showToolbar)可切换显隐。- 工具栏显示时执行会隐藏,隐藏时执行会重新打开;两个入口使用同一命令。
- 菜单项在工具栏显示时带有勾选标记(√),隐藏时取消;关闭按钮、命令面板和切换窗口会同步标记。
- “工具栏”位于视图菜单顶部,紧邻“仅显示编辑区”之前。
- 工具栏默认显示,关闭仅影响当前窗口;重启或新建窗口后恢复显示,不新增默认快捷键。
npm run test:smoke:keyboard验证关闭后释放高度、视图菜单和命令面板双向切换,以及窄窗口关闭按钮可见性。
9.2 标签与滚动
-
内容跳转在目标已完整可见时保持当前滚动位置,仍更新选区、焦点和定位高亮。
- 覆盖搜索结果、行号、Quick Cmd Form 搜索、片段来源、大纲、收藏、差异及链接锚点。
- 编辑器按目标位置或匹配范围的横纵可见性判断;部分可见、横向遮挡或视图外目标仍按原方式滚动。
- 预览搜索按实际匹配范围判断;标题、锚点和内容块按起始显示位置判断,无须整个长段落可见。
- 前进后退仍恢复历史视图;无锚点的文档回顶操作仍滚动到顶部。
-
标签名称过长或标签数量较多时,支持省略显示和横向滚动。
-
标签支持标准键盘焦点以及左右方向键切换。
-
编辑区自动换行可从视图菜单、命令面板或按
Alt+Z切换,默认快捷键与 VS Code 一致。该共享选项会同步到所有窗口以及已打开和后续创建的编辑页。 -
编辑区和预览区均保留可见的滚动条。
9.3 状态栏
- 状态栏显示当前文件名或完整路径。
- 内部只读文件和文档差异视图在左侧路径前显示“只读”,右侧文档统计不重复显示“只读”。
- 状态栏显示当前文件的磁盘修改时间,并在保存或检测到外部修改后即时更新。
- 状态栏显示文档字符数和行数。
- 状态栏显示光标所在的行与列;存在选区时同时显示选择的字符长度,反向选择按活动端定位光标。
- 状态栏显示 UTF-8 BOM 和 LF/CRLF 信息。
10. 同步协议
10.1 加载与身份模型
- 打开笔记库后可从工具栏按需启动同步。
- 普通启动和编辑路径不会加载同步实现。
- 使用稳定的笔记库、设备和文件 ID。
- 使用服务端单调 revision 和拉取 cursor。
- 同一安装重新登录同一账号与服务时复用原设备 ID。
- 重新登录时轮换登录令牌。
- 执行“远程退出当前设备”后,凭正确密码重新登录会重新激活该设备。
- 重新激活设备时保留仓库同步基线,不会从 cursor 0 重新遍历远端。
- 仅当远端已不存在该设备身份时才重新登记。
10.2 队列、重试与幂等
- 本地变更先写入持久化队列。
- 网络失败后显示错误并可安全重试。
- 本地扫描发现未跟踪路径时,先读取远端最终状态。
- 远端已有同路径同内容文件时,直接采用其
fileId和 revision。 - 采用远端文件身份时,不上传正文,也不创建新 revision 或冲突副本。
- 上传前后发生竞态时,同内容路径冲突按相同规则收敛。
- 重复操作使用客户端操作 ID 保证幂等。
- 提交后断网不会生成重复版本。
10.3 收藏同步
- 每个打开的仓库都会安全读取或创建
.mynote/library.json;收藏按其中的稳定仓库 ID 保存,不依赖本机绝对路径。 - 文件收藏和大纲收藏保存在应用数据目录的
repository-favorites-v1.json,渲染端仍只接收原有收藏字段。 - 旧版
workspace-state.json中按路径保存的收藏不迁移;升级后使用新的仓库 ID 收藏集合。 - 尚未创建远端仓库时,收藏仍可在本机使用并保留待同步状态;首次文件同步创建远端仓库后自动上传。
- 多设备按收藏身份、修改时间和变更 ID 逐项合并;取消收藏保留墓碑,避免旧设备重新带回已删除项目。
- 文件移动、删除、回收站恢复、大纲整理和 100 项上限都会生成对应收藏变更。
- 同步中心独立显示收藏云同步状态、待上传数量和最近成功时间。
- 旧服务端没有收藏接口时自动降级为仅本地收藏,不影响文件和用户设置同步;升级服务端后自动恢复。
- 收藏不进入 Markdown 文件 revision、仓库历史恢复或原始文件导出。
10.4 Markdown 合并与冲突处理
- 同路径 Markdown 双设备编辑使用共同祖先执行保守三方合并。
- 非重叠修改自动合并并清理临时版本。
- 重叠修改在原文件旁保留
.base、.local和.remote文件。 - 文件树显示未解决冲突警告。
- 打开的冲突文件会在标签栏显示警告标记,左上角仓库名也会在任一文件存在冲突时显示警告标记。
- 存在任何未解决的文件冲突时,手动与后台自动同步都会停止;点击同步操作会提示先处理冲突。
- 设置中可配置外部合并程序及
%local、%remote、%base和%merged参数。 - 可通过右键菜单直接启动外部合并程序。
- 冲突处理后可标记完成。
- 图片、删除、路径与重命名意图冲突使用普通冲突副本或同步回收目录。
10.5 删除与恢复
- 删除以墓碑同步。
- 远端删除的本地文件进入
.mynote/sync-trash/,以便恢复。
10.6 同步窗口与诊断日志
- 同步窗口分别显示待推送/待拉取数量;任一数量非零时高亮,并同时显示当前状态、远端游标和上次成功时间。
- 同步概览卡片的状态、时间、游标和存储配额支持悬浮提示,展示被省略的完整内容。
- 存储用量和配额按当前容量单位四舍五入为整数,不显示小数;个人中心和套餐容量采用相同格式。
- 同步中心以“待同步(推送)内容”显示本地文件列表,区分新增、修改、重命名和删除。
- 展开待同步文件可查看相对上次同步内容的逐行 diff;待同步预览只扫描本地文件,不上传、下载或改写持久化同步队列。
- 已因失败保留在持久化队列中的内容按队列快照展示,并与本地扫描预览明确区分。
- 诊断日志按时间正序排列,最新记录位于底部。
- 笔记库同步日志位于
<笔记库>/.mynote/sync-hosted-v1/<namespaceKey>/logs/YYYY/MM/DD.log。 - 用户设置同步日志位于 Electron
userData/preference-sync-logs-<namespace>/YYYY/MM/DD.log;Windows 默认userData为%APPDATA%/mynote-client。 - 上述落盘日志每行为一条 JSON 记录,同步中心最多读取并展示最近 200 条。
- 收藏同步供同步中心读取的日志仅保存在当前应用进程内,最多 200 条;退出应用后清空,不建立独立的收藏日志文件。新产生的记录同时写入下述统一日志文件。
- 诊断日志初始定位到最新记录。
- 用户停留在底部时,持续跟随新增记录。
- 用户向上查看旧记录后,保留当前位置。
- 点击远端仓库、登录设备、待同步(推送)内容、最近版本或诊断日志模块的标题时,对应模块滚动到窗口顶部;点击模块内部内容不会触发滚动。
- 关闭同步中心后再次打开时,恢复上次浏览的窗口滚动位置;异步刷新账号和仓库内容后仍保持该位置。
- 诊断日志始终展开显示。
6.6.1 客户端统一每日日志
- 客户端额外将日志汇总到 Electron
userData/logs/YYYY/MM/DD.log。- Windows 默认目录为
%APPDATA%/mynote-client/logs/。 - 按本机日期每天一个文件,所有窗口和笔记库共用;重启后继续追加。
- 历史同步日志不迁移;原有同步日志文件和同步中心读取规则不变。
- Windows 默认目录为
- 覆盖主进程和主窗口、片段窗口、隐藏导出页面的控制台日志,以及笔记库、用户设置、收藏同步诊断和客户端错误摘要。
- 保留现有控制台输出的内容、参数和级别,仅额外记录文件副本。
- 独立部署的服务端、构建脚本和测试运行器输出不纳入客户端统一日志。
- 未登录、离线或远端上报失败时,客户端错误摘要仍记录到本地;原有远端上报规则不变。
- 文件使用 UTF-8、LF,每行一条 JSON,包含
at、level、category、source、message和args。at使用 ISO 时间;日期目录使用本机日期。- 已有分类前缀原样保留;无前缀的文件副本补充主进程、渲染器或对应同步类别,控制台文本不添加前缀。
- 来源包括主进程 PID;渲染器还记录
webContentsId和页面 URL。 - 参数在产生时快照,保留嵌套详情和错误堆栈;循环引用、BigInt 和不可读取属性使用明确标记。
- 主进程启动时启用构建产物自带的 Source Map,之后产生的主进程错误堆栈定位到 TypeScript 源文件和行号。
- Electron 和 Node 内部帧,以及没有 Source Map 的模块,仍显示原有位置;已有日志不会回写转换。
- 保留现有日志内容,包括 DeepSeek 请求正文、打包内容和回答;此功能不增加脱敏、自动清理、大小轮转或日志查看界面。
- 主进程串行追加;正常退出会等待队列写完,强制结束进程或系统崩溃可能丢失尚未写出的记录。
src/main/app-log.ts负责按日期写入、控制台与诊断镜像,以及等待写入队列清空;文件头和各函数头部注释说明对应职责。
- 文件写入失败不阻断控制台、业务操作或远端上报;失败期间在原控制台提示一次,后续记录继续尝试写入,失败记录不自动补写。
- 需要重启客户端后启用新增的统一日志机制。
10.7 运行时边界
- 同步窗口的刷新按钮引用、刷新标记、滚动恢复和注册流程状态由
runtime/sync/library.mts私有管理。 runtime/sync/library.mts还处理侧边栏和命令调用的手动同步,以及文件历史复用的同步结果处理。- 后续集中提取这些跨界面处理时,保留同步中心入口与现有调用行为。
- 上述局部状态不挂载到共享 runtime state;跨模块使用的同步状态仍由共享 runtime state 管理。
- 该模块包含私有可变状态,开发模式下修改时走现有的页面刷新恢复流程。
- 产品同步入口只连接托管服务。
- 协议测试使用
test/helpers/memory-sync-remote.ts中的内存远端替身。 - 内存远端替身不进入应用运行时或安装包。
渲染器后续集中提取
- 状态局部化后,另安排一次统一的模块提取,不在本轮按变量零散拆文件。
runtime/editor/selection-toolbar.mts按选区工具栏、编辑器上下文菜单和图片下载流程提取内聚模块。runtime/keyboard.mts按命令类别整理注册模块,保持命令 ID、默认键位和可用性检查不变。runtime/shell.mts按面板视图控制与应用生命周期协调提取模块。- 提取时保留原有注释、日志和错误处理;适合按需加载的界面沿用现有按需加载方式。
11. 托管同步
11.1 服务与账号
- 可配置 HTTPS 托管服务地址。
- 支持注册或登录邮箱账号。
- 点击“注册账号”进入邮箱验证码注册表单,点击“返回登录”切回密码登录。
- 输入邮箱后点击“发送验证码”,填写邮件中的 6 位数字验证码,再点击“验证并注册”。
- 验证码发送不要求先填写密码;提交注册时仍要求密码为 10–200 个字符。
- 验证成功后创建账号并自动登录,登录已有账号不需要验证码。
- 验证码有效期为发送成功后 10 分钟,至少等待 60 秒才能重发。
- 每个验证码最多允许 5 次错误尝试,重发会使旧验证码失效。
- 每个邮箱每小时最多请求发送 5 次,每个来源 IP 每 10 分钟最多请求发送 10 次。
- 发送失败的请求也计入限额,并保留 60 秒重发间隔。
- 发送期间不能重复发送或提交注册;服务端返回重试时间后,发送按钮显示倒计时。
- 修改邮箱或服务地址、返回登录、成功注册或关闭同步中心时清空验证码。
- 服务端提供移动端邮箱找回密码接口:独立重置验证码、10 分钟有效期、最多错误 5 次,复用 SMTP 与注册发信配额;成功后使全部旧会话失效,保留设备及笔记数据。
- 移动端重置成功后返回登录;PC 端本次不新增找回入口,旧会话失效后按现有流程重新登录。
- 服务端未配置 SMTP 时暂不开放注册,已有账号仍可登录和同步。
- 所有新注册都必须提供有效验证码,旧客户端不能继续直接注册。
- 密码不会保存在客户端。
- 登录或注册失败时保留当前密码输入,方便修正账号信息后重试。
- 登录、注册成功或关闭窗口后清空密码。
- 已保存登录凭据但服务地址暂时不可达时,同步中心保留并重新显示服务地址与登录表单。
- 服务地址不可达时,允许修改地址后重新登录。
- 瞬时网络故障不会自动删除本机安全凭据。
- 同步中心直接显示托管服务地址和登录表单,不提供本地原型模式选择。
- 同步中心不显示邮箱和用户 ID;账号信息集中在设置的个人中心。
- 个人中心提供一键复制完整用户 ID 到系统剪贴板的按钮。
11.2 登录凭据与设备会话
- 登录令牌使用系统安全凭据能力加密。
- 系统加密不可用时,不会退回明文保存。
- 支持让其他设备远程退出。
- 支持撤销当前设备会话并清除本机凭据。
11.3 自动同步
用户设置云同步
-
同步包含“侧栏手风琴模式”(
sidebarAccordionEnabled),默认启用,仅接受布尔值。 -
新字段需要客户端与同步服务端配套升级并重启;旧服务端会拒绝未知设置字段。
-
登录后,以下账号级设置自动跨设备同步:
- 编辑器字号;
- 编辑器自动换行;
- 单击文件时使用预览标签;
- 拼音搜索;
- 输入法状态显示;
- 激活大纲后聚焦编辑器;
- 导航大纲时即时跳转;
- 笔记库 Markdown 文件上限;
- 快捷键 JSON;
- 热键 JSON。
-
本机路径、外部冲突工具命令及参数、窗口布局、仓库级界面状态、自动同步配置和登录凭据不同步。
-
服务端启动时清理旧版本写入云端的
hotkeysEnabled字段;热键总开关仅由各设备本机设置决定。 -
设置保存后立即尝试上传,并每 60 秒独立检查其他设备的修改;关闭笔记库自动同步不会关闭用户设置云同步。
-
从其他设备拉取设置并保存后,立即更新已打开窗口的设置和拼音搜索菜单状态。
-
用户通过侧栏“同步”、同步中心“立即同步”或
sync.run命令手动同步当前仓库时,会同时同步上述账号级设置。 -
首次登录以云端已有值为准;覆盖前将本机可同步设置备份到应用数据目录的
preference-backups。 -
不同字段分别同步,同一字段以服务端最后成功提交的版本为准;快捷键 JSON 和热键 JSON 分别作为独立字段处理。
-
离线修改在连接恢复后重试;同步中心显示用户设置同步状态、上次成功时间、待重试数量和不含配置值的诊断日志。
移动端悬浮菜单配置
- 账号偏好接口支持
mobileShortcutMenu,值为{ "hiddenIds": ["save"] };只同步菜单项选择,不接收位置、路径或凭据。 - 服务端校验配置对象、菜单 ID 和最多 256 个条目的限制;同一账号多设备共享配置,每次写入独立递增版本。
- 桌面端验证并保留该云端字段,不将其应用到桌面设置,也不上传或覆盖移动端菜单配置。
- 启用此字段需要同时更新服务端和桌面客户端;旧桌面版本不支持该新字段。服务端需重启以加载更新。
笔记库自动同步
- 登录后可启用按秒计时的全局自动同步。
- 默认同步间隔为 60 秒,上限为 86400 秒,仅允许整数。
- 普通模式最低 60 秒;本机隐藏功能开启后最低 1 秒。
- 间隔输入仅在失去焦点时校验;空值、小数或超出当前范围的间隔不保存。
- 输入过程中不校验、不保存,已有错误文字及错误状态保持不变,避免提示晃动。
- 失去焦点后,非法值显示当前模式的实际上下限;合法值清除旧错误并自动保存。
- 按 Enter 让间隔输入失去焦点,复用同一校验与保存流程。
- 普通模式启动或关闭隐藏功能时,已有的 1–59 秒间隔及记忆间隔提升并保存为 60 秒。
- 自动同步关闭时保持关闭;重新开启隐藏功能不恢复旧的短间隔,可手动重新设置。
- 开关修改后立即自动保存;同步间隔失去焦点且校验通过后自动保存,无需额外点击保存按钮。
- 间隔字段仅显示保存失败与失焦校验错误;等待、保存中、保存成功及关闭自动同步时均不显示状态文案。
- 当前同步间隔以输入框中的秒数为准。
- 关闭自动同步时持久化保留当前间隔,重新打开应用或再次开启后可继续使用该值。
- 关闭全局自动同步后禁用全部后台调度。
- 开启全局自动同步后,当前仓库始终进入定时任务,不受仓库级开关影响。
- “切换仓库后仍自动同步”默认关闭。
- “切换仓库后仍自动同步”不依赖全局开关,可在全局自动同步关闭时预先选择;全局关闭期间不执行调度。
- “安全的自动同步”是独立的仓库级选项,不依赖“切换仓库后仍自动同步”或全局开关,可单独预先选择。
- 当前仓库和切换后继续参与的后台仓库都遵循各自的安全模式设置:
- 未选择时执行原有完整同步。
- 选择后,仅本地待推送或远端待拉取其中一侧有变化时才同步。
- 双向变化或同步请求间发生竞态时,保留队列与工作文件并跳过,不生成冲突副本。
- 当前仓库因此跳过自动同步时,侧栏仓库标题显示警告,tooltip 标明具体阻止原因,直至后续同步成功或关闭安全自动同步。
- 多个目标按顺序同步,一个仓库失败不会阻断其余仓库。
- 手动“立即同步”不受仓库级开关影响。
- “立即同步当前仓库”作为
sync.run命令显示在命令面板和快捷键设置中;默认快捷键为Alt+A Alt+S,仅在已打开仓库且没有模态窗口时可执行。
11.4 远端仓库与克隆
- 无需先打开本地仓库即可进入同步中心。
- 登录后列出当前账号的全部远端仓库。
- 远端仓库列表显示 revision、每库云端用量、当前未删除 Markdown 文件数和创建时间。
- 用量按 MiB / GiB 显示,保留两位小数,与 mobile 一致。
- 默认按名字升序,可在标题旁切换为用量降序;同用量按名字、同名按仓库 ID 升序。
- 切换排序使用已加载列表,不重新请求服务;刷新列表时保留选择,重启应用后恢复默认排序。
- 图片附件不计入 Markdown 文件数。
- 未命名仓库显示完整 ID。
- 手动命名后,仓库显示为
名称(完整 ID)。 - 可选择远端仓库克隆到本地,并直接切换为当前工作区。
- 选择空文件夹时直接克隆。
- 选择非空文件夹时,在其中新建以仓库名称或完整 ID 命名的安全子文件夹。
- 新设备选择空文件夹后,自动接入账号中唯一已有数据的远端笔记库,无需手工复制隐藏元数据。
- 同一台机器可保留同一远端库的多个本地目录副本。
- 每个本地目录副本维护独立同步游标。
11.5 配额、设备与版本历史
- 显示账号配额、登录设备、最近版本和当前同步状态。
- 登录设备支持复选多选,并提供“全选”和“取消全选”;当前设备不可选。
- 设备名称靠左对齐,设备 ID 直接显示在名称后的括号内,不使用 tooltip;长文本可换行。
- 设备操作按钮位于“登录设备”标题旁;点击“刷新”重新获取同步状态及设备列表,清空设备选择。
- 同步中心的标题与同行按钮、选项垂直居中,标题栏与下方内容的间距由整行统一保留。
- 对所选设备可批量“退出登录”或“删除记录”,执行前通过应用内对话框确认。
- “退出登录”跳过已退出设备,保留设备记录。
- “删除记录”同时撤销设备会话并移除记录,不删除笔记、仓库或版本历史。
- 批量操作逐台执行,单台失败不影响其他设备;完成后刷新列表并显示失败原因。
- 首次成功同步会分页下载全部版本元数据和版本正文,并按账号、设备和仓库隔离保存在本地
.mynote同步目录中。- 后续同步以本轮已应用的远端游标为上限,只下载并写入本地连续缓存之后的新增 revision。
- 已完整覆盖该游标时不发起历史请求。
- 每个成功分页都会形成可恢复检查点;缓存缺页或损坏时才重新构建完整历史。
- 同步进度将实际文件拉取显示为“下载远端变更”,将离线历史缓存显示为独立的“同步版本历史”阶段。
- 同步中心版本列表、单文件版本历史、展开差异和编辑器按时间比较只读取本地历史缓存,不发起服务器请求;本地存在尚未同步的修改或持久化待推送队列时同样如此。
- 打开或刷新同步中心时,“最近版本”会立即读取并渲染本地历史,不等待配额、远端仓库和设备等网络数据加载完成;服务器关闭或暂时不可达时仍显示本地缓存,并同时保留连接失败提示。
- 最近版本标明新增、修改、重命名、删除或恢复动作。
- 最近版本显示修改时间和设备名。
- 同步中心“最近版本”中未删除的版本也提供“另存”,可将本地缓存的该版本原始内容保存到用户选择的文件;断网或未登录时仍可使用已缓存的版本。
- 文件树或已保存标签的右键菜单可查看指定文件的远端版本历史;命令面板同时提供
sync.showFileHistory“查看文件历史”命令,并按标签、文件树选中项、当前文档的顺序确定目标。 - 指定文件历史与同步中心“最近版本”共用可展开条目、版本元数据、差异渲染和恢复流程。
- 文件历史中未删除的版本可通过“恢复”旁的“另存”按钮,将本地缓存的该版本原始内容保存到用户选择的文件;网络断开或未登录时仍可使用已缓存的版本。
- 取消另存不写入文件;没有缓存正文的版本不能另存。
- 两处版本详情均可在“与上一版本比较”和“与当前版本比较”之间切换。
- 当前文件按稳定文件 ID 跟随重命名后的路径;已删除时按空内容展示删除差异。
- 仓库级“整体恢复”仍仅在同步中心提供。
- 同步中心“最近版本”中仍存在于当前本地笔记库的文件可直接“定位到文件树”;操作会关闭同步中心、显示并展开文件树、选中对应文件,但不会打开文件或切换当前标签。
- revision 高于当前本地同步游标的最近版本以“待同步到本地”高亮,拉取完成并刷新列表后自动取消高亮。
- 最近版本列表上方常驻说明蓝色高亮条目代表待拉取(同步到本地)的版本。
- 展开版本后可查看以下信息:
- 设备、文件和操作标识;
- 哈希;
- 原路径;
- 恢复来源;
- 逐行正文 diff。
- 大型 Markdown 的版本 diff 会按中间未变化行持续对齐,不会因超过内存保护阈值而把首尾变化之间的内容误显示为整段删除和整段新增。
- 同步中心、文件历史、待同步正文 diff、文件树比较和编辑器差异模式都按内容相似度做保序行对齐:
- 每个旧行后紧跟对应新行;保留原句但大幅扩写的行仍可配对。
- 匹配的旧行与新行分别用高亮红色块和高亮绿色块标出行内删除、增加片段。
- 中间插入不会造成后续修改错配;无法配对的删除行和新增行分别单独显示。
- 正文 diff 使用 13px 等宽字体,行高为字号的 1.5 倍。
- 差异框随内容展开,不再单独限制为最高 300px。
- “精简差异”默认启用,只显示每处变化及其前后 3 行。
- 取消“精简差异”后显示完整 diff。
- “自动换行”默认关闭。
- 自动换行关闭时,长行使用横向滚动。
- 自动换行启用后,长行在差异框内换行。
- 切换差异显示选项时,不重复请求服务端。
- 展开版本的标题与恢复按钮在详情滚动期间吸附在列表顶部。
- 二进制附件显示修改前后的大小。
- 未删除的历史正文可恢复为新版本。
- 每条最近版本都提供“整体恢复”,可将本地同步文件和已打开的编辑内容强制还原为该全局 revision 的仓库快照,并丢弃原有本地待推送队列。
- 整体恢复在全局自动同步关闭时只产生本地待推送变更,不修改远端;全局自动同步开启时会在恢复后立即遵循该仓库的普通或安全自动同步策略。
11.6 本地同步状态
- 同步基线、待上传队列、cursor 和诊断日志保存在仓库
.mynote内。 - 状态文件名不依赖仓库绝对路径。
11.7 图片与录音附件
- 同步 PNG、JPEG、GIF、WebP 和 BMP 图片附件,以及 M4A 录音附件。
- 跨设备保留原始二进制字节。
- 单文件上限为 20 MB。
11.8 服务端能力与诊断
- 服务端使用关系元数据、加密对象存储、版本历史、墓碑和审计事件。
- 同步失败、渲染进程异常和未处理错误可发送有界诊断摘要。
- 诊断摘要不包含登录令牌。
- 可将服务端当前完整 Markdown 与图片库导出为普通目录。
- 导出目录保留
.mynote/library.json。
11.9 当前限制
- 尚未提供图片与 M4A 录音之外的通用附件。
- 尚未提供密码重置。
- 尚未提供团队共享。
- 尚未提供端到端加密。
11.10 设备间 P2P 文件传输
- 从工具 → P2P 文件传输或命令面板执行
p2pTransfer.show。- 每个主窗口最多一个传输标签页,重复打开会激活已有标签。
- 同步中心其他有效设备的“发送文件”打开该标签并预选设备。
- 工具标签不进入文档保存、导出、搜索正文或恢复稿。
- 选择同账号在线设备后,可以选择 1 至 100 个任意本机文件。
- 在线设备可在下拉框中选择;离线设备显示离线状态并禁用。
- 接收设备在应用内确认清单,并选择保存目录;无需打开笔记库。
- 接收确认请求到达时,若接收窗口未获焦点,则通过系统窗口闪烁提醒,不抢占焦点。
- 窗口获得焦点、用户处理请求或请求取消/超时后停止闪烁;前台窗口不额外闪烁。
- 每台设备同时处理一个批次,按文件顺序分块传输。
- 同一设备间成功建立的 WebRTC 连接可供后续同向或反向发送复用,免去重复连接协商。
- 每批文件使用独立数据通道,仍需接收方确认并选择目录,不复用上一批文件的读写授权。
- 仅保留最近一个设备连接;连接失效后再次发送重新协商。
- 设备离线、账号或服务状态变化、连接故障、关闭所属窗口时释放连接。
- 发送方可配置“分块大小(KB)”和“在途块数”,默认分别为 64 和 16。
- 1 KB 按 1024 字节计算;分块大小支持 1–256 KB,在途块数支持 1–128,均为整数。
- 两者乘积不得超过 16384 KB(16 MiB),避免未确认数据占用过多内存。
- 分块大小还受当前 WebRTC 连接协商的消息上限约束,超限时提示调小后重新发送。
- 点击发送时固定本批参数,后续修改仅对下一次发送生效;当前窗口关闭后恢复默认值。
- 采用流水线发送,默认最多允许 16 个 64 KiB 分块未确认,总计不超过 1 MiB。
- 每块仍由接收方写入后确认;文件结束前等待全部分块确认,再校验保存,速度和进度按确认字节计算。
- 双方应用必须保持运行;没有离线投递、文件夹传输或断点续传。
- 显示单文件和整批的字节数、百分比、整批进度条,以及最近三秒确认落盘的平均速度。
- 发送完成以接收方 SHA-256 校验和保存确认作为依据。
- 已接收完成的文件以列表展示,每行显示文件名、大小和“定位到文件”按钮。
- 点击列表项中的“定位到文件”,在系统文件管理器中选中对应文件;文件移走后提示错误。
- 同名文件自动添加编号,取消或失败清除未完成文件,已完成文件保留。
- 关闭标签页不会中断传输,重新打开可查看当前任务和本次运行中的接收结果。
- 多窗口共享任务状态,设备的首个在线窗口负责 WebRTC 和接收确认。
- 关闭负责传输的窗口前会确认取消;账号变化、离线、校验失败或超时会终止任务。
- 文件正文通过 WebRTC 直连传输,不写入同步服务器或计入云存储配额。
- 托管服务只负责设备在线登记和有界信令,客户端每两秒轮询,45 秒无登记判定离线。
- 等待接收最多两分钟;连接建立或传输无进展最多一分钟。
- 管理员通过
MYNOTE_P2P_STUN_URLS配置 STUN,不默认连接第三方服务。 - 无 STUN 时提示跨网络受限;即使配置 STUN,部分 NAT 和防火墙仍无法直连。
- 不提供 TURN 中继;客户端和托管服务需要同时更新并重启。
12. 快捷键
12.1 热键与快捷键独立配置
- 设置弹窗顶部在「设置」标题右侧依次显示「快捷键设置」「热键设置」按钮,点击打开对应配置。
- 配置中心的「快捷键 / 热键」选择同时决定列表、编辑、添加、删除、恢复默认和 JSON 操作的配置类型。
- 快捷键用户覆盖存入应用数据目录的
User/keybindings.json。 - 系统级热键用户覆盖独立存入
User/hotkeybindings.json。 - 「编辑 JSON」仅编辑当前类型的用户文件;「定位文件」打开对应文件位置,「默认 JSON」仅显示当前类型的默认绑定,标题和说明文案同步显示“快捷键”或“热键”。
- 两个文件均使用现有 JSON 数组格式,支持平台覆盖和默认绑定移除;不按命令分类拒绝整个文件,也不自动将规则移动到另一个文件。
- 默认绑定移除始终只按命令 ID 和通用
key匹配;同命令、同通用键位的默认绑定会一并移除。- 移除规则里的
when和平台覆盖仍需符合字段格式,但不会缩小匹配范围。 - 列表删除、修改默认绑定及尚未加载插件的移除规则均遵循相同规则。
- 移除规则里的
- 两类文件分别监听外部更新,保存后立即生效;文件损坏时保留该类型当前有效绑定,JSON 修复只更新当前文件。
- 热键注册仅读取热键文件;修改快捷键不会重新注册全局热键。
- 未被当前执行端使用的命令或移除规则不会阻止其他有效配置加载;JSON 格式、键位和 When 仍需通过校验。
- 启动和重新读取快捷键、热键文件时逐条校验;无效条目跳过,前后有效条目继续生效。
- 错误提示与日志包含原数组中的条目序号和原因;命令和键位均为字符串时一并显示。
null、非对象条目及字段类型错误均逐条报告,不中断后续有效条目的加载;无效移除规则不会移除默认绑定。- 应用通知保留错误列表的换行,长命令、键位和连续文本自动换行,避免超出通知宽度。
- JSON 语法损坏、顶层不是数组或文件读取失败仍按整文件错误处理;重载失败时保留当前绑定。
- 列表新增、编辑、删除、恢复默认和导出 JSON 都保留跳过条目的原始 JSON 值及相对位置,便于后续修复。
- 保留原始值,不保证原来的缩进;有效绑定的编辑和优先级继续沿用现有规则。
- JSON 编辑器保存仍严格校验全部条目;修复保存成功后清除相应无效条目记录。
- 热键列表保存允许原样保留已有无效条目,新增或修改出的无效条目仍会被拒绝。
- 热键总开关仅保存在本机
workspace-state.json的localSettings.hotkeysEnabled,不参与云同步,缺省启用,禁用时保留 Quick Cmd Form 启动热键的现有例外规则。 - 账号同步仅使用
keybindings和hotkeybindings字段同步绑定规则,localSettings中的所有值均不参与同步,不兼容旧位置或旧云端开关字段;热键字段缺失时默认空用户覆盖。 - 不兼容旧混合配置,不读取其中的热键、不自动迁移或删除本地旧文件,也不迁移云端旧值。
- 本次更新需配套更新并重启桌面客户端与同步服务。
12.2 快捷键参考
-
快捷键注册与响应技术流程:命令与绑定注册、平台覆盖、When 求值、Chord 状态机、输入法保护、菜单与命令面板入口、配置持久化及全局热键注册。
-
Windows 上使用
Alt+左/右或Ctrl+Alt加非修饰键后,先松开Alt不会将焦点转移到原生菜单。单独按Alt仍可使用原生菜单。
| 快捷键 | 功能 |
|---|---|
Ctrl+N |
新建文档 |
Ctrl+O |
打开文件 |
Ctrl+P |
快速打开文件;输入 @ 搜索全库大纲,输入 @! 搜索收藏大纲,输入 @@ 搜索当前文件大纲 |
Ctrl+Alt+N |
系统级热键:显示或隐藏片段管理器;可在快捷键设置中修改 |
Ctrl+H |
替换当前文件(macOS 为 Cmd+Option+F) |
Ctrl+G(Windows、macOS) |
输入行号并跳转到当前文档的对应行 |
Ctrl+R |
打开最近笔记库;macOS 同样使用 Ctrl 而不是 Command |
Ctrl+Shift+Alt+S |
在当前已打开的应用窗口间循环切换;Windows 与 macOS 相同 |
Ctrl+F |
在当前编辑区或预览区内搜索 |
Ctrl+Shift+F |
在文件中查找 |
Ctrl+Shift+R |
在文件中替换 |
Ctrl+= / Ctrl+Shift+=(Ctrl++) |
放大整个应用页面 |
Ctrl+- |
缩小整个应用页面 |
Ctrl+0 |
重置页面缩放为 100% |
Enter / Shift+Enter |
查找栏打开时跳到下一个/上一个匹配 |
F3 / Shift+F3 |
从编辑器最新 caret/选区位置跳到下一个/上一个匹配;查找栏关闭时会先在当前编辑区或预览区重新打开 |
Alt+C |
查找栏打开时切换区分大小写 |
Alt+S |
打开同步中心 |
Alt+Shift+D |
切换当前文件的差异模式 |
Ctrl+Alt+D |
打开文件树差异;macOS 使用 Cmd+Option+D |
Windows/Linux:Ctrl+Shift+V |
在编辑、并排和预览三种文档视图间循环切换 |
macOS:Cmd+Shift+V |
在编辑、并排和预览三种文档视图间循环切换 |
Alt+A Alt+S |
立即同步当前仓库 |
Escape |
关闭当前查找栏 |
Ctrl+S |
保存当前文档 |
Alt+Shift+S |
系统级热键:主窗口已显示且激活时,macOS 像 Cmd+H 一样隐藏应用的所有窗口、Windows/Linux 最小化主窗口;已显示但未激活时置于前台并激活;隐藏或最小化时恢复显示并激活 |
Ctrl+W |
关闭当前标签 |
Ctrl+Q |
退出应用;macOS 使用 Command+Q |
Ctrl+Tab |
打开最近使用标签列表并向前选择,松开 Ctrl 后切换 |
Ctrl+Shift+Tab |
打开最近使用标签列表并向后选择,松开 Ctrl 后切换 |
Alt+1–Alt+9 |
按 1-based 顺序切换到第 1–9 个标签;对应位置没有标签时不执行操作;Windows 下使用小键盘时会阻止 Alt 数字码的延迟字符写入编辑器 |
macOS:Command+Shift+[ |
循环切换到上一个标签 |
macOS:Command+Shift+] |
循环切换到下一个标签 |
Windows/Linux:Ctrl+PageUp |
循环切换到上一个标签 |
Windows/Linux:Ctrl+PageDown |
循环切换到下一个标签 |
Ctrl+Shift+I |
插入本地图片 |
除表中明确标为所有平台统一使用 Ctrl 的快捷键外,macOS 可以使用 Command 代替 Ctrl。显示或隐藏主窗口的快捷键是系统级热键,在应用位于后台时同样生效。
-
启动时优先按已保存的热键配置注册全局热键,不会先尝试注册已被替换或删除的默认热键。
- 主窗口显示/隐藏热键统一通过可配置热键控制器注册,不再保留独立的固定键位注册入口;默认仍为
Alt+Shift+S。 - 配置无法读取、JSON 语法损坏或顶层不是数组时才回退默认配置;单条错误不会触发整批回退。
- 热键总开关沿用 Quick Cmd Form 启动热键的例外规则;读取、外部刷新和开关操作均跳过无效条目。
- 主窗口显示/隐藏热键统一通过可配置热键控制器注册,不再保留独立的固定键位注册入口;默认仍为
-
全局热键逐个注册;任意热键被系统占用或注册异常都不会阻止其他热键继续注册。
-
热键列表页的删除、恢复默认与启用开关,以及修改页和 JSON 编辑器的保存,不会因热键注册失败而失败。
- 配置仍会保存,注册成功的热键立即生效,注册失败的热键暂不生效;失败原因写入应用日志。
- 读取或重新加载配置会重试失败热键;条目错误报告后继续处理其余条目。
- JSON 保存严格校验;整文件格式错误和文件写入失败仍会正常报错,写入失败时撤销本次新注册。
-
缩放快捷键在编辑器聚焦时同样生效,可在设置 → 快捷键中修改,也可通过命令面板执行。
-
同时支持
Ctrl+小键盘 +放大和Ctrl+小键盘 -缩小(macOS 使用Command),不需要按Shift。 -
小键盘加减键可独立录制和修改;快捷键 JSON 中分别写为
numadd和numsub,例如ctrl+numadd。 -
视图菜单保留缩放操作;键盘缩放由应用快捷键系统统一处理,避免原生菜单抢占用户配置的按键。
13. 工作区性能与验证
13.1 性能基准
运行 npm run benchmark:workspace 会创建 1000 个小型 Markdown 文件,测量目录扫描、首次正文搜索和缓存搜索。
2026-08-14 开发环境的多次运行参考范围:
- 扫描约 130–180 ms。
- 首次搜索约 470–1200 ms。
- 缓存搜索约 160–420 ms。
结果用于比较相对回退,不作为所有设备的硬性 SLA。真实笔记库规模或延迟超过当前方案能力时,再评估 SQLite FTS。
13.2 自动化覆盖
- 笔记库 IPC 处理器直接使用
WorkspaceManager类型,便于从管理器方法查询实际调用引用。 npm run test:smoke:voice使用 Electron 自带的模拟麦克风验证 M4A 编码、暂停与恢复、计时、保存重试、批量锁定、终止竞态、外部更新保护和撤销。node scripts/run.mts node --test test/voice.test.js test/voice-recordings.test.js验证录音命名与重名、分段落盘、重启恢复、独占任务、授权边界、倍速持久化、引用调整、凭据存储和豆包异步任务恢复;语音服务请求使用模拟响应。npm run test:smoke:voice-player验证完整语音条、实际 M4A 播放、拖动、全局倍速、播放互斥、失败提示与缓存清理。npm run test:smoke:voice-app验证应用按钮位置、命令面板触发、模式禁用、录音锁定、附件插入、倍速保存、编辑区播放器与撤销重做。- 录音 UI 修改及 macOS 麦克风用途说明需要重新构建并重启桌面应用;Windows 原生编码使用模拟音源验证,系统锁屏/真实设备拔出及 macOS 真机需手工验证。
- 工作区扫描、文件读取、新建文件和文件夹,以及搜索、最近记录、收藏和设置持久化。
- 仓库被外部删除后的失效选择清理、文件重命名、移动、复制与系统回收站调用。
- 文件操作和跨文档剪贴板中的图片相对路径重写;路径穿越、符号链接逃逸、名称冲突和递归移动拒绝。
- 打开文档迁移后的状态更新;目录树选中态、文件夹展开、右键与
Shift+F10菜单、键盘导航和路径复制。 - 编辑器右键菜单的鼠标与键盘入口、格式操作、撤销与重做、粘贴、全选、只读禁用状态及焦点恢复。
- Electron 冒烟测试中的工作区恢复、目录树、搜索、打开文件、新建文件和文件夹,以及手动刷新反馈。
- 拖放时按下或释放 Ctrl(macOS 为 Cmd)即时切换复制与移动提示,即使鼠标不再移动;最终执行移动。
- 同步冲突的
Markdown.base、Markdown.local、Markdown.remote临时版本在原文件旁显示警告。- 临时版本本身不作为工作区 Markdown 节点或同步文件显示。
- 仓库存在未解决冲突时阻止手动与后台同步;右键菜单可清理临时版本,配置工具后可启动外部三方合并。工具路径逐项替换参数,不通过 shell 展开文件名。
- 文档大纲的层级提取、代码块排除、实时更新、文件名根节点、面板切换、顶部定位、即时跳转、双击折叠、递归折叠与展开、折叠时的滚动位置、命令面板、视图菜单快捷键和键盘导航。
13.3 冒烟测试诊断输出
- 测试中的控制台 mock 和诊断捕获默认保持静默,同时保留供断言使用的记录。
- 设置环境变量
MYNOTE_TEST_DIAGNOSTICS=1后,捕获调用仍记录,并通过原方法输出原始参数。 - PowerShell 示例:
$env:MYNOTE_TEST_DIAGNOSTICS='1',随后执行测试或启动 VS Code 调试。 - 关闭时执行
Remove-Item Env:MYNOTE_TEST_DIAGNOSTICS;该开关不关闭正常测试结果或失败报告。 - 冒烟运行器启用此开关后保留完整预期拒绝堆栈,不再合并为摘要。
- 独占锁测试子进程的标准输出也由此开关控制,标准错误始终保留。
- 设置环境变量
- 无论是否启用诊断输出,始终屏蔽整行匹配的 libpng
iCCP: known incorrect sRGB profile警告。 - 外部删除笔记库用例在关闭索引和工作区锁后恢复夹具的过期根路径,继续验证失效仓库提示及最近列表清理。
- 隐藏编辑器的大纲跳转夹具将目标放在预览视口外,验证实际滚动,避免已可见目标无需滚动导致误报。
- 收集器多窗口用例共享一个工作区所有者,避免独占锁使后续窗口未加载夹具;最后关闭时释放工作区。
- HTML 粘贴用例清理时停止快捷键、等待在途 IPC 并关闭工作区,释放 Windows 工作区锁后再删除临时目录。
- 目录树多选删除用例显式筛掉夹具中的文本和图片,验证未显示文件的二次确认及取消后整批保留。
- 不依赖文件扩展名或点号前缀默认隐藏,适配目录树默认展示所有文件的行为。
- 主冒烟入口和粘贴撤销入口注册真实收集器 IPC,避免启动读取出现
collector:read未注册错误。 - 主冒烟入口的收集器与文件、同步处理器共享应用状态,清理测试目录前停止收集器。
- 错误弹窗场景仅在
app-alert专项和full综合流程中执行;其他专项不再重复触发预期读取失败。 - 默认情况下,用例通过时,故意读取不存在笔记和移动到同名目标产生的 IPC 拒绝按消息合并。
- 显示次数并省略重复调用栈;启用诊断输出时保留原始完整输出。
- 其他错误保留完整诊断;用例失败、崩溃或超时时也保留这些拒绝的完整诊断,便于排查。
Smoke suite failed和非零退出码仍表示真实失败,不能当作预期拒绝忽略。- 后续单独集中提取
test/electron-smoke.ts和test/paste-undo-smoke.ts的启动与清理模块;本次不拆分测试流程。- 将
test/smoke/renderer/initial-editor-flow.ts的场景提取一并纳入后续集中整理。
- 将
13.4 人工平台验证
发布前仍需在 Windows/macOS 测试制品上检查:
- 系统文件夹对话框与最近笔记库切换。
- 中文、空格、长路径和只读目录。
- 回收站中的恢复操作。
- 文件夹跨层级移动及含附件目录的复制。
- 外部程序修改目录结构后手动刷新。
- 1000–10000 文件笔记库的滚动和搜索体验。
14. 管理后台 API 初始化
- 独立管理前端复用托管同步服务的 SQLite 和对象存储。
/admin/v1提供管理员登录、会话恢复、退出、概览、分页账号列表和分页笔记库列表。- 管理员凭据与用户同步账号、metrics 管理令牌独立。
- 管理会话通过 HttpOnly Cookie 保存,普通用户 token 无法访问管理接口。
- 初版只读;完整配置和接口约定见 管理后台 API。
15. Quick Cmd Form
- 通过“工具 → Quick Cmd Form”或命令面板
quickCmdForm.open打开。 - 默认全局热键为
Ctrl+Alt+S,命令 ID 为quickCmdForm.toggleWindow。- 可在快捷键设置中修改或移除。
- 在外部应用中先选中内容,再按热键打开,输入短命令后立即执行。
- Windows 下窗口置顶显示但不激活,来源窗口保留焦点和选区。
- 窗口显示期间使用 Windows 低级键盘钩子(
WH_KEYBOARD_LL)读取字母、数字、退格及控制键,在输入法处理前接收并拦截,短命令不会输入到来源应用。- 关闭、执行命令、窗口销毁或应用退出时解除钩子;执行失败重新显示时恢复钩子。
- 模拟复制按键不被钩子拦截。macOS/Linux 保留聚焦窗口后的 DOM 输入及快捷键监听。
- Windows 钩子和 DOM 按键入口共用 Escape、Tab/F1、F2、F3 的处理;DOM 中 Tab/F1 仅在命令输入框内切换目标,其他控件保留正常焦点导航。
- 从主窗口打开时复制该窗口保留的选区。
- 短命令仅在 Quick Cmd Form 窗口内输入执行;命令面板保留打开窗口的
quickCmdForm.open,快捷键设置保留quickCmdForm.toggleWindow。- 不再注册每个短命令对应的命令面板命令,也不提供主窗口直接执行短命令的 API。
- 已有短命令自定义快捷键或命令历史不再提供直接执行入口,请先打开窗口再输入短命令。
- 界面、代码标识符及命令 ID 统一使用 Quick Cmd Form 命名。
- 打开窗口和全局热键的自定义配置使用上述两个命令 ID,不兼容旧命令 ID。
- 相关源码及测试文件统一使用
quick-cmd-form文件名前缀;冒烟验证入口为npm run test:smoke:quick-cmd-form。
Esc关闭窗口,Tab/F1在命令输入框切换当前笔记和临时笔记,F3执行z。- 粘贴目标使用按钮显示当前值,鼠标每点击一次切换到下一个目标,无需激活窗口或展开下拉框;目标旁标注
F1,代码片段选项旁标注F2。 - 右上角最小化、最大化/还原和关闭按钮保持可用;关闭只隐藏 Quick Cmd Form,不退出应用。
- Windows 使用不激活窗口的原生样式保留来源窗口焦点,同时保留正常标题栏操作。
- 最小化时暂停命令按键监听;还原后继续监听,也可用 Quick Cmd Form 快捷键重新显示。
- 命令开始执行时保持 Quick Cmd Form 可见,任务成功完成后再自动隐藏;失败时保留界面和错误信息,便于重试。
- 底部状态栏显示当前步骤:获取源文件路径、复制选区、粘贴、保存比较对象、打开比较器或启动终端等。
- 执行中显示活动进度指示,不显示无法准确计算的百分比;HTML 转换及图片导入的粘贴会等待实际完成确认后再隐藏。
- 执行期间锁定命令输入、目标和代码片段选项,并暂停命令按键监听;原生窗口按钮仍可使用,手动关闭只隐藏界面,不取消正在执行的任务。
Code Snippet Paste(代码片段粘贴)默认关闭,可点击复选框或按F2切换;选项在应用重启后保留。- 开启后作用于
z、vv、da、o1/o2/o3,不改变搜索、比较等其他命令。 - 先复制源文件绝对路径,再复制选区,以纯文本生成 Markdown 路径代码块,保留缩进并自动加长围栏以容纳代码中的反引号。
- 从应用自身已保存的笔记采集时,使用来源笔记路径;未保存来源文件时路径留空。
- Windows 外部 IDE 沿用旧版复制路径快捷键:Visual Studio、Notepad++ 使用
Alt+Shift+F,VS Code、JetBrains 使用Alt+Shift+C,需要 IDE 支持对应绑定。 - 无法获取路径或路径无效时不报错,路径位置留空,仍插入代码片段;稍后在开始围栏后补填路径,即可使用检查、整理和比较功能。
- 路径留空的代码块按普通代码块处理,不参与现有路径代码片段操作;选区没有文本时仍提示错误。
- 生成的顶层路径代码块可直接使用现有代码片段检查、整理和比较功能;不生成旧版外层标记。
- 分隔符、标题前缀、当前/临时笔记目标和粘贴后的额外换行继续生效,主窗口保持后台状态。
- 开启后作用于
- 当前笔记在光标处粘贴并替换选区;临时笔记首次使用时创建,后续追加到同一标签末尾。
z、vv、da、o1/o2/o3在后台插入,保持主窗口原有的隐藏、最小化或可见状态,不抢夺来源应用焦点。- 所有粘贴命令在粘贴内容后额外追加一个换行符,光标停在换行之后;原内容已有的末尾换行也予以保留。
- HTML 转换、内部 Markdown 引用重写和图片导入完成后再追加换行,不把换行插到内容前面。
- 只有
s(全文搜索)和n(标题检索)主动显示并激活主窗口,以便查看和操作结果。 - 其他命令不会主动显示主窗口;
cm和比较命令按用途打开终端或第三方比较器。 - 临时笔记走普通文档保存与草稿恢复流程;关闭该标签后再次采集会新建标签。
- 目标只读、收集器锁定或存在打开的对话框时拒绝插入,并显示原因。
15.1 短命令
| 命令 | 行为 |
|---|---|
h |
切换并保存全局热键启用状态,复用设置中的热键开关。禁用后保留 Quick Cmd Form 启动热键,可再次打开并输入 h 恢复其他热键;菜单和命令面板也可操作。 |
s |
复制选中文本,填入常规笔记库全文搜索。 |
n |
复制选中文本,在快速打开中检索全库标题节点;优先提取旧 <<node: 标题>> 标记。 |
z |
复制并粘贴到目标笔记,不加分隔符;复用现有 HTML 转 Markdown、图片导入及粘贴规则。 |
vv |
复制选中文本并以纯文本粘贴到目标笔记,保留原始文本中的空白和 Markdown 字符,不转换 HTML。 |
da |
复制并粘贴,前置 Markdown 分隔符 --- 和空行。 |
o1/o2/o3 |
复制并粘贴,前置空行及对应 Markdown 标题前缀 #/##/###。 |
cc |
清空主进程及应用窗口的控制台显示,保留磁盘日志。 |
cm |
将选中的绝对目录路径作为工作目录打开 Windows cmd.exe;目录内容不作为 shell 命令执行。 |
q1/q2 |
保存第一/第二个比较对象;现有文件或目录直接复用路径,其他文本写入 UTF-8 临时快照。 |
q3 |
保存第二个比较对象后立即比较。 |
qq |
比较已经保存的两个对象,不重新复制或覆盖第二项。 |
15.2 比较工具与错误处理
-
全局热键开关不禁用
quickCmdForm.toggleWindow,但仍遵守它的自定义键位、平台覆盖和显式移除配置。- 配置草稿无效时,关闭开关仍会注销其他热键,并保留当前已注册的 Quick Cmd Form 启动键位。
- 开关操作按读取模式处理现有草稿;关闭热键后,保存损坏的 JSON 仍会被拒绝。
-
比较优先复用设置中的“外部冲突工具命令”,以两个独立路径参数启动文件、文本或目录比较。
- 两项比较不使用四项冲突合并参数模板;原有冲突解决流程保持不变。
- macOS Beyond Compare 仍复用已有
bcomp可执行文件解析规则。 - 未配置工具时,文件和文本比较沿用 VS Code;目录比较提示先配置外部冲突工具。
-
比较对象保存在本次应用进程内,退出后需重新设置;临时快照退出时尽力清理。
-
复制失败时拒绝使用旧剪贴板,恢复之前的文本、HTML、RTF 和图片内容。
-
短命令窗口显示执行错误并允许重试;命令面板直接执行时通过应用通知显示错误。
每日提示
展示与轮换
- “帮助 → 每日提示”和命令面板共用
help.tipOfDay,默认没有快捷键,可在快捷键设置中绑定。 - 默认每天首次启动时,在首个主编辑窗口恢复完成后自动展示一条提示。
- 按本机日历日期判断,所有窗口共用当天展示记录;同一天重启不会再次自动展示。
- 等待窗口获得焦点及现有弹窗关闭,不抢占其他弹窗或应用的焦点。
- 只有实际打开后才保存当天记录;打开失败或窗口销毁会释放未提交的展示资格。
- 应用持续运行跨过午夜、切换笔记库或新建窗口时不主动弹出。
- 提示窗口显示正文与当前位置,并提供“上一条”“下一条”和“关闭”。
- 按列表顺序循环,首尾相接;手动打开及浏览也推进下次展示位置。
- “每天启动时显示”修改后立即保存,关闭后仍可从菜单或命令面板手动打开。
- 正文仅按纯文本显示,保留换行和空白,不执行 HTML 或渲染 Markdown。
服务器提示与本机缓存
- 首次使用内置 10 条中文技巧,涵盖命令面板、快速打开、大纲、搜索、预览、收藏、
导航历史、代码片段、剪贴板收集器和快捷键设置。
- 已有本机提示保留为缓存,在首次成功获取服务器内容前继续使用。
- 提示内容统一由当前配置的同步服务器下发,客户端不再提供本机编辑功能。
- 启动和打开提示窗口时,后台请求匿名公开接口
GET /v1/system-configs,无需登录。 - 读取
configs["tips.ofDay"]字符串并解析为 JSON 文本数组;管理员通过系统配置维护该键。 - 客户端最多接受 200 条,每条最多 4000 字符,正文不能仅有空白。
- 管理接口的配置值仍受总计 16,384 字符的上限约束,示例与维护方法见 管理 API。
- 同时发起的刷新共用一个请求,后续打开可重新尝试;未配置服务器时直接使用缓存。
- 启动和打开提示窗口时,后台请求匿名公开接口
- 启动恢复、自动展示和手动打开都不等待网络请求完成,直接使用当时已有的缓存。
- 网络失败、配置缺项、无效内容或缓存保存失败都保留原缓存;发生异常时记录完整错误。
- 获取成功且内容变化后才原子保存新缓存,并重置下次轮换位置;不改动开关和当天展示记录。
- 内容未变化时保留轮换位置;服务器地址切换后,丢弃旧服务器尚未完成的响应。
- 已打开窗口保留原内容快照,更新后的内容从下次打开开始使用,不在阅读中途跳换正文。
- 浏览旧快照及确认已展示时,不用旧轮换位置覆盖新缓存的位置。
- 服务端可下发
[]清空缓存并停止后续自动展示。- 手动打开空缓存时显示“暂无提示”,仍会后台检查更新。
- 重启后保留空缓存,不重新填入示例。
- 提示库、开关、轮换位置和展示日期都存储在本机应用级
localSettings。- 所有笔记库和窗口共用,重启保留,不参与账号云同步。
- 本地状态文件读取上限为 8 MiB,以容纳最大合法中文或 JSON 转义提示库。
- 上线需重新构建并重启同步服务端及桌面应用;后续修改服务器提示内容无需重启。
验证与后续整理
test/tip-of-day.test.ts覆盖默认缓存、输入边界、后台请求合并、失败回退和每日展示资格。npm run test:smoke:tip-of-day使用真实慢响应和失败 HTTP 请求,验证启动不等待网络、缓存落盘、 重启恢复、菜单及命令面板、跨窗口开关、只读接口、纯文本安全、键盘焦点和窄窗口布局。- 本次涉及的现有大文件后续集中按职责提取,不为单次功能零散拆分:
src/preload.ts与types/markdown-api.d.ts:按职责整理桥接接口和类型声明。src/renderer/runtime/keyboard.mts与src/renderer/runtime/shell.mts:集中提取命令注册和窗口启动绑定。src/renderer/styles/dialogs.css:按对话框职责拆分样式,并保留加载顺序。- 提取时保留原有注释、日志、异常处理和接口行为。
Windows 应用自动更新
- 正式 Windows x64 NSIS 安装版通过自有 HTTPS 更新源检查稳定版并自动下载。
- 启动 30 秒后及每 6 小时检查;多个窗口共享任务,后台错误保留完整日志。
- 帮助菜单和命令面板共用以下命令。
app.checkUpdate:检查应用更新,显示版本、下载进度和错误。app.installUpdate:重启并安装更新,确认后保存会话和恢复稿。
- 下载优先使用差分,失败时回退全量;安装使用完整 NSIS 包。
- 普通退出不安装;取消关闭或更新前保存失败时撤销安装。
- 更新包通过哈希与签名校验,缓存命中及安装前重新核验发布者身份。
- 开发版、目录测试包和 macOS 禁用自动更新;旧客户端需手动安装一次带更新能力的正式包。
- 详细构建、签名、发布顺序及故障处置见 Windows 自动更新与发布。
托管同步 VIP 空间配额
- 同步 API 支持后台配置普通用户及 VIP 档位,并为账户设置 VIP 与到期时间。
- VIP 档位支持后台价格说明,登录用户通过
/v1/vip-plans获取每档配额和报价,用于移动端升级弹窗。 - 普通档位初始 10 MiB;到期按服务端时间立即回落普通档位,当前文件和每条非删除历史版本按原始字节分别计量,相同内容不去重。
- 超额仅限制增加空间,保留下载、克隆、历史读取及不增加用量的操作;不自动删除数据。
- 档位、到期时间、管理鉴权、迁移和审计接口详见
docs/admin-api.md;本次不扩展桌面 UI。
设置中的个人中心与 VIP 云空间
- 个人中心使用与下方设置分组一致的
fieldset布局,标题显示在legend中。 - 打开设置时,顶部个人中心异步读取邮箱、账号 ID、VIP 名称、到期时间及空间用量。
- VIP 信息只显示一次,不另列“当前档位”。
- 配额超限时,个人中心提示使用与同步中心一致的警示边框、背景和文字样式。
- 无需打开笔记库;账号 ID 可以复制。
- 未登录时可进入现有云同步登录界面;网络失败可重试,其他设置仍可使用。
- 个人中心没有可编辑设置项,不参与保存、取消和未保存修改检查。
- 账号切换、退出或关闭界面后,旧请求结果不会重新显示。
- VIP 状态和有效配额由服务器判定,到期时间使用本机时区展示。
- 到期回落普通档位,过期 VIP 名称仍显示“已过期”。
- 空间用量按当前文件和每条非删除历史版本分别累计,相同内容及跨库引用不去重;删除当前文件保留历史占用。
- 配额旁的“升级空间”打开应用内弹窗。
- 当前用量和 VIP 档位、配额、价格说明来自服务端,价格包含后台填写的计费周期。
- 未填写价格时显示“请联系管理员询价”,档位或用量读取失败可重试。
- 弹窗提示添加管理员微信
unicyb,提供复制微信号和关闭按钮。 - 复制成功在弹窗内反馈,不自动关闭弹窗。
- 手动、普通自动及安全自动同步遇到账号空间不足时,显示需手动关闭的提示。
- 手动触发的同步每次遇到空间不足都会重新提示。
- 每次自动同步优先读取当前会话的本地配额缓存;缓存为空时获取一次,已超额时直接跳过,不扫描文件,不上传、下载或补齐历史。
- 跳过时不刷新文件树或追加仓库同步后的收藏同步;保留本地文件、草稿、队列和上次成功时间。
- 自动重试不重复请求配额;个人中心、同步中心的主动刷新会更新缓存,恢复后正常同步。
- 浮动提示复用同一份缓存用量,不因展示提示额外查询配额。
- 缓存按服务地址、账号和登录会话隔离,仅保留在当前运行内;获取失败不覆盖已有缓存。
- 同步结果同步更新缓存中的空间不足状态;没有缓存且获取失败时不启动文件同步。
- 普通、安全自动同步及整体恢复后的自动同步均遵守该规则。
- 即使没有待上传内容,同步完成后也会检查最新配额并按手动/自动规则提示。
- 自动触发的同步在同一账号本次登录会话中只提示首次;关闭提示后不因定时重试再次弹出。
- 同步中心在配额超限或同步返回空间不足时显示显著警示;关闭弹出提示不隐藏该警示。
- 空间不足错误仅展示带升级入口的配额警示,不重复显示下方通用错误条;其他同步错误仍显示错误条。
- 同步成功并刷新到正常配额后清除中心警示;切换账号时清空旧账号提示状态。
- 提示展示用量,说明部分上传未完成、待同步内容已保留及下载仍可用,并提供“前往个人中心升级”链接;个人中心的“升级空间”再打开升级弹窗。
- 点击“前往个人中心升级”时关闭浮动提示,保留同步中心和个人中心内的配额警示;自动重试不会因此重新弹出。
- 浮动提示始终固定在窗口右下角,不占用任何弹窗的内容布局,也不随弹窗内容滚动。
- 设置、同步中心、升级等模态弹窗打开或切换时,提示仍可点击、关闭或跳转个人中心。
- 重复自动配额错误不替换尚未关闭的提示,普通通知也不覆盖它;手动同步重新提示。
- 上传受阻项目留在持久队列中;独立项目继续处理,同一文件和关联路径保持操作顺序。
- 手动同步,或自动同步启动后才遇到空间不足时,仍尝试拉取远端更新,并保留现有冲突保护。
- 部分完成不更新完整同步成功时间,升级后下次同步重试;请求正文过大不会误报为空间不足。
- PC 端依赖 VIP 版本的
/v1/quota和/v1/vip-plans接口,发布后需重启桌面应用。
后续集中模块提取
- 输入校验修改涉及的超长文件后续统一整理:
src/renderer/runtime/sync/library.mts:提取同步中心列表操作。src/renderer/runtime/editor/selection-toolbar.mts:提取链接弹窗与选区工具栏的协调逻辑。test/electron-smoke.ts:集中提取冒烟场景调度与清理流程。- 本次先在现有职责位置补齐行为,不为单项校验零散拆分模块。
- 个人中心与升级界面集中在独立模块,现有同步入口和通知入口保持原位置。
- 本次涉及的下列现有文件仍超过 800 行,另行集中按职责提取:
src/renderer/runtime/shell.mts:提取窗口事件与同步通知绑定。src/renderer/runtime/sync/library.mts:提取同步中心注册、历史恢复与列表操作。src/renderer/styles/dialogs.css:按对话框职责拆分样式,保持既有加载顺序。test/smoke/renderer/initial-editor-flow.ts:按初始化、编辑和界面入口场景集中整理冒烟流程。types/markdown-api.d.ts:按同步、设置及文档接口分组提取声明。- 合并规划账号 IPC、同步传输与设置界面的模块边界,避免为单次功能零散拆分。
- 提取时保留原有注释、日志、异常处理、公开接口和按需加载行为。
