Dans le mode de C / C dans Emacs, face changement de code dans #if 0 ... # endif bloc à visage commentaire

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

Question

Je suis en train d'ajouter des fonctionnalités trouvée dans d'autres éditeurs de code à ma configuration Emacs, dans lequel le code C / C dans les #if 0 # ... blocs endif est automatiquement réglé sur la face de commentaire / police. Sur la base de mes tests, cpp-highlight mode fait quelque chose comme ce que je veux, mais nécessite une action de l'utilisateur. Il semble que lier dans la fonctionnalité de verrouillage de la police est la bonne option pour rendre le comportement automatique.

J'ai suivi avec succès des exemples dans la documentation de GNU pour changer le visage des expressions régulières une seule ligne. Par exemple:

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

fonctionne très bien pour déboguer en surbrillance des mots-clés liés à ne importe où dans un fichier. Cependant, je rencontre des problèmes correspondant à #if 0 ... # endif comme une expression régulière multiligne. J'ai trouvé des informations utiles dans ce post ( Comment composer région comme « < ? php foo, bar,?> "), qui a suggéré que Emacs doit être dit spécifiquement pour permettre des correspondances multilignes. Mais ce code:

(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))))))

ne fonctionne toujours pas pour moi. Peut-être mon expression régulière est mauvaise (mais il semble fonctionner en utilisant M-x re-constructeur ), je l'ai foiré ma syntaxe, ou que je suis tout à fait la mauvaise approche. J'utilise Aquamacs 2.1 (qui est basé sur GNU Emacs 23.2.50.1) sur OS X 10.6.5, si cela fait une différence.

Toute aide serait appréciée!

Était-ce utile?

La solution

Même si vous avez la multiligne regexp au travail, vous auriez encore des problèmes avec son #ifdef/#endif imbriqué car il arrêterait de verrouillage police au premier #endif. Ce code fonctionne, bien que je ne sais pas s'il y aura un ralentissement notable pour les gros fichiers:

(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: Prendre en compte #else

EDIT # 2: Code Niftier pour gérer l'imbrication arbitraire de if / else / endif de

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top