Copy/paste from terminal [WAS: visual selection and X primary behavior]
Sanel Zukan
sanelz at gmail.com
Fri Nov 14 16:09:43 CET 2014
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.
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 :)
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