読者です 読者をやめる 読者になる 読者になる

@koshian's Tech Log

主に日本語に関する技術などこちらに書こうかと

Emacs でファイルを読んだら文字化けしたときの対処法が大変めんどくさいので関数書いた

長年 Emacs を使っててもなかなか覚えられない操作というのがあって、その代表格ではないかと思うのがファイルを読んだら Emacs文字コードを認識失敗して文字化けした時の対処法である。

C-x RET c utf-8-unix RET C-x C-v RET

毎回毎回覚えられずにググってる気がする。

IRC で相談しながら F1 k して調べてみると、C-x RET c は universal-coding-system-argument という関数に binding されている。コードツリーの lisp/international/mule-cmds.el を見てみると、

(defvar mule-keymap
  (let ((map (make-sparse-keymap)))
    (define-key map "f" 'set-buffer-file-coding-system)
    (define-key map "r" 'revert-buffer-with-coding-system)
    (define-key map "F" 'set-file-name-coding-system)
    (define-key map "t" 'set-terminal-coding-system)
    (define-key map "k" 'set-keyboard-coding-system)
    (define-key map "p" 'set-buffer-process-coding-system)
    (define-key map "x" 'set-selection-coding-system)
    (define-key map "X" 'set-next-selection-coding-system)
    (define-key map "\C-\\" 'set-input-method)
    (define-key map "c" 'universal-coding-system-argument)
    (define-key map "l" 'set-language-environment)
    map)
  "Keymap for Mule (Multilingual environment) specific commands.")

こんな感じでいろいろと定義されてるようだ。universal-coding-system-argument は要するにファイルの読み込み環境を設定して他のコマンドを実行する(上記の場合だと C-x C-v (find-alternate-file)) わけだが、もうこんな複雑なの覚えられないので、universal-coding-system-argument の実装を参考に関数を定義してショートカットをあてがった。

(defun set-buffer-correct-coding-system(coding-system &optional force nomodify)
  "Correct coding system"
  (interactive
   (list (read-buffer-file-coding-system)
         current-prefix-arg))
  (let ((coding-system-for-read coding-system)
        (coding-system-for-write coding-system)
        (coding-system-require-warning t))
    (find-alternate-file buffer-file-name)))

(global-set-key [(super c)] 'set-buffer-correct-coding-system)

しかしこれだと補完で utf-8-unix が出てこないんだがなんでだろうか?