24

Often I find myself copying a code snippet into my operating system's clipboard from the internet. Then, I take the following simple steps:

  1. Switch to my Emacs window
  2. Find the place where I want to paste the code
  3. Use C-y (yank) to insert the copied text.

However, sometimes I find (to my great disappointment) that I unwittingly used some form of kill command (such as kill-word or kill-line) while I was on step 2. In such cases, the copied text from the "clipboard" never makes it into the kill ring.

Is there a way to make sure that copied text from other applications always makes it into my kill ring?

I work in Linux most often, but I also use Emacs regularly on Windows and Mac OS X, so an OS-agnostic answer is preferred.

  • May I suggest this link? browsing the whole page, you'll see lots of different way of copy/paste from/to clipboard – Nsukami _ Oct 7 '14 at 14:34
  • @Nsukami_ Thanks. I will try to digest it, but the linked page is a prime example of why I get tired of looking for answers at EmacsWiki. Many of the elisp hackers there seem to think that elisp code is self-documenting and requires no comments, and no explanation about function or usage. I don't usually have time to reverse-engineer the code just to decide whether it does what I want it to or not. – nispio Oct 7 '14 at 14:39
  • haha, I understand ;) – Nsukami _ Oct 7 '14 at 14:55
30

You need to customize save-interprogram-paste-before-kill to t. This will push your clipboard onto the killring in case you kill something in emacs before pasting the clipboard. A related customization is yank-pop-change-selection which pushes your current yank in emacs onto the clipboard. For both of these to work, you need x-select-enable-clipboard (replaced by gui-select-enable-clipboard in emacs 25.1) to be t which is default.

The reason this is turned off by default is to prevent inadvertant pushing of large amount of data onto the killring which persists through out the session unlike the clipboard which is easily replaced.

  • 1
    Even cleaner and easier than I expected. save-interprogram-paste-before-kill seems to do exactly what I want! – nispio Oct 7 '14 at 14:56
  • I'm on emacs 26, and gui-select-enable-clipboard is called just select-enable-clipboard. – Rune Kaagaard Apr 10 at 7:34
3

another solution is just use cli tool if possible,

  • pbcopy/pbpaste on Mac

  • getclip/putclip on Cygwin

  • xsel on Linux
  • x-clipboard in GUI Emacs (as others mentioned, you need turn on the flag x-select-enable-clipboard).

The advantage of this solution is that the clipboard is always usable (for example, when you remote ssh).

My answer has two parts. part one introduce some handy tools to manipulate the clipboard. part two will answer your original question (store clipboard into kill ring).

PART ONE

Insert below code into your ~/.emacs:

(setq *is-a-mac* (eq system-type 'darwin))
(setq *cygwin* (eq system-type 'cygwin) )
(setq *linux* (or (eq system-type 'gnu/linux) (eq system-type 'linux)) )
(defun copy-to-x-clipboard ()
  (interactive)
  (if (region-active-p)
      (progn
        (cond
         ((and (display-graphic-p) x-select-enable-clipboard)
          (x-set-selection 'CLIPBOARD (buffer-substring (region-beginning) (region-end))))
         (t (shell-command-on-region (region-beginning) (region-end)
                                     (cond
                                      (*cygwin* "putclip")
                                      (*is-a-mac* "pbcopy")
                                      (*linux* "xsel -ib")))
            ))
        (message "Yanked region to clipboard!")
        (deactivate-mark))
        (message "No region active; can't yank to clipboard!")))

(defun paste-from-x-clipboard()
  (interactive)
  (cond
   ((and (display-graphic-p) x-select-enable-clipboard)
    (insert (x-selection 'CLIPBOARD)))
   (t (shell-command
       (cond
        (*cygwin* "getclip")
        (*is-a-mac* "pbpaste")
        (t "xsel -ob"))
       1))
   ))

(defun my/paste-in-minibuffer ()
  (local-set-key (kbd "M-y") 'paste-from-x-clipboard)
  )

(add-hook 'minibuffer-setup-hook 'my/paste-in-minibuffer)

PART TWO

insert below code into your ~/.emacs, and from now on, use "M-x paste-from-clipboard-and-cc-kill-ring" to paste:

(defun paste-from-clipboard-and-cc-kill-ring ()
  "paste from clipboard and cc the content into kill ring"
  (interactive)
  (let (str)
    (with-temp-buffer
      (paste-from-x-clipboard)
      (setq str (buffer-string)))
    ;; finish the paste
    (insert str)
    ;; cc the content into kill ring at the same time
    (kill-new str)
    ))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.