0

如何为指定的关键字设置面,但只有第一行的关键字?例如有这个文件

--- cut here ---
hello world    <-- this "hello" should have face set
hello world    <-- while this "hello" should not
--- cut here ---

只有第一个你好应该有面部设置

我试过这个

(defun first-line-hello(limit)
  (and (save-excursion (beginning-of-line)
                       (bobp))
       (re-search-forward "hello" limit)))

 (font-lock-add-keywords 'emacs-lisp-mode
                         '((first-line-hello . font-lock-warning-face)))

但似乎由于某种原因(bobp)在字体锁定关键字中使用时总是返回真。我也尝试使用 line-number-at-pos 得到相同的结果。

4

3 回答 3

2

你很接近,但有一些问题。'limit' 可能远远超出第一行的末尾,如果搜索失败,您不需要出错,并且无论搜索通过/失败,您都需要移动点。这一切都归结为更改函数中的一行:

(defun first-line-hello(limit)
  (and (save-excursion (beginning-of-line)
                       (bobp))
       (re-search-forward "hello" (min (point-at-eol) limit) 'go)))
于 2011-05-23T15:46:23.527 回答
1

Emacs 有一个正则表达式结构,它只匹配缓冲区开头的空字符串,所以试试这个:

(font-lock-add-keywords 'emacs-lisp-mode '(("\\`hello" . font-lock-warning-face)))

文档说:

‘\`’
    matches the empty string, but only at the beginning of the buffer or string being matched against. 
于 2011-05-23T14:10:45.077 回答
0

缓冲区的第一行?段落的第一行?

无论如何,我认为您可以使用自己的次要模式来做到这一点,在这种模式下,您可以按照自己喜欢的方式扫描缓冲区/区域。在您的扫描中,您需要从头开始,记下您第一次看到每个关键字的位置,突出显示它,然后继续扫描。如果您在扫描过程中看到重复的关键字,请不要突出显示该关键字。

我相信你不能用简单的字体锁定关键字来做到这一点。它们始终是关键字,无论它们出现在何处。但是您可以使用字体锁定的自定义匹配器来做到这一点。获得帮助font-lock-keywords,您将看到:

用户级关键字列表中的每个元素都应具有以下形式之一:

匹配器
...

其中 MATCHER 可以是要搜索的正则表达式,也可以是要
调用以进行搜索的函数名称(使用一个参数调用,即搜索的限制;
它应该返回非零,移动点,如果 成功match-data则适当设置;
喜欢re-search-forward)。

这些匹配器函数或正则表达式在看似任意的时间在缓冲区中的任意位置被调用或评估。由于这个原因,使用正则表达式是行不通的,但是使用函数,您可以扫描回缓冲区的开头,re-search-forward查找关键字,并确定它是否是您第一次看到该关键字,然后采取适当的行动。您还可以缓存关键字的首次出现位置,然后在更改后挂钩中管理缓存,但这变得相当复杂。

重新阅读时编辑我看到您已经尝试过后一种想法,但它对您不起作用。奇怪的。

于 2011-05-23T13:25:25.723 回答