diff options
| author | Federico Angelilli <code@fedang.net> | 2024-03-08 11:23:49 +0100 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2024-03-08 11:23:49 +0100 |
| commit | b560a593f21feaba1e4b4c11a8adc50c1a84281d (patch) | |
| tree | 21d5a4bdd73cd4e0666704fed46442109e3670c3 /extension/clip.bash | |
| parent | 5942f372315cfdf39aae8a6b74188503b6f11b0e (diff) | |
Add clip extension
Diffstat (limited to 'extension/clip.bash')
| -rwxr-xr-x | extension/clip.bash | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/extension/clip.bash b/extension/clip.bash new file mode 100755 index 0000000..b6e572e --- /dev/null +++ b/extension/clip.bash @@ -0,0 +1,77 @@ +#!/bin/bash + +# The clipboard code was taken from pass + +X_SELECTION="${CRYPT_X_SELECTION:-clipboard}" +CLIP_TIME="${CRYPT_STORE_CLIP_TIME:-45}" +BASE64="base64" + +_clip() { + if [[ -n $WAYLAND_DISPLAY ]]; then + local copy_cmd=( wl-copy ) + local paste_cmd=( wl-paste -n ) + if [[ $X_SELECTION == primary ]]; then + copy_cmd+=( --primary ) + paste_cmd+=( --primary ) + fi + local display_name="$WAYLAND_DISPLAY" + elif [[ -n $DISPLAY ]]; then + local copy_cmd=( xclip -selection "$X_SELECTION" ) + local paste_cmd=( xclip -o -selection "$X_SELECTION" ) + local display_name="$DISPLAY" + else + error "No X11 or Wayland display detected" + fi + + if [[ "$2" == "clear" ]]; then + local sleep_argv0="password store sleep on display $display_name" + + # NOTE: base64 is needed to store binary data in bash + pkill -f "^$sleep_argv0" 2>/dev/null && sleep 0.5 + local before="$("${paste_cmd[@]}" 2>/dev/null | $BASE64)" + echo -n "$1" | "${copy_cmd[@]}" || error "Could not copy data to the clipboard" + ( + ( exec -a "$sleep_argv0" bash <<< "trap 'kill %1' TERM; sleep '$CLIP_TIME' & wait" ) + local now="$("${paste_cmd[@]}" | $BASE64)" + [[ $now != $(echo -n "$1" | $BASE64) ]] && before="$now" + qdbus org.kde.klipper /klipper org.kde.klipper.klipper.clearClipboardHistory &>/dev/null + echo "$before" | $BASE64 -d | "${copy_cmd[@]}" + ) >/dev/null 2>&1 & disown + echo "Copied $NAME to clipboard. Will clear in $CLIP_TIME seconds." + else + echo -n "$1" | "${copy_cmd[@]}" || error "Could not copy data to the clipboard" + echo "Copied $NAME to clipboard" + fi +} + +clip_file() { + local opts noclear=clear + opts="$($GETOPT -o '' -l clip-persistent -n "$PROGRAM" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + --clip-persistent) noclear=; shift ;; + --) shift; break ;; + esac done + _clip "$(<"$FILE")" "$noclear" +} + +clip_wrap() { + local cmd="$1" args=() clip=0 noclear=clear + shift + + # NOTE: For whatever reason here I didn't use getopt + for a in "$@"; do + case $a in + -c|--clip) clip=1 ;; + --clip-persistent) clip=1; noclear= ;; + *) args+="$a" ;; + esac + done + + if [[ $clip -eq 1 ]]; then + _clip "$(eval "$cmd" "${args[@]}")" "$noclear" + else + eval "$cmd" "${args[@]}" + fi +} |
