ターミナル上のEmacsにペーストしたい

普段、PuTTY上でEmacsを使っているのですが、そのEmacsにコード等をペーストしたいときに、
S-Insert等でそのままペーストしても、キー入力として送られるので、自分の環境だといろいろ問題が起きてました。

  • global-mapのC-mに'newline-and-indentを設定してるので、コードを貼り付けたときに階段状に余計なインデントがされてしまう。
  • key-chordで設定したキーの文字列が含まれるとkey-chordが起動してしまう。("jk"とか)
  • undo一発で元の状態に戻せるようにしたい。

いろいろ調べてみたのですが、良い解決方法が見つけられなかったので
今までは我慢するか、vimを起動して:set pasteをしてたのですが、
やっぱりEmacsにペーストしたい!!ってことで、ちまちま調べながらelispを書いてみました。


undoの部分はundo-groupを使うようにしました。load-path上に置いておきます。
http://www.mahalito.net/~harley/elisp/undo-group.el

term-paste-mode.el

;; http://www.mahalito.net/~harley/elisp/undo-group.el
(require 'undo-group)

(defvar term-paste-mode-map
  (let ((map (make-keymap))
        (i ? ))
    (while (< i ?~) ;; 取りあえずスペース 〜 ~までself-insert-commandをセットして上書く
      (define-key map (char-to-string i) 'self-insert-command)
      (setq i (1+ i)))
    (define-key map "\C-m" 'newline)
    map))

(defcustom term-paste-mode-on-hook nil
  "Hook to run when term-paste-mode is activated."
  :group 'term-paste
  :type 'hook)

(defcustom term-paste-mode-off-hook nil
  "Hook to run when term-paste-mode is deactivated."
  :group 'term-paste
  :type 'hook)

(define-minor-mode term-paste-mode
  "Minor mode for pasting from any terminal applications."
  :lighter " Paste"
  :group 'term-paste
  (cond (term-paste-mode
         ;; minor-mode-mapの優先順位を上げる
         (setq minor-mode-map-alist
               (cons (cons 'term-paste-mode term-paste-mode-map)
                     (delete (assq 'term-paste-mode minor-mode-map-alist) minor-mode-map-alist)))
         (undo-group-boundary)
         (run-hooks 'term-paste-mode-on-hook))
        (t
         (run-hooks 'term-paste-mode-off-hook)
         )))

(provide 'term-paste-mode)

.emacs

(require 'term-paste-mode)

(add-hook 'term-paste-mode-on-hook
          (lambda ()
            (key-chord-mode 0)
            ))
(add-hook 'term-paste-mode-off-hook
          (lambda ()
            (key-chord-mode 1)
            ))
(defalias 'p 'term-paste-mode)

M-x pでterm-paste-modeをtoggleさせます。

  1. M-x p でterm-paste-modeをonに
  2. S-Insertで貼り付け
  3. M-x p でterm-paste-modeをoffに

元に戻す場合は
M-x undo-group

ちゃんと動かなかったらすみません。もっと良い方法あるかなあ。

追記 2009-10-01

githubにあげました。http://github.com/tetsujin/term-paste-mode