diff --git a/example-scripts/clipboard.sh b/example-scripts/clipboard.sh new file mode 100755 index 00000000..0c7d57a4 --- /dev/null +++ b/example-scripts/clipboard.sh @@ -0,0 +1,69 @@ +#! /bin/sh +# Wrapper for various clipboard I/O on Linux desktop environments and Windows emulations thereof + +if [ -z "$STDIN_COPY_COMMAND" ] || [ -z "$STDOUT_PASTE_COMMAND" ] +then + if [ $WAYLAND_DISPLAY ] + then + STDIN_COPY_COMMAND="wl-copy --foreground --type text/plain" + STDOUT_PASTE_COMMAND="wl-paste --no-newline" + elif [ $DISPLAY ] + then + if command -v xclip + then + STDIN_COPY_COMMAND="xclip -quiet -i -selection clipboard" + STDOUT_PASTE_COMMAND="xclip -o -selection clipboard" + elif command -v xsel + then + STDIN_COPY_COMMAND="xsel --nodetach -i --clipboard" + STDOUT_PASTE_COMMAND="xsel -o --clipboard" + fi + elif command -v lemonade + then + STDIN_COPY_COMMAND="lemonade copy" + STDOUT_PASTE_COMMAND="lemonade paste" + elif command -v doitclient + then + STDIN_COPY_COMMAND="doitclient wclip" + STDOUT_PASTE_COMMAND="doitclient wclip -r" + elif command -v win32yank.exe + then + STDIN_COPY_COMMAND="win32yank.exe -i --crlf" + STDOUT_PASTE_COMMAND="win32yank.exe -o --lf" + elif command -v clip.exe + then + STDIN_COPY_COMMAND="clip.exe" + STDOUT_PASTE_COMMAND=":" + elif [ $TMUX ] + then + STDIN_COPY_COMMAND="tmux load-buffer -" + STDOUT_PASTE_COMMAND="tmux save-buffer -" + else + echo 'No clipboard command' >&2 + exit 10 + fi > /dev/null +fi + +case "$1" in + copy) exec $STDIN_COPY_COMMAND > /dev/null 2>/dev/null ;; + paste) exec $STDOUT_PASTE_COMMAND < /dev/null 2>/dev/null ;; + "") # Try to guess intention + if ! [ -t 0 ] # stdin is piped + then + exec $STDIN_COPY_COMMAND > /dev/null 2>/dev/null + elif ! [ -t 1 ] # stdout is piped + then + exec $STDOUT_PASTE_COMMAND < /dev/null 2>/dev/null + else + export STDIN_COPY_COMMAND STDOUT_PASTE_COMMAND + fi + ;; + *) cat << EOF +Usage: + clipboard copy + clipboard paste + . clipboard +EOF + exit 10 + ;; +esac diff --git a/src/sysclip.cc b/src/sysclip.cc index 5f97d576..4b4830d1 100644 --- a/src/sysclip.cc +++ b/src/sysclip.cc @@ -42,32 +42,69 @@ struct clip_command { static clip_command *get_commands() { + static clip_command NEOVIM_CMDS[] = { + { { "win32yank.exe -i --crlf > /dev/null 2>&1", + "win32yank.exe -o --lf < /dev/null 2>/dev/null" } }, + { { nullptr, nullptr } }, + }; static clip_command OSX_CMDS[] = { { { "pbcopy > /dev/null 2>&1", "pbpaste -Prefer txt 2>/dev/null", } }, { { "pbcopy -pboard find > /dev/null 2>&1", "pbpaste -pboard find -Prefer txt 2>/dev/null" } }, }; + static clip_command TMUX_CMDS[] = { + { { "tmux load-buffer - > /dev/null 2>&1", + "tmux save-buffer - < /dev/null 2>/dev/null" } }, + { { nullptr, nullptr } }, + }; + static clip_command WAYLAND_CMDS[] = { + { { "wl-copy --foreground --type text/plain > /dev/null 2>&1", + "wl-paste --no-newline < /dev/null 2>/dev/null" } }, + { { nullptr, nullptr } }, + }; static clip_command WINDOWS_CMDS[] = { { { "clip.exe > /dev/null 2>&1", nullptr } }, { { nullptr, nullptr } }, }; - static clip_command X_CMDS[] = { + static clip_command XCLIP_CMDS[] = { { { "xclip -i > /dev/null 2>&1", "xclip -o < /dev/null 2>/dev/null" } }, { { nullptr, nullptr } }, }; - if (system("which pbcopy > /dev/null 2>&1") == 0) { + static clip_command XSEL_CMDS[] = { + { { "xsel --nodetach -i -b > /dev/null 2>&1", + "xclip -o -b < /dev/null 2>/dev/null" } }, + { { nullptr, nullptr } }, + }; + if (system("command -v pbcopy > /dev/null 2>&1") == 0) { return OSX_CMDS; } - if (system("which xclip > /dev/null 2>&1") == 0) { - return X_CMDS; + if (getenv("WAYLAND_DISPLAY") != nullptr) { + return WAYLAND_CMDS; } + if (getenv("DISPLAY") != nullptr) { + if (system("command -v xclip > /dev/null 2>&1") == 0) { + return XCLIP_CMDS; + } + if (system("command -v xsel > /dev/null 2>&1") == 0) { + return XSEL_CMDS; + } + } + if (getenv("TMUX") != nullptr) { + return TMUX_CMDS; + } + /* + * NeoVim's win32yank command is bidirectional, whereas the system-supplied + * clip.exe is copy-only. * xclip and clip.exe may coexist on Windows Subsystem for Linux */ - if (system("which clip.exe > /dev/null 2>&1") == 0) { + if (system("command -v win32yank.exe > /dev/null 2>&1") == 0) { + return NEOVIM_CMDS; + } + if (system("command -v clip.exe > /dev/null 2>&1") == 0) { return WINDOWS_CMDS; } return nullptr;