如何在次要模式下添加复杂的语法突出显示?


10

我想在次要模式下以各种面孔突出显示代码。

这是接近我想要的屏幕截图:

python语法高亮

有一两件事,我缺少的是具有注释字符#font-lock-comment-face。这样做的想法是使注释“属于”以纯文本突出显示的轮廓,因此更易于阅读。经常以平常不太显眼的表情发表评论。

这是我使用的代码:

(setq-local font-lock-defaults
            '(python-font-lock-keywords
              nil nil nil nil
              (font-lock-syntactic-face-function
               . lpy-font-lock-syntactic-face-function)))

(defun lpy-font-lock-syntactic-face-function (state)
  "Return syntactic face given STATE.
Returns 'defalt face for comments that belong to an outline."
  (cond ((nth 3 state)
         (if (python-info-docstring-p state)
             font-lock-doc-face
           font-lock-string-face))
        ((save-excursion
           (while (and (> (point) (point-min))
                       (progn (move-beginning-of-line 0)
                              (eq (char-after) ?\#))))
           (forward-line 1)
           (looking-at "#\\*+ "))
         'default)
        (t
         font-lock-comment-face)))

问题是,font-lock-syntactic-face-function除了它接收到复杂的数据结构state,具有不同的点状态并返回一张脸之外,我对在其上进行操作的接口一无所知 。

有人可以解释这个界面吗?也许有更好的一个?

Answers:


6

font-lock-syntactic-face-function是Font Lock(更具体地来说是Syntax的Font Lock阶段)(强调我)的常规变量:

如果此变量为非nil,则它应该是一个函数,用于确定给定句法元素(字符串或注释)使用哪张面孔。该值通常通过font-lock-defaults中的other-vars元素设置。

使用一个参数调用该函数,该函数在返回的点处解析状态parse-partial-sexp,并且应该返回face。默认值返回font-lock-comment-face(注释)和font-lock-string-face(字符串)(请参见Faces for Font Lock)。

parse-partial-sexp依次返回一个描述Emacs当前语法状态的列表,该列表本质上是将语法表应用于当前缓冲区的结果。该列表相当复杂,因此在这里我将不作赘述。您可以在的文档字符串中看到完整的参考parse-partial-sexp。此功能的目的是在某些规则下更改应用于语法元素的面。函数的开头演示了这一点:如果当前字符串是docstring,请为其使用不同的外观。

但是,面孔始终适用于整个语法元素,即整个字符串或注释。您不能使用此功能突出显示各个部分,并且您仅应state为此目的查看给定的部分,就像(python-info-docstring-p state)代码中一样。千万不能在这个地方使用点; 我什至不确定point在字体锁定此阶段是否正确定义了的值。


将各个部分放在一起,您出于目的使用了错误的功能,这就是为什么您无法使用它的原因。

我没有尝试实现您想要的突出显示,但是我认为您的挖掘方式太深了,无法达到您的目的。如果我理解正确,那么您只需要在注释中突出显示轮廓即可。

如果我是对的,那么您只需要font-lock-keywords一种特殊的方式,即:

(my/find-outline-in-comment-p 0 'outline-face t)

outline-face您要在标题上应用的面孔在哪里,t意味着要覆盖此位置之前的所有字体锁定,并且my/find-outline-in-comment是一个匹配函数(请参阅的文档字符串font-lock-defaults),该函数占据位置并在注释中搜索第一个轮廓在(point)该位置之间,并返回要在比赛数据中突出显示的轮廓范围。

要查找轮廓,您可以向前扫描注释(使用font-lock-comment-face或语法状态),然后使用looking-at来检查注释是否具有轮廓。


1

考虑这样定义font-lock-syntactic-face-function

(setq font-lock-syntactic-face-function
      (lambda (state)
    (cond ((nth 3 state)
           font-lock-string-face)
          ((and (nth 4 state)(nth 8 state))
            MY-COMMENT-FACE
          (t  font-lock-comment-face))))

这使用python-mode.el进行了测试,保留了以“#*”开头的部分,且没有注释:

(setq py--font-lock-syntactic-face-function
      (lambda (state)
    (cond ((nth 3 state)
           font-lock-string-face)
          ((and (nth 4 state)(nth 8 state)
            (progn (save-excursion
                 (goto-char (nth 8 state))
                 (looking-at (concat comment-start (regexp-quote "*"))))))
           nil)
          (t font-lock-comment-face))))

使用模式管理时:

(font-lock-syntactic-face-function
                    . py--font-lock-syntactic-face-function)

代替nil,任何有效的面孔都应该起作用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.