Emacs での編集中ファイルのバックアップ設定

Emacs でバックアップを有効にすると ~ で始まるバックアップファイルが大量にできて見苦しく,以前はバックアップをオフにして使っていた.ところが最近,ESS を使ってトライアンドエラーでスクリプトを書くことが多くなり,git コミットよりも短いスパンで変更を戻したい場合が多くなった.そこで,Emacs 標準のバージョン管理ツールを,自分の使いやすいようにカスタマイズすることにした.

書いた emacs lisp はこんなところ.バックアップファイルは Emacs の version-control に従ってナンバリングされ,ファイルを閉じたときに同時に削除.保存場所は ls にひっかからないよう,ディレクトリごとに .bak サブディレクトリを作成し,その下に保存することにした.

;;; Use emacs version-control, saving in .bak directory
(setq make-backup-files t)
(setq version-control t)
(defun backup-dir (fpath)
  (expand-file-name ".bak/" (file-name-directory fpath)))
(defun make-backup-file-name (fpath)
  (let ((backup-dir (backup-dir fpath)))
    (if (not (file-exists-p backup-dir))
        (make-directory backup-dir))
    (concat backup-dir (file-name-nondirectory fpath) "~")))
(defun find-backup-file-name (fpath)
  (cons (let ((backup-dir (backup-dir fpath))
              (fname (file-name-nondirectory fpath))
              (version 1))
          (defun vfpath (v)
            (concat backup-dir fname ".~" (number-to-string v) "~"))
          (if (not (file-exists-p backup-dir))
              (make-directory backup-dir))
          (while (file-exists-p (vfpath version))
            (setq version (1+ version)))
          (vfpath version))
        nil))

;;; Delete backup files when the buffer is killed
(defun delete-backup-files (fpath)
  (if fpath
      (let ((backup-dir (backup-dir fpath))
            (fname (file-name-nondirectory fpath)))
        (dolist (vfpath (file-expand-wildcards (concat backup-dir fname "*~")))
          (delete-file vfpath)))))
(add-hook 'kill-buffer-hook
          (lambda () (delete-backup-files buffer-file-name)))
(add-hook 'kill-emacs-hook
          (lambda ()
            (dolist (buffer (buffer-list))
              (if (buffer-file-name buffer)
                  (delete-backup-files (buffer-file-name buffer))))))

;;; Make a copy of the newest version
(defun make-dup-file (fpath)
  (if fpath
      (let ((backup-dir (backup-dir fpath))
            (fname (file-name-nondirectory fpath)))
        (if (not (file-exists-p backup-dir))
            (make-directory backup-dir))
        (write-region nil nil (concat backup-dir fname) nil 1))))
(add-hook 'after-save-hook
          (lambda () (make-dup-file buffer-file-name)))

コメントを残す

メールアドレスが公開されることはありません。