1.
我不是一个重度的笔记用户,我也不需要知识库,一直以来我都期望有这样一个应用,它的功能不用比苹果备忘录更多,遵循标准的 Markdown 语法,所见即所得,并使用 iCloud 同步。
尝试过一些产品:
- 苹果备忘录并不支持 Markdown,于此同时我也不喜欢它的三栏结构、因为 Tahoe 而变得更细碎的工具栏、黄色的高亮。
- Notion 的性能不太好,书写体验糟糕,当然它的定位也并不是写作应用。
- Craft 曾经能一定程度上能满足我的需求,直到转型「协作」后不可避免地变得臃肿。
- 我不喜欢 Bear 的视觉和它基于 Tag 的文件管理方式。
- Typora 的 UI 很粗糙,像 Windows 的一样经不起推敲 (误)。
- …
最终我停留在了 Obsidian 和 Raycast Notes。
Obsidian 的 UI 不比 Typora 好更多,但是可以通过插件隐藏很多我不需要的功能和元素来维持一种相对简洁的状态。由于没有所见即所得,大部分时间我其实只是把内容粘贴进去。
Raycast Notes 很好地满足了我随手记的需求,它的书写体验优秀,也是少数真正能够隐藏 Marker 的 WYSIWYG,但它几乎没有文件管理的能力,并且非订阅用户只能创建5个笔记,但 Raycast 良心到没有任何其他功能需要我订阅以至于为了 Notes 订阅而显得不太值。
2.
在尝试开发过 iOS app 后,我确实对 AI 的 Coding 能力过于自信了,第一版天真地选择了以纯原生为目标。我尝试用 Tree-sitter 做 AST,TextKit 2 做渲染,但是最关键的 Editing Model 并没有现成方案,在这一层中,每一次编辑都需要被解释为对文档的结构操作,同时还要维持文本与 AST 的一致性、支持增量更新,并处理选中、输入法、undo/redo 等一系列细节。知乎上有一个关于「为什么都说富文本编辑器是天坑?」的讨论,在这里我算是体会到了。
第二版我转向了 CodeMirror + Webview,花了不少时间,虽然最终可以通过语法树与 decoration 构建出接近所见即所得的体验,但其底层仍是基于字符范围的编辑模型。当渲染结果与原始 Markdown 出现偏离时 (比如将 **bold** 渲染为不显示语法标记的 bold ),光标、选区以及结构操作都会变得不稳定。所以很少有项目用 CodeMirror 来做所见即所得,确实也是有道理的。唯一的收获是这个阶段参考 MarkEdit 学习了一些 Webview 架构。
第三版,彻底放弃了自定义编辑语义,转向了 Tiptap。Tiptap 是基于 ProseMirror 实现的,而 ProseMirror 和 CodeMirror 竟然是同一个作者,令人惊叹。
3.
Tiptap 在 Webview 上的表现其实很一般,光标的表现甚至有些 buggy,比如在淡出时尝试点击会触发一瞬间的高频闪烁,硬换行后光标也会莫名变长一点…不过基于这些表现倒是可以发现不少应用也采用了类似的技术方案,比如 Raycast Notes。
唯独有一点与 Tiptap 自带的 List 不同,Raycast Notes 的列表层级是扁平的,相比自带列表基于嵌套节点的层级结构,我更喜欢这种自由的用法。调研了一圈我找到了 prosemirror-flat-list,我高度怀疑 Raycast Notes 集成了它。
这里有个插曲,我后来发现 Xcode 自带的开发者工具 Accessibility Inspector 可以直接读取选中元素的 UI 层级结构,在选中 Webview 内容时,能够看到某些框架特有的 Dom Class,这让我得以验证对 Raycast Notes 技术架构的判断。
最后,虽然仍然花费了大量时间在处理编辑交互细节和 Webview 特有的糟糕体验,但好歹能用了。当然有了 AI,这些其实都并不值得一提。
4.
我终于可以按照自己的想法来定制。
我避开了 Tahoe 可笑的悬浮侧栏,使用 Appkit 来手写一整套侧栏交互,这带来了不小的复杂度:AppKit 会把一个用户动作拆成很多彼此独立的回调,而这些回调又会和异步的数据写入、状态恢复、选中投影交错,导致很容易出现 UI 状态和业务状态发生漂移。
我不打算放置用来格式化的工具条,也不打算增加数学公式渲染,我认为大部分人和我一样不需要,事实上我也认为大部分博客系统/主题不应该默认携带这个功能。
我使用最简单的文件夹层级来管理,使用 SQLite 来存储数据因此能获得高效的搜索能力。
在 Figma 上我最喜欢的一个小功能是折叠所有图层 (⌥ L),现在我也可以效仿它来一键折叠所有文件夹,相对的,我也增加了快速定位文件以展开对应文件夹的功能。
作为快捷键爱好者,我为大部分功能增加了快捷键。
我提供了一些简单的外观定制选项,大部分都是因为我觉得都不错而拿不定主意但是也不会因此增加复杂度的地方。
当然我还是想说,在每个人都可以用自然语言捏制软件的当下,这些其实也不值一提。
5.
我还没有加入任何 AI 功能,虽然这在今天显得有些落后。
我不认为笔记这种自然语言文本产物,会比代码这种需要严格结构才能成立的内容更需要定制化的 AI 能力,实际上在 Claude Code 出现之后,我认为通用的 Agent 会接管所有可被抽象为意图的需求,谁曾想 Cursor 一度是人们想象中的用 AI 写代码的样子,但现在就连 ide 都不再被需要。
我不希望为了耦合未必有人会使用的 AI 功能而牺牲产品架构的整洁性,追赶 AI 很累,今天加入的功能也许明天就会被更通用的外部能力吞并,最后什么都留不下来。
如果可能的话,我希望苹果在系统层做好文本的通用生成能力。所以国区究竟什么时候可以准备好 (x)
6.
最近经常看到的一个观点是「不要把 AI 当作许愿机」,我当然知道它的本意是不要直接向 AI 提出模糊的需求,但事实上 AI 确实变成了我的电子许愿机。
我能理解那些以技术门槛标榜自己并以此获得满足感的人在此时感到沮丧,但如果使用技术的目标始终是满足自己的癖好时,这件事情会简单很多。
事实上有很多软件的需求,都因为养不活团队而在以往的市场环境里无法被满足,那么现在就是最好的时机自己来动手。至于「GUI 不再被需要」「未来软件只需要给 Agent 使用」,我不知道,我现在就只是需要一个简单的笔记应用而已。