В режиме C/C ++ в EMACS измените лицо кода в #IF 0… #блок ENDIF, чтобы прокомментировать лицо
-
13-10-2019 - |
Вопрос
Я пытаюсь добавить функциональность, найденные в некоторых других редакторах кода в мою конфигурацию 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