13

I have noticed that zsh has a lot of things I see in emacs. I can make a selection with ctrl+space and selecting a region. I can make copies just like in emacs while I stay inside zsh. In emacs I'm able to use my system clipboard (previously with some additional configuration needed but this works out of the box now in emacs). In zsh I can't seem to paste from my clipboard using C-y and copying from zsh to my system cliipboard has the same issue. Is there a way around this?

4 Answers 4

15

Zsh's has a built-in clipboard that doesn't communicate with other applications. Since it's very scriptable, you can make it communicate with a few lines in your ~/.zshrc. You'll need xclip or xsel. See Pasting from clipboard to vi-enabled zsh or bash shell for a proof-of-concept in vi mode. Here's the corresponding code for emacs mode (you'll probably want to do something similar to other kill-* widgets).

x-copy-region-as-kill () {
  zle copy-region-as-kill
  print -rn $CUTBUFFER | xsel -i -b
}
zle -N x-copy-region-as-kill
x-kill-region () {
  zle kill-region
  print -rn $CUTBUFFER | xsel -i -b
}
zle -N x-kill-region
x-yank () {
  CUTBUFFER=$(xsel -o -b </dev/null)
  zle yank
}
zle -N x-yank
bindkey -e '\ew' x-copy-region-as-kill
bindkey -e '^W' x-kill-region
bindkey -e '^Y' x-yank

This uses the X11 clipboard (typically accessed with Ctrl+C/Ctrl+V); remove the -b option to use the X11 primary selection instead (automatic copy on select, and paste with the middle mouse button).

6
  • If you use vi mode, simply replace kill-region with vi-delete and yank with vi-put-after etc. Similarly wrap vi-yank, and others. (I haven't found a way to do it more centrally)
    – olejorgenb
    Commented Sep 5, 2017 at 15:19
  • What is equivalent for xsel -o -b on pbcopy/pbpaste ?
    – alper
    Commented Jul 20, 2020 at 12:07
  • @alper xsel -o corresponds to pbpaste and xsel -i corresponds to pbcopy. There's no equivalent to -b since macOS doesn't have multiple selections. Commented Jul 20, 2020 at 12:09
  • I tried ctrl-k seems like it does not copy the cutted line , is it a normal behavior?
    – alper
    Commented Jul 20, 2020 at 12:17
  • 1
    @alper It one of the other kill-* widgets for which you need to write similar code. Commented Jul 20, 2020 at 12:18
5

I had been wanting to integrate Zsh's cut buffer with the X clipboard. I tried the aforementioned http://stchaz.free.fr/mouse.zsh but I found I disliked having all my Zsh operations populate the clipboard. For instance, sometimes I would copy something in a browser, and then go to a shell and edit the command line and then paste. But often editing the command line - deleting a word, for instance - modifies the Zsh cut buffer. For better or worse, X just has a clipboard, not a kill ring, so when a Zsh editing operation overwrites the clipboard, the thing I wanted to paste is lost - I can't yank-pop it (C-y M-y) as I could do in Zsh or Emacs.

So what I did instead is create new special keybindings to interact with the X clipboard through zsh. Turns out "^Xw" and "^Xy" are unused in both Emacs and Zsh, so I can get a consistent interface by binding them in both applications. This way the normal editing operations, cutbuffer, and kill ring are left alone. If I want to copy something to the clipboard I set the region and do "^Xw" (or if I've already killed it and the region is inactive I can just do "^Xw" to copy the cut buffer). Pasting from the clipboard is done with "^Xy".

# define commands to copy and paste x clipboard

# ^Xw - copy region, or cut buffer
# ^Xy - paste x clipboard

# in both cases, modifies CUTBUFFER

copy-to-xclip() {
    [[ "$REGION_ACTIVE" -ne 0 ]] && zle copy-region-as-kill
    print -rn -- $CUTBUFFER | xclip -selection clipboard -i
}

zle -N copy-to-xclip
bindkey "^Xw" copy-to-xclip

paste-xclip() {
    killring=("$CUTBUFFER" "${(@)killring[1,-2]}")
    CUTBUFFER=$(xclip -selection clipboard -o)
    zle yank
}

zle -N paste-xclip
bindkey "^Xy" paste-xclip
2

You may want to have a look at http://stchaz.free.fr/mouse.zsh which in addition to add mouse support also tries to interact with the X Clipboard.

1

For macOS users: here is how to make ESC-w (a.k.a. Meta-w or Option-w) copy to the macOS pasteboard as well as the zsh built-in clipboard.

pb-copy-region-as-kill () {
  zle copy-region-as-kill
  print -rn $CUTBUFFER | pbcopy
}
zle -N pb-copy-region-as-kill
bindkey -e '\ew' pb-copy-region-as-kill

For completeness: here is code for Ctrl-u and Ctrl-k too

pb-backward-kill-line () {
  zle backward-kill-line
  print -rn $CUTBUFFER | pbcopy
}
zle -N pb-backward-kill-line
bindkey -e '^u' pb-backward-kill-line
pb-kill-line () {
  zle kill-line
  print -rn $CUTBUFFER | pbcopy
}
zle -N pb-kill-line
bindkey -e '^k' pb-kill-line

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .