Skip to content

Instantly share code, notes, and snippets.

@geraldlai
Created November 10, 2017 06:47
Show Gist options
  • Save geraldlai/90c17c4fe235bf70b8949c9870a806db to your computer and use it in GitHub Desktop.
Save geraldlai/90c17c4fe235bf70b8949c9870a806db to your computer and use it in GitHub Desktop.
tmx: send keystrokes to tmux panes and new/split windows
#!/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