-*- encoding: UTF-8 -*- とか

;;; -*- encoding: XXX -*- を取ってくる
;;; encoding じゃなくて coding でもおk(emacs がそうなってるみたい?)
(defun file-param-encoding (&optional buffer)
  "Return encoding name specified in file header."
  (save-excursion
    (when buffer (set-buffer buffer))
    (let ((params (ed::find-file-scan-params)))
      (cdr (or (assoc "encoding" params :test #'string-equal)
               (assoc "coding" params :test #'string-equal))))))

;;; 名前->エンコーディング
(defparameter *utf8-without-BOM-please* t)

(defun find-encoding (&optional (name (file-param-encoding)))
  "Return encoding of `name'."
  (if (null name) nil
    (let ((it (gethash name *mime-charset-name-hash-table*)))
      (unless it
        (error "エンコーディング ~A が見つからない" name))
      (if (and (eql it *encoding-utf8*)
               *utf8-without-BOM-please*)
          *encoding-utf8n*
        it))))

;;; 保存するときに -*- encoding: XXX -*- を適用
(defun set-fileio-encoding-from-param (&optional buffer)
  "Set buffer fileio encoding to what specified in header."
  (save-excursion
    (when buffer (set-buffer buffer))
    (let ((specified (find-encoding)))
      (when (and specified
                 (not (eql (buffer-fileio-encoding) specified)))
        (set-buffer-fileio-encoding specified)
        nil))))

(add-hook '*before-save-buffer-hook* 'set-fileio-encoding-from-param)

;;; *** 組み込み関数上書き注意報 ***
;;; ファイルを開くときに file-specified-encoding-param を使う
(defun ed::find-file-auto-encoding (filename)
  (unwind-protect
      (let ((encoding
             (progn
               (ignore-errors (insert-file-contents filename t nil 4096))
               (goto-char (point-min))
               (dolist (x *auto-encoding-alist* nil)
                 (when (string-matchp (car x) filename)
                   (return (funcall (cdr x))))))))
        (when (stringp encoding)
          (setq encoding (gethash encoding *mime-charset-name-hash-table*)))
        (if (char-encoding-p encoding)
            encoding
          (find-encoding)))
    (erase-buffer (selected-buffer))))