fix(tmux): replace pbcopy with cross-platform clipboard command - #1220
Conversation
Replaces hardcoded pbcopy with a portable clipboard handler that detects the environment: pbcopy on macOS, wl-copy on Wayland, xclip on X11. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
You do not have enough credits to review this pull request. Please purchase more credits to continue. |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the tmux configuration to provide a truly cross-platform clipboard experience. By abstracting the clipboard command into a dynamically determined variable, users can now seamlessly copy content across different operating systems and display servers without manual configuration changes, improving usability and consistency. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe PR replaces hardcoded Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Mesa DescriptionTL;DRReplaces hardcoded What changed?
Description generated by Mesa. Update settings |
There was a problem hiding this comment.
Code Review
This pull request introduces a cross-platform clipboard command for tmux by replacing hardcoded pbcopy calls with a dynamic command stored in a tmux variable. This is a good improvement for portability. However, the new implementation misses a check for reattach-to-user-namespace, which was previously used and is often required for clipboard integration on macOS. I've suggested a modification to the clipboard command to restore this check and ensure broader compatibility.
|
|
||
| # Clipboard | ||
| set -g set-clipboard on | ||
| set -g @clipboard_cmd "command -v pbcopy >/dev/null 2>&1 && pbcopy || { [ -n \"$WAYLAND_DISPLAY\" ] && wl-copy || xclip -selection clipboard; }" |
There was a problem hiding this comment.
The removal of reattach-to-user-namespace could cause clipboard issues on some macOS systems where it's required for tmux to access the system pasteboard. The original configuration used it for mouse-drag copying.
To ensure compatibility, I recommend updating the @clipboard_cmd to check for reattach-to-user-namespace and use it with pbcopy if it's available. This makes your cross-platform solution more robust.
set -g @clipboard_cmd "command -v reattach-to-user-namespace >/dev/null 2>&1 && reattach-to-user-namespace pbcopy || command -v pbcopy >/dev/null 2>&1 && pbcopy || { [ -n \"$WAYLAND_DISPLAY\" ] && wl-copy || xclip -selection clipboard; }"
There was a problem hiding this comment.
Pull request overview
Updates the tmux Home Manager configuration to use a single, runtime-detected clipboard command (macOS/Wayland/X11) instead of hardcoding pbcopy, applying it across multiple copy/yank bindings.
Changes:
- Adds a global tmux user option
@clipboard_cmdthat selectspbcopy,wl-copy, orxclipat runtime. - Updates copy-mode and mouse selection yank bindings to pipe to
@clipboard_cmd. - Updates pane-history yank bindings to use the same clipboard command.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| bind y run-shell 'tmux capture-pane -pS - | #{@clipboard_cmd} && tmux display-message "Full pane history copied to clipboard"' | ||
| bind v run-shell 'tmux capture-pane -p | #{@clipboard_cmd} && tmux display-message "Visible pane copied to clipboard"' |
There was a problem hiding this comment.
The run-shell bindings are referencing @clipboard_cmd as {@clipboard_cmd} (missing the leading #), so tmux will not expand the option and the shell will try to execute a literal {...} token, breaking these bindings. Use the tmux format form #{@clipboard_cmd} here (matching the copy-mode bindings).
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@home-manager/programs/tmux/tmux.conf`:
- Line 40: The tmux option set -g `@clipboard_cmd` currently uses double quotes so
$WAYLAND_DISPLAY is expanded at tmux parse time; change the value assigned by
set -g `@clipboard_cmd` to use single quotes so the shell evaluates
$WAYLAND_DISPLAY at runtime, and update the shell expression referenced by
`@clipboard_cmd` to check for the existence of wl-copy and xclip (e.g., using
command -v wl-copy >/dev/null 2>&1 && wl-copy) before falling back, ensuring
each fallback has a command-existence test and pbcopy remains checked first.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8ae9e2ac-7924-499f-bf1c-f337502e77a2
📒 Files selected for processing (1)
home-manager/programs/tmux/tmux.conf
|
|
||
| # Clipboard | ||
| set -g set-clipboard on | ||
| set -g @clipboard_cmd "command -v pbcopy >/dev/null 2>&1 && pbcopy || { [ -n \"$WAYLAND_DISPLAY\" ] && wl-copy || xclip -selection clipboard; }" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -nP '^\s*set\s+-g\s+@clipboard_cmd\s+".*\$WAYLAND_DISPLAY.*"$' home-manager/programs/tmux/tmux.conf
# Expected (current state): one match at Line 40
# Expected (after fix): no matchesRepository: shunkakinoki/dotfiles
Length of output: 212
🌐 Web query:
In tmux config, are $ENV vars expanded when parsing set -g @option "..."? What is the recommended way to preserve $WAYLAND_DISPLAY for runtime shell evaluation in clipboard commands?
💡 Result:
No, $ENV vars like $WAYLAND_DISPLAY are not expanded when parsing set -g @option "..." in tmux config. Tmux config parsing replaces $ENV with values from the global environment at parse time, storing the literal expanded string as the user option value. User options (@options) are arbitrary strings without further shell-like expansion. This follows the general command parsing rule where $vars expand during parsing, before execution. The recommended way to preserve $WAYLAND_DISPLAY for runtime shell evaluation in clipboard commands is to use set -s copy-command "wl-copy" (requires tmux 3.2+ and wl-clipboard package). This sets a server option where the command string has $WAYLAND_DISPLAY expanded at config parse time from the global env (inherited when tmux server starts). At runtime, when copy-pipe or similar invokes the copy-command during copy operations, it runs the shell command in a new shell inheriting the current session's environment, which includes $WAYLAND_DISPLAY if preserved via set-environment -g WAYLAND_DISPLAY or update-environment WAYLAND_DISPLAY in .tmux.conf. To ensure $WAYLAND_DISPLAY is available in sessions/shells: set-environment -g WAYLAND_DISPLAY $WAYLAND_DISPLAY or set update-environment "WAYLAND_DISPLAY" The latter copies it from global to session env on new sessions. For copy bindings (vi mode example): bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "wl-copy" With set -g mouse on, mouse selections will use copy-command automatically. This works because the subshell launched by copy-pipe/copy-command inherits the pane's environment, including $WAYLAND_DISPLAY.
Citations:
- 1: https://stackoverflow.com/questions/55838828/how-to-set-and-use-variable-in-tmux-conf-depending-on-whether-an-environment-var
- 2: Environment variables set in
if-shellhave unexpected behaviour tmux/tmux#3725 - 3: https://unix.stackexchange.com/questions/15453/using-environment-variables-in-tmux-conf-files
- 4: setenv does not update global environment at start tmux/tmux#2517
- 5: https://man7.org/linux/man-pages/man1/tmux.1.html
- 6: https://www.daemon-systems.org/man/tmux.1.html
- 7: https://man.openbsd.org/i386/tmux.1
- 8: https://www.guyrutenberg.com/2021/07/02/tmux-wayland-clipboard-integration/
- 9: https://github.com/tmux/tmux/wiki/Clipboard
Runtime detection frozen at parse time due to double-quote expansion.
Line 40 uses $WAYLAND_DISPLAY inside double quotes in the tmux option value. Tmux expands $ENV variables during config parsing (not at runtime), so the clipboard backend selection locks to whatever environment was present when the tmux server started. This directly breaks runtime environment adaptation. Additionally, wl-copy and xclip should have command existence checks before use.
🔧 Suggested fix
-set -g `@clipboard_cmd` "command -v pbcopy >/dev/null 2>&1 && pbcopy || { [ -n \"$WAYLAND_DISPLAY\" ] && wl-copy || xclip -selection clipboard; }"
+set -g `@clipboard_cmd` 'if command -v pbcopy >/dev/null 2>&1; then pbcopy; elif [ -n "$WAYLAND_DISPLAY" ] && command -v wl-copy >/dev/null 2>&1; then wl-copy; elif [ -n "$DISPLAY" ] && command -v xclip >/dev/null 2>&1; then xclip -selection clipboard; else exit 1; fi'Use single quotes to defer variable expansion until shell execution time, and add command checks for both fallback commands.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@home-manager/programs/tmux/tmux.conf` at line 40, The tmux option set -g
`@clipboard_cmd` currently uses double quotes so $WAYLAND_DISPLAY is expanded at
tmux parse time; change the value assigned by set -g `@clipboard_cmd` to use
single quotes so the shell evaluates $WAYLAND_DISPLAY at runtime, and update the
shell expression referenced by `@clipboard_cmd` to check for the existence of
wl-copy and xclip (e.g., using command -v wl-copy >/dev/null 2>&1 && wl-copy)
before falling back, ensuring each fallback has a command-existence test and
pbcopy remains checked first.
Summary
pbcopy(macOS-only) with a portable clipboard command defined once as@clipboard_cmdpbcopyon macOS,wl-copyon Wayland,xclipon X11Test plan
pbcopywl-copyxclip🤖 Generated with Claude Code
Summary by cubic
Replace macOS-only
pbcopyin tmux with a cross‑platform clipboard command defined as@clipboard_cmd. It auto-detects the environment (pbcopyon macOS,wl-copyon Wayland,xclip -selection clipboardon X11) and is used for vi copy-mode yank, mouse drag copy, and pane history yanks.Written for commit 15029e9. Summary will update on new commits.