【问题标题】:Emacs -- How to create a vertical strike-through effectEmacs -- 如何创建垂直删除线效果
【发布时间】:2014-07-07 19:06:57
【问题描述】:

我正在寻找一些关于如何创建垂直 strike-through 视觉效果的建议(垂直条 ("\u007C") 的字符 在顶部)可见)。如果可以分层,则垂直条应位于下方,以使字母大部分可见。

我搜索了一种叠加字符、分层叠加的方法,并查看了一些 xpm 图像,但是,我没有找到任何与我正在寻找的东西相近的东西。目标是获得类似于下图的真正十字准线效果 - 灰色背景将替换为黄色垂直删除线,以便字母仍然可见。

【问题讨论】:

  • 你见过column-marker吗?我用它来突出显示通过预定义限制的字符,并想知道它是否可以用于您的目的。不过,这是一个好主意,你会用十字准线做什么(如果你不介意分享的话)?
  • 如果你还没有,也可能想看看crosshair highlighting
  • @nymo 和@Carl Groner -- 公开可用的垂直线库使用的突出显示方法使用字体锁定或覆盖或 .xpm 图像。但是,我从未见过 vertical 行实际上可以删除另一个字符的示例。尽管可以使用:strike-through t 创建水平的strike-through,但没有垂直的strike-through。本质上,我正在寻找一种方法来合并两个叠加层——或者,创建一个半透明的叠加层,让下面的东西被看到。简而言之,我想在字母下面有一个管道(“\u007C”)。
  • nymo 和@Carl Groner -- 我添加了第二张图片来说明我正在寻找的视觉效果。
  • @nymo -- 我最喜欢的 Sublime Text 2 和 3 的功能之一是 Ron Martinez 编写的 CursorRuler。我结合了 Emacs 公开可用的各种垂直线库的功能,并创建了与 visual-line-modewhitespace-mode 兼容的东西。对于空格和没有字符的任何内容,我使用竖线——Unicode 007C。垂直线非常适合在视觉上对齐内容,它可以帮助我准确地看到我在屏幕上的位置,而无需寻找光标。

标签: emacs elisp


【解决方案1】:

功能请求 #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.elhttp://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))

以下屏幕截图是使用第二个示例制作的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-29
    • 2015-03-06
    • 2020-03-11
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    • 2012-08-01
    • 2016-09-22
    相关资源
    最近更新 更多