From 176d528f97352afd968b0eaa5fc0c5190618de53 Mon Sep 17 00:00:00 2001 From: Louis Rubet Date: Tue, 7 Oct 2025 18:03:46 +0200 Subject: [PATCH 1/3] feat(plugin): Add ghostty-copypaste plugin --- plugins/ghostty-copypaste/README.md | 15 +++++++ .../ghostty-copypaste.plugin.zsh | 43 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 plugins/ghostty-copypaste/README.md create mode 100644 plugins/ghostty-copypaste/ghostty-copypaste.plugin.zsh diff --git a/plugins/ghostty-copypaste/README.md b/plugins/ghostty-copypaste/README.md new file mode 100644 index 000000000..36fde068c --- /dev/null +++ b/plugins/ghostty-copypaste/README.md @@ -0,0 +1,15 @@ +# zsh-ghostty-copypaste + +[ghostty](https://ghostty.org/) users, this `zsh` plugin allows you to copy / paste a text selected with the keyboard with `ctrl+shift+c` / `ctrl+shift+v`. + +To use it, add `ghostty-copypaste` to the plugins array of your `.zshrc` file: + +``` +plugins=(... ghostty-copypaste) +``` + +## Principle + +- `ghossty` allows to copy / paste a text selected with the mouse, but not with the keyboard, because this is an action devoted to a terminal (`zsh`) and not to a terminal emulator (`ghostty`). +- When no mouse selection is started, `ghostty` passes a Control Sequence Introducer `^[[99;6u` / `^[[118;6u` to `zsh`. The plugin binds these CSI to the correct copy / paste functions for X11 or Wayland. +- Be careful, `ghostty` can lose focus when copying and pasting because of `xclip` or `wl-copy`/`wl-paste` in the plugin. If you use it as a context terminal ("quake"), it is best not to close it when it loses focus. diff --git a/plugins/ghostty-copypaste/ghostty-copypaste.plugin.zsh b/plugins/ghostty-copypaste/ghostty-copypaste.plugin.zsh new file mode 100644 index 000000000..d0d764d91 --- /dev/null +++ b/plugins/ghostty-copypaste/ghostty-copypaste.plugin.zsh @@ -0,0 +1,43 @@ +function zle-copy-to-clipboard { + local selected_text start_pos end_pos + + (( $MARK < $CURSOR )) + && { start_pos=$MARK; end_pos=$CURSOR; } + || { start_pos=$CURSOR; end_pos=$MARK; } + + (( start_pos < 0 || end_pos < 0 )) + && zle -R && return + + selected_text="${BUFFER[$start_pos+1, $end_pos]}" + + command -v xclip &> /dev/null + && ( echo -n "$selected_text" | xclip -selection clipboard ) + && zle -R && return + + command -v wl-copy &> /dev/null + && ( echo -n "$selected_text" | wl-copy ) + && zle -R && return + + zle -R +} + +function zle-paste-from-clipboard { + local clipboard_content + + command -v xclip &> /dev/null + && clipboard_content=$(xclip -selection clipboard -o 2>/dev/null) + command -v wl-paste &> /dev/null + && clipboard_content=$(wl-paste --no-newline 2>/dev/null) + + [[ -z "$clipboard_content" ]] && return + + LBUFFER+="$clipboard_content" + zle -R +} + +zle -N zle-copy-to-clipboard +zle -N zle-paste-from-clipboard + +# these 2 CSI from ghostty are sent for Ctrl+Shift+C and Ctrl+Shift+V +bindkey '^[[99;6u' zle-copy-to-clipboard +bindkey '^[[118;6u' zle-paste-from-clipboard From 784c200258cc529f8001f1d3c784dd6d144b8065 Mon Sep 17 00:00:00 2001 From: Louis Rubet Date: Tue, 7 Oct 2025 18:37:59 +0200 Subject: [PATCH 2/3] feat(doc): link to zsh-shioft-select --- plugins/ghostty-copypaste/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/ghostty-copypaste/README.md b/plugins/ghostty-copypaste/README.md index 36fde068c..f5d4f34cf 100644 --- a/plugins/ghostty-copypaste/README.md +++ b/plugins/ghostty-copypaste/README.md @@ -2,6 +2,8 @@ [ghostty](https://ghostty.org/) users, this `zsh` plugin allows you to copy / paste a text selected with the keyboard with `ctrl+shift+c` / `ctrl+shift+v`. +This is a complement to [zsh-shift-select](https://github.com/jirutka/zsh-shift-select), allowing to copy with `{ctrl+}shift+{left,right,up,down,home,end}`. + To use it, add `ghostty-copypaste` to the plugins array of your `.zshrc` file: ``` From 0347ab360fa77e7fcb1c222a0c81eb892ad26931 Mon Sep 17 00:00:00 2001 From: Louis Rubet Date: Tue, 7 Oct 2025 18:38:43 +0200 Subject: [PATCH 3/3] fix: Multi-line syntax after coding style --- .../ghostty-copypaste.plugin.zsh | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/plugins/ghostty-copypaste/ghostty-copypaste.plugin.zsh b/plugins/ghostty-copypaste/ghostty-copypaste.plugin.zsh index d0d764d91..95e8d05b6 100644 --- a/plugins/ghostty-copypaste/ghostty-copypaste.plugin.zsh +++ b/plugins/ghostty-copypaste/ghostty-copypaste.plugin.zsh @@ -1,22 +1,21 @@ function zle-copy-to-clipboard { local selected_text start_pos end_pos - (( $MARK < $CURSOR )) - && { start_pos=$MARK; end_pos=$CURSOR; } + (( $MARK < $CURSOR )) \ + && { start_pos=$MARK; end_pos=$CURSOR; } \ || { start_pos=$CURSOR; end_pos=$MARK; } - (( start_pos < 0 || end_pos < 0 )) + (( start_pos < 0 || end_pos < 0 )) \ && zle -R && return selected_text="${BUFFER[$start_pos+1, $end_pos]}" - command -v xclip &> /dev/null - && ( echo -n "$selected_text" | xclip -selection clipboard ) + command -v xclip &> /dev/null \ + && ( echo -n "$selected_text" | xclip -selection clipboard ) \ && zle -R && return - command -v wl-copy &> /dev/null - && ( echo -n "$selected_text" | wl-copy ) - && zle -R && return + command -v wl-copy &> /dev/null \ + && ( echo -n "$selected_text" | wl-copy ) && zle -R && return zle -R } @@ -24,9 +23,9 @@ function zle-copy-to-clipboard { function zle-paste-from-clipboard { local clipboard_content - command -v xclip &> /dev/null + command -v xclip &> /dev/null \ && clipboard_content=$(xclip -selection clipboard -o 2>/dev/null) - command -v wl-paste &> /dev/null + command -v wl-paste &> /dev/null \ && clipboard_content=$(wl-paste --no-newline 2>/dev/null) [[ -z "$clipboard_content" ]] && return