tmux client library for Ruby
Control tmux, navigate sessions, windows, and panes, send keys, watch for changes via control mode, capture pane contents.
Guides
Task guides for Ruby.
Topics
Subject-by-subject, with Ruby in every code block.
Examples
Complete programs, sourced from the code each port tests.
API reference
Types and functions of the Ruby API.
Install
bundle add libtmuxlibtmux 0.1.0 is pre-1.0 and can change between minor versions. Pin to a range:
gem "libtmux", "~> 0.1.0"At a glance
Server → Session → Window → Pane. Each level of the tmux hierarchy has its own entry in the Ruby API, with the tmux object it wraps.
| Type | Wraps |
|---|---|
LibTmux::Server | A tmux server |
LibTmux::Session | A session, ID $n |
LibTmux::Window | A window in a session, ID @n |
LibTmux::Pane | A pane in a window, ID %n |
What it does
Capability: Navigate tmux via a typed object graph
require "libtmux"
snapshot = LibTmux::Server.start do |server| session = server.new_session( name: "work", window_name: "main", command: ["/bin/cat"] )
window = session.new_window(name: "logs", command: ["/bin/cat"]) window.split( direction: :horizontal, size: "40%", command: ["/bin/cat"] )
server.snapshotend
snapshot.windows.each do |window| pane_ids = window.panes.map(&:id).join(", ") puts "#{window.name}: #{pane_ids}"endrequire "libtmux"
begin snapshot = LibTmux::Server.start do |server| session = server.new_session( name: "work", window_name: "main", command: ["/bin/cat"] )
window = session.new_window(name: "logs", command: ["/bin/cat"]) window.split( direction: :horizontal, size: "40%", command: ["/bin/cat"] )
server.snapshot end
snapshot.windows.each do |window| pane_ids = window.panes.map(&:id).join(", ") puts "#{window.name}: #{pane_ids}" endrescue StandardError => error warn "tmux quickstart failed: #{error.message}" raiseendrequire "libtmux"
server = LibTmux::Server.start
begin session = server.new_session( name: "work", window_name: "main", command: ["/bin/cat"] )
window = session.new_window(name: "logs", command: ["/bin/cat"]) window.split( direction: :horizontal, size: "40%", command: ["/bin/cat"] )
snapshot = server.snapshot snapshot.windows.each do |window| pane_ids = window.panes.map(&:id).join(", ") puts "#{window.name}: #{pane_ids}" endensure server.closeendrequire "libtmux"
server = LibTmux::Server.start
begin session = server.new_session( name: "work", window_name: "main", command: ["/bin/cat"] )
window = session.new_window(name: "logs", command: ["/bin/cat"]) window.split( direction: :horizontal, size: "40%", command: ["/bin/cat"] )
snapshot = server.snapshot snapshot.windows.each do |window| pane_ids = window.panes.map(&:id).join(", ") puts "#{window.name}: #{pane_ids}" endrescue StandardError => error warn "tmux quickstart failed: #{error.message}" raiseensure server.closeendRun this example
POSIX shell, tmux 3.3a or newer, Ruby 4.0.7, Bundler 4.0.20, a C build toolchain for gems and access to rubygems.org.
Save the program above as quickstart.rb in a new directory, along with the files below.
The Ruby block closes its server automatically. Cleanup shows the explicit ensure form. The program stops its private tmux server and removes any temporary files it created when it finishes. Error handling adds diagnostics; every version checks required results and deadlines.
Gemfile
source "https://rubygems.org"gem "libtmux", "~> 0.1"Gemfile.lock
GEM remote: https://rubygems.org/ specs: fiddle (1.1.8) fileutils (1.8.1) io-console (0.9.4) json (3.0.2) libtmux (0.1.0) fiddle (~> 1.1) io-console (~> 0.8) json (~> 3.0.2) securerandom (~> 0.4) tmpdir (~> 0.3) securerandom (0.4.1) tmpdir (0.3.2) fileutils
PLATFORMS ruby x86_64-linux
DEPENDENCIES libtmux (~> 0.1)
CHECKSUMS fiddle (1.1.8) sha256=7fa8ee3627271497f3add5503acdbc3f40b32f610fc1cf49634f083ef3f32eee fileutils (1.8.1) sha256=2d541a1ee34a9ed5c4f054be8fb819a26b5d654488a31dc8806917cf448b9cc3 io-console (0.9.4) sha256=a403304f32928ee85e56d457b4612ca43f2703b561a3258844992bd24085fbb1 json (3.0.2) sha256=8e6d7e7b11384c21230430cef90b71f14849a34a1f4452796670f7c981bd19df libtmux (0.1.0) sha256=e1cc928de46d517fc9956ba6161a5b9d205ae8ed337bfd31689b1adb75f3ef00 securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 tmpdir (0.3.2) sha256=e276ef386182169f8d417d9e90f12dba82a54e81646df0caf21de4a7987a0c27
BUNDLED WITH 4.0.20Setup and run
bundle config set --local path vendor/bundlebundle install --jobs 2unset TMUX TMUX_PANEexport ENV=/dev/null BASH_ENV=/dev/null SHELL=/bin/shbundle exec ruby quickstart.rbExpected output
main: %0logs: %1, %2Library revision: c8b839595d5a.
# frozen_string_literal: true
begin # docs:begin main require "libtmux"
LibTmux::Server.start do |server| created = server.new_session( name: "capture", command: ["/bin/sh"], environment: {"ENV" => "/dev/null"}, receipt: true ) pane = created.pane pane.send_text("printf '\\nlibtmux capture ready\\n'") pane.send_keys("Enter") deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 5 captured = pane.capture.stdout.lines(chomp: true) until captured.include?("libtmux capture ready") raise "Output did not arrive within five seconds" if Process.clock_gettime(Process::CLOCK_MONOTONIC) > deadline sleep 0.05 captured = pane.capture.stdout.lines(chomp: true) end raise "Expected output is absent from the pane" unless captured.include?("libtmux capture ready") puts "libtmux capture ready" end # docs:end mainrescue StandardError => error warn "#{error.class}: #{error.message}" exit 1end
The whole program, examples/api/capture.rb. The port's CI runs it in .github/workflows/compatibility.yml: bundle exec scripts/matrix.
# frozen_string_literal: true
begin # docs:begin main require "libtmux"
LibTmux::Server.start do |server| session = server.new_session(name: "work", command: ["/bin/cat"]) window = session.new_window(name: "logs", command: ["/bin/cat"]) puts "window: #{window.snapshot.name}" puts "session windows: #{session.list_windows.length}" end # docs:end mainrescue StandardError => error warn "#{error.class}: #{error.message}" exit 1end
The whole program, examples/api/new_window.rb. The port's CI runs it in .github/workflows/compatibility.yml: bundle exec scripts/matrix.
Typed API
- Typed objects instead of parsed format strings:
LibTmux::PaneSnapshot - Filtering and queries over tmux objects:
LibTmux::FilterExpr - Typed errors instead of exit codes and stderr:
LibTmux::Error
What you get over the tmux CLI
- Traversal from a server down to its panes:
LibTmux::Server#list_panes - Send keys to a pane:
LibTmux::Pane#send_keys - Watch for changes through tmux control mode:
LibTmux::ControlConnection - Capture pane contents:
LibTmux::Pane#capture - Arguments passed as a list, with no shell quoting:
LibTmux::Server#run