Crystal Vault

by Zhangrunyao
5
4
3
2
1
Score: 51/100

Description

把知识卡片从一堆笔记,变成一张能看、能读、能改、能长的工作台。

Reviews

No reviews yet.

Stats

1
stars
193
downloads
0
forks
15
days
1
days
1
days
0
total PRs
0
open PRs
0
closed PRs
0
merged PRs
0
total issues
0
open issues
0
closed issues
96
commits

README file from

Github

Crystal Vault(晶体库)

把一文件夹的 Markdown 卡片变成一座能看的知识晶体库。 QQ 群:831440768

截图预览:

桌面模式:

故事线模式:

而它真正的战场是文献模式:一边读 PDF / 图片 / Markdown,一边把读到的东西当场立成结构—— 读完一章,那一章的结构也就搭好了。桌面把这些摆成一桌能拖能缩的窗, 结构窗让库的结构跟你正在读的那一页并排待着,不用切走。

卡片就是普通的 Markdown,文件夹就是文件夹。没有任何东西被锁进数据库,也不出你的 vault。

English: README.en.md。


主功能:文献模式 · 桌面

阅读器有两种版式:网格是一屏摊开 N 页(翻页扫读用),桌面是一页一扇窗 ——后者是主力,因为它把「我要同时看几样东西」这件事交回给你自己。

  • 一页一扇窗,摆法自己定。 拖标题栏挪位置、拉右下角改大小, 关掉阅读器再打开,摆法原样还在。

  • 桌上不只有文献页。 卡片、结构、网页都是同一种窗,共用同一套拖、缩、收。 卡片窗顶上会显示这张卡的概念,那行里的公式照常渲染。

  • 收纳栏(顶栏那颗按钮)。左边出来一条竖栏,是这些窗的架子:把窗拖到栏上, 或者按窗上的「收纳」,它就收起来、栏里留一条,点一下再拿出来。 收着的窗,关掉阅读器也还在库里。

  • 外部标签页(收纳栏最上面那颗 +)。填一条网址,网课、文档站就挂在你正读的 那一页旁边,和别的窗一样能拖能收。

    ⚠️ 网页嵌不嵌得进来由那个站说了算,不是这个插件说了算:站点可以用响应头 拒绝被别的页面嵌(Google 系一律拒绝),这是浏览器的规矩,绕不过去。 所以那扇窗里常驻一颗「用系统浏览器打开」——嵌得进去当窗用,嵌不进去也始终有出路, 不会给你一个白框。

  • 右栏也能收。 同一颗「收纳栏」按钮还能把右边「边看边记」那一栏挤回去,读宽一点。

+ 页:Markdown 是按行分页的

顶栏那颗「+ 页」每按一次,就把这份文献的下一段摆到桌面上。 对 Markdown 来说「一段」是行数——接着桌上最后一扇的结束行,往下 40 行。

想改某一扇看的是哪几行,就改它标题栏里那两个框:「起始行」和「结束行」, 改完按回车。旁边那颗「共 N 行」是这份文件今天的总行数,挑区间时拿它当尺子。

同样的规矩也适用于 PDF / 图片那一档:它标题栏里那个框是页码,也是改完按回车。

这是和桌面配着用的那一半。

读文献最烦的是「这块东西在库里到底长什么样」——切过去看一眼,回来就得重新找刚才那行。 结构窗把这层结构开成你桌上的一扇窗,和正在读的那一页并排:

  • 看一眼,不是离开。 切走是「离开」;一扇窗只是瞥一眼。
  • 固定看一颗。 顶栏那颗「晶体:…」换看哪颗,下次打开还是它。
  • 顶栏挡着就收起来。 顶栏最左边那颗 ▲ 是整条栏的开关,颜色就是状态: 蓝 = 按钮都摆着;白 = 全收起来了,屏幕上只剩这一颗。再点一下全回来。 收没收起记着,下次开窗不用重收。

画线:看 / 写

顶栏那颗「画线:看 / 写」管的是拖一根线的后果:

档位 拖一根线,会发生什么
看(默认) 画一根金线。它存在库里,一个字都不碰你的笔记。
写 往起点那张卡的正文里真写一条 [[目标卡]]——笔记跟着变。线是蓝的。

蓝跟金的区别说的就是这件事:金线是一种看法,蓝线是笔记里真有的东西。

你亲手拖过连接点的那一根线,接法会写进这张卡自己的 frontmatter(字段 晶体接法)——所以它跟着笔记文件走:改名、搬到别的文件夹、压缩发给别人, 都还在。没过手的那些不写,它们按位置算就够了。

蓝线接在卡片的哪一边,默认按位置算:上下叠着的两张走「下→上」,左右摆的走 「右→左」。想改成别的走法,在写模式下从你要的那条边拖一次,那一根就按你拖的走 (手动拖过的永远压过默认)。

在写模式下把蓝线框住删掉,删的是卡片正文里那条 [[链接]],不是画在屏幕上的东西。 删错了可以撤销一次(和卡片编辑那条撤销同一套)。

右键:三种落点,三种结果

  • 对着卡片右键 → 隐藏这张卡片所有的入链和出链。 一张卡连进连出十几根线的时候,把它整个收干净、只留别的, 一眼就能看清剩下的结构。再右键一次就放回来; 只要有东西藏着,顶栏就会出现一颗「显示全部」,一下全放回来。
  • 右键落在金线上 → 进连线编辑模式。 顶栏出现「选框:线」和「选框」两颗, 拖鼠标就能框住几根线;框住之后出现「删除实线(N)」。 (右边那颗「选框:线」点一下会变成「框:卡」,那是整批挪卡片用的,见下一节。)
  • 右键空白处(在「写」档下)→ 也出现「选框」,但这一档框的是蓝线。 框住之后是「删除蓝线(N)」——按下去会从卡片正文里把对应的那条 [[链接]] 删掉。

一个细节:「对着卡片右键」这个入口是由「写」档开的——在「看」档下, 右键卡片仍然是老行为(进连接模式)。但已经藏起来的卡,两种档位下右键它都管用, 不然你一切回「看」,藏起来的东西就只剩顶栏那颗按钮能救了。

收纳方框:把一片收干净,但线不算断

画面上那些虚线框是收纳方框。每个子晶体自动一个,名字就是文件夹名; 框可以改名(点名字)也可以收起(点左边那个小三角)。

框有两种颜色,含义不一样:

是什么 是容器吗
金色(点线,暖) 子晶体——文件夹长出来的 是,见下
蓝色(虚线,冷) 你用「+ 框」自己画的 不是,卡片随便进出

金框一层一个、层层套起来(1.3.88 起)。一个文件夹的框里,装着它自己的卡, 外加它每个子文件夹各自的框,所以整棵树的层级一路看得见。框内部横着切:

┌ A ─────────────────────────────────┐
│  [A 自己的卡]  ┃  [B1 的卡]  ┊  [B2 的卡] │
└────────────────┸────────────┸──────┘
        珊瑚橙竖线 ↑      金色竖线 ↑
      (本级 ↔ 子文件夹)  (同级 ↔ 同级)
  • 珊瑚橙 #FF6B6B 分的是这个文件夹自己的卡和它的子文件夹;
  • 金色分的是两个同级子文件夹。

金框是容器。 里面的卡拖不进别的金框,也拖不过那条珊瑚橙线到上一级"自己的卡"里 ——卡片停在边界上。蓝框不能移出它所在的那个金框(拖和拉大小都出不去), 但蓝框本身不是容器,卡片照样进出。拖金框时里面所有东西跟着走,蓝框也跟。

你画的框属于你画它的那一层。 在「Python/数据分析」里建的框,切到 「Python/爬虫」就看不见了——回到那一层它原样还在。以前不是这样:框是全局的, 换一个文件夹看,别的层画的框还在原地摆着。

点「+ 框」建出来的框落在你正看着的地方(视口正中),而不是世界的某个固定角落 ——以前框建在固定的 (60,60),视口推远了就得先推回去找它。新建的卡片同理。

框里任何一块空白都能拖动整框(1.3.83 起),不只是顶上那条标题栏——按住框的边、 框的空处都行,框和里面的卡一起挪。压在卡片上时拖的仍然是卡片(卡片层级更高), 所以想挪卡片就按卡片,想挪整框就按框的空白处。拖动按格点走,见下面 「一格一格地摆」。

收起之后,框里的卡和连着它们的线一起收起来——但「那边还有东西」这件事不会丢:

  • 外面凡是有蓝线连进去的卡,右上角点一个黄色实心圆点;
  • 鼠标悬停那张卡,和它有关联的、正收着的框会绕边闪一圈。

不这么做的话,收起读起来就是「我的双链丢了」,而你明明没删。 框展开着的时候,里面的卡照常可以往外连蓝线——跨级连也没问题。

框:卡 —— 一次挪好几张

结构窗顶栏有两颗挨着的按钮,各管一件事,别混:

按钮 它说的是
选框:线 ⇄ 框:卡 框住的东西是什么
选框 ⇄ 退出选框 现在能不能框

默认是「选框:线」:右键进连线编辑模式之后,拖鼠标框住几根线,再点「删除实线 / 删除蓝线」。 点一下「选框:线」,它变成「框:卡」——这时拖出来的方框框的是卡片:

  1. 框住几张卡,它们会亮起青边;
  2. 按住其中任意一张拖走 = 整批一起动;
  3. 松手时整批一起判归属:拖进收纳方框就归它,拖到框外就移出来;
  4. 想清掉它们:点顶栏那颗红框的「删除卡片(n)」——连笔记文件一起进回收站。

少了这一条,把十几张卡收进一个框就只能一张一张拖;要清掉一批,就只能切回库里 一张一张走「删除卡片」。

  • 按住没被框住的那张,只挪它自己——框选之后顺手拖一张别的, 意思显然是「我要挪这一张」,不是「顺便把刚才那几张也带上」。
  • 「删除卡片」删的是卡片文件本身(不是解绑、不是隐藏):它连那张笔记一起进 回收站,能捡回来;那张卡所在的晶体不动。它只在真有卡被框住时才出现, 张数写在按钮上——这扇窗没有确认弹窗,按钮上的数、悬停那句话、底下那条说明 就是全部的告知。
  • 按 D 在卡档里不删卡:一个裸按键就能把好几个文件扔进回收站太容易误触 (那会儿手正放在方向键上挪卡片)。要删就走那颗按钮。
  • 框选本身不动你的笔记一个字——「删除实线 / 删除蓝线」那颗按钮在卡档里会 自己收起来,因为卡档里没有线可删。
  • 框选完之后想让它们不亮:点一下空白,或者按 Esc。

卡片的位置会跟着笔记走

卡片摆在哪儿,写进卡片自己的 frontmatter 里(字段叫 晶体坐标)。所以换一台电脑、 装同一个插件、打开同一个库,卡片的相对摆放位置和你这台机器上一模一样—— 视图状态是每台机器各存各的,只有写进文件才跟着走。

字段长这样,单位是「格」(最小单位 = 卡片宽的 1/10 = 21px),以左下角为准:

晶体坐标: [3, 5]

字段名带「晶体」前缀是故意的:这个插件装在别人的库里,而 坐标 是个 太通用的名字——谁要是有个自用的同名字段,会被静默顶掉。

  • 金色方框不用单独存:它的位置和大小就是里面卡片的包围盒,卡片跟着文件走, 它自然跟着走。
  • 收纳方框也有自己的文件:每颗晶体一个 .crystal-boxes.json,就放在那颗晶体的 文件夹里。点开头 → Obsidian 的文件列表里看不见,也不会变成一张卡片 (适配层另外只认 .md,两道都挡得住)。里面存的是框的左下角坐标、 名字、大小、收起状态和成员。手改前先关掉 Obsidian。
  • ⚠️ 同步通道必须带点开头的文件。FNS 走文件系统那一层,没问题; 换成会跳过 . 开头的通道(Obsidian 自带的 Sync 就是),这个文件传不过去, 框就只在你这台机器上——那种情况下你不会收到任何提示。
  • 外来卡(「导入卡片」引过来的)也不写:它在你这层的落点和它在自己晶体里的 位置是两回事,写进去就等于改了它老家的位置。
  • 写盘是拖完停一小会儿才做的(你有多端同步,拖几下就写几次会引发同步风暴)。 写完之前关掉库也会催一下,不会白摆。

一格一格地摆:卡片的格点与方向键

卡片在故事线里落在一层格点上,坐标以左下角为准——两张卡并排时,是下边对齐。

按键 一步走多远
← → 42px(最小单位的 2 倍,5 步正好一张卡宽)
↑ ↓ 21px(最小单位)

最小单位 = 卡片宽的 1/10 = 21px。 就是这么算出来的:每张卡大小一样,拿它当尺子, 整张图自然就对得齐。

拖一张卡,停在哪儿就自动落到最近的格点上;框选之后按方向键,一格一格挪。

  • 收纳方框也走格点(1.3.83 起):拖动时框的左下角吸到格点上,框里的卡按 同一段位移整体挪,它们之间的相对位置一点不变。大小仍然随你拉—— 框是你画出来的容器,多大由你定,只有摆在哪儿才需要对齐。
  • 金色方框(文件夹长出来的那个)按整格移动。 它的位置和大小是从里面的卡片 算出来的,自己没有坐标可吸,所以吸的是位移:框和里面的卡一起按整格的 整数倍走,同样是整体平移。
  • 已经摆好的旧位置不会被集体挪动。 格点只在你下一次拖它 / 按方向键时生效 ——不然那是一次没人按过按钮的破坏。代价是一张从没被碰过的老卡可能停在格外, 动它一下就归位。

导入卡片:把别的晶体里的卡借过来

一颗晶体只画得下它自己文件夹里的卡。可你常常想让 A 晶体的卡去连 B 晶体的卡—— 这时候点结构窗顶栏的「导入卡片」,从别的晶体挑一张进来:

  1. 它落在窗的正中间(不是自动排到某个角落——你看得见,才知道它进来了);
  2. 拖它进任意一个收纳方框就归它,跨级连蓝线从此成立;
  3. 不想要了,点它右上角那颗 ✕。

引进来的卡是点线紫框,一眼能和本层的卡分开。它本身一个字都不动: 还在原来那个文件夹里,别人指向它的双链也都在。拿走再引回来,连你给它摆的位置都还在。

  • 引一张本来就在这颗晶体里的卡会被挡下来,并告诉你为什么。
  • 只有结构窗里能引;引进来之后,在晶体库的故事线上看同一颗晶体,它也在那儿。
  • 「删除实线 / 删除蓝线」和它无关——引卡不会删任何东西。
  • 一颗晶体最多引 500 张(这只是一个防坏存档的上限,正常用不到)。
  • 引来的卡进不了子晶体框——那种框的成员是文件夹长出来的。拖进去它会告诉你 一句,要给它分组请用「+ 框」建一个手动框。
  • 选择器里点文件夹名是展开它(不是"就选这个文件夹")。挑卡片的三档 (导入 / 删除卡 / 重命名卡)都是这个手感。

边看边记:读到什么,当场立成卡

阅读器右边那一栏。填卡片名 / 概念 / 来源 / 正文就能建卡,不用离开这一页。

  • 想用真编辑器写:点「✎ 在编辑器里写」,它先把卡建出来,正文改用 Obsidian 自己的 实时渲染编辑器(边写边渲染、自动存盘)。
  • 反悔了:点「返回」,刚建的那张卡撤掉,正文原封不动转进草稿纸。
  • 草稿纸:一块用原生编辑器写的便签,落在你指定的文件夹里,不建成卡片。
  • 卡片盒:搜库里的卡片,点一张就摆到桌面上,并在那张卡里留一行指回这一页的链接。
  • 重命名卡片 / 重命名晶体就在这一栏。走的是 Obsidian 自己的改名通道, 所以全库指向它的 [[双链]] 会一起跟着改。
  • 挑文件夹那块面板抬头有一颗「取消」(1.3.83 起)。「将建在」、新建 / 删除 / 重命名晶体、删除 / 重命名卡片、结构窗挑晶体,打开的都是这块面板,关闭统一走 这一颗——它只收起面板,什么都不改。

晶体库:不读文献的时候

  • 一个文件夹 = 一颗晶体。卡片目录下的每个子文件夹在环上就是一颗晶体,可以一层层钻进去, 面包屑随时告诉你站在哪儿。
  • 双链变成形状。正文里写 [[另一张卡]],两张卡之间就出现一根线。故事线按连线拓扑 把整颗晶体铺开。A→B 与 B→A 合成一条、两头带箭头:一个箭头是单向,两个是互相。
  • 孤岛是信号,不是错误。既没链出去也没人链它的卡会被标出来——那是还没接进任何脉络的卡。
  • 先想再看。回忆模式下卡片内容默认遮住,点一下才显示;复习模式全部摊开。
  • 就地改。点面板右上角那颗笔,原地改概念 / 来源 / 标签 / 正文——不跳转、不开新标签页。
  • 删除走回收站。删晶体、删卡片,都按你在「文件与链接 → 删除的文件」里选的那一档,能捡回来。

为什么不直接用图谱?

图谱回答的是「这张笔记和谁有关系」——它以笔记为起点、连线是主角,而文件夹根本不在图里。 如果你的知识是按科目和章节组织的,图谱会把你所有东西搅成一团。 这正是很多人觉得它「好看但没用」的原因:他们找不到自己组织知识的那条线。

晶体库问的是另一个问题:「这一块知识里有什么、长到什么程度了」。它以文件夹为起点, 结构本身就是主角。

它不是更好的图谱,是不同的起点。

三种打开方式:全屏 / 浮窗 / 嵌入

点侧边栏图标打开晶体库,默认是全屏——铺满整个窗口、盖在笔记上。 另外两档在插件设置的「打开方式」里选,库里顶栏那颗按钮也能随时循环切 (全屏 → 浮窗 → 嵌入,按钮上写的就是下一档叫什么):

长什么样
全屏 铺满整个窗口,盖在笔记上。老行为,也是出厂默认。
浮窗 收成屏幕上一块矩形,浮在笔记上——一边看笔记一边用库。
嵌入 就长在它那颗 Obsidian 标签页里,不盖任何东西。可以和别的标签页左右分屏。

浮窗:拖顶栏挪位置、拖右下角改大小;位置和大小跟着 vault 走, 换台机器打开也在你放的地方。

  • 三档切换都会重开一次视图(阅读器里开着的文献、桌面上的窗会没)。这一档换的是 库的几何,原地改总有一块不跟着变。
  • 文献阅读器、卡片面板这些也都待在当前这一档里——浮窗里点开一张卡, 面板不会盖住你的笔记;嵌入模式下它也只占这颗标签页。
  • 嵌入模式不锁笔记的滚动(另外两档会——它们盖在笔记上,背后不该跟着滚)。
  • dataviewjs 那种用法没有这几档(它本来就嵌在笔记里),所以那颗按钮不会出现。

遇到问题 / 想提意见

QQ 群:831440768

装不上、用着哪儿不对劲、想要个什么功能,都可以直接进来说。 (在 GitHub 上开 Issue 也一样, 只是群里问一句通常快得多。)

安装

在 设置 → 第三方插件 → 浏览 里搜 Crystal Vault。

手动装:从 最新 Release 下载 main.js / manifest.json / styles.css,放进 <你的 vault>/.obsidian/plugins/crystal-vault/, 然后在 设置 → 第三方插件 里启用。

上手

  1. 在插件设置里把卡片目录指到你放笔记的那个文件夹。默认是 cards—— 还没有的话,在 vault 里建一个叫这个名字的文件夹就行。 设置页会当场告诉你这个路径在不在、里面有几颗晶体。
  2. 往卡片目录里放一份能读的东西——你在看的那本书、那门课的讲义、那份论文。 PDF 最好(图片也行)。别放一个空文件进去:阅读器只会说一句 「这份文献里没有可显示的内容」。放进去之后它就会出现在阅读器的文献清单里, 第 6 步要用。
  3. 点侧边栏那颗宝石图标(或运行命令 Crystal Vault: Open)。
  4. 在卡片目录里建一个子文件夹——那就是一颗晶体。
  5. 按下面的格式写一张卡,再用 [[双链]] 把它连出去。
  6. 点顶栏的「文献」进阅读器,选刚才放进去的那一份,开始读; 切到「桌面」,再点「结构窗」——这就是它日常的样子。

放什么格式:阅读器认 PDF / 图片(png、jpg、jpeg、gif、webp、bmp、svg、avif)/ Markdown。 PPTX 不在里面,也加不了——先自己导出成 PDF 再放进来。

⚠️ 放进卡片目录的 .md 会同时是一张卡片(子文件夹 = 晶体,.md = 卡片), 也就是说那份 markdown 会一起出现在库里。想图干净就放 PDF。

卡片格式

---
概念: 一句话说清它是什么
来源: 哪本书 / 哪节课 / 哪份文献
tags: [科目, 类型]
---

先用自己的话说清它是什么……

接着看 [[02-下一张]] 连过去的原因就写在后面

==高亮== 的部分会被抽成自测点。
字段 在库里长什么样
(文件名) 卡片的标题,卡片- / 卡片_ 前缀会自动剥掉
概念 面板顶部那一行
来源 悬停浮层里的「来源」
tags 卡面上最多显示前 6 个

四条让库活起来的习惯:至少连一次(不然是孤岛)· 连的时候写下理由 · 用编号前缀控制顺序(01- 02-)· 想自测的地方用 ==高亮==。

更新记录

新的在上。这一份跟着每一版一起改,只记用户看得见的东西。

1.3.97 · 修:一篇笔记都没开的时候,桌面卡片点「编辑」会弹一句看不懂的话。

插件要挂 Obsidian 的原生编辑器,而 Obsidian 不公开导出编辑器类 —— 只能从 一个活着的笔记实例上把类「借」过来。原来的判据是「必须有一颗 Markdown 笔记开着」, 可这个前提从来没写出来过,而你的用法很可能就是从来不打开 .md 标签页 (都在晶体库里读)—— 于是每一次点「编辑」都借不到、都掉进降级那条路, 还顺带弹一句给开发看的报错。

现在借类有三条路,依次试,任何一条走通就不再往下:

  1. 活着的 Markdown 实例(原路,判据放宽了)
  2. Obsidian 的视图类型表(viewRegistry.viewByType)—— 不需要任何笔记开着
  3. 上一次借成的那一份,本会话内一直有效

三条都不通时,那句话也换成正常人话了:说清楚为什么、下一步做什么, 并点明下面那个输入框照样能写(它不是错误,是降级)。

1.3.96 · 修:删掉一条蓝线,那条线还在——关掉 Obsidian 重启也在,可文件里已经没有它了, 而且它还会变成幽灵。

根因是算关系的时候读到 frontmatter 里去了。「晶体接法」那个字段长这样:

晶体接法: ["[[花式索引和布尔索引]] b t"]

目标写成 [[双链]] 是故意的——给卡片改名时 Obsidian 会连它一起改,接法不会失联。 可"算出两张卡之间有没有关系"那一步,是在整份文件上找 [[…]] 的, 于是 frontmatter 里这一条也长出一条边:

  • 删蓝线删的是正文里的链接,动不到 frontmatter → 线还在
  • 它在文件里 → 重启照样在
  • 目标卡不在这一层时 → 变成幽灵

现在算关系只看正文。剥的只是文件最开头那一段 frontmatter——正文中间的分隔线 (--- 单独一行)不受影响。

1.3.95 · 结构窗和故事线里,「写」模式下右键空白处不再弹那条说明条。

原来是这么一条:点顶栏「选框」,然后拖出方框 · Esc 退出。它出现在"右键空白处、 进了删蓝线模式、但还什么都没选中"这一档——那时候屏幕上一个选中物都没有,弹这句话是噪音。

其余三档照旧留着,尤其是「看」模式下右键金线那一条:金色线框选唯一的入口就是顶栏 那颗「选框」按钮,少了这句用户只会盯着线发呆。

1.3.94 · 修:关掉 Obsidian 再打开,框的位置变回旧的(1.3.93 没修干净,这次是根因)。

线索是你自己给的那两句:「只要我不关 Obsidian,一切正常,关了再打开,又变成这个 bug 了」。能同时满足这两句的只有一种情况——存下去的是旧的那一份。

根因:两条持久化路线读的不是同一个对象。

进故事线 / 结构窗就是进相机档,那一刻会开一份草稿,你的改动全落在草稿里。 问题在于保存视图状态的那个函数只读 state.view,压根不看草稿——所以开着故事线时, 每一次"保存"写下去的都是那份还没并进草稿的旧状态。而边车(.crystal-boxes.json) 读的是"草稿优先"。

于是:屏幕上一切正常(界面读草稿)、边车是对的、唯独视图状态是旧的。 两条路线必然分叉,而分叉只在重开之后才显形。

现在那个函数改成和"提交草稿"用同一个式子({ ...view, ...draft }), 两条路线读同一份东西,不可能再分叉。

这条也解释了为什么 1.3.93 的时间戳没能救你:那一版保证"谁新听谁的", 而新的那一份本身就没被写进视图状态——它一直躺在草稿里。

1.3.93 · 修:关掉 Obsidian 再打开,蓝色收纳方框会跳回旧位置——而开着的时候 怎么看都是对的。

你报的原话是「只要我不关 Obsidian,一切正常,关了再打开,又变成这个 bug 了」。 这两句合起来就把它锁死了:不是跟随坏了,是那一笔没写进文件。

根因是落盘规则本身:边车(.crystal-boxes.json)一直是**「文件无条件优先」**。 那条规矩有一个它自己写明了的前提——文件永远是较新的那一份。而它不是:

写边车是异步的,而且关库那条路上催写盘的调用没有被等待 (closeFullscreen 整个是同步函数,没地方 await)。 那一笔没走完,文件就停在旧值上;而视图状态是同步写掉的,是新的。

于是开库时旧文件盖掉新状态:框跳回原处、卡片留在新位置, 看上去就是「卡片跑到蓝框外面了」——而且只在重开之后才出现。

现在每一笔都盖上时间戳,开库时逐框比时间、谁新听谁的:

  • 文件不比我旧 → 听文件的(平手也让文件赢,它本来就是为跨机器准备的那一份);
  • 我严格更新 → 留着我的,并把文件补写出去(不然它永远追不上);
  • 两边都没有时间戳(1.3.93 之前写的存档)→ 听本地的。本地那份是这台机器上 你最后看到的样子,而文件恰恰可能是写丢的那一份。

某一次写丢了,从此不会再毁掉你的摆法——不管它是为什么丢的。 你库里那个框(m:6)现在正好是「视图状态说 2667、边车说 2730」的状态, 这一版开库就会自己取新的那个,不用你再拖一遍。

1.3.92 · 跨层拖金框,蓝框现在跟着走了。(这一条是前几版都没接住的那个。)

蓝框是按层存的——你在哪一层画的,它就记在哪一层。而金框从 1.3.88 起 逐层都有。这两件事撞在一起就是一个天天会踩的形状:

你站在浅层(比如「机器学习」),拖某个深文件夹(比如 「…/准确度的陷阱与混沌矩阵」)的金框。这个动作会带动那个文件夹里的卡—— 可你给那个文件夹画的蓝框,存在更深那一层(你是进去画的), 它压根不在这一屏上,于是一个都不跟。

然后你打开结构窗(钉着最深那层)——卡片已经在蓝框外面好一段距离了。

现在按文件夹的包含关系去找:拖一个金框,凡是在里面(它自己那层、 以及它下面任何一层)画的蓝框,只要有成员卡在这一趟里动,就一起跟着走。

那些框在浅层不画(它们属于别的层,画出来就是幽灵),所以你看不到它们动 ——但你打开结构窗时它们已经在正确的位置上了,这才是要紧的。 顺带修了落盘:跨层拖动时,边车写的是框自己那一层,不是"你站在哪一层"。

1.3.91 · 修三条,都跟「拖动金色方框」有关:

① 拖金框时,蓝色收纳方框还是不跟。 判据一直是错的,而且正好错在你这一类上:

原来问的是「我这个蓝框的全部成员是不是都在你里面」。可是一个蓝框跨两个同级 子文件夹的时候,它的共同祖先正是你当时站的那一层——而按你拍板的「本级不画框」, 那一层根本不长金框。于是哪个框都装不下它,判据回 false,代码就退回一条更老的、 「看蓝框画出来的中心落在哪」的位置判据——而你手画的框比贴身的金框大,中心落在 外面,于是静默不跟。框里混一张引进来的外来卡也是同一个下场。

现在换成一句充要的话:这一趟要动的卡,恰好就是那个金框底下的所有卡。 蓝框里只要有任何一张在里面,它就得跟;一张都不在,它就该留在原地。 跟你怎么画、画多大、收没收起,全都无关。

顺带:收起来的蓝框现在也跟着走了(它那条标题栏摆在重心上,位移得从它真正的 位置加起,以前干脆跳过了它)。

② 金框的身份被拼重复了。 同一个文件夹,站在不同层看会拿到不同的 id——而框的 名字和收起状态是按 id 存的两张全局表。所以「我在这一层把它收起来了,换一层它又自己 展开了」,改名同理,而且不报错。根因是递归发框时把完整路径又和父路径拼了一遍。

③ 边框位置的那个文件,会被静默丢掉一笔。 这个是从你库里真实的数据里查出来的:

data.json(视图状态,每次拖动同步写)  m:6  x=3003  bottom=294
.crystal-boxes.json(边车,11:55:52)  m:6  x=2709  bottom=252

两份对不上,而落盘规则是文件优先——所以下次开库那个框会跳回旧位置、卡片却 留在新的地方,看就是「卡片跑到蓝框外面去了」,跟你拖不拖没关系。根因是关库那条 路上催写盘的调用没有被等待(closeFullscreen 整个是同步函数),而排队表又在写 成之前就被清空了。现在改成写成了才出队,并把合并窗口从一个 700ms 的防抖压到 一个 tick(同一次松手里的几笔合并,跨 tick 立刻写)——窗口小到几乎没有。

1.3.90 · 结构窗顶栏能整条收起来了。 最左边那颗 ▲ 现在是一颗按钮两种状态, 颜色就是状态:

  • 蓝 = 顶栏所有按钮都摆着(默认,和以前一样);
  • 白 = 全收起来,屏幕上只剩这一颗 ▲;再点一下全回来。

收没收起记着,下次开窗不用重收。(它顶替了 1.3.84 那对只收晶体名的 ▲/▼—— 那把粒度更细,但现在这一颗一次就把名字和按钮一起收了,所以 ▼ 撤掉了。)

为什么这回敢连"换晶体"那颗入口一起收(上一版的注释里明令禁止过):出口就在 原地——同一颗 ▲ 再点一下全回来。原来那条禁令防的是"入口在需要它的那一刻恰好 不可见,而且没有回头路",这两件事不一样。底线没松:收起态下这颗 ▲ 永远 留在屏幕上,它是唯一能把顶栏叫回来的东西。

1.3.89 · 修两条(都是 1.3.88 带出来的):

① 拖金色方框时,里面的蓝色收纳方框还是不跟着走。 你报的原话是「打开结构窗时候, 卡片已经移出蓝色方框之外好一段距离了,但是这个蓝色方框里面仍然算着这些卡片, 然后移动蓝色方框,就连同这些物理位置上不在这个方框里面的卡片一起移动」。

根因是 1.3.88 那条跟随的判据写错了:它问的是「蓝框的中心落不落在金框矩形里」。 而蓝框是你手画的,通常比那个贴身的金框大——往一边探出去之后中心就跑到金框外面, 于是这一趟一个跟随者都找不到,一声不响。

现在改成看成员:一个蓝框"住在"哪个金框里,看它收的那几张卡是不是全都在那个 金框里。这个判据跟你怎么画无关。顺带两条:

  • 拖外层的金框,住在里层的蓝框也跟着(拖 A 的时候 C 里的卡同样在动);
  • 蓝框"不许移出金框"那条约束用的是同一个判据——它原来有一模一样的毛病, 蓝框画大一点约束就静默失效了。

② 金色方框的标题栏下面,加了一条金色实线。 金框现在一层层套着,抬头和数据之间 没有分界,一眼看不出"这一条是这个框的名字"还是"里面某个子框的东西"。

1.3.88 · 金色方框一层一层地分开了。 以前一个文件夹长出来的金框,会把它整棵 子树的卡全摊平吞进去——A 里面嵌着 B1、B2,B2 里面又嵌着 C 的时候,屏幕上只有 A 一个 框,四层的卡混在一起,层级完全看不出来,而那正是结构窗存在的意义。

现在每一层文件夹都发一个框,框就自然套起来了,一个框内部按你拍板的方式横着切:

┌ A ─────────────────────────────────┐
│  [A 自己的卡]  ┃  [B1 的卡]  ┊  [B2 的卡] │
└────────────────┸────────────┸──────┘
        珊瑚橙竖线 ↑      金色竖线 ↑
      (本级 ↔ 子文件夹)  (同级 ↔ 同级)
  • 珊瑚橙 #FF6B6B 实线分的是跨层:这个文件夹自己的卡 ↔ 它的子文件夹;
  • 金色实线(和框同一个金)分的是同级:两个兄弟子文件夹之间。 再深一层也一样——C 在 B2 里,B2 内部又是「B2 自己的卡 ┃ C」,还是珊瑚橙。

另外三条一起改了(都是同一次报告的):

  • 蓝色收纳方框现在压在金色方框上面。 金框变成嵌套的之后,一个蓝框常常嵌在好几层 金框里面,不给它一个更高的层级就会被内层金框盖住。
  • 金框是容器了:里面的卡拖不进别的金框,也不能拖进上一级"自己的卡"那一块 (就是珊瑚橙线的另一边)。拖动时卡片停在那条边界上,不是滑进去再弹回来。 蓝色收纳方框也不能移出它所在的那个金框——拖和拉大小都出不去。 而蓝框不是容器:卡片照样可以拖进拖出。
  • 拖金框,里面所有元素跟着走。 卡片本来就跟着;这次补上的是蓝色收纳方框 ——它是个自己记着矩形的容器,以前拖金框时它钉在原地不动。

1.3.87 · 连线接法现在跟着卡片走——把一颗晶体压缩发给别人,对方打开时线的 走向和你这边一模一样。(用户 10-01 报:「压缩发给朋友,他那边只有左右连线」。)

根因是接法一直存在本机:它在视图状态里,而且键是"你当时站在哪一层"。所以 换台电脑是空的、把文件夹复制到库里别处键也对不上——压缩包本身没带走它。 现在它写进卡片自己的 frontmatter:

晶体接法: ["[[02-中继]] b t"]

一条 = 「往 02-中继 那根线,从我的下边出去、进它的上边」(t/r/b/l 是上下右左)。 只在你亲手拖过连接点的那些线才写,没动过的一律不写(默认接法是按位置算出来的, 本来就换哪台电脑都一样)。一张卡手动调过 10 根线,也就多约 250 字节。

  • 目标写成 [[双链]] 的形状,所以给那张卡改名时 Obsidian 会连它一起改, 接法不会失联。
  • 老接法会在开库时自动搬进文件(一次最多搬一批,剩下的下次开接着搬)。
  • 顺手把「写进文件却读不回来」那条路堵了:解析器原来被调两道,第二道拿到的 已经是对象,被当成字符串整表丢掉——文件里写着、屏幕上却没生效,一声不响。

1.3.86 · 修:蓝色连线不管卡片怎么摆,永远从左右两边接。上下叠着的两张卡, 线也是从右边出去、绕一圈回到左边。根因是"没有手工指定时"的兜底判据写死了左右 (只看谁在左谁在右)。现在改成按位置挑面对面的一边:上下叠着的走「下→上」, 左右摆的走「右→左」。 这件事跟换电脑还有一层关系:你亲手拖过的接法是存在本机视图状态里的,不跟着 卡片走——所以你把资料搬到别人电脑上一跑,一条接法都不在,整屏退化成清一色左右。 改成按位置算之后,默认接法是从排布推出来的,哪台电脑都一样;你亲手拖过的那根 仍然以你拖的为准(手动 > 自动)。

1.3.85 · 修:点方框的名字改不了名了——1.3.83 带进来的。1.3.83 让整个方框 都能起手拖动,而拖动在按下的那一刻就把指针抓走了。于是「按在名字上、原地松手」 那一下:按下的目标是名字、松开的目标变成了整个方框,而 click 的目标是这两者的 最近公共祖先——落到方框上,那就查不到名字了,改名当场哑掉。 (1.3.83 之前它只在空框上是好的:那会儿空框在守卫上直接早退,压根没抓指针。 我放开那道早退的时候,把「空框能拖」和「点名字改名」共用的一扇门一起拆了。) 改法和 panzoom / holodrag 里早就写着的那条一致:过了 4px 才抓指针。 没真拖的那一下,从头到尾什么都没发生。

1.3.84 · 修:结构窗顶栏的晶体名太长,会把后面的按钮挤出窗外。那条栏是 不换行、也没有宽度上限的,而晶体名是里面唯一会长的东西——名字一长,它一路 往右顶,而窗的外层是 overflow:hidden,被顶出去的按钮就再也点不到了。 现在给名字封了顶(超长用省略号,完整的那颗在悬停提示里),顶栏本身也改成到边 换行——两道一起上,按钮再也不会跑出窗外。名字左边多了一对 ▲ / ▼: ▲ 收起名字,▼ 放出来(收起后那颗按钮缩成「晶体」两个字,换晶体的入口还在)。 收起来的这件事记进偏好,下次开窗不用重收。 (顺带一句:上一版 1.3.83 修好的「空方框拖不动」,要是你还看得到,多半是插件 没重载——在 设置 → 第三方插件 里把它关掉再打开一次。)

1.3.83 · 四条,都在故事线 / 结构窗里(用户 09-30)。

方框整块都能拖了。 以前只有顶上那条 26px 的标题栏能抓,现在框里任何一块空白 都能起手。压在卡片上时拖的仍然是卡片——卡片层级比框高,这一条是层级给的,不用额外判 (所以「拖卡片区域不会拖框」是白拿的)。代价说清楚:在框的空白处按下不再平移画面, 推画面请拖框外面,或者用滚轮。顺带修好一条:一个还没装卡的框以前拖不动, 现在也能摆了。

金色方框里的连线,走线方式和进到那个文件夹里一样了。 「接法」(这根线从卡片的 哪一边出去、怎么拐)是按层记的,站在外面看金色方框时查不到那一份,就退回默认的 「看谁在左谁在右」——同一对卡、同一根线,两个地方长得不一样,而屏幕上没有任何东西 解释这件事。现在各层的接法都算数,当前这一层优先。

方框也走格点了。 手动框吸到格点上(判据和卡片同一把尺子,左下角),框里的卡 按同一段位移整体挪——相对位置一点不变,不会被挤到一起;金色方框没有自己的坐标, 退一步按整格移动。大小仍然随你拉,只有摆在哪才需要对齐。 (格点 1.3.34 撤过一次,这一版按你的要求装回来。)

挑文件夹那块面板的抬头多了一颗「取消」。 将建在、新建 / 删除 / 重命名晶体、 删除 / 重命名卡片、结构窗挑晶体——它们打开的都是这块面板,关法从这一版起统一成 这一颗(以前只能再点一次「将建在」把它收起来,那颗按钮叫「将建在」,不像一个"关")。

1.3.82 · 新增:结构窗里可以一次删掉一批卡片。框选卡片(顶栏「框:卡」+「选框」, 框住几张)之后,顶栏多出一颗红框的「删除卡片(n)」——点一下,这几张 连笔记文件一起进回收站(能捡回来),卡片所在的晶体不动。 删的是文件,所以代价写了三处:按钮上的张数、悬停那句话、底下那条说明条 ——这扇窗没有确认弹窗是既定的规矩(09-20 定的),说明条就是仅有的告知。 按 D 不删卡:一个裸按键就能把好几个文件扔进回收站,太容易误触 (那会儿手正放在方向键上挪卡片)。要删就走那颗按钮。 (库那一屏的卡档仍然只有移动——那边没有这颗按钮。)

1.3.81 · 修:点「编辑」会凭空多出一个空白标签页(全屏 / 浮窗 / 嵌入都中)。 根因是插件向宿主"借一颗现成的标签页"时用的是 getLeaf(false),而那句话的语义 不是"拿一颗现成的"——宿主内部走的是 getUnpinnedLeaf():"拿一颗没被钉住的", 当前活动的那颗要是钉住的,它就当场造一个新的空页。你在阅读器里时,活动的那颗 正是晶体库自己,于是每点一次 ✎ 就多一个。 实证是往宿主 Console 挂了个探针,在标签页被插进 DOM 的那一刻打出了调用栈 (mountEditor → getLeaf → getUnpinnedLeaf → setActiveLeaf → … → insertBefore)。 改法:那个位置根本不需要一颗真标签页,只需要它的"类"——改成从已经查到的 markdown 标签页上取构造器,只是查表,不激活、不新建。

1.3.80 · 修:别的机器改过的卡,这边从 1.3.59 起就没跟上过。多设备同步把 改好的正文、概念、来源、标签、坐标传过来时,一样都不会变,屏幕上什么都不发生—— 看着像通知根本没送到。根因是加「晶体坐标」那一次,调用参数错位了一格, 卡片对象被挤掉;而那个名字在作用域里正好还有一份,于是不报错。 测试只逮到 2 条,实际断掉的是整条同步链路。

1.3.79 · 修:新卡还是落在"默认坐标"。1.3.77 里我拿屏幕坐标当世界坐标用了, 而这两者只在"相机停在原点、缩放 1"时才重合——所以新卡永远落在一个 和你推到哪儿毫无关系的固定地方。现在先换算再落座:你说的"当前视口"就是相机 此刻的位置,新卡因而真的落在你正看着的那一屏右边 5%、上下居中。

1.3.78 · 修:浮窗 / 嵌入档下点「编辑」会把笔记开到一颗空标签页旁边。 根因不在"编辑"本身,在它依赖的那个前提:从"当前活动的那颗叶子"裂一半—— 而这两档多了一颗属于插件自己的标签页,它完全可以就是活动的那颗。 现在 split 的基准自己挑一颗已有的 markdown 叶子。全屏档逐字不变 (那两档下"最近用过的那颗"本来就是你的笔记)。

1.3.77 · 修:建在子文件夹里的新卡还是落在默认坐标——建卡有两条路, 我只在其中一条里摆了位,而你走的恰好是另一条(「✎ 在编辑器里写」)。 两条路都是"建一张卡",位置这件事只能一样。落点也按你定的公式改成 视口右侧 5%(卡片右边缘落在"右边减 5% 宽"上,纵向居中), 不吸附格点——你给的是具体公式,硬吸反而会差半格。

1.3.76 · 修:建在子文件夹里的新卡不会被摆进结构窗的视口(落回默认位置)。 判据原来写的是"卡片所属晶体的链必须和你看着的那一层完全相等",而卡片常常建在 更深的子文件夹里——它明明画在这一屏上(取卡片是递归的),却被这条判据挡掉了。

1.3.75 · 阅读器顶栏可以收起来了:顶栏最右端多一颗图标,点一下把它压成一颗图标, 桌面就多出一条——结构窗和页面窗能摆到原先顶栏占的位置上。图标两档之间转 180° (展开态箭头朝上=按下去内容往上走,收起态朝下=按下去挤回来), 图形始终是同一个,状态的差别由鼠标悬停那句话讲清楚。展开时被压在顶栏下面的窗 会跟着往下让。

1.3.74 · 修 1.3.73 的四处 + 一处你报的:嵌入档那个"跟着标签页大小走"的观察器 因为一个声明顺序错误从来没建起来过(而且被一个 catch 吞掉了,没留任何痕迹); 嵌入档按整块屏幕而不是标签页缩放(卡片会撑出半宽的分屏);连点两下切换按钮会跳档; 顶栏那颗按钮的刷新漏了重排。另外:把卡片存进晶体库之后,结构窗现在会实时显示 ——以前要关一次再打开(刷新的收口从"逐个入口"移到了"库重画就刷窗")。

1.3.73 · 新增第三档「嵌入」:库就长在它那颗 Obsidian 标签页里,不盖任何东西, 可以和别的标签页分屏。顶栏那颗按钮变成三档循环(全屏 → 浮窗 → 嵌入), 按钮上写的就是下一档叫什么。嵌入模式不锁笔记的滚动(另外两档会,它们盖在笔记上)。

1.3.72 · 浮窗模式的六处修正:卫星和悬浮窗跑偏(它们的坐标是屏幕坐标, 而它们住的那一层是"层内坐标",浮窗时差一个窗口原点);右下角抓手关库后还留在笔记上 (而且只增不减);拖拽监听没摘(每开一次漏六个);卡片面板会高于窗口 (vh 量的永远是视口)→ 现在 CSS 改问"这一层多大";顶栏在窄窗口里被裁掉 (连 ✕ 都点不到)→ 改成可换行;窗口比屏幕宽时抓手跑到屏幕外。

1.3.71 · 修 1.3.70 的致命错误:晶体库打不开(报 Cannot access 'j' before initialization)。 原因是我把 viewBox 的声明放在了用到它的那行之后(一个 TDZ 错误),而生产包里变量名被压成 一个字母,从报错上完全看不出是谁。现在声明挪到了使用之前。

1.3.70 · 浮窗模式:库可以不占满屏,收成一块可拖可缩的矩形浮在笔记上方, 一边看笔记一边用库。插件设置里选默认档,库里顶栏那颗按钮随时切。 (版本号从 1.3.60 跳到这里:这是一次架构调整——库第一次有了"占多少屏幕"这个概念, 所有"拿视口当边界"的坐标计算都改成了"拿这一层界面当边界"。)

1.3.60 · 收纳方框落盘:每颗晶体一个 .crystal-boxes.json(点开头,Obsidian 里看不见), 名字、大小、收起状态、成员都在里面。老版本里只存在本机的位置,升级后第一次开库会自动搬进去。

1.3.59 · 卡片坐标写进卡片自己的 frontmatter(晶体坐标: [3, 5],以左下角为准) ——换台电脑打开,相对摆放位置一样。同时:收纳方框取消格点(拖到哪停哪), 新建的卡片和 + 框 落在你正看着的地方(以前建在世界的固定角落,视口推远了得推回去找)。

1.3.58 · 收纳方框按晶体分层。以前它是全局的——换一个文件夹看,别的层画的框还在原地摆着。

1.3.57 · 卡片的格点与方向键:拖动吸附到格点,选中后方向键一格一格挪。 最小单位 = 卡片宽的 1/10,坐标以左下角为准。

1.3.56 · 修「导入卡片」的四件事。其中两件要紧的:在挑卡片的选择器里点文件夹名 会静默改掉你的「将建在」;外来卡拖进子晶体框时一声不响(现在会告诉你去用「+ 框」)。

1.3.55 · 导入卡片:从别的晶体引一张卡到这一屏上来,拖进收纳方框, 跨级连蓝线从此成立。卡片本身一个字都不动。

1.3.54 · 框选卡片、整批拖走。顶栏多一颗「框:卡」——框住几张,按住其中任意一张 整批一起动,松手整批判归属。在这之前,把十几张卡收进一个框只能一张一张拖。

1.3.53 · 修:拖框走的世界距离和卡片不一致(相机会缩放时框走得短);收起态的框一拖就把卡片甩到框外。

1.3.52 · 收纳方框改成「你自己画的框」:可以拖、可以拉大小,不再只是卡片周围一圈算出来的外壳。 收起之后外面有蓝线连进来的卡会点一个黄点,鼠标悬停它,相关的框边框闪一圈。

1.3.51 · 收纳方框的颜色加深。第一版太浅,在库自绘的深底上几乎看不见。

1.3.50 · 修:空框不画 → 「点了 + 框 一点反应都没有」。建完框要能把卡拖进去,而拖进去的前提是屏幕上看得见那个框。

1.3.49 · 拖收纳方框的标题栏 = 整组卡片一起挪。

1.3.48 · 手动收纳方框的入口「+ 框」;卡片拖进拖出;删框(框只是分组,删框不动你的卡)。

1.3.47 · 修:方框没被清场,每重画一次就叠一层。

1.3.46 · 结构窗的收纳方框:每个子晶体自动一个,可改名、可收起;收起后里面的卡和线一起收起来, 但「那边还有东西」这件事不丢。

1.3.45 · 桌面卡片窗顶上补一行「概念」。

1.3.44 · 结构窗那一节补全(看 / 写模式、右键三种落点);+页的 markdown 按行分页、改完按回车; 上手补一步「往卡片目录里放一份能读的东西」。README 在这版重写过一次——把文献模式 · 桌面提到主功能位置。

1.3.43 · 重命名卡片 / 重命名晶体两颗按钮;修「别人在 Obsidian 里改了名,插件不知道」—— 以前会在图上留下一张灰色的、点进去什么都没有的卡。

1.3.42 · 每一扇窗都有一颗「收纳」,不带条件。

1.3.41 · 收纳栏最上面那颗 +:外部标签页,可以内嵌 deepseek、Google 这些站点。

1.3.40 · 阅读器的收纳栏,以及「边看边记」那一栏的开关。

1.3.39 · 故事线也有「看 / 写」两档了:写模式下拖线真写 [[双链]]、选框删蓝线、一层撤销。

1.3.38 · 去掉写模式里那个「为什么连过去?」输入框——连着拖几根线时每根都被它截一下。 理由照样可以手写在 ]] 后面,只是不再由插件代劳。

1.3.37 · 写模式下多一颗「选框」删蓝线:框住几根,从卡片正文里精确挖掉那条 [[链接]] (两个方向一起删、逐字节可还原、一次撤销)。

1.3.36 · 蓝线改成和金线一样的折线(直线 + 圆弧拐角),不再是贝塞尔弧 ——弧线从卡片中段穿过去,两根一交就看不出谁接谁。

1.3.35 · 蓝线能从上 / 下 / 左 / 右接(认你拖的那个连接点); 写模式下右键一张卡就藏掉它所有入链出链,顶栏「显示全部」一键收回;橡皮筋预览和落地同形同色。

1.1.31 / 1.1.3 / 1.1.2 / 1.1.1 / 1.1.0 · 草稿纸、边看边记的「返回」、删除卡片; 草稿纸从一堆文字改成摆到桌面上的一张真卡。几个补丁版本号是因为发过的号不能复用。

1.0.2 / 1.0.1 / 1.0.0 · 默认卡片目录改成中性的 cards;按自动审查改三处;首次提交。

许可

GPL-3.0。