Skip to content

插件 ​

文档编写中

部分内容可能尚不完整。

插件是一个独立的程序,它在右侧栏里加一个面板。ThinkTerm 启动它、和它通信,并把它发来的内容画出来 —— 桌面窗口里和浏览器里都一样 —— 但它的代码一行也不在 ThinkTerm 里面运行。一个插件崩溃,带走的只是它自己的面板,别的都不受影响。

文件与笔记 里讲的片段也是一个插件。它是内置的,用的接口和你安装的插件完全一样。

插件出现在哪里 ​

只在右侧栏里。带面板的插件会以它自己的名字出现在侧栏的切换器里,和文件、笔记、片段并列,同时列在 设置 › 侧栏与插件 里。它不会添加自己的命令、菜单项或通知。

设置 › 侧栏与插件:内置的片段插件,以及 Diff 和股票插件

要显示的东西多于侧栏放得下的面板,可以在侧栏左边打开一个更宽的视图,宽度由你拖动决定。没有地方放它时 —— 窗口太窄、手机上 —— 插件会把原本要放在那里的内容收进面板本身。

面板在浏览器里和在桌面端看起来一样,因为两边用同一份代码、按 ThinkTerm 自己的配色来画它。浏览器用的是为它提供页面的那个 server 所在机器上的插件,而不是浏览器所在设备上的 —— 所以一台无界面的主机显示的是它自己的插件,server 安装包也正因此附带了插件 server。见 网页访问。

安装与移除 ​

一个插件就是一个目录,里面放着 plugin.toml 和它要运行的程序。安装一个插件,就是把这个目录放进插件目录:

系统插件目录
macOS~/Library/Application Support/ThinkTerm/plugins
Linux~/.local/share/ThinkTerm/plugins
Windows%APPDATA%\ThinkTerm\plugins

没有安装步骤,也不用重启。ThinkTerm 下一次去看的时候就会发现新插件:打开 设置 › 侧栏与插件 时,或者运行 thinkterm plugin list 时。删掉目录就移除了它。

没有任何东西会替你下载或安装插件,也没有可供挑选的插件目录。机器上的每一个插件,都是有人亲手复制过去的。

命令行 ​

thinkterm plugin 在 shell 里查看和操作插件:

命令作用
thinkterm plugin list每个插件、它的状态和版本
thinkterm plugin enable <id>打开一个插件
thinkterm plugin disable <id>关闭一个插件
thinkterm plugin reload [<id>]停下一个插件并重新读取它的清单;不给 id 时针对每一个已安装的插件
thinkterm plugin call <id> <json>向一个插件发出一次调用,并打印它的回答
thinkterm plugin dir打印插件目录

reload 还会清除插件的崩溃或失败状态,让它可以再试一次。同样的开关、一个 重新加载 按钮,以及打开插件文件夹的入口,都在 设置 › 侧栏与插件 里。

插件怎样运行 ​

插件不是由窗口来运行的。它们跑在 thinkterm-plugin-server 之下,这是一个独立于 GUI、也独立于会话 server 的小进程,桌面端、浏览器和命令行都和它通信。每台机器上每个用户只有一个。第一次有东西需要插件时它启动,最后一个使用者离开 30 秒后退出,并把所有插件一起停掉。

每个已安装的插件又各是一个独立进程,在第一次被用到时启动 —— 一个面板出现,或者命令行发来一次调用。意外退出的插件会显示为已停止,下次被用到时再启动;一分钟内崩溃三次的插件会被标记为失败,在你重新加载它、或它的文件发生变化之前不再碰它。它的程序在磁盘上变了,ThinkTerm 会在下次使用前重启它。

插件闲着时运行多久 ​

插件的某个面板正在任何地方显示时 —— 窗口里或浏览器里 —— 或者有一次对它的调用正在等回答时,它就算在使用中。不再使用之后,它的程序还会跑多久,取决于它的后台模式:

设置何时启动何时停止
保活随这台机器上的 ThinkTerm 启动这台机器上的 ThinkTerm 不在了
按需(默认)用到时最后一次使用 2 分钟后
用完就停用到时最后一次使用 10 秒后

插件的清单写明它需要哪一种。设置 › 侧栏与插件 里每个插件旁的菜单可以逐个插件覆盖它,桌面端和浏览器里都可以改;菜单会把清单要求的那一项标为 插件默认。

这里的取舍,是在「打开面板时它已经就绪」和「你不看的时候它没在跑」之间。保活 适合替你盯着某样东西的插件;这也是 ThinkTerm 不经要求就启动插件的唯一一种模式。保活的插件自己停掉时,2 秒后会被再次启动,直到它被标记为失败。

「这台机器上的 ThinkTerm」指桌面应用或会话 server,哪个在跑算哪个。在一台没有桌面端的主机上就是会话 server,所以在那里保活的插件,会和那个 server 跑得一样久。每台机器各自记住自己的选择:同一个插件,可以在服务器上保活,在笔记本上按需运行。

另一台机器上的终端 ​

面板属于它旁边的那个终端 —— 所在窗口里获得焦点的那个 pane —— 插件会被告知那个终端的目录。当那个终端跑在通过 SSH 连上的另一台机器上时,插件本身仍然跑在这里,跑在本机上。它想在那边做的事,要请 ThinkTerm 代劳:运行一个程序、读一个文件,或者看看某个路径上是什么。ThinkTerm 用文件面板所用的同一条连接、以你的身份去做。

这些请求有几条值得知道的限制:

  • 它们只能够到插件面板旁边那个终端所在的机器,而且只在那个终端还在那里时有效。为一台终端已经离开的机器发出的请求会失败。
  • ThinkTerm 只在你允许之后才会连接一台机器 —— 在文件面板里,或者用面板在内容位置显示的那个按钮。在那之前,每个请求都会失败。
  • 在那边运行的程序,20 秒后会被停掉。

这是桌面端的功能。浏览器里的面板不会用这种方式够到其他机器。

插件能做什么 ​

插件是你放到机器上的程序,它以你的身份、带着你的权限运行。ThinkTerm 不会在侧栏以外显示插件的任何东西,但这拦不住程序本身去读你的文件、访问网络或运行别的程序:只有沙箱才拦得住,而这里没有沙箱。请像安装任何其他程序那样安装插件。

远程请求把这一点延伸到了你通过 SSH 连上的机器:你在这里信任的插件,也就是你在每一台「终端挨着它面板」的主机上信任的插件。上面那些限制收窄的是它何时能够到那些机器,而不是够到之后能做什么。

ThinkTerm 源码里的插件 ​

ThinkTerm 的源码在 plugins/ 下带了三个插件。它们不在下载的安装包里:每一个都要用 Cargo 构建,再把它的 plugin.toml 和程序复制到插件目录下它自己的目录里来安装。

  • Diff(diff)以 GitHub Desktop 的方式,显示旁边终端所在 git 仓库自上次提交以来的改动:面板里是改动过的文件,更宽的视图里是选中文件的各行,每一处改动都有标记。面板显示期间它每两秒运行一次 git,在 git 处理得慢的仓库里会放慢一些,并且不运行仓库配置可以为它指定的那些程序 —— fsmonitor、外部 diff、文本转换器。挨着另一台机器上的终端时,它通过 ThinkTerm 在那边运行 git。
  • 股票(stocks)是一份来自 Yahoo Finance 的自选行情,每个代码当天的走势画成一条线,外加选中那只的图表。Yahoo 的图表 API 不是官方接口,随时可能拒绝或变化。
  • 文本工具(text-tools)在 plugins/example 里,没有面板。它从命令行回答两种调用,是写插件的起点。

编写插件 ​

插件的程序通过标准输入和标准输出与 ThinkTerm 通信,每次一行 JSON。面板是手画的:插件发来一组矩形、文字、线条和填充区域,以及点击能落到它身上的位置,由 ThinkTerm 画出来。没有控件。

Rust crate thinkterm-plugin-sdk 实现了这套协议,上面那些插件用的都是它。清单、消息、面板元素和各项限制,在 ThinkTerm 仓库的 docs/thinkterm/plugins.md 里有完整说明。开发时,把你的源码目录链接进插件目录,然后重新构建即可;程序写到标准错误的内容会进入插件 server 的日志。

相关 ​