Copy/Paste in Emacs
CREATED:
UPDATED:
Prepare
At Linux, xsel is required.
At Cygwin, please install package cygutils-extra
.
At macOS, no external tool is required.
At Windows 10 Linux Subsystem, no external tool is required.
Solution
This solution works reliably in any environment.
Insert below code into ~/.emacs
. Run M-x paste-from-xclipboard
to paste.
(defun my-gclip ()
"Get clipboard content."
(cond
((eq system-type 'darwin)
(with-output-to-string
(with-current-buffer standard-output
(call-process "/usr/bin/pbpaste" nil t nil "-Prefer" "txt"))))
((eq system-type 'cygwin)
(with-output-to-string
(with-current-buffer standard-output
(call-process "getclip" nil t nil))))
((memq system-type '(gnu gnu/linux gnu/kfreebsd))
(let* ((powershell-program (executable-find "powershell.exe")))
(cond
(powershell-program
;; PowerLine adds extra white space character at the end of text
(string-trim-right
(with-output-to-string
(with-current-buffer standard-output
(call-process powershell-program nil t nil "-command" "Get-Clipboard")))))
(t
(with-output-to-string
(with-current-buffer standard-output
(call-process "xsel" nil t nil "--clipboard" "--output")))))))))
(defun my-pclip (str-val)
"Copy STR-VAL into clipboard."
(cond
((eq system-type 'darwin)
(with-temp-buffer
(insert str-val)
(call-process-region (point-min) (point-max) "/usr/bin/pbcopy")))
((eq system-type 'cygwin)
(with-temp-buffer
(insert str-val)
(call-process-region (point-min) (point-max) "putclip")))
((memq system-type '(gnu gnu/linux gnu/kfreebsd))
(let* ((win64-clip-program (executable-find "clip.exe")))
(with-temp-buffer
(insert str-val)
(cond
;; Linux Subsystem on Windows 10
(win64-clip-program
(call-process-region (point-min) (point-max) win64-clip-program))
(t
(call-process-region (point-min) (point-max) "xsel" nil nil nil "--clipboard" "--input"))))))))
(defun paste-from-x-clipboard(&optional n)
"Paste string clipboard."
(interactive "P")
;; paste after the cursor in evil normal state
(when (and (functionp 'evil-normal-state-p)
(functionp 'evil-move-cursor-back)
(evil-normal-state-p)
(not (eolp))
(not (eobp)))
(forward-char))
(insert (my-gclip)))
(add-hook 'minibuffer-setup-hook
(lambda ()
(local-set-key (kbd "M-y") 'paste-from-xclipboard)))
My actual setup is more robust. See https://github.com/redguardtoo/emacs.d/blob/master/lisp/init-clipboard.el for details.
Tips
Clipboard manager
I suggest Parcellite on Linux, Ditto on Windows, Flycut on macOS.
My parcellite setup ($HOME/.config/parcellite/parcelliterc):
[rc]
use_copy=true
use_primary=true
synchronize=true
save_history=true
history_limit=64
hyperlinks_only=false
confirm_clear=false
single_line=true
reverse_history=false
item_length=50
ellipsize=2
history_key=<Super>Y
actions_key=
menu_key=
history_pos=false
history_x=1
history_y=1
case_search=false
type_search=false
data_size=0
ignore_whiteonly=false
trim_wspace_begend=false
trim_newline=false
Clipboard in ssh
Use ssh -X -C username@some-server.whatever.domain
.