You can use the external utilities xsel or xclip (they have mostly the same features, I'll use xsel in this answer) to copy data from or to the X clipboard. To copy to the clipboard, pass the desired content on standard input. When pasting from the clipboard, the content is written to standard output.
To copy the selection to the X clipboard, use M-| xsel -bi RET
(shell-command-on-region
). If you want to copy to the X selection (which can be pasted with the middle mouse button), use xsel -i
. To paste from the X selection, you can use the middle mouse button or M-1 M-! xsel -o RET
(shell-command
with a prefix argument to insert the output into the current buffer); make that xsel -bo
to insert the clipboard content.
If you want to copy and paste automatically to the X selection or clipboard (when available) when running in a terminal under X, like what happens when running in an X window, you can set the variables interprogram-cut-function
and interprogram-paste-function
to functions that call xsel
. Here's some minimally-tested code to automatically copy to the X clipboard when running in a text terminal under X.
(defmacro with-x-environment (&rest body)
`(let ((process-environment
(cons (concat "DISPLAY=" (getenv "DISPLAY" (selected-frame)))
process-environment)))
(if (getenv "XAUTHORITY" (selected-frame))
(setq process-environment
(cons (concat "XAUTHORITY=" (getenv "XAUTHORITY" (selected-frame)))
process-environment)))
,@body))
(defun x-terminal-copy (text)
(with-temp-buffer
(insert text)
(with-x-environment
(call-process-region (point-min) (point-max) "xsel" nil nil nil "-bi"))))
(defadvice x-select-text
(before x-select-text-in-tty activate)
"Use xsel to copy to the X clipboard when running in a terminal under X."
(when (and (eq (framep (selected-frame)) t)
(getenv "DISPLAY" (selected-frame)))
(x-terminal-copy text)))
If you want automatic pasting as well, the following code should do it, but in a possibly annoying way: it always considers the X clipboard to be newer than Emacs's internal buffers, so it will always paste from X. You may find it more convenient to bind X pasting to a different key instead.
(defun x-terminal-paste ()
(with-temp-buffer
(with-x-environment
(call-process "xsel" nil t nil "-bo"))))
(defadvice x-cut-buffer-or-selection-value
(before x-cut-buffer-or-selection-value-in-tty activate)
"Use xsel to paste from the X clipboard when running in a terminal under X."
(when (and (eq (framep (selected-frame)) t)
(getenv "DISPLAY" (selected-frame)))
(x-terminal-paste text)))