diff options
| author | 2026-05-13 13:43:13 +0100 | |
|---|---|---|
| committer | 2026-05-13 13:43:13 +0100 | |
| commit | bcb3792e45de4b880013cc2ed0f4c2bfccb1671c (patch) | |
| tree | d6d82842a5e5cc9e26b5d2fd9f209e4bc692210d /dot_config/zsh | |
| parent | 38220f5fbb12fd4327e9515a7040d7a7ac0d55c7 (diff) | |
| download | dotfiles-bcb3792e45de4b880013cc2ed0f4c2bfccb1671c.tar.gz dotfiles-bcb3792e45de4b880013cc2ed0f4c2bfccb1671c.tar.bz2 dotfiles-bcb3792e45de4b880013cc2ed0f4c2bfccb1671c.zip | |
feat(zsh): add Alt-Shift-Y widget to copy last command output
Zellij has no native "copy last command output" feature, and ghostty's
jump_to_prompt (Ctrl+Shift+J/K, via OSC 133) can't work inside zellij
because zellij sits between the shell and the terminal emulator.
Build it ourselves: a zle widget runs 'zellij action dump-screen --full',
finds the last two lines matching the prompt prefix (user@host:), and
pipes everything between them to wl-copy. Bound to Alt+Shift+Y.
Requires running inside zellij and at least two prompts in the scrollback.
Diffstat (limited to 'dot_config/zsh')
| -rw-r--r-- | dot_config/zsh/dot_zshrc | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/dot_config/zsh/dot_zshrc b/dot_config/zsh/dot_zshrc index c7d5e90..db9fa85 100644 --- a/dot_config/zsh/dot_zshrc +++ b/dot_config/zsh/dot_zshrc @@ -241,6 +241,45 @@ alias sub='subliminal download -l en' # Use `| wlc` to copy AND see the output. wlc() { tee >(wl-copy "$@"); } +# Copy the *last* command's output to the clipboard, retroactively. +# Works only inside zellij — uses `zellij action dump-screen --full` and +# locates prompt boundaries by matching the prompt prefix `user@host:`. +# Bound to Alt+Shift+Y as a zle widget. +copy-last-output() { + emulate -L zsh + if [[ -z $ZELLIJ ]]; then + zle -M "copy-last-output: not inside a zellij session" + return 1 + fi + local dump + dump=$(zellij action dump-screen --full 2>/dev/null) || { + zle -M "copy-last-output: dump-screen failed" + return 1 + } + local prompt_re='^[[:alnum:]_-]+@[[:alnum:]_-]+:' + local -a lines + lines=("${(@f)dump}") + local -a prompt_idx + local i + for (( i = 1; i <= ${#lines}; i++ )); do + [[ ${lines[i]} =~ $prompt_re ]] && prompt_idx+=($i) + done + if (( ${#prompt_idx} < 2 )); then + zle -M "copy-last-output: need at least 2 prompts in scrollback" + return 1 + fi + local start=$(( ${prompt_idx[-2]} + 1 )) + local end=$(( ${prompt_idx[-1]} - 1 )) + if (( start > end )); then + zle -M "copy-last-output: previous command produced no output" + return 0 + fi + printf '%s\n' "${lines[start,end]}" | wl-copy + zle -M "copied $((end - start + 1)) line(s) of last command output" +} +zle -N copy-last-output +bindkey '^[Y' copy-last-output # Alt+Shift+Y + # Neovim alias n='nvim' alias ndiff='nvim -d' |
