Emacs: выделение TODO * только * в комментариях

17

Этот вопрос связан с другим, Emacs: индикатор TODO на левой стороне . Недавно я натолкнулся на второстепенный режим, который мне очень понравился FixmeMode . Он поддерживает автоматическое выделение меток TODO и перемещение между ними. Тем не менее, я думаю, что имеет смысл распознавать строки «TODO» только в комментариях, а не загрязнять весь файл. Возможно ли это?

    
задан Wei Hu 03.03.2010 в 00:11
источник

3 ответа

24

Посмотрите библиотеку fic-mode.el , она была проверена на C ++ и Emacs- Лисп.

Это было написано специально, чтобы ответить на этот вопрос.

Установка похожа на любой стандартный пакет:

(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)
    
ответ дан Trey Jackson 10.10.2010 в 13:10
  • Хорошая работа, спасибо! Не могли бы вы вкратце объяснить, как вам удалось решить эту задачу с таким маленьким кодом? Кроме того, было бы неплохо иметь настраиваемые переменные fic-режимы, которые могут использоваться для определения всех разрешенных режимов, вместо того, чтобы добавлять к переключателям режима один за другим. –  Wei Hu 11.10.2010 в 05:49
  • @WeiHu Что касается того, как он был разрешен с таким маленьким кодом, стоит просто прочитать код - font-lock предоставляет достаточно богатую инфраструктуру для решения проблемы. Реальный ключ состоял в том, чтобы использовать параметр блокировки шрифта, который вызывает процедуру (в отличие от только регулярного выражения), которая определяет, какие строки выделять (это будет «fic-search-for-keyword»), и эта процедура просто проверяет, строка находится в комментарии / строке. –  Trey Jackson 11.10.2010 в 23:58
  • Итак, вы используете тот факт, что строки и комментарии используют специальные шрифтовые грани. Могут ли быть ложные срабатывания? –  Wei Hu 12.10.2010 в 02:43
  • @WeiHu Поскольку FIXME распознается только тогда, когда он помечен как строка / комментарий, ложный позитв произойдет только тогда, когда функция font-lock имеет ложные положительные значения для этих типов. –  Trey Jackson 12.10.2010 в 18:13
3

Это возможно, но немного сложнее. Режим Fixme использует font-lock для выделения, поэтому он работает по принципу «как есть», чтобы выделить ключевые слова. Font-lock захватывает на очень низком уровне, в основном работает после каждого изменения содержимого буфера. Тем не менее, он оптимизирован, что позволяет ему мгновенно появляться на современных компьютерах.

Индикатор TODO в левой полосе статичен. Выполните функцию, и все текущие TODO будут выделены; изменение буфера (добавление или удаление TODO) не изменяет индикатор полосы; это изменяется только тогда, когда функция снова запускается.

Ваш подход должен был бы попасть в синтаксические таблицы, определяя сначала, когда вы в комментарии, а затем ищем ключевые слова. Сложная часть заключается в том, чтобы делать это интерактивно (т. Е. По мере ввода). Вы должны иметь возможность подключаться к конструкциям font-lock , чтобы сделать это, но функция, которую вы предоставляете для поиска таблицы синтаксиса комментариев, а затем для ключевых слов лучше быть очень эффективной, поскольку она будет запускаться каждый раз при изменении буфера (хотя он будет работать только в измененном регионе, я думаю). Вы хотели бы наполнить все это в font-lock-syntactic-keywords , а не font-lock-keywords , потому что синтаксический ключевой проход проходит до синтаксического прохода (который происходит до прохождения ключевого слова), и вам нужно установить внутренние комментарии TODO до того, как будут установлены сами комментарии .

Извините, это не полный ответ рабочего кода .....

    
ответ дан Joe Casadonte 03.03.2010 в 14:29
  • Ничего себе. Это намного сложнее, чем я думал. –  Wei Hu 03.03.2010 в 20:12
  • Это проще и сложнее, чем я думал. Легче в том смысле, что весь крюк для блокировки шрифтов и привязка не были такими трудными, но способ, намного сложнее, потому что очень сложно выяснить, есть ли у вас комментарий. По крайней мере, я пока не смог понять это. Так что еще пример кода ..... –  Joe Casadonte 06.03.2010 в 14:59
2

Возможно, это поможет: есть fn c-in-literal в cc-mode и аналогичный csharp-in-literal в режиме csharp. возвращаемое значение c , если в комментарии в стиле C, c++ , если в C ++ стиль комментария. Вы можете добавить это к коду в Emacs: индикатор TODO на левой стороне чтобы получить то, что вы хотите.

(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))))))))))
    
ответ дан Cheeso 03.03.2010 в 14:33
  • Спасибо за ваш ответ. Мне бы очень хотелось получить ответ, который улучшится на FixmeMode, потому что он работает на основе типа as-you-type, как сказал @Joe. –  Wei Hu 03.03.2010 в 20:12
  • Да, это имеет смысл. Как побочный пункт, я думаю, что подсветка вещей, которые уже находятся на экране, не так полезна, как визуальная индикация приблизительного местоположения FIXME в исходном коде. инструменты визуального разграничения делают это, как и Eclipse при отображении ошибок компиляции и Visual Studio. Я спросил об этом отдельно: stackoverflow.com/questions/2348679/... –  Cheeso 03.03.2010 в 20:18