Tmux: Send and execute highlighted code in other pane

idetmux

I want to have two tmux panes going – the first could have one of several programs in it (often, but not always, vim) and the second will have an interactive session in R, python, or bc.

The two panes aren't always going to be showing the same system – usually I'll be running tmux on system A, doing something in one pane there, but then have the second pane ssh'd to system B and running an interactive session of R/Python/bc there.

My goal is to be able to highlight something in the first pane, and have it sent and executed in the other pane.

I know tmux can copy/paste between panes. And I know tmux can send-keys a specific command to another pane and end it with an enter so it is executed. But can I make it send-keys "whatever I have highlighted in the first pane" to the second pane then end with the enter character for execution?

(In other words, I'm trying to emulate the behavior of an IDE, where you can highlight a block of code and click "run". I am looking to do this specifically using tmux, not a special vim plugin, because sometimes I'll be using something other than vim in the first pane.)

Best Answer

I believe you can achieve what you're after by:

1) entering copy mode (prefix [)

2) selecting some text (most likely v(isual select)/y(ank))

3) sending it to another pane via tmux paste-buffer -t [left/right]

Here's a proof of concept I just sketched out:

Given a Ruby script called foo.rb in your current directory:

# foo.rb
x = "hello there"
puts x

... and two panes, vertically split (bash in left/irb session in right), if you run cat foo.rb, enter copy-mode, yank the file's contents and then run tmux paste-buffer -t right from the left pane, you should see the following output in the right pane:

λ irb
2.5.1 :001 > x = "hello there"
 => "hello there"
2.5.1 :002 > puts x
hello there
 => nil

From there, you could write a shell script and/or wire up a key binding to prevent you from having to type out/recall tmux paste-buffer -t [left/right].

paste-buffer should also handle "ending with enter" for you. From the tmux man page's paste-buffer entry:

When output, any linefeed (LF) characters in the paste buffer are replaced with a separator, by default carriage return (CR).

If the default separator doesn't work for some reason, you can also specify one using paste-buffer -s ....