Unverified Commit 65642dfc authored by Marc Cornellà's avatar Marc Cornellà Committed by GitHub
Browse files

lib: support additional clipboard types (#7996)

* clipboard: Reduce unnecessary special-casing on stdin

Ideally the parameter would just be removed-users could always
just do "clipcopy < some-file". but removing the parameter would break
backwards compatibility.

In any case, this simplifies the logic considerably.

* clipboard: Avoid unnecessary re-detection each time

Previously, OS detection would happen on each invocation. This makes it
happen once (unless it fails, in which case it will try again on the
next invocation).

This has the additional benefit of localizing the platform-specific
checks and commands, too, versus spreading them out in separate
functions.

* clipboard: Add support for several more clipboards

This implements essentially the same heuristic as neovim, with the additional
(existing) special support for Cygwin.
See: https://github.com/neovim/neovim/blob/e682d799fa3cf2e80a02d00c6ea874599d58f0e7/runtime/autoload/provider/clipboard.vim#L55-L121
  - pbcopy, pbpaste (macOS)
  - cygwin (Windows running Cygwin)
  - wl-copy, wl-paste (if $WAYLAND_DISPLAY is set)
  - xclip (if $DISPLAY is set)
  - xsel (if $DISPLAY is set)
  - lemonade (for SSH) https://github.com/pocke/lemonade
  - doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/
  - win32yank (Windows)
  - tmux (if $TMUX is set)

* clipboard: Fix tmux clipcopy after testing

Tmux must have special handling for /dev/stdin since it's managing the
terminal itself. This was tested with tmux-2.9a on macOS.

* clipboard: Fix bad expansion of exit-code test
parents 368198b7 18ee5dff
...@@ -3,10 +3,23 @@ ...@@ -3,10 +3,23 @@
# This file has support for doing system clipboard copy and paste operations # This file has support for doing system clipboard copy and paste operations
# from the command line in a generic cross-platform fashion. # from the command line in a generic cross-platform fashion.
# #
# On OS X and Windows, the main system clipboard or "pasteboard" is used. On other # This is uses essentially the same heuristic as neovim, with the additional
# Unix-like OSes, this considers the X Windows CLIPBOARD selection to be the # special support for Cygwin.
# "system clipboard", and the X Windows `xclip` command must be installed. # See: https://github.com/neovim/neovim/blob/e682d799fa3cf2e80a02d00c6ea874599d58f0e7/runtime/autoload/provider/clipboard.vim#L55-L121
#
# - pbcopy, pbpaste (macOS)
# - cygwin (Windows running Cygwin)
# - wl-copy, wl-paste (if $WAYLAND_DISPLAY is set)
# - xclip (if $DISPLAY is set)
# - xsel (if $DISPLAY is set)
# - lemonade (for SSH) https://github.com/pocke/lemonade
# - doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/
# - win32yank (Windows)
# - tmux (if $TMUX is set)
#
# Defines two functions, clipcopy and clippaste, based on the detected platform.
##
#
# clipcopy - Copy data to clipboard # clipcopy - Copy data to clipboard
# #
# Usage: # Usage:
...@@ -15,41 +28,8 @@ ...@@ -15,41 +28,8 @@
# #
# clipcopy <file> - copies a file's contents to clipboard # clipcopy <file> - copies a file's contents to clipboard
# #
function clipcopy() { ##
emulate -L zsh #
local file=$1
if [[ $OSTYPE == darwin* ]]; then
if [[ -z $file ]]; then
pbcopy
else
cat $file | pbcopy
fi
elif [[ $OSTYPE == (cygwin|msys)* ]]; then
if [[ -z $file ]]; then
cat > /dev/clipboard
else
cat $file > /dev/clipboard
fi
else
if (( $+commands[xclip] )); then
if [[ -z $file ]]; then
xclip -in -selection clipboard
else
xclip -in -selection clipboard $file
fi
elif (( $+commands[xsel] )); then
if [[ -z $file ]]; then
xsel --clipboard --input
else
cat "$file" | xsel --clipboard --input
fi
else
print "clipcopy: Platform $OSTYPE not supported or xclip/xsel not installed" >&2
return 1
fi
fi
}
# clippaste - "Paste" data from clipboard to stdout # clippaste - "Paste" data from clipboard to stdout
# #
# Usage: # Usage:
...@@ -67,20 +47,55 @@ function clipcopy() { ...@@ -67,20 +47,55 @@ function clipcopy() {
# #
# # Paste to a file # # Paste to a file
# clippaste > file.txt # clippaste > file.txt
function clippaste() { #
function detect-clipboard() {
emulate -L zsh emulate -L zsh
if [[ $OSTYPE == darwin* ]]; then
pbpaste if [[ "${OSTYPE}" == darwin* ]] && (( ${+commands[pbcopy]} )) && (( ${+commands[pbpaste]} )); then
elif [[ $OSTYPE == (cygwin|msys)* ]]; then function clipcopy() { pbcopy < "${1:-/dev/stdin}"; }
cat /dev/clipboard function clippaste() { pbpaste; }
elif [[ "${OSTYPE}" == (cygwin|msys)* ]]; then
function clipcopy() { cat "${1:-/dev/stdin}" > /dev/clipboard; }
function clippaste() { cat /dev/clipboard; }
elif [ -n "${WAYLAND_DISPLAY:-}" ] && (( ${+commands[wl-copy]} )) && (( ${+commands[wl-paste]} )); then
function clipcopy() { wl-copy < "${1:-/dev/stdin}"; }
function clippaste() { wl-paste; }
elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xclip]} )); then
function clipcopy() { xclip -in -selection clipboard < "${1:-/dev/stdin}"; }
function clippaste() { xclip -out -selection clipboard; }
elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xsel]} )); then
function clipcopy() { xsel --clipboard --input < "${1:-/dev/stdin}"; }
function clippaste() { xsel --clipboard --output; }
elif (( ${+commands[lemonade]} )); then
function clipcopy() { lemonade copy < "${1:-/dev/stdin}"; }
function clippaste() { lemonade paste; }
elif (( ${+commands[doitclient]} )); then
function clipcopy() { doitclient wclip < "${1:-/dev/stdin}"; }
function clippaste() { doitclient wclip -r; }
elif (( ${+commands[win32yank]} )); then
function clipcopy() { win32yank -i < "${1:-/dev/stdin}"; }
function clippaste() { win32yank -o; }
elif [ -n "${TMUX:-}" ] && (( ${+commands[tmux]} )); then
function clipcopy() { tmux load-buffer "${1:--}"; }
function clippaste() { tmux save-buffer -; }
else else
if (( $+commands[xclip] )); then function _retry_clipboard_detection_or_fail() {
xclip -out -selection clipboard local clipcmd="${1}"; shift
elif (( $+commands[xsel] )); then if detect-clipboard; then
xsel --clipboard --output "${clipcmd}" "$@"
else else
print "clipcopy: Platform $OSTYPE not supported or xclip/xsel not installed" >&2 print "${clipcmd}: Platform $OSTYPE not supported or xclip/xsel not installed" >&2
return 1 return 1
fi fi
}
function clipcopy() { _retry_clipboard_detection_or_fail clipcopy "$@"; }
function clippaste() { _retry_clipboard_detection_or_fail clippaste "$@"; }
return 1
fi fi
} }
# Detect at startup. A non-zero exit here indicates that the dummy clipboards were set,
# which is not really an error. If the user calls them, they will attempt to redetect
# (for example, perhaps the user has now installed xclip) and then either print an error
# or proceed successfully.
detect-clipboard || true
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment