emacsclient で一時ファイルを編集する

gnudoit で一時ファイルを編集する - 適当めものやりなおし。


Emacs22 付属の emacsclient が良さそうだったから gnuclient はやめて emacsclient にした。
やれる事は:

  • ファイルを開く
    • coding-system を server-edit-file-coding-system-alist で指定できる。
    • elscreen がある場合、同時に新しい screen を開く
  • C-cC-c でファイルを保存と同時に kill-buffer
    • 変更がなくてもファイルの日付だけは更新
      • touch してる事が前提の場合にうれしいはず
    • elscreen がある場合、同時にその screen を閉じる
  • C-cC-k で変更を破棄
    • ただし、一度保存しちゃった場合はその状態になる。

server-visit-files を載っとって無理矢理 coding-system を渡せるようにもできたけど、さすがにそれはやめた。

emacs側の準備

まずはこれを .emacs に書いておく。

(require 'server)
(require 'elscreen nil t)

(defvar server-edit-file-coding-system-alist nil
  "*A alist of file name REGEXP to CODING-SYSTEM for server edit.
If file name is matched by REGEXP, file coding-system is decied to CODING-SYSTEM.")

(defvar server-edit-screen nil)

(defun server-edit-visit ()
  (local-set-key "\C-c\C-c" 'server-edit)
  (local-set-key "\C-c\C-k" 'server-edit-cancel)
  (setq mode-line-buffer-identification
        (append mode-line-buffer-identification
                (list
                 (propertize " [SERVER]" 'face 'mode-line-buffer-id))))
  (let ((cs (cdr
             (assoc-if (lambda (re) (string-match re buffer-file-name))
                       server-edit-file-coding-system-alist)))
        (mod (buffer-modified-p)))
    (when cs
      (encode-coding-region (point-min) (point-max) buffer-file-coding-system)
      (decode-coding-region (point-min) (point-max) cs)
      (set-buffer-modified-p mod)
      (set-buffer-file-coding-system cs nil t)))
  (when (fboundp 'elscreen-find-and-goto-by-buffer)
    (set (make-local-variable 'server-edit-screen)
         (elscreen-find-and-goto-by-buffer (current-buffer) 'create))
    (elscreen-notify-screen-modification 'force-immediately))
  (add-hook 'server-done-hook 'server-edit-done nil t))

(add-hook 'server-visit-hook 'server-edit-visit)
  
(defun server-edit-cancel (&optional arg)
  (interactive "P")
  (when (y-or-n-p (concat "Cancel file " buffer-file-name "? "))
    (set-buffer-modified-p nil)
    (server-edit arg)))

(defun server-edit-done ()
  (when (file-exists-p buffer-file-name)
    (set-file-times buffer-file-name (current-time)))
  (when (and (fboundp 'elscreen-kill)
             server-edit-screen
             (= server-edit-screen (elscreen-get-current-screen)))
    (elscreen-kill)))

(setq server-edit-file-coding-system-alist
      '(("/mozex[^/]+\.txt" . utf-8)))

(server-mode 1)

使う

例えば mozex で使う場合は

firefox 側の設定
  • Edit textbox in UTF-8 を ON にしておく
c:\path\to\emacsclientw.exe %t
    • Unix系なら Text editor に以下を設定
/path/to/emacsclient %t
Emacs 側の設定
;; mozex のファイルは必ず utf-8 とする
(setq server-edit-file-coding-system-alist
      '(("/mozex[^/]+\.txt" . utf-8)))

変更履歴

  • [2007-11-17]: server-edit-cancel でファイルが無いときは set-file-times をしないようにした。