From 29778ee845b2d9e30f76342c607bed6232075191 Mon Sep 17 00:00:00 2001 From: Fabian Boehm Date: Tue, 11 Oct 2022 20:19:21 +0200 Subject: [PATCH] fish_clipboard_copy/paste: Handle redirected stdout/stdin This makes these tools usable in a pipe. You can run ```fish some-long-command | fish_clipboard_copy ``` to copy some command's output to your clipboard, and ```fish fish_clipboard_paste | some-other-command ``` To feed your clipboard to some command. --- share/functions/fish_clipboard_copy.fish | 16 +++++++++++++--- share/functions/fish_clipboard_paste.fish | 23 ++++++++++++++--------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/share/functions/fish_clipboard_copy.fish b/share/functions/fish_clipboard_copy.fish index 66072fbf4..67dd53971 100644 --- a/share/functions/fish_clipboard_copy.fish +++ b/share/functions/fish_clipboard_copy.fish @@ -1,7 +1,17 @@ function fish_clipboard_copy - # Copy the current selection, or the entire commandline if that is empty. - set -l cmdline (commandline --current-selection | string collect) - test -n "$cmdline"; or set cmdline (commandline | string collect) + set -l cmdline + if isatty stdin + # Copy the current selection, or the entire commandline if that is empty. + # Don't use `string collect -N` here - `commandline` adds a newline. + set cmdline (commandline --current-selection | string collect) + test -n "$cmdline"; or set cmdline (commandline | string collect) + else + # Read from stdin + while read -lz line + set -a cmdline $line + end + end + if type -q pbcopy printf '%s' $cmdline | pbcopy else if set -q WAYLAND_DISPLAY; and type -q wl-copy diff --git a/share/functions/fish_clipboard_paste.fish b/share/functions/fish_clipboard_paste.fish index 90c86c08d..8ce4991c1 100644 --- a/share/functions/fish_clipboard_paste.fish +++ b/share/functions/fish_clipboard_paste.fish @@ -1,25 +1,30 @@ function fish_clipboard_paste set -l data if type -q pbpaste - set data (pbpaste 2>/dev/null) + set data (pbpaste 2>/dev/null | string collect -N) else if set -q WAYLAND_DISPLAY; and type -q wl-paste - set data (wl-paste 2>/dev/null) + set data (wl-paste -n 2>/dev/null | string collect -N) else if set -q DISPLAY; and type -q xsel - set data (xsel --clipboard) + set data (xsel --clipboard | string collect -N) else if set -q DISPLAY; and type -q xclip - set data (xclip -selection clipboard -o 2>/dev/null) + set data (xclip -selection clipboard -o 2>/dev/null | string collect -N) else if type -q powershell.exe - set data (powershell.exe Get-Clipboard | string trim -r -c \r) + set data (powershell.exe Get-Clipboard | string trim -r -c \r | string collect -N) end # Issue 6254: Handle zero-length clipboard content - if not string match -qr . -- "$data" + if not string length -q -- "$data" return 1 end - # Also split on \r to turn it into a newline, - # otherwise the output looks really confusing. - set data (string split \r -- $data) + if not isatty stdout + # If we're redirected, just write the data *as-is*. + printf %s $data + return + end + + # Also split on \r, otherwise it looks confusing + set data (string split \r -- $data | string split \n) # If the current token has an unmatched single-quote, # escape all single-quotes (and backslashes) in the paste,