cashmere

cashmere

kitty-graphics.el v0.2.1: Org 内联修复、LaTeX 预览、PDF 查看和 Dirvish 集成

首次发布 三天后,我发布了 v0.2.1。第一个版本在 r/emacs 上获得了热烈的反响,大家马上开始提出各种需求:LaTeX 片段预览、doc-view 支持、折叠标题时隐藏图片。我把这些功能全都实现了。

这篇文章介绍 v0.2.1 中的所有新功能。

Org 内联图片

首次发布中的核心功能,现在更加稳健。使用 C-c C-x C-v 切换内联图片显示。文件链接、附件链接和相对路径均可正常工作。

img

LaTeX 片段预览

这是呼声最高的功能之一。现在可以在 org-mode 中使用 C-c C-x C-l 直接预览 LaTeX 片段,和你熟悉的快捷键完全一样。片段通过 dvipng 渲染,并通过 Kitty 图形协议内联显示。不需要 GUI 窗口。

img

实现方式是通过 advise org-latex-previeworg--make-preview-overlay 来拦截图片生成管线。Org 的 LaTeX 渲染实际上不需要 GUI,它调用的是 dvipng=/=dvisvgm 外部命令,所以我们只需要绕过 display-graphic-p 检查,然后把生成的 PNG 传给 Kitty 协议即可。

一个烦人的边界情况:终端 Emacs 有时会将 face 颜色报告为 =unspecified-fg=,这会导致 org 的颜色格式化出错。advice 会强制使用具体的前景色/背景色,确保 LaTeX 输出不会变成不可见的。

使用 =C-u C-c C-x C-l=(区域)或 =C-u C-u C-c C-x C-l=(整个 buffer)清除预览。

doc-view 集成

PDF、DVI 和 PostScript 文件现在可以通过 doc-view 在终端中渲染。页面导航正常工作,=n=/=p= 翻页。缩放也可以:=+= 放大,=-= 缩小,=0= 重置。每页在窗口中居中渲染。

img

实现方式是 patch doc-view-mode-p 来绕过 GUI 检查(和 LaTeX 同样的方法,用 cl-letf 临时让 display-graphic-p 返回 t=),并 patch =doc-view-insert-image 通过 Kitty 图形协议显示页面 PNG,而不是使用 Emacs image spec。

Image-Mode

Image-mode 现在会在窗口中居中显示图片,并支持缩放控制:

img

为了避免与 evil-mode 冲突(这在首次发布时是个问题),终端图片查看器现在使用自己的 kitty-gfx-image-mode major mode,而不是直接劫持 =image-mode=。这意味着 evil-collection 的 image-mode 按键绑定(那些调用在终端中无法工作的原生图片函数的绑定)不会产生干扰。

Dirvish 集成

Dirvish 中的图片预览现在可以在终端中原生工作。该包注册了一个 kitty-image 预览分发器,在你浏览文件时渲染预览窗格中的图片。不需要额外配置。如果 kitty-graphics-mode 已启用且 dirvish 已加载,它就能直接工作。

img

折叠 Org 标题时隐藏图片

这是首次发布后的第一个 bug 报告,也可以说是最烦人的问题。折叠标题时图片仍然可见,悬浮在空中,与其上下文脱节。

修复方案同时检查 =org-fold=(org 9.6+,基于 text-property)和传统的基于 overlay 的不可见性。当标题被折叠时,折叠内的图片 overlay 会删除其终端放置。展开时,刷新循环会重新放置它们。它还正确地忽略装饰性的不可见性,如隐藏的链接括号(=org-link=)。

稳健性大修

内部机制进行了全面改造。这些改动不影响用户可见的行为,但使整个系统显著更加可靠。

LRU 图片缓存

旧的缓存是一个无限增长的哈希表,曾经显示过的每张图片都永远留在终端内存中。现在有了一个带有可配置大小限制的 LRU 缓存(=kitty-gfx-cache-size=,默认 64)。当缓存满时,最近最少使用的图片会被淘汰,其终端数据也会被删除。

缓存也不再存储图片尺寸。尺寸每次都从像素大小和当前单元格度量重新计算。这意味着缩放、调整窗口大小,或在不同上下文中查看同一张图片(org-mode vs. image-mode vs. dired)总能获得正确的尺寸,而不是过时的缓存值。

减少闪烁

Buffer 和窗口切换以前会删除 所有 放置并从头重新创建。这会导致明显的闪烁,尤其是在分屏中切换 buffer 时。现在:

溢出保护

超出窗口底部边缘的图片现在会被隐藏而不是放置。在此之前,屏幕底部附近的高图片会溢出到窗口下方的内容中,导致视觉混乱。

更安全的清理

关闭 buffer 时现在会检查其他 buffer 是否仍然引用相同的图片 ID,然后才删除终端端的图片数据。这防止了破坏共享图片的问题,例如同时在 org-mode 和 image-mode 中打开同一个文件。

其他改动

安装

kitty-graphics.el 放到你的 load path 中并启用该模式:

(require 'kitty-graphics)
(kitty-graphics-mode 1)

或者使用 use-package 和 =straight.el=:

(use-package kitty-graphics
  :straight (:host github :repo "cashmeredev/kitty-graphics.el")
  :if (and (not (display-graphic-p)) (getenv "KITTY_PID"))
  :config
  (kitty-graphics-mode 1)
  (with-eval-after-load 'dired
    (define-key dired-mode-map (kbd "P") #'kitty-gfx-dired-preview)))

如果你遇到问题或有功能建议,请在 GitHub 上提 issue。

发布版本:GitHub 上的 v0.2.1