auto-save で文字コードが変わったら警告を出す

auto-save-buffers 関連のお話。

ここに書いた現象には自分が認識していたよりも頻繁に遭遇していたようで、対策してから結構な回数助けられました。慣れってコワいね。もっと早くにやっときゃよかった。

ただ、僕が思うに auto-save がもたらす最凶の被害は

  • 知らないうちに意図しない文字コードで保存されている

これだと思ってます。めったに起こらないけど。バッファを消す前にモードラインの表示を見て気付けば `C-x RET f' で正しい文字コードを指定してやれば済むんですが、そんなことは稀な訳で。んで、再度ファイルを開いてみたら日本語が化け化けで「あわわわわ」といったことになる。

化け方から想像して `C-x RET c' で復旧を試みるんですが、運が悪かったり(日頃の行ないか?)勘が冴えてなかったり(そういう問題か?)するとどうにも復旧できなかったり。泣く泣くバックアップやリポジトリから書き戻すことになって激しい虚脱感に襲われます。

これじゃいかん。

そこで「保存した際に文字コードが以前と変わっていたら(auto-save を切りつつ)警告を出す」というのをやってみました。以前どっか(bookshelf さんあたり?)で見掛けた気がするんですが見つかんなかったので自前で。

--- auto-save-buffers.el	06  7月 2005 09:31:17 +0900	1.1
+++ auto-save-buffers.el	12  4月 2006 22:34:56 +0900	
@@ -24,7 +24,7 @@
 (defun auto-save-buffers ()
   "Save buffers if `buffer-file-name' matches `auto-save-buffers-regexp'."
   (let ((buffers (buffer-list))
-	buffer)
+	buffer orig-coding-system)
     (unwind-protect
 	(save-excursion
 	  (fset 'write-region 'auto-save-buffers-write-region)
@@ -39,9 +39,14 @@
 					  buffer-file-name))
 		       (string-match auto-save-buffers-regexp buffer-file-name)
 		       (file-writable-p buffer-file-name))
+	      (setq orig-coding-system buffer-file-coding-system)
 	      (basic-save-buffer)
 	      (set-visited-file-modtime)
-	      (set-buffer-modified-p nil))
+	      (set-buffer-modified-p nil)
+	      (unless (eq buffer-file-coding-system orig-coding-system)
+		(auto-save-buffers-toggle t)
+		(lwarn 'auto-save :warning
+		       "Coding system changed: %s" buffer-file-name)))
 	    (setq buffers (cdr buffers))))
       (fset 'write-region (symbol-function 'original-write-region)))))

us-ascii のみのファイルに日本語を書き込んだ時も警告が出ちゃうので欝陶しいといえば欝陶しいかなあ…。常用している文字コードだったら警告を出さないとか工夫の余地はあるかも。まぁとりあえずこれで生活してみようかな。