写了个 VS Code 摸鱼插件,顺便聊聊怎么用装饰器“假装”在写代码

8 阅读5分钟

写了个 VS Code 摸鱼插件,顺便聊聊怎么用装饰器“假装”在写代码

VS Code 插件市场地址: Chill Reader - Visual Studio Marketplace

前言

大家好,我是 Chill Reader 的作者。

作为一个每天都在和代码打交道的程序员,相信大家都有这种时刻:代码写累了,脑子转不动了,或者单纯就是在等一个漫长的编译过程。这时候想看两页小说放松一下,但切出去看浏览器或者电子书软件又太显眼,还得时刻提防背后有没有人经过。

市面上的摸鱼插件我也试过不少,有的在底部状态栏滚动显示(字太小,看得眼晕),有的在侧边栏(占地方,一眼就能看出不是项目文件)。

我就在想,最好的隐蔽,难道不是让小说长得像代码一样吗?

于是我花了两天周末时间,写了这个叫 Chill Reader 的插件。它的核心逻辑很简单:把小说内容伪装成代码注释,渲染在当前编辑行的末尾。

今天分享一下这个插件是怎么做出来的,以及开发过程中遇到的一两个比较有意思的技术点。

功能介绍

功能主打一个实用,基本覆盖了看小说的所有高频需求:

  1. 隐身模式:小说内容出现在代码行尾,颜色和注释一样。支持自定义透明度,你可以把它调得若隐若现,只有凑近屏幕才能看清。
  2. 老板键:支持一键清除所有显示,瞬间回到纯净代码界面。建议配置一个顺手的快捷键(如 Alt+Q),紧急时刻极速切换。
  3. 划词翻译
    • 英文原著党福音:支持英文单词、长句的悬浮翻译。因为目标语言固定为中文,所以如果你看的是中文小说,悬浮就不会有反应(毕竟没必要把中文翻译成中文)。
    • 智能识别:它能自动识别你是在查代码变量还是在看小说。鼠标指在小说内容上,直接显示整句翻译;指在代码上,显示代码的翻译。
    • 小贴士:内置的是公共翻译接口,如果大家刷得太快,可能会偶尔提示“调用频繁”或“翻译过快”,稍微歇一秒再试就行。
  4. 全文搜索:支持关键词搜索并列出匹配结果(为保证性能,目前最多显示 100 条),点击即可通过坐标转换算法实现跨页跳转。
  5. 精准跳页:支持输入页码直接跳转,并能自动记忆阅读进度,下次打开位置一字不差。

技术细节:怎么把小说“画”上去?

这个插件的核心在于“怎么在不改变文件内容的前提下显示文字”。

如果直接往编辑器里插入文本,那肯定不行,Git diff 会炸。VS Code 提供了一个很强大的 API:TextEditorDecorationType。它支持 after 属性,可以在指定位置后面追加“伪元素”。

1. 动态分页与“幽灵文本”

在实现过程中,最大的难点在于分页。因为是渲染在行尾,每行能放多少字是不确定的(取决于你的屏幕宽度、代码缩进长度)。

我的做法是:

  1. 计算可用空间:根据配置的行字数,预估一个渲染块。
  2. 生成装饰器:通过 Range 定位到行尾,利用 contentText 将小说内容渲染出来。
  3. 回写进度:渲染完成后,计算实际消耗了多少个字符,更新进度。这样保证了无论你的窗口怎么变,下一次翻页都能无缝衔接,不会丢字。

2. 悬浮翻译的实现技巧

VS Code 的 HoverProvider 通常是用来给真实存在的代码提供悬浮提示的。但问题是:装饰器生成的文本并不是文档的一部分,鼠标悬停在上面是不会触发 Hover 事件的。

为了解决这个问题,我做了一个处理:

  1. 监听行 Hover:当用户的鼠标悬停在某一行代码上时,获取当前行的行号。
  2. 反向查找:去后台查一个 Map,这个 Map 记录了“第 N 行渲染了小说的哪一段文字”。
  3. 合成 Hover:如果鼠标指着代码里的单词,就翻译这个单词;如果指在行尾空白处(也就是小说显示的位置),就直接显示小说的译文。

这样就绕过了“装饰器无法交互”的限制,体验非常丝滑。

3. 流式内容中的搜索定位

在“隐身模式”下,小说是被切碎了按页渲染的。为了实现搜索跳转,这就涉及到坐标转换:先在内存中对整本小说进行正则匹配,拿到匹配项的绝对位置,再换算成页码并强制跳转。

关于快捷键配置

为了避免和大家现有的快捷键冲突,插件默认没有强制绑定翻页快捷键。

建议大家在安装后,自行在 VS Code 的 keybindings.json 中配置。比如我个人习惯用 Alt+N 和 Alt+P:

[
  {
    "key": "alt+n",
    "command": "chill-reader.nextPage",
    "when": "editorTextFocus"
  },
  {
    "key": "alt+p",
    "command": "chill-reader.prevPage",
    "when": "editorTextFocus"
  },
  {
    "key": "alt+q",
    "command": "chill-reader.bossKey",
    "when": "editorTextFocus"
  }
]

结语

这个插件目前还在迭代中,肯定还有不少可以优化的地方。比如目前的 EPUB 解析还比较粗糙,大文件的性能优化也还有提升空间。

如果你也觉得这个插件有意思,欢迎来 GitHub 提意见或者 PR。

GitHub 地址: github.com/wq758511990…

最后提醒一句:摸鱼虽爽,可不要贪杯,工作进度还是要保证的。