Copying commands with PuTTY and tmux

6,190

Solution 1

If you're copying something to paste it within tmux, you can use its built-in copying/pasting. If you have vi key-bindings enabled and default settings, it's <prefix> [ to enter copy mode, navigate to your text, space to start highlighting, and enter to finish. Then you can use prefix ] to paste inside tmux. Note that this keeps the copied text within tmux's own buffers, and it doesn't go into your local machine's clipboard.

If you need to paste outside of PuTTY, you can hold Alt while selecting with the mouse to do a block selection within a pane.

Solution 2

With some trickery, it is possible to get the tmux buffer back through PuTTY and onto the client. I accomplished this using ANSI escape codes for the "AUX" port (serial printer).

Here is just one implementation of that method of transfer:

1) In server-side tmux.conf, add:

# Send the tmux copy buffer to a file.  The file is read for ANSI printing by "t" alias in .bashrc
bind -t vi-copy y copy-pipe 'cat > ~/.tmux-buffer' 

2) In server-side .bashrc, add:

t() {
  # Configure a PuTTY profile to send "t" as the "Remote command".  This
  # function will automatically reattach to an existing tmux session if one
  # exists, or start a new one.  This function also repeatedly sends our
  # homemade tmux clipboard back to the PuTTY client in the form of an ANSI
  # printer escape sequence.  The contents of the homemade clipboard are
  # populated by `bind -t vi-copy y copy-pipe 'cat > ~/.tmux-buffer'` in
  # tmux.conf.  It is expected that the PuTTY client will be configured to
  # print to a "Microsoft XPS Document Writer" which saves the printer output
  # to a file.  The file is subsequently read by an AutoHotkey macro, and the
  # contents are made available for paste.
  [[ "$TERM" == "xterm" ]] || return 0 # This prevents recursive runs, in case t() is called after tmux is started.
  { while :; do tput mc5; cat ~/.tmux-buffer; tput mc4; sleep 5; done } &
  tmux attach || tmux
}

3) On client-side (Microsoft Windows), create new printer:

  • Add a Printer
  • Create a new port > Local Port
  • Enter a port name > "PuTTY_Printer_File"
  • Driver > Microsoft XPS Document Writer
  • Printer name > "PuTTY Printer"
  • Optional: Print a test page and make sure it shows up in contents of file @ "%USERPROFILE%\Documents\PuTTY_Printer_File"

4) In client-side PuTTY configuration:

  • Set Terminal > "Printer to send ANSI printer output to:" to newly created printer named "PuTTY Printer"
  • Set Connection > SSH > "Remote command:" to "t" (referencing the .bashrc function above)

At this point you can send the contents of the tmux buffer to your PuTTY client by highlighting some text in tmux's copy-mode, and pressing y. The selected text will end in up %USERPROFILE%\Documents\PuTTY_Printer_File back on the client. If you want to go a step further and emulate "pasting" out of this file, you can use a hotkey sequence to read the contents of the file and insert it. Here's an example that leverages AutoHotKey, but it is probably possible to achieve the same result in PowerShell if you prefer.


5) Client-side AutoHotKey macro:

;### Get contents of PuTTY ANSI printer device output and paste it
#v:: ;Winkey + v
FileRead, PuTTYPrinter, %USERPROFILE%\Documents\PuTTY_Printer_File
SendInput %PuTTYPrinter%
PuTTYPrinter = ; Free up memory
return

6) Complete usage procedure:

  • Connect to server with PuTTY and get dropped into tmux by t() function.
  • When ready to select text for copy, use tmux hotkey for copy-mode ( Ctrl + b, [ )
  • Move cursor with arrow keys
  • Begin selection with spacebar
  • End selection and copy it with y
  • Back on client-side running PuTTY, WindowsKey + v will paste the selection

Since pictures are worth 1,000 words, here's an overview of what's happening:

Links:
My answer on Stack Overflow - https://stackoverflow.com/a/41560941/3163993
Video demonstration / explanation - https://www.youtube.com/watch?v=kEIpE2XpDdY

Solution 3

A workaround to the problem is to first maximize the pane and then copy the text using mouse. Use prefix-Z to maximize the current pane.

Share:
6,190

Related videos on Youtube

Trevor Sullivan
Author by

Trevor Sullivan

Updated on September 18, 2022

Comments

  • Trevor Sullivan
    Trevor Sullivan over 1 year

    I use PuTTY from Windows 10 to access various Linux systems via SSH. Within these systems, I often use Tmux to simplify my life inside the Linux environment. Within a Tmux session, I typically have one or more windows that are subdivided into multiple panes.

    I regularly use the mouse to select / copy text in PuTTY, and then right-click to paste it in. Normally this works fine outside of Tmux, when lines wrap, but inside a tmux session, I can't do a multi-line selection inside a specific pane.

    How can I accomplish this?

  • Trevor Sullivan
    Trevor Sullivan over 7 years
    The block selection is pretty close to what I need, but it creates a line break when there shouldn't be one. Thanks for that tip.
  • ThiefMaster
    ThiefMaster over 5 years
    The image link is broken; could you upload it to the stack exchange imgur in case you still have those pictures or otherwise remove the link?
  • ThiefMaster
    ThiefMaster over 5 years
    This results in trailing space for all but the longest line
  • jdhao
    jdhao over 5 years
    This, you need to remove it yourself.
  • Petrucci
    Petrucci over 5 years
    Thanks @ThiefMaster. Here's the image: i.imgur.com/uQOzDfc.jpg
  • information_interchange
    information_interchange about 4 years
    The ALT tip isn't perfect but so far the only solution that somewhat works for me. Thanks