Подтвердить что ты не робот

В режиме C/С++ в Emacs измените лицо кода на #if 0... # endif block, чтобы комментировать лицо

Я пытаюсь добавить функциональность, содержащуюся в некоторых других редакторах кода, в мою конфигурацию Emacs, в которой код C/С++ в #if 0... # endif-блоках автоматически устанавливается на лицо/шрифт комментария. Основываясь на моем тестировании, cpp-highlight-mode делает что-то вроде того, что я хочу, но требует действия пользователя. Кажется, что привязка к функции блокировки шрифтов - это правильная опция автоматического создания поведения.

Я успешно выполнил примеры в документации GNU, чтобы изменить грань однострочных регулярных выражений. Например:

(add-hook 'c-mode-common-hook
  (lambda ()
    (font-lock-add-keywords nil
      '(("\\<\\(FIXME\\|TODO\\|HACK\\|fixme\\|todo\\|hack\\)" 1 
        font-lock-warning-face t)))))

отлично работает, чтобы выделять ключевые слова для отладки в любом месте файла. Однако у меня возникают проблемы с соответствием #if 0... # endif как многострочного регулярного выражения. Я нашел полезную информацию в этом сообщении (Как составить такой регион, как "<? Php foo; bar;" "), который предположил, что Emacs должен следует сказать, чтобы разрешить многострочные совпадения. Но этот код:

(add-hook 'c-mode-common-hook
  (lambda ()
    '(progn
      (setq font-lock-multiline t)
      (font-lock-add-keywords nil
        '(("#if 0\\(.\\|\n\\)*?#endif" 1
          font-lock-comment-face t))))))

все еще не работает для меня. Возможно, мое регулярное выражение неверно (хотя, похоже, оно работает с использованием M-x re-builder), я испортил свой синтаксис или полностью придерживаюсь неправильного подхода. Я использую Aquamacs 2.1 (который основан на GNU Emacs 23.2.50.1) на OS X 10.6.5, если это имеет значение.

Любая помощь будет оценена!

4b9b3361

Ответ 1

Даже если вы используете многострочное регулярное выражение, у вас все еще будут проблемы с вложенным #ifdef/#endif, поскольку он остановит блокировку шрифтов на первом #endif. Этот код работает, хотя я не уверен, будет ли заметное замедление для больших файлов:

(defun my-c-mode-font-lock-if0 (limit)
  (save-restriction
    (widen)
    (save-excursion
      (goto-char (point-min))
      (let ((depth 0) str start start-depth)
        (while (re-search-forward "^\\s-*#\\s-*\\(if\\|else\\|endif\\)" limit 'move)
          (setq str (match-string 1))
          (if (string= str "if")
              (progn
                (setq depth (1+ depth))
                (when (and (null start) (looking-at "\\s-+0"))
                  (setq start (match-end 0)
                        start-depth depth)))
            (when (and start (= depth start-depth))
              (c-put-font-lock-face start (match-beginning 0) 'font-lock-comment-face)
              (setq start nil))
            (when (string= str "endif")
              (setq depth (1- depth)))))
        (when (and start (> depth 0))
          (c-put-font-lock-face start (point) 'font-lock-comment-face)))))
  nil)

(defun my-c-mode-common-hook ()
  (font-lock-add-keywords
   nil
   '((my-c-mode-font-lock-if0 (0 font-lock-comment-face prepend))) 'add-to-end))

(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

EDIT: Примите во внимание #else

РЕДАКТИРОВАТЬ № 2: Код Niftier для обработки произвольного вложенности if/else/endif