Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Yank: Yank Terminal Output to Clipboard (github.com/mptre)
88 points by polm23 on March 28, 2021 | hide | past | favorite | 55 comments


You can do this with tmux too.

    ~/.tmux.conf:

    # export to clipboard.
    bind-key > run-shell -b 'tmux save-buffer - | xclip'
    # paste from clipboard.
    bind-key < run-shell -b '( xclip -o | tmux load-buffer - ) && tmux paste-buffer'
(edit: my actual setup is slightly different. It interacts with a Windows clipboard via ssh where the terminal is running. cf. https://github.com/euske/pyrexecd/blob/master/tools/tmux.con... )


You could also use `xclip -selection clipboard` if you wanted it to end up in your clipboard (so you can use ctrl-v to paste) instead of in your primary selection (the one where highlighting text copies and middle click pastes).


I use xsel : ./command | xsel -ib


I've been using ubuntu for over a decade and I have no idea how the clipboard works.

There seems to be multiple clipboards and I have no idea when I am using which. I generally spam some combination of ctrl-v, shift-insert, rightclick context menu paste, middleclick, etc until I get what I want.

I've abandoned vim for a gui solely because I have no idea how to copy stuff to/from it.

Can someone finally explain it to me? Or tell me what to do to make it sane.

(it of course did occur to me to google the question over the past 10 years but every time I did, I didn't find a satisfactory answer for something that ought to be a basic computer literacy skill)


Clipboards in x11 are based on selections. There are two selections of note, the primary selection and clipboard selection. In GUI applications, selecting text copies it to the primary selection, middle clicking pastes the primary selection. Ctrl-C copies to the clipboard selection, Ctrl-V pastes the clipboard selection. The happy path is to stick to those operations only.

For terminals, ctrl-c/Ctrl-v have conflicting interpretations so are usually bound to ctrl-shift-c/ctrl-shift-v. Some (e.g. iterm) try to emulate copy on select on operating systems that don't support it by copying the selection to the single clipboard.

For vim, the selections are bound to buffers. * Is the primary/selection buffer, + is the clipboard. Use "+y/"+p for ctrl-c/ctrl-v equivalents, or "*y/"*p for copy-on-select/middle click equivalents. Note that some distros ship a default "vim-minimal"/"vim-tiny" package built without this support so they can use it as "vi" for POSIX compatibility without pulling in x11 libraries. In that case look for a "vim-x11", "vim-full" or "gvim" package. Or use neovim, I haven't seen packagers slice that up the same way. Depending on your terminal, you may be also able to use the GUI equivalents in insert mode anyway (don't try use your terminal paste in normal mode, it'll paste into the command buffer).

Shift-Insert is unfortunately application dependent. I think it _should_ be equivalent to middle click, but some apps treat it as ctrl-v.

Some clipboard managers or applications will overwrite the primary contents with the clipboard contents when you perform an explicit copy.


I think you'll unfortunately be left unsatisfied since there is no "simple" answer due to the way clipboards work in x11 and the historical baggage a lot of terminal apps drag with them (everyone did text-copying differently before ctrl-c and ctrl-v became ubiquitous).

A nice thing you can do in Vim though is to make the default clipboard the system clipboard like this in your .vimrc:

  set clipbaord=unnamedplus


On another note, rebinding ctrl-c, ctrl-v, ctrl-s etc. in the terminal (including Vim) can be confusing, since most ctrl commands will be caught by stty (in most terminal emulators) and never passed on to the running application. If you really wanted to, you could rebind Vim's yank/paste to ctrl-c, ctrl-v by unbinding the stty commands.

  # 1. check the bindings for your system
  stty -a
  # 2. put the stuff you want to unbind in your shell rc file
  stty <command name> undef
And then rebinding yank/paste in your .vimrc to only use your system clipboard.

This would, however, become painful as soon as you need to quickly use a machine remotely where all your local configs won't be present. It also generally raises the question why one is using Vim in the first place, if one is not planning to use its powerful features.


clipboard = regular C-c and C-v stuff

primary = highlight / middle click

vim has its own used by default when you dd, p, etc. You can copy to one of the previous things (assuming your build enabled it) with "+y and "*y key sequences. You can also paste the same way, but I usually just let the term emu handle that with ctrl-shift-v or similar.

shift-insert is kinda weird actually. AFAIK it should paste from selection, but it often surprises me, so I avoid it.

edit: s/selection/primary/


Vim has it's own clipboards by default (as mentioned) but you can also configure it to use the system clipboard.

    set clipboard=unnamedplus " Use system clipboard.
(I don't know if the exact name depends on OS but this works on Linux and IIRC macOS)


I select and copy from Firefox and ctrl-shift insert pastes it into a terminal 95% of the time.

Rightclick paste always pastes it into a terminal.

Selecting in the terminal window and right click copying is the only way to reverse it which is pretty attrocious as I have to zoom way out and other shenanigans.

If any emacs-fu greybeards know of how to emacs Yank to the Gnome clipboard I will be eternally grateful.

caveat my terminal app is usually emacs.


Same, which is why I made my own bash aliases which basically streams files and text into temporary files in my home directory. I can then paste them as plaintext or move them as files. Should make a function to keep a list of the 10 latest files and query those then.


In most terminal emulators you can use ctrl+shift+c/v to copy/paste to and from the clipboard. Works with vim to.


Back in the day, on the Amstrad CPC, there was a way to duplicate the cursor, move the duplicate around on any part of the screen and copy any text below the duplicate to where the actual cursor was. I always thought that this simple but powerful feature was missing on modern computers.

The submission is not equivalent but clearly can help avoid having to move your mouse around. Still wish I didn't have to modify the original command as, very often, I realize that I want to copy the command's output after I execute it.


I built some of those kinds of cursors features into my terminal. http://extraterm.org/features.html

It is never too late to steal features that the Commodore 64 could do in the early 80s (!!!).

oh, Extraterm can help you reuse previous output after the fact and without having to be clairvoyant.


> I realize that I want to copy the command's output after I execute it.

With Zsh, cheating a little, you can achieve it with:

    _insert-last-command-output () {
        LBUFFER+="$(LS_COLORS= TERM=vt220 eval $history[$((HISTCMD-1))])"
    }
There's some junk used for my configuration, the relevant part is the "eval" of the last command on the history, it doesn't paste the output of the previous command but it's execute d again, this time with the output going straight in the edit buffer. I use it to manipulate the output of the previous command on the shell — it works better if the output is a single line — but I think it could be modified to put the output also on the clipboard...


In iterm2, with shell integration enabled, hitting Command-Shift-A selects all the output since the last prompt.


On Mac OS, a much less powerful but built in tool is `pbcopy`.


To replicate pbcoby on X11 systems, add to your bashrc:

    alias clip="xclip -selection clipboard"
`echo hello | clip` will copy 'hello' to the clipboard, and similarly `ls | clip` will copy a bunch of lines to the clipboard. You might need to install xclip through your package manger (the package is just named xclip on Arch).


I like `xsel --clipboard` which Does The Right Thing by automatically deciding if it should copy or paste.

    # Paste clipboard into command.
    xsel --clipboard | grep foobar
    # Copy into clipboard
    grep foobar somefile.txt | xsel --clipboard
    # Transform clipboard.
    xsel --clipboard | tr A-Z a-z | xsel --clipboard
I find this so useful that I have it aliased to `c`.


On Wayland there's wl-clipboard (with wl-copy and wl-paste commands) which works basically the same.


This is how I make pbcopy/pbpaste work on both Linux and WSL (Windows Subsystem for Linux).

    if [[ "$(uname)" == "Linux" ]]; then
      if ! grep -q Microsoft /proc/version; then
        alias pbcopy='xsel --clipboard --input'
        alias pbpaste='xsel --clipboard --output'
      else
        alias pbcopy='clip.exe'
        alias pbpaste='powershell.exe -command "Get-Clipboard"'
      fi
    fi


Was going to say this myself. I find myself using it (and it’s counterpart, `pbpaste`) surprisingly frequently.

This tool looks great for more involved use cases though I think for most scenarios I’d use it for, using the mouse with iTerm2 with “copy on highlight” might be quicker - can be nice to avoid the mouse though!


I have used VM in Emacs to read my email for more than a quarter century. I run the Emacs session remotely, and open inline URLs locally on the Macbook I `mosh` out of. The remote machine connects to the local one and passes on the URL with `open`.

Sometimes I need the URL itself, as opposed to actually opening it. I wrote elisp to modify the command that displays the URL the cursor is over within Emacs to also use the above method, but use `pbcopy` to pass the URL onto the Mac clipboard.


This tool seems to be more about the selection part, once it knows exactly what you want it passes it onto another clipboard tool, which for the Mac is pbcopy.


I use that very often. Is there any equivalent on the WSL2 world ?


“| clip.exe” should work


That works outside WSL2, not inside, right?


clip.exe works to and from WSL 2.

But if you run VcXsrv you can use the native Linux clipboard and have it shared between WSL 2 and Windows. This is what I do because then tools like Vim, the pass utility and other command line tools can write to and read from the native Linux clipboard and everything will work out of the box.

If you wanted to reproduce pbcopy / pbpaste in native Linux or WSL 2 you can set up aliases for:

    alias pbcopy="xclip -selection clipboard"
    alias pbpaste="xclip -o"
And in case you don't already have xclip installed in WSL 2, you can apt-get install xclip or use whatever package manager you have. I can't remember if xclip is installed by default in WSL 2 distros.


Oh that’s neat. Do you use the x server for just this purpose or do you also run linux gui apps? I’ve been thinking about investing more into it but the high dpi stuff does not work properly.


I use it just for the clipboard but I used to run Sublime Text through it years ago (using WSL 1). It was really fast and worked great, at least at 2560x1440.

A video walk through of my current Windows / WSL 2 / etc. dev environment is here: https://nickjanetakis.com/blog/a-linux-dev-environment-on-wi...


ls | yank -- clip.exe


Very cool tool!

Two immediate thoughts: one, the naming had me confused for a while. The only place I've seen the word "yank" in computing is in Emacs context, where it means "paste", not "copy"...

Two, natural extension of this idea is "interactively select and transform data in the pipe". I think existing text editors would be natural fit for this, especially if configured with some conveniences (like field-based navigation and ability to delete everything except a particular column/line with one command). Then, you could drop such editor into a pipe using something like [0]. I'm gonna try this with terminal Emacs client at some point.

--

[0] - https://stackoverflow.com/a/49289440


> The only place I've seen the word "yank" in computing is in Emacs context, where it means "paste", not "copy"...

This is a confusing difference between Emacs and Vim. Emacs uses it for pasting, Vim uses it for copying.


How did the Emacs developers ever thought "yank" would convey the meaning of "paste"?

(Legitimate question. I'm aware some UX faux-pas do happen, but I don't see how)


Emacs developers viewed it as yanking out of the buffer into the document. Vim viewed it as yanking out of the document into the buffer. It's poor terminology either way, as yanking to me implies moving rather than copying as in both applications


Maybe Emacs yanks from a clipboard (into a buffer), while vim yanks from a buffer into a register (buffer)?


Oh oh. Someone had a too harmonic day and wants to add some spice to it.


also VIM. It is probably that. I guess he could have call it Put. But yank sounds cooler.


This is actually a solution to a problem I've been looking at recently. My current experimental answer is using the terminal within Neovim, which is kind of a superset of this in some ways.

I'm wondering if there's a standard way to invoke vim and just get a selection. Might make a good analog for vim users who don't want to commit to using its terminal.


With kitty you can map keyboard shortcuts to open the scrollback buffer in an editor. It's super neat and it has pretty much completely replaced using the neovim terminal for me. Below are my mappings for opening the scrollback in the current tab or a new one. What makes the former even better is that after closing it you are back in your regular terminal view.

[0] https://sw.kovidgoyal.net/kitty/launch.html

[1]

  #: You can pipe the contents of the current screen + history buffer as
  #: STDIN to an arbitrary program using the ``pipe`` function. For
  #: example, the following opens the scrollback buffer in less in an
  #: overlay window::
  # map f1 pipe @ansi overlay less +G -R
  map f1 pipe @text tab /usr/local/bin/nvim '+ normal GA' -
  map f2 pipe @text overlay /usr/local/bin/nvim '+ normal GA' -


I'm not quite sure whether I understand what you're trying to say, but this should be close (put into vimrc):

    " bind leader-y and leader-p to clipboard copy/paste
    noremap <Leader>y "+y
    noremap <Leader>p "+p
(\y or ,y is easier to use than "+y which is the default binding)

`ps ux | vim -`, go into visual mode and select the stuff you want, then ,y to copy it to the clipboard.

If you don't use a clipboard manager then of course it will be destroyed once you :q out of vim. You could probably add the :q! to the binding to make it automatically exit vim once you 'confirm' (copy) the selection.


In iTerm, searching for the text selects it, and you can use tab to expand the selection. Not quite vim, but it’s better than many other terminal emulators in that space.


Similarly, if you're using tmux there is the very handy tmux-fingers[1] plugin that kind of works like the vim-shortcut browser addons but inside tmux.

You initialize the plugin and it shows you hints of what to copy, you press the wanted key and it copies the text next to the hint. Works with bunch of things (hashes, urls, numbers) and usually highlights what I want to copy, otherwise tmux with it's normal keyboard shortcuts work fine to manually select things.

- [1] https://github.com/Morantron/tmux-fingers


The final example `yank -- xsel -b` is probably the most directly useful for me, but it still doesn't solve the following problem which irritates me to all hell:

  $ git push
   fatal: The current branch new has no upstream branch.
   To push the current branch and set the remote as upstream, use

    git push --set-upstream origin new

Is there any sane way to copy the perfectly formatted `git push -u` command shown above without resorting to the following eval, which doesn't alias nicely?

  $(git push 2>&1 | grep git)


I think “thefuck” handles this case really well: https://github.com/nvbn/thefuck


This is perfect, because it's an after-the-fact solution instead of me trying to remember to type the right git command in the first place, much like copy-pasting the suggested command is. Thanks for the suggestion!


I have the following alias which simply parses the branch name and passes with carts

  alias gpsu='git rev-parse --abbrev-ref HEAD | xargs git push --set-upstream origin'


You can also just do

  git push -u origin HEAD


This looks great.

clip.exe does similar on Windows, although much simpler - e.g:

  dir /b c:\windows\*.exe |clip
Been an integral part of my workflow for well over a decade!


Useful tool indeed, thanks for sharing. I use clipper[1], which delivers a similar function through a different implementation. What I like about that one is that with right config you can also pipe output from remote servers back into your machine's clipboard, which is quite handy in so many situations.

[1] https://github.com/wincent/clipper


There's a better way to do it. Terminals have a special escape sequence called OSC 52, which allows you to insert into the clipboard from even remote SSH sessions. Try this:

printf "\033]52;c;$(printf "%s" "blabla" | base64)\a"


Hey, that's quite interesting. Just tested it here with alacritty and was able to get data from a remote server into the clipboard. The downside here is that it did not seem to work immediately from inside tmux, but a quick search shows that there are ways to make it work. Also found a vim-plugin[1] that would allow it to work from inside vim as well. If I can also find a way to pipe random commands to it, it might indeed work better than clipper for my use cases. Finally, there is the added benefit of removing the need to forward the local UNIX socket over SSH, which I find to be a bit flaky. Thanks for sharing it!

[1] https://github.com/ojroques/vim-oscyank


I've found a couple of random blog posts and some user's pages laying out the OSC codes, but is there an open reference of them?

I have also considered trawling through the various terminal emulator source repos in order to know which are actually implemented (since that can for sure be a different set from those which are specified)


This looks really useful.

Paradoxically, I find that the terminal is the place where I end up using the mouse the most.


Alacritty's vi mode has clipboard support, so I just make selections and yank with the v and y keys.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: