Emacs:在评论中突出显示 TODO *only*

Posted

技术标签:

【中文标题】Emacs:在评论中突出显示 TODO *only*【英文标题】:Emacs: highlighting TODO *only* in comments 【发布时间】:2011-01-22 23:33:44 【问题描述】:

这个问题与另一个问题Emacs :TODO indicator at left side 有关。我最近遇到了一种我非常喜欢的次要模式,称为FixmeMode。它支持自动突出显示 TODO 标记,并在它们之间导航。但是,我认为只在 cmets 中识别“TODO”字符串更有意义,而不是污染整个文件。有可能吗?

【问题讨论】:

【参考方案1】:

查看库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,它可用于定义所有启用的模式,而不必一一添加到模式挂钩。 @WeiHu 这么少的代码是怎么解决的,看代码就知道了——font-lock 提供了足够丰富的框架来解决这个问题。真正的关键是使用一个字体锁定设置来调用一个例程(而不仅仅是一个正则表达式),该例程确定要突出显示的字符串(即'fic-search-for-keyword),并且该例程只是验证字符串是否在注释中/字符串。 因此,您正在利用字符串和 cmets 使用特殊字体的事实。会不会有误报? @WeiHu 由于 FIXME 仅在标记为字符串/注释时才被识别,因此误报只会在 font-lock 对这些类型有误报时发生。【参考方案2】:

这是可能的,但有点棘手。 Fixme 模式使用font-lock 进行突出显示,因此它可以在键入时突出显示关键字。字体锁定挂钩在非常低的级别,基本上在每次更改缓冲区内容后运行。不过,它经过高度优化,可以在现代计算机上即时显示。

左边缘的 TODO 指示器是静态的。执行该函数,所有当前的 TODO 都会被高亮显示;更改缓冲区(添加或删除 TODO)不会更改边缘指标;只有当函数再次运行时才会改变。

您的方法必须进入语法表,首先确定您何时在评论中,然后查找关键字。棘手的部分在于以交互方式执行此操作(即在您键入时)。您应该能够挂钩到 font-lock 构造来执行此操作,但是您提供的用于搜索注释语法表然后搜索关键字的功能非常有效,因为它会在每次缓冲区更改时运行(尽管我认为它只会在更改后的区域上运行)。您可能希望将所有这些都放在font-lock-syntactic-keywords 而不是font-lock-keywords 中,因为语法关键字传递发生在语法传递之前(发生在关键字传递之前),并且您需要在 cmets 本身设置之前在 cmets 中设置 TODO .

抱歉,这不是一个完整的工作代码答案.....

【讨论】:

这比我想象的更容易也更棘手。从某种意义上说,整个字体锁定钩子和绑定并不难,但方式更难,因为要确定你是否在评论中真的很棘手。至少到目前为止我还没有弄清楚。所以还没有代码示例.....【参考方案3】:

也许这会有所帮助:有一个 fn c-in-literal 在 cc-mode,以及 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 所说,它可以在你输入的基础上工作。 是的,这是有道理的。顺便说一句,我认为突出显示屏幕上已经显示的内容不如在源代码中提供 FIXME 的大致位置的视觉指示有用。视觉差异工具可以做到这一点,Eclipse 在显示编译错误时也是如此,我认为 Visual Studio 也是如此。我单独询问了这个问题:***.com/questions/2348679/…

以上是关于Emacs:在评论中突出显示 TODO *only*的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Emacs 中选择或突出显示一个块?

Emacs支架和支架突出显示?

如何突出显示 Emacs 缓冲区中所有出现的单词?

在 vim 中用于 inc-search 的 Emacs 样式突出显示

为啥 Pycharm 不突出 TODO 的?

在批处理模式下使用 emacs 转储带有语法突出显示的文件?