2010-12-28 7 views
12

他のコードエディタの機能をEmacsの設定に追加しようとしています。 #if 0 ...#endifブロック内のコードは自動的にコメントのface/fontに設定されます。私のテストに基づいて、cpp-highlight-modeは私が望むようなことをしますが、ユーザーの操作が必要です。フォントロック機能に縛られているように見えるのは、ビヘイビアを自動的にする正しいオプションです。EmacsのC/C++モードで、#if 0 ...#endifのブロックをコメントの表記に変更する

私は、単一線正規表現の表情を変えるために、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と複数行の正規表現のマッチングに問題があります。私はこの記事(How to compose region like "<?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)))))) 

まだ私のために働いていません。おそらく私の正規表現が間違っているかもしれません(M-xの再ビルダーを使用しているように見えますが)、私は構文を乱してしまいました。 OS X 10.6.5上でAquamacs 2.1(GNU Emacs 23.2.50.1に基づいています)を使用しています。

ご協力いただければ幸いです!

答えて

15

マルチライン正規表現が機能したとしても、最初に#endifにフォントロックを停止するので、ネストされた#ifdef/#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) 

EDIT: に考慮#else

EDIT#2: Niftier私は目立つ大きなファイルのためにスローダウンがあるだろうかはわからないが、このコードは、動作しますif/else/endifの任意のネストを処理するコード

+0

これはうまくいくようです。ありがとう!! – pogopop77

+0

別のキーワードとして 'else'を追加してコメントの顔を止めました。したがって、1行は次のようになります。(while(and depth> 0)(re-search-forward "^ \\ s - *#\\ s - * \\(if \\ | endif \\ | else \\\)また、小さなファイル(<100-200k)の場合、スローダウンは最小です。大きなファイル(4.3MB)では目立ちますが、それほど大きなファイルは編集しません。 – pogopop77

+0

@ pogopop77 : '#else'の扱いはあなたのやり方よりやや厄介なので、コードを更新しました。#if 0の'#else'の '#if 0 'では動作しませんが、おそらく後でそれを更新するでしょう。また、200kは小さなファイルですか;) – scottfrazer

関連する問題