首页
/ 思源笔记 v2.12.7 版本发布详解:编辑器交互优化、关键缺陷修复与 API 演进

思源笔记 v2.12.7 版本发布详解:编辑器交互优化、关键缺陷修复与 API 演进

2026-09-08 21:53:28作者:秋泉律Samson

本文依据仓库内发布说明 app/changelogs/v2.8.4-v2.12.8/v2.12.7/v2.12.7_zh_CHT.md 撰写。该版本是一次以"修复缺陷、改进细节"为主的稳定迭代,聚焦 Pad 端编辑器操作、表情面板交互、复制粘贴行为、数据库表格视图、移动端滚动与闪卡复习等日常高频使用场景,同时面向开发者开放了文件树接口的新参数。文中除忠实梳理每条变更外,还结合当前仓库源码对若干关键机制进行了印证与展开,便于理解这些改动背后的实现原理。

版本定位与变更总览

思源笔记 v2.12.7 是一个典型的次版本迭代。发布说明开篇即明确其定位:该版本主要是修复缺陷和改进细节,没有引入颠覆性的新特性,而是围绕编辑器、移动端、插件市场、闪卡等模块做细粒度打磨。这一策略保证了主版本(如随后的 v3.x 系列)上线前日常使用体验的稳定性。

整个变更记录分为四大类,具体数量与主题如下表所示:

类别 数量 主要涉及模块
改进功能 14 项 Pad 端编辑器、表情面板、复制粘贴、插件市场、停靠栏、闪卡、移动端、文件树
修复缺陷 5 项 Android 端、表情对话框、数据库表格视图、闪卡复习、卡片复习状态机
开发重构 2 项 Electron 升级至 v28.2.1、KaTeX 升级至 v0.16.9
开发者(API/细节) 2 项 listDocsByPath 新参数、数据库表格视图文本列换行滚动

Pad 端与编辑器交互改进

撤销、重做与 Tab 按钮补齐(#6804)

v2.12.7 在 Pad 端(平板) 新增了撤销、重做和 Tab 按钮(对应 GitHub issue #6804)。此前 Pad 用户需要依赖系统键盘或手势完成撤销、重做与缩进操作,触发路径不直观。本版本将这些高频编辑动作显式化到界面按钮,使平板端在连接外接键盘或使用软键盘时都能快速操作。

从源码结构看,撤销/重做最终落到 Protyle 的历史栈机制,涉及 app/src/protyle 目录下编辑相关模块对撤销记录(undo)与重做记录(redo)的入栈、出栈管理,Tab 则对应文档块的缩进层级调整,与键盘事件的 Tab/Shift+Tab 处理逻辑复用同一套块级操作路径。

表情面板支持 ↑/↓ 键选择(#9133)

表情面板此前主要依赖鼠标点选与搜索过滤,本版本为其加入了 ↑/↓ 方向键选择能力。实现集中在 app/src/emoji/index.ts,该文件通过 keydown 事件监听(约 L437 起)统一处理键盘输入,其中对 ArrowDownArrowUp(L501、L519 附近)进行响应,在面板结果集中移动高亮,随后由回车或再次确认完成插入。

该文件同时展示出表情面板的完整职责链:

  • 通过 filterEmoji() 依据输入框内容过滤并渲染结果;
  • 依据分类(含 custom 自定义分类)分组展示,并将"最近使用"记录维护在 window.siyuan.config.editor.emoji 数组中;
  • 通过 fetchPost("/api/setting/setEmoji", ...) 将最近使用序列持久化到后端设置。

因此方向键选择并非孤立功能,而是深度嵌入了"搜索 → 过滤 → 高亮 → 确认 → 回写最近使用"的既有流程。

自定义表情支持点击编辑与随字号自适应(#9164、#10286)

本版本对自定义表情做了两处交互增强:

  1. 支持点击编辑自定义表情(#9164)。此前在文档中使用自定义表情(自定义 emoji 实际对应仓库内 app/guide 这样的文档资源,或配置中登记的图片资源)时,无法在插入后直接进入编辑状态。本版本补上了"点击即编辑"的入口,例如文件图标等场景也可复用该对话框能力。
  2. 调整字体大小后自动调整自定义表情大小(#10286)。当用户全局调整编辑区字体大小时,正文内以字体尺度渲染的自定义表情应当同步缩放,否则会出现文字变大而表情不跟随的割裂感。该改动让表情尺寸与字号的联动保持一致。

需要说明:以上交互改动属于历史版本的行为调整,当前仓库已演进至 v3.x,相关文件图标与表情对话框的调用入口可在 kernel/api/icon.go(图标 API)与 app/src/emoji/index.ts(表情面板)中追踪。

其余编辑器细节改进

  • 折疊或展開子文件不再跳動(#10311):文件树(文档列表)在折叠/展开包含大量子文档的节点时,此前可能因文档计数或高度重新计算导致视口跳动,本版本对相关计算时机做了稳定化处理。
  • 縮放 150% 時支援完整顯示匯出 PDF 預覽(#10309):在高 DPI / 系统缩放 150% 场景下,导出 PDF 的预览窗口此前可能显示不完整,本版本修正了预览容器尺寸计算。

复制粘贴与剪贴板行为修正

复制纯文本不再携带零宽空格(#10281)

这是本版本中最容易从源码层面印证的一项改动。思源笔记在渲染行级元素(如列表、代码、引用等)时,为满足块与光标定位需求会插入零宽空格字符 \u200b(即 Constants.ZWSP,定义见 app/src/constants.ts)。

为避免用户把"看起来是纯文本"的内容复制到其他应用后出现隐性字符,v2.12.7 在复制纯文本的入口做了清洗:

// app/src/protyle/util/compatibility.ts
export const copyPlainText = (text: string) => {
    text = text.replace(new RegExp(Constants.ZWSP, "g"), ""); // `复制纯文本` 时移除所有零宽空格
    writeText(text);
};

该逻辑在 app/src/protyle/util/compatibility.ts 中仍然保留,注释与发布说明一致。它说明"复制纯文本"与"复制 HTML"是两套不同出口:前者会经过零宽空格剥离,确保目标端不残留不可见字符;后者保留结构信息以用于跨文档粘贴。

改进复制数据库表格视图的粘贴效果(#10282)

数据库(属性视图)表格视图中的单元格复制到外部或内部粘贴时,本版本优化了粘贴结果的保真度,减少因列内容包含换行/复杂结构导致的串列或错位。这项改进与同版本"数据库表格视图文本列换行滚动"(#10307,见下文"开发者"一节)同属对表格视图渲染与复制链路的持续打磨。

文件树、插件市场与移动端细节改进

文件树:新建文件存放位置 为空 / 时自动重置(#10305)

当用户在设置中把"新建文件存放位置"配置为根目录 / 时,v2.12.7 会将其重设为 /Untitled(对应 issue #10305)。

之所以引入该约束,是因为若将新文档默认直接建到笔记本根路径,用户在大量顶层文档混排的笔记本中会不断产生顶层散落文件,后续整理成本较高。将默认位置强制指向 /Untitled 目录,既避免误配置产生的"失控感",也让新内容默认落入明确的归类目录。这属于配置层防御性修正——在后端逻辑中检测到该配置值非法时回退到安全默认值。

停靠栏:浮動觸發位置改為動態計算(#10295)

停靠列(dock)在鼠标靠近屏幕边缘或特定热区时的浮动触发点,此前多为固定偏移,不同屏幕比例/窗口位置下可能出现"明明靠近边缘却不弹出"或"轻微误触即弹出"的问题。本版本将触发位置改为依据窗口当前几何状态动态计算,提升悬浮面板唤出的准确度。相关布局逻辑位于 app/src/layout 下停靠栏(dock)各布局模块中。

插件市场:下载后启动提示与已下载滚动(#10285、#10297)

针对市场(市集)使用体验的两处细节改进:

  • 下載外掛後啟動提示對話框(#10285):插件安装完成后,若该插件要求重启生效,界面会给出更明确的对话框提示,避免用户困惑于"装了为何没生效"。
  • 改進"市集 - 已下載"的滾動互動(#10297):已下载插件列表的分页/滚动加载交互被调整,减少滚动到底部时因加载更多内容而出现的跳动或断档。

市场前后端实现可分别在 kernel/bazaar(插件市场核心逻辑)与 app/src/plugin(前端插件管理)中追踪。

移动端滚动与 Android 状态栏(#10308、#10278)

  • 滾動塊元素時不再觸發左右欄面板(#10308):移动端在文档内纵向滚动较长的块元素(如长表格、代码块内的滚动容器)时,此前可能被误判为"水平滑动"从而拉出左右侧栏。本版本对滚动方向判定增加了约束,只有明确的方向意图才会切换面板。
  • Android 端狀態列顏色異常(#10278,缺陷修复):修复 Android 上沉浸式状态栏在浅色/深色主题切换或键盘弹出后颜色不跟随主题的问题。相关实现可参考 app/src/mobile 下移动端 UI 适配代码与 app/src/config 主题配置项。

闪卡相关改动:样式、计数与状态机

本版本在闪卡(Flashcard)模块集中处理了三处问题:

Issue 类型 改动说明
#10296 改进 退出对焦后显示闪卡样式——复习结束或取消聚焦后,确保卡片恢复正确的视觉样式而不停留在"编辑中"的高亮态
#10312 缺陷修复 复习时切换文件树后刷新计数——闪卡复习界面与文件树联动时,若用户在复习过程中切换了文档树位置,卡片数量统计需要同步刷新,此前存在不刷新的问题
#10320 缺陷修复 卡片为 0 时 updateCards 返回完成页——当待复习卡片数为 0 时,前端更新卡片列表的逻辑会直接进入"完成"页面状态,避免卡在空白或加载态

闪卡内核实现位于 kernel/model/flashcard.go,前端的复习流程、卡片刷新与状态切换逻辑则分布在 app/src/config 相关闪卡面板模块中,可通过 updateCards 字样在 app/src 内检索对应调用链。

开发重构:Electron 与 KaTeX 升级

  • 升級 Electron v28.2.1(#10291):桌面端外壳从既有版本升级到 Electron 28.2.1,以获得该版本中 Chromium 与 Node.js 运行时层面的安全修复与稳定性改进。Electron 相关配置位于 app/electron(主进程 main.js)以及根目录 electron-builder*.yml 打包配置中。
  • 升級 KaTeX v0.16.9(#10321):数学公式渲染库升级至 0.16.9,属于小版本安全/缺陷跟进。KaTeX 主要服务于行内与块级数学公式渲染,在渲染管线中由内核通过 kernel/util/lute.go 配合 Lute 引擎处理 Markdown 数学语法后交给前端 KaTeX 输出。

需要说明的是,当前仓库已处于更高版本(应用版本见 app/package.json,桌面壳依赖的 Electron 版本亦已远高于 28.x),说明项目在后续版本中持续跟进依赖升级,v2.12.7 的这两次升级正是该演进路径上的中间步骤。

面向开发者:listDocsByPath 新增可选参数 ignoreMaxListHint(#10290)

这是 v2.12.7 中唯一面向 API 调用者的正式接口变更,值得展开。内核实现可直接在当前仓库源码中验证:函数体位于 kernel/api/filetree.go

接口语义

listDocsByPath 用于按路径列出某笔记本(notebook)下的文档。为保护前端性能,内核默认有文档树最大返回数量限制(读取自 model.Conf.FileTree.MaxListCount)。当某目录下文档总数超过该阈值时,内核只返回前 N 条,并通过消息中心向客户端推送"列表过长"的提示。

ignoreMaxListHint 的作用正是抑制这条提示。相关实现(L1152-L1164):

if maxListCount < totals {
    // API `listDocsByPath` add an optional parameter `ignoreMaxListHint`
    ignoreMaxListHintArg := arg["ignoreMaxListHint"]
    if nil == ignoreMaxListHintArg || !ignoreMaxListHintArg.(bool) {
        // 仅当未显式开启 ignoreMaxListHint 时才推送提示
        ...
        util.PushMsgWithApp(app, fmt.Sprintf(model.Conf.Language(48), len(files)), 7000)
    }
}

与既有参数的关系

注意 ignoreMaxListHint 与早先引入的 maxListCount(#7993,同样见 kernel/api/filetree.go)职责互补:

  • maxListCount控制截断阈值。调用方可传更大的值(传 0 或负值则被内核解释为 math.MaxInt,即不限制)来"多拿一些结果";
  • ignoreMaxListHint只控制提示,不影响返回数量。即便目录总数仍超过阈值、返回结果仍被截断,只要置 true 就不会弹出提示。

两者都未显式传值时,行为与旧版本一致:按全局 MaxListCount 截断并弹提示,保证向后兼容。

典型调用示例

以 REST API 方式调用(思源内核默认监听 127.0.0.1:6806,需携带 Authorization: Token <token> 头,具体鉴权方式见 kernel/conf/api.go):

{
    "notebook": "20210808180117-6v0mkxr",
    "path": "/",
    "sort": 0,
    "ignoreMaxListHint": true
}

当调用方(如移动端、第三方脚本)在周期轮询目录明知结果可能超限的场景下,置 true 可避免每条超限请求都触发 7 秒的消息提示干扰;若仍需完整列表,应同时配合较大的 maxListCount

同类参数在内核中并非孤例:getTag API 也提供了 ignoreMaxListHint,用于在标签总量超过阈值时跳过提示(见 kernel/api/tag.gokernel/model/tag.go 中对 Conf.FileTree.MaxListCount 的比较)。这从侧面印证了该提示机制在文件树与标签两大模块中的通用设计。

开发者相关其余改动:数据库表格文本列换行滚动(#10307)

另一条列入"开发者"分类的改动是数据库表格视图中文本列换行滚动的改进:长文本单元格支持在列宽受限时按需换行并可滚动查看,避免内容被截断或挤压其他列。表格视图的前端渲染逻辑位于 app/src/protyle 中与属性视图表格(NodeAttributeView)相关的模块,内核数据组装可参考 kernel/sql/av_table.go

缺陷修复清单速览

除上文已展开说明的 Android 状态栏(#10278)与闪卡相关修复(#10312、#10320)外,本版本还包括两项值得注意的修复:

  • 文件图标使用自定义表情时无法打开表情对话框(#10280):为文档/文件夹设置图标并选用自定义表情时,点击图标本应唤起表情选择对话框,此前在特定条件下无响应。该对话框入口与自定义表情渲染同属图标/表情模块,相关接口见 kernel/api/icon.go
  • 无法删除数据库块前的表格块(#10284):当普通表格(table block)紧邻数据库/属性视图块之前时,删除操作可能被拦截。该问题与块级删除的事务处理有关,块操作链路见 kernel/model/block.gokernel/api/block_op.go

如何获取与追溯该版本

v2.12.7 属于 v2.8.4–v2.12.8 发布说明目录(app/changelogs/v2.8.4-v2.12.8)中的一个里程碑。除本文依据的繁体中文版外,该目录通常同时提供简体中文与英文版本;完整的历史演进可进一步阅读仓库根目录 CHANGELOG.md

值得留意的是:当前仓库主线版本已明显高于 v2.12.7(应用版本见 app/package.json),阅读本历史发布说明的价值在于理解以下三点:

  1. 日常高频体验(表情、复制粘贴、移动端滚动、闪卡)是如何被逐轮打磨的;
  2. ignoreMaxListHint 这类"向后兼容式新增参数"体现了思源 API 的演进风格——默认行为不变、显式传参即可获得新能力;
  3. Electron/KaTeX 等基础依赖的升级节奏,与仓库当前依赖树(Electron 主进程与打包配置见 app/electron)形成对照,可观察项目技术栈的持续迭代路径。

对于仍停留在 v2.12.x 的部署,可依据官方下载渠道获取对应安装包进行升级;对于已升级到 v3.x 的用户,本版本绝大多数改动能力均已并入后续主版本,无需单独回退安装。

小结

思源笔记 v2.12.7 以"小步快跑"的方式完成了编辑器、表情、复制粘贴、文件树、移动端、闪卡、插件市场等多个模块的细节打磨,并以 listDocsByPath 的可选参数 ignoreMaxListHint 为 API 使用者提供了更可控的超限提示策略。从源码印证角度看,零宽空格清理(app/src/protyle/util/compatibility.ts)、表情面板键盘选择(app/src/emoji/index.ts)与文件树列表提示抑制(kernel/api/filetree.go)三条主干的实现至今仍清晰可查,读者可直接按文中给出的相对路径进入仓库继续深挖每条改动的具体代码上下文。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391