libtmux for Raku
Raku-based tmux client
tmux client library for Raku. Control tmux, connect to and create servers, navigate sessions, windows, and panes, send keys, watch for changes via control mode, capture pane contents
use LibTmux;
my $server = Server.start(:name<work>, :shell-command('exec cat'));LEAVE $server.close if $server.defined;
my $before = $server.snapshot;my $left = $before.panes.single.ref;my $right = $left.split(:horizontal, :shell-command('exec cat'));$left.set-title('editor');$right.set-title('logs');
my $after = $server.snapshot;my $editor = $after.panes.filter(*.title eq 'editor').single;say "{$editor.title}: {$after.panes.elems} panes";tmux before the first call: no server is running.
tmux after Server.start: added session work.
tmux after Server.snapshot: unchanged.
tmux after PaneSelection.single: unchanged, the call sent no command.
tmux after PaneRef.split: added pane %1 to window 0:sh.
tmux after PaneRef.set-title: unchanged.
tmux after PaneRef.set-title: unchanged.
tmux after Server.snapshot: unchanged.
tmux after PaneSelection.single: unchanged, the call sent no command.
tmux after Server.close: the server has exited; the call sent no command.
Before the first call
No tmux server is running yet.
Server.start returned Server
{ "socket": "libtmux-owned-AbC123"}1 tmux command, 1 that changes tmux
-
new-session -d -P -F LTM1-session-#{session_id} -s work -x 80 -y 24 -- 'exec cat'LTM1-session-$0
Before these, the library asked tmux about itself 4 times (its version, its daemon, how a control client reads escapes).
Server.snapshot returned Snapshot
{ "panes": 1, "sessions": 1, "windows": 1}7 tmux commands
-
list-sessions -F 'LTM1\011libtmux.format/v1:session:session:qa:none:id,name,windows-count,attached-count,created,activity,path,grouped,group-name\011qa\011#{session_id}\011#{q/a:session_name}\011#{session_windows}\011#{session_attached}\011#{session_created}\011#{session_activity}\011#{q/a:session_path}\011#{session_grouped}\011#{q/a:session_group}\011END'LTM1 libtmux.format/v1:session:session:qa:none:id,name,windows-count,attached-count,created,activity,path,grouped,group-name qa $0 work 1 0 1794634589 1794634589 /tmp/marked 0 END -
list-windows -a -F 'LTM1\011libtmux.format/v1:window-link:window-link:qa:none:session-id,window-id,index,active,last,activity,bell,silence\011qa\011#{session_id}\011#{window_id}\011#{window_index}\011#{window_active}\011#{window_last_flag}\011#{window_activity_flag}\011#{window_bell_flag}\011#{window_silence_flag}\011END'LTM1 libtmux.format/v1:window-link:window-link:qa:none:session-id,window-id,index,active,last,activity,bell,silence qa $0 @0 0 1 0 0 0 0 END -
list-windows -a -F 'LTM1\011libtmux.format/v1:window:window:qa:none:id,name,width,height,panes-count,layout,visible-layout,zoomed,modal-pane-id\011qa\011#{window_id}\011#{q/a:window_name}\011#{window_width}\011#{window_height}\011#{window_panes}\011#{q/a:window_layout}\011#{q/a:window_visible_layout}\011#{window_zoomed_flag}\011#{window_modal_pane}\011END'LTM1 libtmux.format/v1:window:window:qa:none:id,name,width,height,panes-count,layout,visible-layout,zoomed,modal-pane-id qa @0 sh 80 24 1 "{\"V\":2,\"L\":{\"t\":\"p\",\"w\":80,\"h\":24,\"x\":0,\"y\":0,\"a\":true,\"i\":0,\"I\":\"%0\"}}" "{\"V\":2,\"L\":{\"t\":\"p\",\"w\":80,\"h\":24,\"x\":0,\"y\":0,\"a\":true,\"i\":0,\"I\":\"%0\"}}" 0 END -
list-panes -a -F 'LTM1\011libtmux.format/v1:pane:pane:qa:none:id,window-id,index,active,width,height,left,top,pid,tty,title,current-command,current-path,start-command,start-path,dead,dead-status,dead-signal,dead-time,in-mode,mode,pipe,synchronized,floating,modal,x,y,z,command-running,command-status,at-top,at-bottom,at-left,at-right\011qa\011#{pane_id}\011#{window_id}\011#{pane_index}\011#{pane_act…LTM1 libtmux.format/v1:pane:pane:qa:none:id,window-id,index,active,width,height,left,top,pid,tty,title,current-command,current-path,start-command,start-path,dead,dead-status,dead-signal,dead-time,in-mode,mode,pipe,synchronized,floating,modal,x,y,z,command-running,command-status,at-top,at-bottom,at-left,at-right qa %0 @0 0 1 80 24 0 0 2005202 /dev/pts/19 host cat /tmp/marked "\"exe… -
list-clients -F 'LTM1\011libtmux.format/v1:client:client:qa:none:name,session-id,session-name,tty,pid,width,height,created,activity,control-mode,read-only,terminal-name,key-table\011qa\011#{q/a:client_name}\011#{session_id}\011#{q/a:client_session}\011#{q/a:client_tty}\011#{client_pid}\011#{client_width}\011#{client_height}\011#{client_created}\011#{client_activity}\011#{client_control_mode}\011#{…no output -
list-sessions -f #{session_grouped} -F 'LTM1\011libtmux.format/v1:session-group:grouped-session:qa:none:name,size,attached-count\011qa\011#{q/a:session_group}\011#{session_group_size}\011#{session_group_attached}\011END'no output -
list-buffers -F 'LTM1\011libtmux.format/v1:buffer:buffer:qa:none:name,size,created,sample\011qa\011#{q/a:buffer_name}\011#{buffer_size}\011#{buffer_created}\011#{q/a:buffer_sample}\011END'no output
Before these, the library asked tmux about itself 6 times (its version, its daemon, how a control client reads escapes).
PaneSelection.single returned PaneRef
{ "id": "%0"}The call sent no tmux command.
PaneRef.split returned PaneRef
{ "id": "%1"}1 tmux command, 1 that changes tmux
-
split-window -P -F LTM1-pane-#{pane_id} -t %0 -h -d -- 'exec cat'LTM1-pane-%1
PaneRef.set-title returned void
null1 tmux command, 1 that changes tmux
-
select-pane -t %0 -T editorno output
PaneRef.set-title returned void
null1 tmux command, 1 that changes tmux
-
select-pane -t %1 -T logsno output
Server.snapshot returned Snapshot
{ "panes": 2, "sessions": 1, "windows": 1}7 tmux commands
-
list-sessions -F 'LTM1\011libtmux.format/v1:session:session:qa:none:id,name,windows-count,attached-count,created,activity,path,grouped,group-name\011qa\011#{session_id}\011#{q/a:session_name}\011#{session_windows}\011#{session_attached}\011#{session_created}\011#{session_activity}\011#{q/a:session_path}\011#{session_grouped}\011#{q/a:session_group}\011END'LTM1 libtmux.format/v1:session:session:qa:none:id,name,windows-count,attached-count,created,activity,path,grouped,group-name qa $0 work 1 0 1794634589 1794634589 /tmp/marked 0 END -
list-windows -a -F 'LTM1\011libtmux.format/v1:window-link:window-link:qa:none:session-id,window-id,index,active,last,activity,bell,silence\011qa\011#{session_id}\011#{window_id}\011#{window_index}\011#{window_active}\011#{window_last_flag}\011#{window_activity_flag}\011#{window_bell_flag}\011#{window_silence_flag}\011END'LTM1 libtmux.format/v1:window-link:window-link:qa:none:session-id,window-id,index,active,last,activity,bell,silence qa $0 @0 0 1 0 0 0 0 END -
list-windows -a -F 'LTM1\011libtmux.format/v1:window:window:qa:none:id,name,width,height,panes-count,layout,visible-layout,zoomed,modal-pane-id\011qa\011#{window_id}\011#{q/a:window_name}\011#{window_width}\011#{window_height}\011#{window_panes}\011#{q/a:window_layout}\011#{q/a:window_visible_layout}\011#{window_zoomed_flag}\011#{window_modal_pane}\011END'LTM1 libtmux.format/v1:window:window:qa:none:id,name,width,height,panes-count,layout,visible-layout,zoomed,modal-pane-id qa @0 sh 80 24 2 "{\"V\":2,\"L\":{\"t\":\"h\",\"w\":80,\"h\":24,\"x\":0,\"y\":0,\"c\":[{\"t\":\"p\",\"w\":40,\"h\":24,\"x\":0,\"y\":0,\"a\":true,\"i\":0,\"I\":\"%0\"},{\"t\":\"p\",\"w\":39,\"h\":24,\"x\":41,\"y\":0,\"i\":1,\"I\":\"%1\"}]}}" "{\"V\":2,\"L\":{\"t\":\"h\",\"w\":80,… -
list-panes -a -F 'LTM1\011libtmux.format/v1:pane:pane:qa:none:id,window-id,index,active,width,height,left,top,pid,tty,title,current-command,current-path,start-command,start-path,dead,dead-status,dead-signal,dead-time,in-mode,mode,pipe,synchronized,floating,modal,x,y,z,command-running,command-status,at-top,at-bottom,at-left,at-right\011qa\011#{pane_id}\011#{window_id}\011#{pane_index}\011#{pane_act…LTM1 libtmux.format/v1:pane:pane:qa:none:id,window-id,index,active,width,height,left,top,pid,tty,title,current-command,current-path,start-command,start-path,dead,dead-status,dead-signal,dead-time,in-mode,mode,pipe,synchronized,floating,modal,x,y,z,command-running,command-status,at-top,at-bottom,at-left,at-right qa %0 @0 0 1 40 24 0 0 2005202 /dev/pts/19 editor cat /tmp/marked "… -
list-clients -F 'LTM1\011libtmux.format/v1:client:client:qa:none:name,session-id,session-name,tty,pid,width,height,created,activity,control-mode,read-only,terminal-name,key-table\011qa\011#{q/a:client_name}\011#{session_id}\011#{q/a:client_session}\011#{q/a:client_tty}\011#{client_pid}\011#{client_width}\011#{client_height}\011#{client_created}\011#{client_activity}\011#{client_control_mode}\011#{…no output -
list-sessions -f #{session_grouped} -F 'LTM1\011libtmux.format/v1:session-group:grouped-session:qa:none:name,size,attached-count\011qa\011#{q/a:session_group}\011#{session_group_size}\011#{session_group_attached}\011END'no output -
list-buffers -F 'LTM1\011libtmux.format/v1:buffer:buffer:qa:none:name,size,created,sample\011qa\011#{q/a:buffer_name}\011#{buffer_size}\011#{buffer_created}\011#{q/a:buffer_sample}\011END'no output
Before these, the library asked tmux about itself 6 times (its version, its daemon, how a control client reads escapes).
PaneSelection.single returned Pane
{ "id": "%0", "title": "editor"}The call sent no tmux command.
Server.close returned void
nullThe call sent no tmux command.
Run this example
Linux, Raku 6.d with zef, and tmux 3.3a through 3.8 on PATH. The first command installs the published LibTmux distribution from Raku Land, so it needs network access to the zef ecosystem. The program starts its own private tmux server.
Save the program above as quickstart.raku in a new directory, along with the files below.
This complete program owns a private tmux server and closes it with LEAVE when the program exits, including on an exception.
Setup and run
zef install 'LibTmux:ver<0.0.1+>:auth<zef:libtmux>'raku quickstart.rakuExpected output
editor: 2 panesInstall LibTmux
$ zef install 'LibTmux:auth<zef:libtmux>'Requires Linux, Raku 6.d and tmux 3.3a through 3.8. The authority names the Fez publisher, zef:libtmux.
Install a checkout instead of the published distribution.
Topics
Subject-by-subject, with Raku in every code block.
Guides
Task guides for Raku.
Examples
Complete programs, sourced from the code each port tests.