我正在尝试为主模式设置字体锁定。以下是一些示例代码:
USING: foo bar bar ;
IN: fuelcolors
TUPLE: font < super-class
name
size
bold?
italic?
{ foreground initial: COLOR: black }
{ background initial: COLOR: white } ;
TUPLE: rgb red green blue ;
: foobar ( seq -- seq )
hello there { 1 2 3 } ;
以下符号应该用一些面突出显示(不管是哪一个,我的问题是匹配的部分):名称、大小、粗体?,斜体?,前景,背景,红色,绿色,蓝色。它们表示元组中槽的名称。
我知道正则表达式不会这么做,因为匹配的区域不是连续的。斜体?和前景应该匹配,但而不是这些符号之间的{字符。因此,我认为我可以编写一个字体锁定匹配器函数,类似于Dmitri在这里提供的函数:针对非常相似的问题,在emacs中进行上下文敏感的字体锁定。
但事实上,他的解决方案利用了这样一个事实,即要突出显示的项目的"顺序"是在麻醉中,而这里的情况并非如此。
字体锁在这种情况下会遇到问题(regex和字体锁中的匹配数量未知),但我仍然希望有一些"足够好"的解决方案,即使它需要破解字体锁内部。
匹配器函数似乎是一个很好的匹配。
我将使用两个函数,一个用于匹配TUPLE
并设置成员搜索的限制,另一个用于查找每个元素的内部匹配器。内部函数可以被编写为知道{ name ... }
构造。
诀窍是,内部函数对每个元素调用一次,因此永远不会出现匹配数量未知的情况。
规则看起来像:
'(my-match-a-tuple
(1 'font-lock-keyword-name-face) ;; Highlight the word TUPLE
(my-match-tuple-member
;; Pre-match form (can be used move the point around and to set search limits)
nil
;; Post-match form (can be used to move point around afterwords)
nil
(1 'font-lock-variable-face)))
你可以看看我的cmake脚本字体化包,它大量使用matcher函数:https://github.com/Lindydancer/cmake-font-lock
这是我最终得到的解决方案:
(,"\(TUPLE\):[ n]+\(\(?:\sw\|\s_\)+\)\(?:[ n]+<[ n]+\(\(?:\sw\|\s_\)+\)\)?"
(1 'factor-font-lock-parsing-word)
(2 'factor-font-lock-type-name)
(3 'factor-font-lock-type-name nil t)
("\(\(?:\sw\|\s_\)+\)\|\(?:{[ n]+\(\(?:\sw\|\s_\)+\)[^}]+\)"
((lambda (&rest foo)
(save-excursion
(re-search-forward " ;" nil t)
(1- (point)))))
nil
(1 'factor-font-lock-symbol nil t)
(2 'factor-font-lock-symbol nil t)))