I'm running this emacs
GNU Emacs 25.2.2 (x86_64-pc-linux-gnu) of 2017-09-22, modified by Debian
directly in a Gnome terminal by calling emacs
, which is actually a link to /etc/alternatives/emacs
. This is on an Ubuntu 18.04 Linux.
Emacs copy function, C-c
in cua mode, doesn't copy into the clipboard. I followed this advice and installed this package
M-x package-install RET xclip RET
and it still didn't work. Now I have added a simple function to my .emacs
file :
(defun copy-region-to-clipboard ()
"Copies region to X-clipboard invoking `xclip' in shell"
(interactive)
(shell-command-on-region
(region-beginning)
(region-end)
"xclip -i -selection clipboard"))
(global-set-key (kbd "<f1>") 'copy-region-to-clipboard)
which does work. But I have to press F1
and Emacs won't return control of the cursor until cancelling with C-g
. After cancelling with C-g
, the text disappears from the clipboard.
So the order of operation is
Select-region
-> F1
-> Move focus to other window and paste
-> Move focus back to Emacs and C-g before continuing
I wonder if there is a tweak to this program that will allow xclip
to fork asynchronously with necessary input data and return control to Emacs? And then somehow chain this new function async-copy-region-to-clipboard
onto the end of the C-c
functionality?
- Edit: Adding
&
to end of command:xclip -i -selection clipboard &
, does not change behavior - Emacs still waits.
- Edit With the help of the excellent selected answer I tried using
xsel
instead ofxclip
and found thatxsel
doesn't block likexclip
does. This is long known behavior ofxclip
. Also discussed here.
xclip could also be used for this purpose. Unlike xsel, it works better when printing a raw bitstream that does not fit the current locale. Nevertheless, it is neater to use xsel because xclip does not close STDOUT after it has read from the tmux buffer. As such, tmux does not know that the copy task has completed, and continues to wait for xclip to terminate, thereby rendering tmux unresponsive. A workaround is to redirect {{ic|STDOUT} to /dev/null:
However, I found that neither of these worked for the Emacs solution, and Emacs still hung:
xclip -i -selection clipboard > /dev/null
xclip -i -selection clipboard > /dev/null &
My final working code is:
;; .emacs
...
(defun copy-region-to-clipboard ()
"Copies region to X-clipboard invoking `xsel' in shell"
(interactive)
(if (and(use-region-p) (not (display-graphic-p)))
(shell-command-on-region
(region-beginning)
(region-end)
"xsel -i -b"
)))
(global-set-key (kbd "<f1>") 'copy-region-to-clipboard)
(defun workaround-copy-region-as-kill ()
"Run `some-command' and `some-other-command' in sequence."
(interactive)
(when (and(use-region-p) (not (display-graphic-p)))
(copy-region-to-clipboard)
(copy-region-as-kill 0 0 t)))
(defun workaround-kill-region ()
"Run `some-command' and `some-other-command' in sequence."
(interactive)
(when (and(use-region-p) (not (display-graphic-p)))
(copy-region-to-clipboard)
(kill-region 0 0 t)))
;; Note: 'workaround-copy-region-as-kill' is REPLACING 'copy-region-as-kill'
;; in cua--cua-keys-keymap
;; so we call 'copy-region-as-kill' from the end of it.
(define-key cua--cua-keys-keymap (kbd "C-c <timeout>") 'workaround-copy-region-as-kill)
(define-key cua--cua-keys-keymap (kbd "C-k <timeout>") 'workaround-kill-region)
;;(global-set-key (kbd "C-c") 'workaround-copy-region-as-kill) FAIL!
The technique of mapping C-c <timeout>
was provided by this answer to my follow-on question.
C-x C-z
,fg
) than I was using terminal mode inside emacs - and experiencing less emacs buffer bloat. ----- Also, the same emacs usage pattern carries over to working on a remote through an ssh connection inside a terminal. I was previously using tramp for that, but there were problems with that: time, switching between sudo and non-sudo mode, confusion between local and remote file paths.