(defun edit-buffer-in-vi () "Put the content of the buffer into an external file and invoke VI on it." (let ((filename (make-temp-name "silly.vi.user.")) (message (current-buffer))) (with-temp-buffer filename (insert (buffer-string message))) (let ((editor (start-process-shell-command "message editor" nil ; no associated buffer... "xterm" "-e" "vim" filename))) (cons editor filename)))) (defun edit-buffer-in-vi-make-closure (buffer filename) "Restore the content of buffer from filename when invoked." (let ((buffer-name (buffer-name buffer))) ; Oh for closures... `(lambda () (let ((buffer (get-buffer ,buffer-name))) (when buffer (with-current-buffer buffer (erase-buffer) (insert-file-contents ,filename))))))) (add-hook 'message-setup-hook ; am I the right hook? (lambda () "Invoke an external editor on the content of this buffer..." (let ((result (edit-buffer-in-vi))) (set-process-sentinel (car result) (edit-buffer-in-vi-make-closure (current-buffer) (cdr result))))))