En el modo C / C ++ en Emacs, cara cambio de código en #if 0 ... # endif bloque a cara comentario
-
13-10-2019 - |
Pregunta
Estoy tratando de agregar funcionalidad encuentra en algunos otros editores de código a la configuración de mi Emacs, con lo que el código C / C ++ dentro #if 0 ... # endif bloques se ajusta automáticamente a la observación de la cara / la fuente. Basado en mis pruebas, cpp-highlight-mode hace algo parecido a lo que yo quiero, sino que requiere la intervención del usuario. Parece como atar a la funcionalidad font-lock es la opción correcta para hacer que el comportamiento automático.
He seguido con éxito ejemplos en la documentación de GNU para cambiar la cara de las expresiones regulares de una sola línea. Por ejemplo:
(add-hook 'c-mode-common-hook
(lambda ()
(font-lock-add-keywords nil
'(("\\<\\(FIXME\\|TODO\\|HACK\\|fixme\\|todo\\|hack\\)" 1
font-lock-warning-face t)))))
funciona bien para depurar destacado relacionada palabras clave en cualquier parte de un archivo. Sin embargo, estoy teniendo problemas emparejan #if 0 ... #endif como una expresión regular de varias líneas. He encontrado algo de información útil en este post ( cómo componer región como "< ? php foo; bar;?> "), que sugirió que Emacs se le debe decir específicamente para permitir partidos de varias líneas. Pero este código:
(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))))))
todavía no funciona para mí. Tal vez mi expresión regular está mal (aunque parece trabajo utilizando M-x re-constructor ), he perdió mi sintaxis, o yo estoy siguiendo el enfoque equivocado por completo. Estoy usando Aquamacs 2.1 (que está basado en GNU Emacs 23.2.50.1) en OS X 10.6.5, si eso hace la diferencia.
Cualquier ayuda sería apreciada!
Solución
Incluso si usted tiene la expresión regular de varias líneas de trabajo, usted todavía tiene problemas con #ifdef/#endif
de anidado ya que evitaría que la fuente de bloqueo en la primera #endif
. Este código funciona, aunque no estoy seguro de si habrá una desaceleración notable de archivos de gran tamaño:
(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:
Tener en cuenta #else
editar # 2: niftier código para manejar anidación arbitraria de if / else / endif de