28

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.

nispio
  • 8,175
  • 2
  • 35
  • 73
  • May I suggest this [link](http://www.emacswiki.org/emacs/CopyAndPaste#toc12)? browsing the whole page, you'll see lots of different way of copy/paste from/to clipboard – Nsukami _ Oct 07 '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 07 '14 at 14:39
  • haha, I understand ;) – Nsukami _ Oct 07 '14 at 14:55
  • [How to copy text from Emacs to another application on Linux](https://stackoverflow.com/questions/64360/how-to-copy-text-from-emacs-to-another-application-on-linux) – Flux Dec 19 '20 at 23:57

2 Answers2

33

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.

Vamsi
  • 3,916
  • 22
  • 35
  • 1
    Even cleaner and easier than I expected. `save-interprogram-paste-before-kill` seems to do exactly what I want! – nispio Oct 07 '14 at 14:56
  • 2
    I'm on emacs 26, and `gui-select-enable-clipboard` is called just `select-enable-clipboard`. – Rune Kaagaard Apr 10 '19 at 07:34
  • If I had known that there is an canonical, easy, built-in solution then I would have done this 10 years ago. – Kaligule Jun 13 '23 at 14:58
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)
    ))
chen bin
  • 4,781
  • 18
  • 36