В режиме C/C ++ в EMACS измените лицо кода в #IF 0… #блок ENDIF, чтобы прокомментировать лицо

StackOverflow https://stackoverflow.com/questions/4549015

Вопрос

Я пытаюсь добавить функциональность, найденные в некоторых других редакторах кода в мою конфигурацию EMACS, в результате чего код C/C ++ в #IF 0 ... #Блоки ENDIF автоматически устанавливается на лицо Comment Face/Font. На основе моего тестирования, 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 как многослойное регулярное выражение. Я нашел некоторую полезную информацию в этом посте (Как составить регион, как "u003C?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))))))

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

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

Это было полезно?

Решение

Даже если у вас есть многослойный режим работы, у вас все равно будут проблемы с вложенными #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)

РЕДАКТИРОВАТЬ:Принять к сведению #else

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top