En el modo C / C ++ en Emacs, cara cambio de código en #if 0 ... # endif bloque a cara comentario

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

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!

¿Fue útil?

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top