Emacs:仅在注释中高亮显示TODO

19

这个问题涉及到另一个问题:Emacs :TODO indicator at left side。我最近发现了一个我非常喜欢的小模式,叫做FixmeMode。它支持自动突出显示TODO标记,并在它们之间导航。然而,我认为只有在注释中识别“TODO”字符串才比污染整个文件更有意义。这可行吗?

4个回答

25

请查看fic-mode.el库,它已在C++和Emacs-Lisp中进行了验证。

它是专门为回答这个问题而编写的。

安装与任何标准包相同:

(require 'fic-mode)
(add-hook 'c++-mode-hook 'turn-on-fic-mode) 

尽管Wei Hu要求添加到多个模式的方法简单易行,以下是方法:

(defun add-something-to-mode-hooks (mode-list something)
  "helper function to add a callback to multiple hooks"
  (dolist (mode mode-list)
    (add-hook (intern (concat (symbol-name mode) "-mode-hook")) something)))

(add-something-to-mode-hooks '(c++ tcl emacs-lisp) 'turn-on-fic-mode)

好工作,谢谢!你能简要解释一下你是如何用如此少的代码解决这个任务的吗?另外,拥有一个可定制的变量fic-modes会很好,它可以用来定义所有已启用的模式,而不必逐个添加到模式挂钩中。 - Wei Hu
1
@WeiHu 关于如何用如此少的代码解决问题,值得一读的是代码本身 - font-lock 提供了足够丰富的框架来解决问题。真正的关键是使用一个 font-lock 设置,调用一个例程(而不仅仅是一个 regexp),该例程确定要突出显示的字符串(即 'fic-search-for-keyword),并且该例程只验证该字符串是否在注释/字符串中。 - Trey Jackson
所以您正在利用字符串和注释使用特殊字体的事实。会不会有误报呢? - Wei Hu
1
@WeiHu 由于只有在标记为字符串/注释时才能识别 FIXME,因此当字体锁定在这些类型上出现误报时,假阳性才会发生。 - Trey Jackson

3
这是可能的,但会更加棘手。Fixme模式使用font-lock来进行突出显示,因此它可以在您键入时按照关键字进行突出显示。Font-lock钩子在非常低的级别上起作用,基本上在对缓冲区内容进行任何更改后运行。尽管如此,它经过了高度优化,这使得它在现代计算机上看起来是即时的。
左侧边栏中的TODO指示器是静态的。执行该函数可突出显示所有当前的TODO;更改缓冲区(添加或删除TODO)不会更改侧栏指示器;只有再次运行函数时才会更改。
您的方法必须涉及语法表,首先确定您是否在注释中,然后查找关键字。棘手的部分在于交互式地执行此操作(即在输入时)。您应该能够连接到font-lock构造以执行此操作,但是您提供的搜索注释语法表和关键字的函数最好非常高效,因为每次缓冲区更改时都会运行它(尽管我认为它只会在更改区域上运行)。您需要将所有这些内容放入font-lock-syntactic-keywords而不是font-lock-keywords,因为在设置注释之前需要在注释中设置TODO,而注释本身在语法分析(在关键字分析之前)之前进行设置。
很抱歉这不是一个完整的可工作代码答案...

这比我想象中的更容易和更棘手。从字体锁定钩子和关联方面来说,它更容易,但因为很难确定是否在注释中,所以更加困难。至少到目前为止,我还没有能够找出来。因此,暂时还没有代码示例... - Joe Casadonte

2
也许这可以帮助您:在cc-mode中有一个名为c-in-literal的函数,在csharp模式中有一个类似的csharp-in-literal函数。如果处于C样式注释中,则返回值为c,如果处于C++样式注释中,则返回值为c++。您可以将其添加到Emacs :TODO indicator at left side的代码中以获得所需的结果。
(defun annotate-todo ()
   "put fringe marker on TODO: lines in the curent buffer"
  (interactive)
  (let (lit)
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "TODO:" nil t)
      (progn
        (setq lit (c-in-literal)) ;; or csharp-in-literal
        (if (or (eq lit 'c) (eq lit 'c++))
            (let ((overlay (make-overlay (- (point) 5) (point))))
              (overlay-put overlay 'before-string
                           (propertize "A"
                                       'display
                                       '(left-fringe   ;; right
                                         horizontal-bar
                                         better-fringes-important-bitmap))))))))))

感谢您的回答。我确实希望有一个比FixmeMode更好的答案,因为正如@Joe所说,它是基于实时输入的。 - Wei Hu
是的,那很有道理。此外,我认为突出显示已经在屏幕上的内容并不像提供源代码中FIXME的大致位置的视觉指示那样有用。可视化差异工具可以做到这一点,Eclipse在显示编译错误时也可以,Visual Studio也可以,我想。我单独问了这个问题:https://dev59.com/HEzSa4cB1Zd3GeqPk0HL - Cheeso

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接