(setq make-backup-files nil) |
バックアップファイル(*~ )を作らない
|
Emacsのデフォルト設定では,abc.txt
という名前のファイルを更新すると編集前の内容が
abc.txt~
というファイルにバックアップされるようになっています.
この設定は一部の古いUNIXのユーザにはおなじみの設定なんだけども,
普段はあまり有用でない…というかむしろ目障りなバックアップファイルがあちこちにつくられるため,
おおむね不評な印象です.
この設定をオフにしてバックアップファイルをつくらせないようにするには,
make-backup-files
をnil
にしておきます.
~/.bak
に集める
Emacsのデフォルト設定が不評なのは,あっちこっちに“ナントカ~
”みたいなファイルが散らばるからで,
バックアップがとられること自体は好ましいことなんだと思います.
そこで,次のようにするとバックアップファイルが“~/.bak/
”ディレクトリに集められるようになり,
バックアップファイルが散らばる問題を回避しながらバックアップをとれるようになります.
make-backup-file.el |
---|
(setq make-backup-files t) (setq backup-directory "~/.bak") (if (and (boundp 'backup-directory) (not (fboundp 'make-backup-file-name-original))) (progn (fset 'make-backup-file-name-original (symbol-function 'make-backup-file-name)) (defun make-backup-file-name (filename) (if (and (file-exists-p (expand-file-name backup-directory)) (file-directory-p (expand-file-name backup-directory))) (concat (expand-file-name backup-directory) "/" (file-name-nondirectory filename)) (make-backup-file-name-original filename))))) |
上のプログラムは,いろいろ考慮した結果,3行目のif
以降が ずいぶん複雑になってるけど,
もっと簡単に書くこともできます(そうしたほうが設定ファイルが簡潔になります).
以下にシンプルな方から順に説明します.
Emacsは
バックアップファイルのファイル名として
(make-backup-file-name "abc.txt")
のように評価して得られた文字列を使います.
なので,make-backup-file-name
を再定義してしまえば任意のファイル名でバックアップをとれます.
(defun make-backup-file-name (filename) (concat "~/.bak/" (file-name-nondirectory filename)))
とりあえず これでバックアップファイルを~/.bak/
に集めることができるようになりました.
ここで,file-name-nondirectory
は引数として指定された文字列からパス名部分を取り除く関数です.
たとえば(file-name-nondirectory "/home/hatai/abc.txt")
とすると,
abc.txt
という文字列が帰ってきます(UNIXのbasename
コマンドと同じ動作).
しかし,このままでは~/.bak/
ディレクトリが存在しない場合にバックアップファイルの作成が失敗してしまいまうという問題があります.
[注:正確には失敗するわけではなくて%backup%~
のようなファイル名でバックアップされますが,
いずれにしても期待通りの動作にはなりません.]
次の例では~/.bak/
というディレクトリがあるかどうかを調べて,
あればそのディレクトリの下にバックアップファイルをつくり,
なければデフォルトと同じようにファイル名の末尾にチルダ(~
)をつけたものをバックアップのファイル名とします.
[補足:~/.bak
がディレクトリではなく普通のファイルだった場合もデフォルトと同じ動作にしないといけないので,
file-exists-p
ではなくfile-directory-p
を使って判定するのがよいと思います.]
(defun make-backup-file-name (filename) (if (file-directory-p "~/.bak") (concat "~/.bak/" (file-name-nondirectory filename)) (concat filename "~")))
これでとりあえず穴はなくなったのですけど,
このプログラムではデフォルトの動作=(concat filename "~")
だと決めつけてしまっているところがちょっと気になります.
現時点でのファイル名の末尾にチルダをつけるというデフォルトの動作がいつまでも変わらない保証はないし,
サイトごとの設定ファイルなどでデフォルトの動作が既に入れ替えてある可能性もあります.
そこで,ホントのデフォルトの動作=make-backup-file-name
を再定義する前の定義内容を
make-backup-file-name-original
というシンボルに控えておき,
デフォルトの動作をさせたいところでは これを使うようにします.
(fset 'make-backup-file-name-original (symbol-function 'make-backup-file-name)) (defun make-backup-file-name (filename) (if (file-directory-p "~/.bak") (concat "~/.bak/" (file-name-nondirectory filename)) (make-backup-file-name-original filename)))
このプログラムが複数回評価されるかもしれないことを考慮すると,
せっかくmake-backup-file-name-original
に控えておいたデフォルトの動作が
2回目以降の評価で失われてしまう点が気になります.
[たとえば.emacs
を書き換えた際に,書き換えた内容に文法エラーがないかどうかを調べたり,
書き換えた内容をすぐに反映したりするために,
M-x eval-buffer
を実行して.emacs
全体を再評価するというような操作をすることがあると思います.
このような場合にせっかく控えておいたデフォルト動作が上書きされてなくなってしまいます.]
そこで,既にmake-backup-file-name-original
に関数がバインドされていたら,
一連の式を再評価しないようにして,この問題を回避します(C言語のヘッダーファイルの複数回インクルード問題を回避する方法と同じ考え方です).
(if (not (fboundp 'make-backup-file-name-original)) (progn (fset 'make-backup-file-name-original (symbol-function 'make-backup-file-name)) (defun make-backup-file-name (filename) (if (file-directory-p "~/.bak") (concat "~/.bak/" (file-name-nondirectory filename)) (make-backup-file-name-original filename)))))
あとは,バックアップを保存するディレクトリを簡単に変更できるように,
バックアップディレクトリはシンボルbackup-directory
に設定されている値を使うようにします.
同時にbackup-directory
が指定されていない場合は,そもそもデフォルトの動作でOKという意味なんだろうなと解釈して,
make-backup-file-name
の再定義自体を行わないようにしました.
(setq backup-directory "~/.bak") (if (and (boundp 'backup-directory) (not (fboundp 'make-backup-file-name-original))) (progn (fset 'make-backup-file-name-original (symbol-function 'make-backup-file-name)) (defun make-backup-file-name (filename) (if (file-directory-p backup-directory) (concat backup-directory "/" (file-name-nondirectory filename)) (make-backup-file-name-original filename)))))
以上で完成です.
[完全版では,さらにbackup-directory
を参照するところで
(expand-file-name backup-directory)
としてフルパスに展開していますが,
これはホントに不要(冗長)のはずですので書かなくてOKと思います.]
[注:cygwin版のEmacsでは,チルダを含むパス(例えば~/.bak
)の展開がうまくいかないらしく,
このプログラムはうまく動かないようです.
いろいろやってみましたけど,今のところ解決法が見つかっていません….]
[1] | GNU Emacs Lisp Reference Manual - Backup Names |