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?


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).

  • 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
    Sep 5 '17 at 15:19
  • What is equivalent for xsel -o -b on pbcopy/pbpaste ?
    – alper
    Jul 20 '20 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. Jul 20 '20 at 12:09
  • I tried ctrl-k seems like it does not copy the cutted line , is it a normal behavior?
    – alper
    Jul 20 '20 at 12:17
  • 1
    @alper It one of the other kill-* widgets for which you need to write similar code. Jul 20 '20 at 12:18

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

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.


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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.