Repository navigation
fix(tmux): enable OSC 52 clipboard passthrough in nested tmux layers #996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #!/usr/bin/env bash | ||
| # osc52-copy.sh — Write OSC 52 clipboard sequence directly to the SSH PTY, | ||
| # bypassing nested tmux layers that may absorb the sequence. | ||
| set -euo pipefail | ||
|
|
||
| buf=$(cat "$@") | ||
| encoded=$(printf '%s' "$buf" | base64 | tr -d '\n') | ||
| seq=$(printf '\033]52;c;%s\a' "$encoded") | ||
|
|
||
| # Try writing directly to the SSH connection's PTY | ||
| for tty in $(who -m 2>/dev/null | awk '{print $2}'); do | ||
| printf '%s' "$seq" > "/dev/$tty" 2>/dev/null || true | ||
| done | ||
|
|
||
| # Fallback: emit to stdout (works if tmux allow-passthrough is on) | ||
| printf '%s' "$seq" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -431,8 +431,8 @@ export async function setupCommand(options: SetupOptions = {}): Promise<void> { | |
|
|
||
| /** Copy shipped genie.tmux.conf to ~/.genie/tmux.conf if it doesn't exist yet. */ | ||
| function installGenieTmuxConf(): void { | ||
| const { existsSync, copyFileSync, mkdirSync } = require('node:fs') as typeof import('node:fs'); | ||
| const { resolve } = require('node:path') as typeof import('node:path'); | ||
| const { existsSync, copyFileSync, mkdirSync, chmodSync } = require('node:fs') as typeof import('node:fs'); | ||
| const { resolve, dirname } = require('node:path') as typeof import('node:path'); | ||
| const genieHome = process.env.GENIE_HOME ?? join(homedir(), '.genie'); | ||
| const dest = join(genieHome, 'tmux.conf'); | ||
| if (existsSync(dest)) return; // already installed | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The early return on existing Useful? React with 👍 / 👎. |
||
|
|
@@ -452,4 +452,16 @@ function installGenieTmuxConf(): void { | |
| } catch { | ||
| // non-fatal | ||
| } | ||
|
|
||
| // Install osc52-copy.sh clipboard helper alongside the tmux config | ||
| const osc52Src = join(dirname(src), 'osc52-copy.sh'); | ||
| const osc52Dest = join(genieHome, 'osc52-copy.sh'); | ||
| if (existsSync(osc52Src)) { | ||
| try { | ||
| copyFileSync(osc52Src, osc52Dest); | ||
| chmodSync(osc52Dest, 0o755); | ||
| } catch { | ||
| // non-fatal | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Capturing the input into a variable using
buf=$(cat "$@")strips trailing newlines from the copied content, which is likely unintended for a clipboard helper. Additionally, for large clipboard buffers, it is more efficient to pipe the data directly tobase64to avoid unnecessary memory allocation in the shell.