Pasting a text literally to Emacs under terminal

A text editor is distinguished from "cat > file" where it greatly assists the user in writing a structured text by offering such features as auto-indentation, auto-correction, completion for programming, etc., not to mention basic editing features like search, mass replace, cut, copy and paste. These advanced features are quite nice especially in programming, but sometimes they bite.
Suppose you are under terminal editing a ruby program in Emacs with ruby-electric-mode turned on, feeling like pasting a text from outside the editor like clipboard, GNU screen or tmux. You could easily imagine what would happen. The pasted text would be messed up with superfluous closing parenthesis and quotations that are automatically inserted during the character-by-character pasting process. Of course ruby-electric-mode is a minor mode that can be easily turned off, but for example, in cperl-mode there are many individual flags for a variety of its “electric” features and they cannot be turned off all at once (see the following post for cperl-toggle-hairy). Anyway, changing the editing state back and forth is definitely not something you want just for a copy & paste. It is not supposed to be such a pain in the first place.

Here’s my quick answer.

(defun ins ()
  (interactive)
  (let* ((target (current-buffer))
         (buffer (generate-new-buffer (format "*Paste Buffer for <%s>*"
                                              (buffer-name target)))))
    (with-current-buffer buffer
      (make-local-variable 'ins-target-buffer)
      (setq ins-target-buffer target)
      (local-set-key "\C-c\C-c"
                     '(lambda ()
                        (interactive)
                        (let ((buffer (current-buffer)))
                          (switch-to-buffer ins-target-buffer)
                          (insert-buffer-substring buffer)
                          (kill-buffer buffer))))
      (local-set-key "\C-c\C-k"
                     '(lambda ()
                        (interactive)
                        (let ((buffer (current-buffer)))
                          (switch-to-buffer ins-target-buffer)
                          (kill-buffer buffer)))))
    (switch-to-buffer buffer)
    (message (format "Enter a text to paste.  Type C-c C-c when done. (C-c C-k to dismiss)"
                     (buffer-name target)))))

Whenever you feel like pasting a text from clipboard at point, type M-x ins, paste, type C-c C-c and it’s done. Simple.

Leave a Reply

Your email address will not be published.