-
-
Save geraldlai/90c17c4fe235bf70b8949c9870a806db to your computer and use it in GitHub Desktop.
tmx: send keystrokes to tmux panes and new/split windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# tmx: tmux execute (requires tmux v2.4+) | |
# Author: Gerald Lai | |
# License: 0BSD | |
use warnings; | |
use strict; | |
use Cwd qw(cwd); | |
use File::Glob qw(:bsd_glob); | |
use File::Spec::Functions qw(file_name_is_absolute catdir); | |
unless (@ARGV) { | |
print STDERR <<"EOT"; | |
Usage: tmx '[winname:][[startdir:]command]' ... | |
tmx '=TMUX_PANE=command' ... | |
If winname is "-", split window horizontally and issue command there. | |
If winname is "|", split window vertically and issue command there. | |
EOT | |
exit 255; | |
} | |
my $tmux = "tmux"; | |
sub send_seq { | |
my ($cmd, $pane) = @_; | |
return join(' \; ' => | |
(map { | |
$_ eq q{'} | |
? qq{send -l -t $pane "'"} | |
: qq{send -l -t $pane '$_'}; | |
} split /(')/, $cmd), | |
qq{send -t $pane Enter}, | |
); | |
} | |
my $errors = 0; | |
for (@ARGV) { | |
# command existing pane | |
if (s/^=//) { | |
my ($pane, $cmd) = split /=/, $_, 2; | |
$pane = $ENV{TMUX_PANE} unless $pane; | |
$cmd = "" unless defined $cmd; | |
unless ($pane) { | |
# fail silently | |
++$errors; | |
next; | |
} | |
my $send = send_seq($cmd, qq{'$pane'}); | |
++$errors unless 0 == system qq{$tmux $send}; | |
next; | |
} | |
my ($name, $dir, $cmd) = /:/ | |
? (split /:/, $_, 3) | |
: (undef, ($ENV{TMPDIR} || "/tmp"), $_); | |
($name, $dir, $cmd) = (undef, $name, $dir) unless defined $cmd; | |
$dir = bsd_glob($dir); | |
$dir = catdir(cwd(), $dir) unless file_name_is_absolute($dir); | |
unless (-d $dir) { | |
print STDERR "Not a directory: $dir\n"; | |
++$errors; | |
next; | |
} | |
my @tm_cmd = qw(new-window); | |
if ($name && $name =~ m{^[-|]$}) { | |
@tm_cmd = ("split-window", ($name eq "-") ? "-v" : "-h"); | |
$name = undef; | |
} | |
my $send = send_seq($cmd, q{"$TMUX_PANE"}); | |
++$errors unless 0 == system $tmux, @tm_cmd, "-dP", | |
defined($name) ? ("-n" => $name) : (), | |
"-c" => $dir, | |
qq{$tmux $send && \$SHELL}, | |
; | |
} | |
exit $errors; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment