12

他のコードエディターにある機能をEmacs構成に追加しようとしています。これにより、#if 0 ...#endifブロック内のC /C++コードが自動的にコメント面/フォントに設定されます。私のテストに基づくと、cpp-highlight-modeは私が望むようなことをしますが、ユーザーの操作が必要です。フォントロック機能を利用することは、動作を自動化するための正しいオプションのようです。

GNUドキュメントの例に従って、1行の正規表現の外観を変更することに成功しました。例えば:

(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を一致させるのに問題があります。私はこの投稿("<?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を使用して機能しているように見えますが)、構文を台無しにしたか、完全に間違ったアプローチに従っています。OS X10.6.5でAquamacs2.1(GNU Emacs 23.2.50.1に基づく)を使用していますが、違いがあります。

どんな援助もいただければ幸いです!

4

1 に答える 1

15

#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: if / else/endifの任意のネストを処理するためのNiftierコード

于 2010-12-29T13:48:50.133 に答える