Skip to content

Commit

Permalink
Add X clipboard support layer to terminal emacs.
Browse files Browse the repository at this point in the history
The X clipboard allows a user to copy and paste content between different X
windows, e.g. copying text from Chrome into a Terminal. Copy/pasting with the X
clipboard it well supported in GUI Emacs, but not so well in terminal Emacs
(i.e `emacs -nw` or `emacsclient -t`) without resorting to using the mouse,
since terminal Emacs has no awareness of X. There are several incomplete Elisp
solutions out that work for the most part, but may not have cross-platform
support, or may fail over SSH with X forwarding or within a `tmux` session.

This layer adds support for OSX, Linux, Windows, and Cygwin using the relevant
binary on each system. For example on Linux, it uses `xsel` or `xclip` to
interface with the clipboard, depending which one is available. It also adds
support for ssh'ing into a different OS with X forwarding via `ssh -Y hostname`,
and copy/pasting to and from a remote terminal Emacs. It also supports an edge
case of continuing to work in an Emacs instance running inside a `tmux` session
which may have been started by a different ssh session, which relies on
explicitly reseting the `$DISPLAY` environment variable before calling the
relevant binary.

Yank code inspired by https://github.com/tmux-plugins/tmux-yank.

Fix syl20bnr#4662.

Tried to add xclip support but removed it since it freezes.
  • Loading branch information
cweill authored and CodingSolo committed Oct 29, 2018
1 parent 70b64da commit a857e89
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 0 deletions.
15 changes: 15 additions & 0 deletions layers/+tools/xclipboard/README.org
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#+TITLE: xclipboard layer

* Table of Contents :TOC_4_gh:noexport:
- [[#description][Description]]
- [[#key-bindings][Key Bindings]]

* Description
This layer adds copy/paste support to the X-clipboard from the terminal.

* Key Bindings

| Key Binding | Description |
|-------------+---------------------------------------------|
| ~SPC x y~ | Copy selection to clipboard |
| ~SPC x p~ | Paste clipboard contents at cursor position |
97 changes: 97 additions & 0 deletions layers/+tools/xclipboard/funcs.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
;;; funcs.el --- xclipboard layer functions file for Spacemacs.
;;
;; Copyright (c) 2012-2018 Sylvain Benner & Contributors
;;
;; Authors: Charles Weill <weill@google.com>
;; Google LLC.
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;;; License: GPLv3

(defun spacemacs//xclipboard-get-display ()
(shell-command-to-string "if [[ -n $TMUX ]]; then
export DISPLAY=$(tmux show-environment | grep -o '^DISPLAY.*$' | sed 's/DISPLAY=//')
fi
if [[ -z $DISPLAY ]]; then
export DISPLAY=:0
fi
printf $DISPLAY")
)

(defun spacemacs//xclipboard-get-copy-command ()
(shell-command-to-string "command_exists() {
local command=\"$1\"
type \"$command\" >/dev/null 2>&1
}
# Installing reattach-to-user-namespace is recommended on OS X
if command_exists \"pbcopy\"; then
if command_exists \"reattach-to-user-namespace\"; then
printf \"reattach-to-user-namespace pbcopy\"
else
printf \"pbcopy\"
fi
elif command_exists \"clip.exe\"; then # WSL clipboard command
printf \"clip.exe\"
elif command_exists \"xsel\"; then
printf \"xsel -ib\"
elif command_exists \"putclip\"; then # cygwin clipboard command
printf \"putclip\"
fi")
)

(defun spacemacs//xclipboard-get-paste-command ()
(shell-command-to-string "command_exists() {
local command=\"$1\"
type \"$command\" >/dev/null 2>&1
}
# Installing reattach-to-user-namespace is recommended on OS X
if command_exists \"pbpaste\"; then
if command_exists \"reattach-to-user-namespace\"; then
printf \"reattach-to-user-namespace pbpaste\"
else
printf \"pbpaste\"
fi
elif command_exists \"paste.exe\"; then # WSL clipboard command
printf \"paste.exe\"
elif command_exists \"xsel\"; then
printf \"xsel -ob\"
elif command_exists \"getclip\"; then # cygwin clipboard command
printf \"getclip\"
fi")
)

(defun spacemacs/xclipboard-copy ()
"Copies selection to x-clipboard."
(interactive)
(if (display-graphic-p)
(progn
(message "Copied region to x-clipboard!")
(call-interactively 'clipboard-kill-ring-save)
)
(if (region-active-p)
(progn
(shell-command-on-region (region-beginning) (region-end) (format "DISPLAY=%s %s" (spacemacs//xclipboard-get-display) (spacemacs//xclipboard-get-copy-command)))
(message (format "Copied region to clipboard \"%s\"!" (spacemacs//xclipboard-get-display)))
(deactivate-mark)
)
(message "No region active; can't copy to clipboard!")
)
)
)

(defun spacemacs/xclipboard-paste ()
"Pastes from x-clipboard."
(interactive)
(if (display-graphic-p)
(progn
(clipboard-yank)
(message "graphics active")
)
(insert (shell-command-to-string (format "DISPLAY=%s %s" (spacemacs//xclipboard-get-display) (spacemacs//xclipboard-get-paste-command))))
)
(message (format "Pasted from clipboard \"%s\"!" (spacemacs//xclipboard-get-display)))
)
14 changes: 14 additions & 0 deletions layers/+tools/xclipboard/keybindings.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
;;; keybindings.el --- xclipboard layer keybindings file for Spacemacs.
;;
;; Copyright (c) 2012-2018 Sylvain Benner & Contributors
;;
;; Authors: Charles Weill <weill@google.com>
;; Google LLC.
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;;; License: GPLv3

(evil-leader/set-key "x y" 'spacemacs/xclipboard-copy)
(evil-leader/set-key "x p" 'spacemacs/xclipboard-paste)
16 changes: 16 additions & 0 deletions layers/+tools/xclipboard/packages.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
;;; packages.el --- xclipboard layer packages file for Spacemacs.
;;
;; Copyright (c) 2012-2018 Sylvain Benner & Contributors
;;
;; Authors: Charles Weill <weill@google.com>
;; Google LLC.
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;;; License: GPLv3

(defconst xclipboard-packages '())

(defun xclipboard/init-xclipboard ()
(use-package xclipboard))

0 comments on commit a857e89

Please sign in to comment.