12

私の .emacs ファイルには次のものがあります。

 (defun c++-mode-untabify ()
   (save-excursion
     (goto-char (point-min))
     (while (re-search-forward "[ \t]+$" nil t)
       (delete-region (match-beginning 0) (match-end 0)))
     (goto-char (point-min))
     (if (search-forward "\t" nil t)
         (untabify (1- (point)) (point-max))))
   nil)

 (add-hook 'c++-mode-hook
           '(lambda ()
              (make-local-hook 'write-contents-hooks)
              (add-hook 'write-contents-hooks 'c++-mode-untabify)))

主にhttp://www.jwz.org/doc/tabs-vs-spaces.htmlから盗用されています。untabifyこれにより、C++ ファイルを保存する前にemacs がバッファー上で実行されます。

問題は、C++ ファイルをロードした後、他のファイル タイプのバッファであっても、後続のすべてuntabifyのファイル書き込みにフックが適用されることです。これは、C++ ファイルを開いて、たとえばタブ区切りのテキスト ファイルを編集すると、ファイルを保存するときにタブが壊れてしまうことを意味します。

私は elisp の第一人者ではありませんが、行は追加をローカル バッファーにのみ適用(make-local-hook 'write-contents-hooks)しようとしていると思います。write-contents-hooksただし、それは機能しておらず、すべてのバッファーc++-mode-untabifyに対応しています。write-contents-hooks

Windows XP ボックスで EmacsW32 22.0 を使用しています。変更を特定のバッファに対してローカルにする方法や、他の C++ 以外のバッファに切り替えるときに変更write-contents-hooksをリセットする方法を知っている人はいますか?nil

4

3 に答える 3

22

write-contents-hooks も廃止されました。これはあなたが求めているものです:

(add-hook 'c++-mode-hook
      '(lambda ()
         (add-hook 'before-save-hook
                   (lambda ()
                     (untabify (point-min) (point-max))))))

これは、私が使用しているものから抽出されたもので、他のいくつかのことを行い、プログラミング固有のモードで動作するように抽象化されています。

(defun untabify-buffer ()
  "Untabify current buffer"
  (interactive)
  (untabify (point-min) (point-max)))

(defun progmodes-hooks ()
  "Hooks for programming modes"
  (yas/minor-mode-on)
  (add-hook 'before-save-hook 'progmodes-write-hooks))

(defun progmodes-write-hooks ()
  "Hooks which run on file write for programming modes"
  (prog1 nil
    (set-buffer-file-coding-system 'utf-8-unix)
    (untabify-buffer)
    (copyright-update)
    (maybe-delete-trailing-whitespace)))

(defun delete-trailing-whitespacep ()
  "Should we delete trailing whitespace when saving this file?"
  (save-excursion
    (goto-char (point-min))
    (ignore-errors (next-line 25))
    (let ((pos (point)))
      (goto-char (point-min))
      (and (re-search-forward (concat "@author +" user-full-name) pos t) t))))

(defun maybe-delete-trailing-whitespace ()
  "Delete trailing whitespace if I am the author of this file."
  (interactive)
  (and (delete-trailing-whitespacep) (delete-trailing-whitespace)))

(add-hook 'php-mode-hook 'progmodes-hooks)
(add-hook 'python-mode-hook 'progmodes-hooks)
(add-hook 'js2-mode-hook 'progmodes-hooks)
于 2008-11-27T01:17:36.963 に答える
5

私の Emacs のドキュメントによると、make-local-hook は 21.1 で廃止されました。これは、add-hook がフックをバッファーローカルにするためのオプションの引数を取るようになったためです。だからあなたは試すことができます:

(add-hook 'c++-mode-hook
           '(lambda ()
              (add-hook 'write-contents-hooks 'c++-mode-untabify nil t)))

もう 1 つのオプションは、c++-mode-untabify 関数で現在のモードをチェックすることです。私はおそらくそれを次のように書くだけです:

(defun c++-mode-untabify ()
  (if (string= (substring mode-name 0 3) "C++")
      (save-excursion
       (delete-trailing-whitespace)
       (untabify (point-min) (point-max)))))
于 2008-11-25T20:21:14.457 に答える
2

次のようにフックを追加してみてください。

 (add-hook 'c++-mode-hook
           '(lambda ()
              (add-hook 'write-contents-hooks 'c++-mode-untabify nil t)))

add-hook の 2 つの追加引数に注意してください。ドキュメントによると、末尾の t は make-local-hook と同じように (またはその逆) 実行する必要がありますが、make-local-hook が非推奨になっていることへの言及も見てきました。少なくとも私のボックス(linux、gnu emacs 21.3.1)では、必要な効果が見られます-フックはc ++バッファーにのみ接続され、他のすべてのバッファーには接続されません。

最後の手段として、c++-mode-untabify 関数に常にチェックを入れて、現在のメジャー モードが c++-mode の場合にのみ魔法のようにすることができます。

ただし、これは興味深い解決策です。すべてのタブを削除した場合、タブを元に戻すために何をしていますか? それが何であれ止めれば、このハックは必要ありません。

于 2008-11-25T20:23:13.343 に答える