避免使用字体锁定干扰注释

时间:2015-04-30 16:48:10

标签: emacs elisp syntax-highlighting font-lock major-mode

font-lock-defaults我有:

("\\(^\\| \\|\t\\)\\(![^\n]+\\)\n" 2 'factor-font-lock-comment)

评论字符为!,这样就可以让评论得到正确的答案。这主要起作用,除非在注释中有一个竞争的字体锁定实体,比如一个字符串(用双引号分隔):

! this line is font-locked fine
! this one is "not" because "strings"

如何让font-lock理解注释已被字体锁定,并且不需要尝试对其中的任何字符串进行字体锁定?显而易见的方法是将!添加到语法表中的注释starter类:

(modify-syntax-entry ?! "< 2b" table)

此解决方案无法实现,因为包含!的函数名称和其他符号是合法的,例如map! filter!foo!bar。添加!会导致包含此类名称的代码被错误地突出显示。

1 个答案:

答案 0 :(得分:4)

通常,使用font-lock关键字突出显示注释是个坏主意。为此使用句法阶段会更好。

尽管语法表的功能不足以描述您语言的语法,但仍然可以在语法字体锁定阶段突出显示注释。解决方案是提供一个自定义函数,将语法属性分配给应该开始注释的!字符。这是使用变量syntax-propertize-function完成的。

有关详细信息,请参阅elisp manual。此外,this tutorial详细介绍了这一点。

更新:以下是将!定义为评论开始字符但不在标识符内的简单示例。一个真实世界的例子可能需要一种更精确的方法来检查某些东西是否是一个标识符。

(defun exmark-syntax-propertize (start end)
  (funcall (syntax-propertize-rules
            ("[[:alnum:]_]\\(!\\)"
             (1 "_")))
           start
           end))

(defvar exmark-mode-syntax-table
  (let ((table (make-syntax-table)))
    (modify-syntax-entry ?\n ">   " table)
    (modify-syntax-entry ?!  "<   " table)
    table))

(define-derived-mode exmark-mode prog-mode "!-Mark"
  "Major mode for !-mark."
  (set (make-local-variable 'syntax-propertize-function)
       'exmark-syntax-propertize))