功能请求 #17684(十字准线)[https://debbugs.gnu.org/cgi/bugreport.cgi?bug=17684] 和功能请求 22873(多个假光标)[https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22873] 正在进行中。尽管这些功能是否会被纳入官方 Emacs 尚不得而知,但有一个工作草案证明概念已发布到上述两个功能请求中。这些功能需要在从 master 分支(X11、Windows 或 NS)构建 Emacs 的 GUI 版本之前对 C 和 Lisp 内部进行修改。
示例 1,共 3 个:
以下代码 sn-p 适用于 some 操作系统上的 some 字体——例如,它在 Windows 上开箱即用;但是,对于 OSX 10.6.8 Snow Leopard 或 Snow Leopard Server 10.6.8 上的作者,它确实不工作。 [参见错误报告编号 20537 --https://debbugs.gnu.org/cgi/bugreport.cgi?bug=20537 -- 尽管错误报告已被 Emacs 开发团队正式关闭,但在“错误修复”之后,作者从未能够在 Snow Leopard 上使用该功能。 :( ] 用户可能希望尝试使用字形参考点,composite.el 中的变量 reference-point-alist 具有与之相关的详细文档字符串。用户还可能希望尝试使用 after-string 或 @ 987654330@显示属性。库vline.el在http://www.emacswiki.org/emacs/vline.el有一个名为vline-style的变量,可以设置为'face、'compose或'mixed——后两个设置导致vline使用此代码 sn-p 的轻微变化 [参见所述库的第 362 到 370 行]。
(let* (
(point-min (point-min))
(point-max (point-max))
(pt (point))
(pt+1 (1+ pt))
(char (char-after pt))
(line-char (string-to-char "|"))
(str (when char (compose-chars char '(tc . tc) line-char))) )
(overlay-put (make-overlay pt pt+1) 'display str)
(sit-for 2)
(remove-overlays point-min point-max 'display str))
示例 2,共 3 个:
以下代码 sn-p 使用称为带空格的零的 Unicode 字符(即uFEFF)。因为空间不能接收前景色,所以使用背景色来为零宽度空间提供一条延伸整个行高的细垂直线的外观。正如在此代码 sn-p 的上下文中所使用的,零宽度空间的宽度为 1 个像素,并且连接的字符的大小减小,因此两个组合字符的宽度等于 frame-char-width。这个 sn-p 的测试是在 OSX 操作系统上使用默认字体-*-Monaco-normal-normal-normal-*-12-*-*-*-m-0-iso10646-1 完成的。在此示例中,光标会在短时间内被移除,以便更清晰地看到叠加层。
(let* (
(point-min (point-min))
(point-max (point-max))
(pt (point))
(pt+1 (1+ pt))
(char (char-after pt))
(char-str (when char (char-to-string char)))
(ln-char-str (char-to-string ?\uFEFF))
(str (when char
(concat
(propertize ln-char-str 'face '(:background "red"))
(propertize char-str 'face '(:height 100))))) )
(internal-show-cursor nil nil)
(overlay-put (make-overlay pt pt+1) 'display str)
(sit-for 2)
(internal-show-cursor nil t)
(remove-overlays point-min point-max 'display str))
示例 3,共 3 个:
以下是使用 xpm 图像覆盖的示例,用于支持 xpm 图像格式的图形 Emacs 版本。它是 11 像素宽; 20像素高;并有 4 种预选颜色。我在运行 Snow Leopard 10.6.8 的 Mac 上,使用 Emacs 时我更喜欢的字体是 -*-Courier-normal-normal-normal-*-18-*-*-*-m-0-iso10646-1——frame-char-width 是 11,frame-char-height 是 20。我在左边添加了一条细的垂直黄线以大写字母“A”为例,说明如何绘制自定义图像。可以使用(char-after (point)) 以编程方式替换点处的字符并取那个数字——在这种情况下,大写字母“A”是65——并替换适当的变量——例如,(cond ((eq (char-after (point)) 65) cap-ltr-a-xpm) . . .——和在覆盖位置中使用该变量——例如,(overlay-put (make-overlay (point) (1+ (point))) 'display cap-ltr-a-xpm)。这对于截断缓冲区和自动换行都非常有效,因为单词中间字符上的display 覆盖属性不会导致自动换行认为单词的第一部分属于上一行。当然,创建一个收藏的 xpm 图像的自定义库需要时间。在此示例中,光标会在短时间内被移除,以便更清晰地看到叠加层。
ImageMagick 能够根据特定字体系列和大小生成特定字符的半精确 xpm,但它并不像我希望的那样精确——这里是使用该外部实用程序的说明的链接: https://stackoverflow.com/a/14168154/2112489 简而言之,用户应该准备好花时间根据自己的喜好自定义 xpm 图像。
(let* (
(pt (point))
(pt+1 (1+ pt))
(point-min (point-min))
(point-max (point-max))
(cap-ltr-a-xpm `(image :type xpm :mask nil :ascent center :data
"/* XPM */
static char * letters_xpm[] = {
/* columns rows colors chars-per-pixel */
/* columns = 1 pixel in width -- see also (frame-char-width) */
/* rows = 1 pixel in height -- see also (frame-char-height) */
\"11 20 4 1\",
\". c #000000\",
\"+ c #FF0000\",
\"@ c #7F0000\",
\"% c yellow\",
\"%..........\",
\"%....++....\",
\"%....++....\",
\"%..++..++..\",
\"%..++..++..\",
\"%++......++\",
\"%++......++\",
\"%++......++\",
\"%++......++\",
\"%++......++\",
\"%++......++\",
\"%++++++++++\",
\"%++++++++++\",
\"%++......++\",
\"%++......++\",
\"%++......++\",
\"%++......++\",
\"%++......++\",
\"%++......++\",
\"%..........\"};")) )
(internal-show-cursor nil nil)
(overlay-put (make-overlay pt pt+1) 'display cap-ltr-a-xpm)
(sit-for 2)
(internal-show-cursor nil t)
(remove-overlays point-min point-max 'display cap-ltr-a-xpm))
以下代码 sn-p 与上面的代码类似,不同之处在于它使用了after-string 显示属性。在此功能期间,光标会在短时间内移除,以便更清晰地看到叠加层。
(let* (
(point-min (point-min))
(point-max (point-max))
(peol (point-at-eol))
(pilcrow `(image :type xpm :mask nil :ascent center :data
"/* XPM */
static char * pilcrow_xpm[] = {
\"11 20 4 1\",
\". c #000000\",
\"+ c orange\",
\"@ c #7F0000\",
\"% c yellow\",
\"%..........\",
\"%..........\",
\"%..........\",
\"%..........\",
\"%..++++++..\",
\"%.++++.+...\",
\"%.++++.+...\",
\"%.++++.+...\",
\"%..+++.+...\",
\"%....+.+...\",
\"%....+.+...\",
\"%....+.+...\",
\"%....+.+...\",
\"%....+.+...\",
\"%..........\",
\"%..........\",
\"%..........\",
\"%..........\",
\"%..........\",
\"%..........\"};"))
(pilcrow-str (propertize " " 'display pilcrow)) )
(overlay-put (make-overlay peol peol) 'after-string pilcrow-str)
(sit-for 2)
(remove-overlays point-min point-max 'after-string pilcrow-str))
以下屏幕截图是使用第二个示例制作的。