4

I am running Emacs in Gnome-terminal on Ubuntu.

The way I know to copy and paste between emacs and other applications is by Ctrl+C and Ctrl+V, which I think is by the terminal emulator.

A problem with that is it will copy the line continuation symbol \ in Emacs.

How can I do that flawlessly? Can you explain why your way works? Thanks.

Btw, I asked a similar question with output of less, which I heard uses vi. If possible, could you also take a look at it?

6

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)))
  • Thanks. Gilles. Here it says "Use Eshell when you want to move text between Emacs and external processes". Can Eshell also accomplish the same thing as what we discussed here? – Tim Oct 23 '14 at 19:08
  • @Tim I don't understand the connection between this question and eshell. In eshell, the input and output of processes is normal Emacs buffer text. It has nothing to do with copy-paste between Emacs and other X applications. – Gilles Oct 23 '14 at 19:58
1

Gilles's solution actually exists as a package, called xclip available from GNU ELPA. I.e. install it from M-x list-packages and then enable it with M-x xclip-mode RET.

See also Clipboard manager will not work in terminal Emacs which is basically the same question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.