Module: Mxup::Tmux
- Defined in:
- lib/mxup/tmux.rb
Overview
Thin wrapper over the tmux(1) CLI. Every method shells out; nothing here knows about mxup's own config. Kept as a module so callers can reference Mxup::Tmux.list_panes(...) without instantiating anything.
Defined Under Namespace
Classes: Error
Class Method Summary collapse
-
.break_pane(session, window, pane_index, new_window_name) ⇒ Object
Break a pane out into its own window.
-
.capture_pane(session, target, _lines = nil) ⇒ Object
Capture the pane's entire scrollback (-S - is "start of history") so callers can filter and tail as they see fit.
- .esc(val) ⇒ Object
-
.has_session?(name) ⇒ Boolean
--- inspection --------------------------------------------------------.
- .join_pane(session, src_window, dst_window) ⇒ Object
- .kill_session(name) ⇒ Object
- .kill_window(session, name) ⇒ Object
- .list_panes(session) ⇒ Object
- .list_windows(session) ⇒ Object
- .move_window(session, src_name, dst_index) ⇒ Object
-
.new_session(name, first_window_name, root) ⇒ Object
--- mutation ----------------------------------------------------------.
- .new_window(session, name, root) ⇒ Object
- .pane_count(session, window) ⇒ Object
-
.pane_target(window, pane_index) ⇒ Object
Format a pane target string "window.index" for use in other tmux calls.
- .rename_window(session, old_name, new_name) ⇒ Object
-
.run!(action, cmd) ⇒ Object
Run a tmux command that must succeed.
- .select_layout(session, window, layout) ⇒ Object
- .send_interrupt(session, target) ⇒ Object
- .send_keys(session, target, keys) ⇒ Object
- .session_created(name) ⇒ Object
- .set_environment(session, key, value) ⇒ Object
- .set_pane_title(session, window, pane_index, title) ⇒ Object
-
.show_environment(session, key) ⇒ Object
Returns the value stored in the session's environment, or nil if unset (tmux prefixes unset entries with '-').
- .split_window(session, window, root, target_pane: nil) ⇒ Object
- .swap_window(session, idx_a, idx_b) ⇒ Object
Class Method Details
.break_pane(session, window, pane_index, new_window_name) ⇒ Object
Break a pane out into its own window. Without an explicit -t target, tmux places the new window in the current client's session, which would send it to whichever session the user happens to be attached to when running tests. Always pin the destination to the source session.
89 90 91 92 |
# File 'lib/mxup/tmux.rb', line 89 def break_pane(session, window, pane_index, new_window_name) run!('break-pane', "tmux break-pane -s #{esc(session)}:#{esc(window)}.#{pane_index} " \ "-t #{esc(session)}: -n #{esc(new_window_name)} -d") end |
.capture_pane(session, target, _lines = nil) ⇒ Object
Capture the pane's entire scrollback (-S - is "start of history") so callers can filter and tail as they see fit. We deliberately don't pass -S -N here: if the interesting output scrolled past the visible window, a lower bound would silently hide it.
56 57 58 |
# File 'lib/mxup/tmux.rb', line 56 def capture_pane(session, target, _lines = nil) `tmux capture-pane -t #{esc(session)}:#{esc(target)} -p -S - 2>/dev/null` end |
.esc(val) ⇒ Object
145 146 147 |
# File 'lib/mxup/tmux.rb', line 145 def esc(val) Shellwords.escape(val.to_s) end |
.has_session?(name) ⇒ Boolean
--- inspection --------------------------------------------------------
20 21 22 |
# File 'lib/mxup/tmux.rb', line 20 def has_session?(name) system("tmux has-session -t #{esc(name)} 2>/dev/null") end |
.join_pane(session, src_window, dst_window) ⇒ Object
81 82 83 |
# File 'lib/mxup/tmux.rb', line 81 def join_pane(session, src_window, dst_window) run!('join-pane', "tmux join-pane -s #{esc(session)}:#{esc(src_window)} -t #{esc(session)}:#{esc(dst_window)} -d") end |
.kill_session(name) ⇒ Object
118 119 120 |
# File 'lib/mxup/tmux.rb', line 118 def kill_session(name) system("tmux kill-session -t #{esc(name)}") end |
.kill_window(session, name) ⇒ Object
114 115 116 |
# File 'lib/mxup/tmux.rb', line 114 def kill_window(session, name) system("tmux kill-window -t #{esc(session)}:#{esc(name)}") end |
.list_panes(session) ⇒ Object
36 37 38 39 40 41 42 43 44 45 |
# File 'lib/mxup/tmux.rb', line 36 def list_panes(session) fmt = '#{window_index}|#{window_name}|#{pane_index}|#{pane_pid}|' \ '#{pane_current_path}|#{pane_current_command}|#{pane_title}' `tmux list-panes -t #{esc(session)} -s -F '#{fmt}'` .strip.split("\n").map do |line| win_idx, name, pane_idx, pid, cwd, fg, title = line.split('|', 7) { window_index: win_idx.to_i, name: name, pane_index: pane_idx.to_i, pid: pid.to_i, cwd: cwd, fg_cmd: fg, title: title.to_s } end end |
.list_windows(session) ⇒ Object
28 29 30 31 32 33 34 |
# File 'lib/mxup/tmux.rb', line 28 def list_windows(session) `tmux list-windows -t #{esc(session)} -F '\#{window_index}|\#{window_name}'` .strip.split("\n").map do |line| idx, name = line.split('|', 2) { index: idx.to_i, name: name } end end |
.move_window(session, src_name, dst_index) ⇒ Object
130 131 132 |
# File 'lib/mxup/tmux.rb', line 130 def move_window(session, src_name, dst_index) system("tmux move-window -s #{esc(session)}:#{esc(src_name)} -t #{esc(session)}:#{dst_index} 2>/dev/null") end |
.new_session(name, first_window_name, root) ⇒ Object
--- mutation ----------------------------------------------------------
62 63 64 |
# File 'lib/mxup/tmux.rb', line 62 def new_session(name, first_window_name, root) run!('new-session', "tmux new-session -d -s #{esc(name)} -n #{esc(first_window_name)} -c #{esc(root)}") end |
.new_window(session, name, root) ⇒ Object
66 67 68 |
# File 'lib/mxup/tmux.rb', line 66 def new_window(session, name, root) run!('new-window', "tmux new-window -t #{esc(session)} -n #{esc(name)} -c #{esc(root)}") end |
.pane_count(session, window) ⇒ Object
47 48 49 50 |
# File 'lib/mxup/tmux.rb', line 47 def pane_count(session, window) `tmux list-panes -t #{esc(session)}:#{esc(window)} 2>/dev/null` .strip.split("\n").size end |
.pane_target(window, pane_index) ⇒ Object
Format a pane target string "window.index" for use in other tmux calls.
141 142 143 |
# File 'lib/mxup/tmux.rb', line 141 def pane_target(window, pane_index) "#{window}.#{pane_index}" end |
.rename_window(session, old_name, new_name) ⇒ Object
94 95 96 |
# File 'lib/mxup/tmux.rb', line 94 def rename_window(session, old_name, new_name) run!('rename-window', "tmux rename-window -t #{esc(session)}:#{esc(old_name)} #{esc(new_name)}") end |
.run!(action, cmd) ⇒ Object
Run a tmux command that must succeed. Captures stdout+stderr so a failure can be re-raised with tmux's own message; returns true on success. Best-effort calls (predicates, teardown, reordering) keep using system() directly and stay tolerant of failure.
153 154 155 156 157 158 |
# File 'lib/mxup/tmux.rb', line 153 def run!(action, cmd) output = `#{cmd} 2>&1`.strip return true if $?.success? raise Error, "tmux #{action} failed#{output.empty? ? '' : ": #{output}"}" end |
.select_layout(session, window, layout) ⇒ Object
77 78 79 |
# File 'lib/mxup/tmux.rb', line 77 def select_layout(session, window, layout) run!('select-layout', "tmux select-layout -t #{esc(session)}:#{esc(window)} #{esc(layout)}") end |
.send_interrupt(session, target) ⇒ Object
126 127 128 |
# File 'lib/mxup/tmux.rb', line 126 def send_interrupt(session, target) run!('send-keys', "tmux send-keys -t #{esc(session)}:#{esc(target)} C-c") end |
.send_keys(session, target, keys) ⇒ Object
122 123 124 |
# File 'lib/mxup/tmux.rb', line 122 def send_keys(session, target, keys) run!('send-keys', "tmux send-keys -t #{esc(session)}:#{esc(target)} #{esc(keys)} Enter") end |
.session_created(name) ⇒ Object
24 25 26 |
# File 'lib/mxup/tmux.rb', line 24 def session_created(name) `tmux display-message -t #{esc(name)} -p '\#{session_created}'`.strip end |
.set_environment(session, key, value) ⇒ Object
102 103 104 |
# File 'lib/mxup/tmux.rb', line 102 def set_environment(session, key, value) run!('set-environment', "tmux set-environment -t #{esc(session)} #{esc(key)} #{esc(value)}") end |
.set_pane_title(session, window, pane_index, title) ⇒ Object
98 99 100 |
# File 'lib/mxup/tmux.rb', line 98 def set_pane_title(session, window, pane_index, title) run!('select-pane', "tmux select-pane -t #{esc(session)}:#{esc(window)}.#{pane_index} -T #{esc(title)}") end |
.show_environment(session, key) ⇒ Object
Returns the value stored in the session's environment, or nil if unset (tmux prefixes unset entries with '-').
108 109 110 111 112 |
# File 'lib/mxup/tmux.rb', line 108 def show_environment(session, key) out = `tmux show-environment -t #{esc(session)} #{esc(key)} 2>/dev/null`.strip return nil if out.empty? || out.start_with?('-') out.split('=', 2).last end |
.split_window(session, window, root, target_pane: nil) ⇒ Object
70 71 72 73 74 75 |
# File 'lib/mxup/tmux.rb', line 70 def split_window(session, window, root, target_pane: nil) target = target_pane \ ? "#{esc(session)}:#{esc(window)}.#{target_pane}" \ : "#{esc(session)}:#{esc(window)}" run!('split-window', "tmux split-window -t #{target} -c #{esc(root)} -d") end |
.swap_window(session, idx_a, idx_b) ⇒ Object
134 135 136 |
# File 'lib/mxup/tmux.rb', line 134 def swap_window(session, idx_a, idx_b) system("tmux swap-window -s #{esc(session)}:#{idx_a} -t #{esc(session)}:#{idx_b}") end |