【分享】通过stipple使用实线显示行长度标记(fill-column-indicator)

以前一直是使用的unicode字符(?\u254e)以虚线显示的,但这种方式在有些字体上的显示是有问题的,比较 macOS 上的 Manaco 字体就会显示为方块。

如果使用 Emacs 默认的 U+2502 字符,其实也是实线显示。不过默认这个方法不适用于下面两种情况:

  1. 行距大于0,比如设置了 (setq-default line-spacing 0.25)的时候
  2. 中英文混合时,因为中文和英文字符大都不等高,只有极少数是等高的。

为了解决这个问题,找到了 emacs.stackexchang 上的一个关于如何设置fill-column-indicator 为实线的帖子:How to have a solid fill column indicator when line spacing is greater than zero?

这个帖子中题主的需求其实就上述的第1种情况,我个人更多是第2种需求。 不过,从这个帖子中发现了可以通过 Emacs 新引入的 stipple 特性来进行像素级绘制标记线,这样就可以彻底解决问题。(注:此 stipple 特性只支持 GUI 的 Emacs)

要开启使用 stipple 显示标记线,可以使用以下设置:

;; Setup fill column indicator with stipple
(setq-default display-fill-column-indicator-character ?\s)
(defun adjust-fill-column-indicator-stipple()
  "Adjust the fill-column-indicator face with stipple"
  (let* ((w (window-font-width))
         (stipple `(,w 1 ,(apply #'unibyte-string
                                 (append (make-list (1- (/ (+ w 7) 8)) ?\0)
                                         '(1))))))
    (custom-theme-set-faces
     'user
     `(fill-column-indicator ((t (:stipple ,stipple)))))))
(add-hook 'after-init-hook #'adjust-fill-column-indicator-stipple)
(add-hook 'text-scale-mode-hook #'adjust-fill-column-indicator-stipple)
(add-hook 'prog-mode-hook #'display-fill-column-indicator-mode)

显示效果如下:

本人测试过 macOS, Windows, Linux 都可以使用, 建议 Emacs 31

在此也要特别感谢 Emacs TG 群友 Tim 的帮助,上面代码中的函数其实是他提供的。

关于如何测试自己的 Emacs 是否支持 stipple 特性,可以使用 indent-bars 中提供的例子:

2 个赞

如果改为使用 set-face-attribute进行设置,则需要使用 emacs-startup-hook 才能生效。

;; Setup fill column indicator with stipple
(setq-default display-fill-column-indicator-character ?\s)
(defun adjust-fill-column-indicator-stipple ()
  "Adjust the fill-column-indicator face with stipple using set-face-attribute."
  (let* ((w (window-font-width))
         (stipple `(,w 1 ,(apply #'unibyte-string
                                 (append (make-list (1- (/ (+ w 7) 8)) ?\0)
                                         '(1))))))
    (set-face-attribute 'fill-column-indicator nil :stipple stipple)))

(add-hook 'emacs-startup-hook #'adjust-fill-column-indicator-stipple)
(add-hook 'text-scale-mode-hook #'adjust-fill-column-indicator-stipple)
(add-hook 'prog-mode-hook #'display-fill-column-indicator-mode)
5 个赞