Skip to content

Suggestion: sensible pass through of OSC 52 to terminal emulator #4275

Description

@luposmi

Suggestion: Add an option to pass through OSC 52 requests to the last used console (determined through e.g., last key press first, last opened second etc.).

Background:
I am currently working a lot over ssh on projects with Neovim. One annoyance I often face is copying something from another ssh or from a desktop window (e.g., Firefox) into neovim.
The best and most secure way (still insecure, but compared to giving my ssh connections access to my Wayland socket it at least only compromises my clipboard, which still can be read on the local system with wl-copy) I found is to use the OSC 52 for that.

However, as described in #1477, the buffer is currently not read from the terminal emulator, but tmux provides its own. It has to be manually pulled using tmux refresh -l. As there is no way under Wayland to set a hook to copy or paste, it has to be pulled manually and compared to the last buffer. If they are not the same, run refresh. However, setting up this script (and looking that you have to do so) is quite time intensive and isnt perferct.
The issue described above with automatic pulling is that it doesnt know to which terminal to pass through. However, I would assume that most users want to copy from the terminal emulator last used, which explains the proposal above.

Activity

  1. sean-xyz commented on Feb 24, 2025

    @sean-xyz

    i found a workaround for this that may help anyone reading:

    if you use wl-clipboard, you can trigger on clipboard change events and write to tmux's paste buffer with wl-paste --watch tmux load-buffer -. if you don't use wl-clipboard, i'm guessing that there's similar solutions for various other tools.

    make wl-paste --watch tmux load-buffer - a systemd service or exec once in your login shell or something

    neovim uses osc 52 to query tmux, tmux has the system clipboard already loaded in its buffer and returns that. allow-passthrough isn't necessary, nor is osc 52 paste functionality from terminal emulator

  2. dantecriscio commented on Jun 13, 2025

    @dantecriscio

    make wl-paste --watch tmux load-buffer - a systemd service or exec once in your login shell or something

    This has the affect of making the OS "push" its clipboard change events into the tmux buffer. I imagine this works great for using tmux on a local machine!

    However, I commonly use tmux on a remote machine. So I don't imagine this solution will be helpful there, because I'm not aware of any way to push all local clipboard change events over SSH and into the remote tmux buffer. Even if there is some way, I would imagine it is difficult and more insecure than OSC 52 pass-through (which I am told is already imperfect security-wise).

    For that reason, I would prefer a solution where the OSC 52 requests is passed through, like in the original comment

  3. dantecriscio commented on Jun 13, 2025

    @dantecriscio

    For full transparency, I would like a solution where I am in Neovim on a remove machine, and the paste request is passed back all the way from Neovim (Remote) -> Tmux (Remote) -> SSH -> Local Clipboard and then the response goes all the way in the other direction. Tmux is currently the only thing breaking this chain

  4. Lcchy commented on Jun 27, 2025

    @Lcchy

    If you are using neovim remotely inside tmux, there is a specific workaround to trigger the reload before pasting:

    neovim/neovim#29350 (comment)

    But it would be nice to support these use cases natively

  5. dantecriscio commented on Jun 28, 2025

    @dantecriscio

    I’ve used solutions like that before, it’s pretty good. The only problem is that it relies on sleep 0.05. If over SSH, the response might not come in time. Maybe if there was some way to add in a hook or a callback, which makes the tmux refresh-client -l request first and then Neovim makes the OSC52 within the callback (only once the outer console has sent the clipboard contents to tmux).

  6. Lcchy commented on Jul 1, 2025

    @Lcchy

    Yes, I even had to set it to 0.2s in my case to be safe.

    Making the command blocking or adding a callback would make this much safer to use.

  7. realyukii commented on Sep 18, 2025

    @realyukii

    I have nested tmux, I use tmux both from my host and ssh from remote server too.

    The clipboard works on single tmux instance (from my host only and remote server not starting tmux), but it stopped working once I start tmux on the server side.

    Is there a way to fix this?

    Currently I tested the functionality with osc52pty, and this sequence works:

    [reyuki@zero ~]$  osc52pty ssh user@remote
    user@remote:~$  printf "\e]52;c;%s\a" "$(echo -n 'THE TEXT TO COPY' | openssl base64 -A)"
    user@remote:~$  THE TEXT TO COPY
    

    but this one didn't work as expected:

    [reyuki@zero ~]$  osc52pty ssh user@remote
    user@remote:~$  tmux attach -t 0
    user@remote:~$  printf "\e]52;c;%s\a" "$(echo -n 'THE TEXT TO COPY' | openssl base64 -A)"
    user@remote:~$  printf "\e]52;c;%s\a" "$(echo -n 'THE TEXT TO COPY' | openssl base64 -A)"
    
  8. realyukii commented on Sep 18, 2025

    @realyukii

    I just found information about tmux inside tmux in the wiki page, if I understand correctly, all I need to do is to set the outer or parent tmux (which I assume it's tmux instance from the host) to have:

    [reyuki@zero ~]$   tmux show -s set-clipboard
    set-clipboard on
    [reyuki@zero ~]$  echo $TERM
    tmux-256color
    [reyuki@zero ~]$  tmux info|grep Ms
     193: Ms: (string) \033]52;%p1%s;%p2%s\a
    [reyuki@zero ~]$
    

    and in the inner:

    user@remote:~$  echo $TERM
    tmux-256color
    user@remote:~$  tmux show -s set-clipboard
    set-clipboard external
    user@remote:~$  tmux info|grep Ms
     193: Ms: (string) \033]52;%p1%s;%p2%s\a
    

    but even with this setup, it still didn't work, anyone know why?

    EDIT:
    currently the workaround is to copy content to tmux buffer in copy mode and then quit the tmux instance on remote and pipe it using:

    tmux save-buffer - | base64 | tr -d '\n' | printf '\033]52;c;%s\007' $(cat -)
    
  9. nicm commented on Oct 30, 2025

    @nicm
    Member

    Please try this against master: get_clipboard.diff.txt

    This adds a new option get-clipboard:

    "When an application requests the clipboard, whether to "
    "ignore the request ('off'); respond with the newest buffer "
    "('buffer'); request the clipboard from the most recently "
    "used terminal ('request'); or to request the clipboard, "
    "create a buffer, and send it to the application ('both')."
    

    Setting it to request is probably what you want. The default is buffer. You still need set-clipboard set to on, although maybe it would be better if the options were independent.

    I'm not quite sure what to do with request-client -l, most likely I will keep it but remove the forward-to-pane behaviour and instead just make it create a paste buffer.

  10. nicm commented on Nov 12, 2025

    @nicm
    Member

    Updated for recent changes: get_clipboard2.diff.txt

  11. zoriya commented on Nov 17, 2025

    @zoriya

    I think this patch is malformed (or probably i just don't know how to apply it), i was using the first one with success before.

  12. nicm commented on Nov 18, 2025

    @nicm
    Member

    Try this instead: get_clipboard3.diff.txt

  13. zoriya commented on Dec 1, 2025

    @zoriya

    I've been using this patch for 2 weeks, it works great! It also fixes the small issues I had with the previous one.

  14. nicm commented on Dec 2, 2025

    @nicm
    Member

    Thanks for testing, I have applied this to OpenBSD now. I also chose to keep refresh-client -l but to remove its ability to forward the clipboard to a pane, so it can now only set a buffer; if you want the clipboard to go to a pane you need to use get-clipboard. This should be in GitHub later on, let me know if you see any problems.

  15. github-actions commented on Jan 2, 2026

    @github-actions

    This issue has been automatically locked since there has not been any recent activity after it was closed.

  16. locked as resolved and limited conversation to collaborators on Jan 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions