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

Sanel Zukan sanelz at gmail.com
Tue Jan 27 11:21:21 CET 2015


Hi,

Linus Arver <linusarver at gmail.com> writes:
> 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:
>> [...]
> 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.

Hm... GUI Emacs should not call 'xsel' for 'd' and 'x. Can you drop me
your code sample?

You will need to detect if GUI Emacs is running and disable this
feature. Also, you must detect (in case if terminal Emacs is running)
that you are actually running X server, or 'xsel' will fail.

Here is updated version that works for all three cases:

-------------------------->8---------------------------
(unless window-system
   ;; make sure X server is running
   (when (getenv "DISPLAY")
     (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, if GUI Emacs is running it will do nothing, defaulting to Evil
copy/paste that are already working as intended. In case of pure
terminal (without running X server), clipboard is not available anyway.

Maybe this sounds confusing (as is indeed), here is the list of cases we
should cover to emulate Vim copy/paste:

* Emacs GUI - copy/past to clipboard/primary works out of the box with Evil
* Emacs terminal + X running - above hack with xsel to use it
* Emacs terminal and no X - no clipboard/primary selection are present

Again, here we want to have cross-application copy/paste using '+' and
'*' registers, as Vim does, instead of using 'xsel' for every line/character
manipulation.

> 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

Best,
Sanel



More information about the implementations-list mailing list