Copy/paste from terminal [WAS: visual selection and X primary behavior]

Linus Arver linusarver at gmail.com
Tue Jan 27 07:36:41 CET 2015


Hello Sanel,

On Fri, Nov 14, 2014 at 04:09:43PM +0100, Sanel Zukan wrote:
> If you plan to use Emacs from terminal a lot (as I do) with this
> approach, be warned that for every 'x' (character delete), 'xsel'
> would
> be called. This is not that bad, as 'xsel' is pretty fast, but with
> many
> x-ing, things can be noticeable; also for every clipboard cut/past X11
> server has to be notified. That is why (I think) Vim makes this
> available only from specific registers.

All very good points --- I agree fully.

> Because of that, here is updated version:
>
> -------------------------->8---------------------------
> (defadvice x-set-selection (around my-x-set-selection (type data))
>   (message "Copied to %s selection" type)
>   (let ((sel-type
>          (cond
>           ((eq type 'PRIMARY) "--primary")
>           ((eq type 'CLIPBOARD) "--clipboard")
>           (t
>            (error "Got unknown selection type: %s" type)))))
>     (with-temp-buffer
>       (insert text)
>       (call-process-region (point-min) (point-max) "xsel" nil 0 nil
>       sel-type "--input"))))
>
> (defadvice x-get-selection-value (before my-x-get-selection-value)
>   (message "Paste from PRIMARY selection")
>   (insert (shell-command-to-string "xsel --primary --output")))
>
> (defadvice x-get-clipboard (before my-x-get-clipboard)
>   (message "Paste from CLIPBOARD selection")
>   (insert (shell-command-to-string "xsel --clipboard --output")))
>
> (ad-activate 'x-set-selection)
> (ad-activate 'x-get-selection-value)
> (ad-activate 'x-get-clipboard)
> --------------------------8<---------------------------
>
> Now it behaves just like Vim: copy/paste to '*' register will
> copy/paste
> to primary selection and copy/paste to '+' will do the same to
> clipboard
> selection. And no more hammering 'xsel' for every 'd' or 'x' combos :)

This works beautifully well in terminal Emacs, but in GUI Emacs regular
'd' or 'x' combo calls 'xsel'. So, the intention to avoid hammering
'xsel' is lost.

Can you reproduce this behavior? I'm using Emacs 24.4.1 and Evil
evil-20150121.106 from MELPA. I imagine this has something to do with
some core underlying Emacs mechanism... At the same time, I don't think
it's a high priority because I don't press and hold down 'x' or 'd' much
at all --- so the concerns behind hammering xsel, at least for me,
aren't as important.

I apologize for the late response.

-L

> Cheers,
> Sanel
> 
> Linus Arver <linusarver at gmail.com> writes:
> > The second part involves making terminal Emacs yank into the clipboard
> > when we press 'y'. This mirrors the behavior of GUI Emacs/Evil, so I
> > suppose everyone should be using this part if you use terminal
> > Emacs/Evil.
> >
> >     ; When yanking ('y' key) in terminal Emacs, copy into the X clipboard. As
> >     ; suggested from http://permalink.gmane.org/gmane.emacs.vim-emulation/2023, the
> >     ; blog post at
> >     ; http://hugoheden.wordpress.com/2009/03/08/copypaste-with-emacs-in-terminal/
> >     ; touches on this topic; here is a modified version of that blog post:
> >     (unless window-system
> >         (when (getenv "DISPLAY")
> >             ; Callback for when user cuts
> >             (defun xsel-cut-function (text &optional push)
> >                 ; Insert text to temp-buffer, and "send" content to xsel stdin
> >                 (with-temp-buffer
> >                     (insert text)
> >                     ; I prefer using the "clipboard" selection (the one the
> >                     ; typically is used by c-c/c-v) before the primary selection
> >                     ; (that uses mouse-select/middle-button-click)
> >                     (call-process-region
> >                         (point-min)
> >                         (point-max)
> >                         "xsel"
> >                         nil
> >                         0
> >                         nil
> >                         "--clipboard" "--input"
> >                     )
> >                 )
> >             )
> >             ; Call back for when user pastes
> >             (defun xsel-paste-function()
> >                 ; Find out what is current selection by xsel. If it is different
> >                 ; from the top of the kill-ring (car kill-ring), then return
> >                 ; it. Else, nil is returned, so whatever is in the top of the
> >                 ; kill-ring will be used.
> >                 (let
> >                     (
> >                         (xsel-output
> >                             (shell-command-to-string "xsel --clipboard --output")
> >                         )
> >                     )
> >                 (unless (string= (car kill-ring) xsel-output) xsel-output))
> >             )
> >             ; Attach callbacks to hooks
> >             (setq interprogram-cut-function 'xsel-cut-function)
> >             (setq interprogram-paste-function 'xsel-paste-function)
> >             ; Idea from
> >             ; http://shreevatsa.wordpress.com/2006/10/22/emacs-copypaste-and-x/
> >             ; http://www.mail-archive.com/[email protected]/msg03577.html
> >         )
> >     )
> >
> > Please let me know if what I've done can be improved upon.



More information about the implementations-list mailing list