-
-
Save AdamGagorik/54683ac076aa397146715172b626b1b4 to your computer and use it in GitHub Desktop.
osc52 based clipboard script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # cb — clipboard copy / paste using ONLY OSC 52 escape sequences | |
| # Works in any terminal that supports OSC 52 (iTerm2, kitty, | |
| # wezterm, recent xterm, etc.). No tmux handling, no xclip, | |
| # no pbcopy. | |
| set -euo pipefail | |
| TIMEOUT=2 # seconds to wait for terminal’s reply when pasting | |
| ############################################################################### | |
| osc52_copy() { | |
| # read stdin, base-64-encode to one long line | |
| local payload | |
| payload=$(base64 | tr -d '\n') | |
| # ESC ] 52 ; c ; <payload> BEL | |
| printf '\e]52;c;%s\a' "$payload" > /dev/tty | |
| } | |
| osc52_paste() { | |
| local request=$'\e]52;c;?\a' # ask for clipboard | |
| local reply b64 oldstty | |
| # turn off local echo so the control sequence itself is not shown | |
| oldstty=$(stty -g) | |
| stty -echo -icanon time 0 min 0 | |
| printf '%s' "$request" > /dev/tty | |
| # read until BEL (0x07) or TIMEOUT | |
| if ! IFS= read -r -d $'\a' -t "$TIMEOUT" reply < /dev/tty; then | |
| stty "$oldstty" | |
| echo "cb: timed out – terminal didn't answer OSC 52 query" >&2 | |
| return 1 | |
| fi | |
| stty "$oldstty" | |
| # strip the leading “ESC ] 52 ; … ;” | |
| reply=${reply#*$'\e]52;'} # drop up to second field | |
| reply=${reply#*;} # drop up to third semicolon | |
| # some terminals insert newlines into long sequences; remove them | |
| b64=${reply//$'\n'/} | |
| base64 -d <<<"$b64" | |
| } | |
| ############################################################################### | |
| usage() { | |
| cat <<'EOF' | |
| cb – copy to / paste from the clipboard using OSC 52 only | |
| echo "text" | cb copy | |
| cb < file copy | |
| cb -p or cb paste / print | |
| Options | |
| -p, --print paste | |
| -h, --help this help text | |
| EOF | |
| } | |
| ############################################################################### | |
| # argument parsing | |
| mode=auto | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| -p|--print) mode=paste ;; | |
| -h|--help) usage; exit 0 ;; | |
| *) echo "cb: unknown option $1"; usage; exit 1 ;; | |
| esac | |
| shift | |
| done | |
| [[ $mode == auto ]] && { [[ -t 0 ]] && mode=paste || mode=copy; } | |
| if [[ $mode == copy ]]; then | |
| osc52_copy | |
| else | |
| osc52_paste | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment