2

In vim you can explicitly copy/paste to/from the X11 selection buffer and clipboard buffer by using "*y and "+y, respectively.

My emacs is (apparently -- it's not intentional on my part) set up to use the selection buffer for C-w, C-y, and friends.

Are there functions that I can call, analogous to kill-region and yank which use the clipboard buffer?

To be clear, I want selective access to both buffers at the same time. Based on some quick web searches, it looks like there are configuration variables I can set which will globally change yank to use one buffer or the other. I want to be able to select, just like vim's * and + registers allow.

(Hopefully I've gotten the terminology right: when I say "selection buffer", I mean the buffer where you can highlight text with the mouse and middle-click to paste. When I say "clipboard buffer", I mean the place where text goes when copied by ctrl-c in non-emacs apps.)

Edit: bzg's answer is really close.

In gnome-terminal, I select ~/projects with the mouse, then right-mouse -> copy. Then I select /home. Still in gnome-terminal, when I do:

  • middle-mouse: /home
  • right-mouse -> paste: ~/projects

When I move into emacs and do:

  • middle-mouse: /home
  • M-y (yank): /home
  • C-S-y (my-yank): ~/projects

Great! yank uses the selection buffer and my-yank uses the clipboard.

Now, still in emacs, I do:

  • C-SPC M-f M-f C-w (make region "regular kill", and kill it)

then go to gnome-terminal and do:

  • middle-mouse: "regular kill"
  • right-mouse -> paste: ~/projects

Great! Only the selection buffer was changed, not the clipboard.

Then, back in emacs, I do:

  • C-SPC M-f M-f C-S-w (make region "my kill", and kill it)

then go to gnome-terminal and do:

  • middle-mouse: regular kill
  • right-mouse -> paste: ~/projects

That's wrong, the clipboard buffer should contain "my kill".

My interprogram-cut-function is x-select-text. My x-select-enable-clipboard is nil.

3 Answers 3

3

This code will map C-S-y and C-S-w to customized versions of yank and kill-region that will temporarily toggle the use of clipboard:

(defun my-yank (&optional arg)
  (interactive "*P")
  (let ((x-select-enable-clipboard (not x-select-enable-clipboard)))
    (yank arg)))

(defun my-kill-region (beg end)
  (interactive "r")
  (let ((interprogram-cut-function
     (when (not (eq interprogram-cut-function 'x-select-text))
       'x-select-text)))
    (kill-region beg end)))

(define-key global-map (kbd "C-S-w") 'my-kill-region)
(define-key global-map (kbd "C-S-y") 'my-yank)

So if you copied something in X and don't want it when yanking in Emacs, use C-S-y. If you kill something in Emacs and don't want it in the X clipboard, use C-S-w.

All this assuming you are using the default values for x-select-enable-clipboard' andinterprogram-cut-function', of course.

1
  • Merci beaucoup! You got me pointed in the right direction. If you see the edit to my question, one of the test cases fails. Your my-kill-region doesn't put anything in the clipboard. See my answer with revisions to your functions for a working version.
    – bstpierre
    May 3, 2012 at 13:02
1

bzg's answer comes really close, but the toggling of interprogram-cut-function doesn't quite do the trick -- I believe it ends up nil because that variable has a value when the function starts.

This revised set of functions does exactly what I want, by explicitly setting the clipboard/primary enables in each one. Big hat tip to bzg for getting me on the right track!

(defun my-yank (&optional arg)
  "Yank from the clipboard, not the primary selection."
  (interactive "*P")
  (let ((x-select-enable-clipboard t)
        (x-select-enable-primary nil))
    (yank arg)))

(defun my-kill-region (beg end)
  "Kill to the clipboard, not the primary selection."
  (interactive "r")
  (let ((x-select-enable-clipboard t)
        (x-select-enable-primary nil))
    (kill-region beg end)))

(defun my-kill-ring-save (beg end)
  "Save to the clipboard, not the primary selection."
  (interactive "r")
  (let ((x-select-enable-clipboard t)
        (x-select-enable-primary nil))
    (kill-ring-save beg end)))

(define-key global-map (kbd "C-S-w") 'my-kill-region)
(define-key global-map (kbd "C-M-S-w") 'my-kill-ring-save)
(define-key global-map (kbd "C-S-y") 'my-yank)
1
  • my-kill-region should be (interactive "*r") - because kill-region modifies the buffer. May 4, 2015 at 13:03
0

Emacs provides some useful functions in menu-bar.el, of all places. So I have:

 (global-set-key [(control shift ?w)] 'clipboard-kill-ring-save)
 (global-set-key [(control shift ?y)] 'clipboard-yank)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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