Class: Muxr::Pane
- Inherits:
-
Object
- Object
- Muxr::Pane
- Defined in:
- lib/muxr/pane.rb
Overview
A Pane bundles a Terminal emulator buffer with the PTYProcess running the shell that feeds it. The Window keeps a list of panes; the Renderer asks each pane for its current grid contents and cursor position.
Each pane has a stable 6-hex id generated at creation. The id survives promote_to_master and other array reshuffles (since it lives on the Pane, not on the index) and is persisted in the session JSON so it also survives a full cold restart. The drawer pane uses the symbol ‘:drawer` as its id; the MCP control surface treats it specially and never lists it under `panes.list`.
Constant Summary collapse
- READ_BUDGET =
Drain everything currently in the PTY’s kernel read buffer, feeding each chunk to the Terminal. Coalescing reads here means we render once per fully-formed output burst (fzf re-render, vim cursor+status redraw, etc.) instead of once per ~8 KiB chunk — the latter shows intermediate frames and is the main source of in-pane flicker. Bounded by a byte cap so a runaway producer can’t starve other panes on a single tick.
1 << 20
Instance Attribute Summary collapse
-
#foreground_command ⇒ Object
Last value written by Application’s foreground poller thread.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#process ⇒ Object
readonly
Returns the value of attribute process.
-
#rect ⇒ Object
Returns the value of attribute rect.
-
#terminal ⇒ Object
readonly
Returns the value of attribute terminal.
Instance Method Summary collapse
- #alive? ⇒ Boolean
- #close ⇒ Object
- #cwd ⇒ Object
- #drain_writes ⇒ Object
-
#initialize(id: nil, rows: 24, cols: 80, cwd: nil, command: nil, env_overrides: nil, process: nil) ⇒ Pane
constructor
A new instance of Pane.
- #io ⇒ Object
- #mark_private! ⇒ Object
- #mark_public! ⇒ Object
- #pending_write? ⇒ Boolean
- #pid ⇒ Object
-
#private? ⇒ Boolean
Private panes are invisible to the MCP control surface — their cwd is stripped from panes.list and pane.read/send_input/run/subscribe/kill all refuse.
-
#read_from_pty ⇒ Object
1 MiB.
- #resize(rows, cols) ⇒ Object
- #toggle_private! ⇒ Object
- #write(data) ⇒ Object
- #writer_io ⇒ Object
Constructor Details
#initialize(id: nil, rows: 24, cols: 80, cwd: nil, command: nil, env_overrides: nil, process: nil) ⇒ Pane
Returns a new instance of Pane.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/muxr/pane.rb', line 23 def initialize(id: nil, rows: 24, cols: 80, cwd: nil, command: nil, env_overrides: nil, process: nil) @id = id || SecureRandom.hex(3) @rows = rows @cols = cols @terminal = Terminal.new(rows: rows, cols: cols) @process = process || PTYProcess.new( rows: rows, cols: cols, cwd: cwd, command: command, env_overrides: env_overrides || {} ) @rect = nil @initial_cwd = cwd || @process.cwd @private_flag = false @foreground_command = nil end |
Instance Attribute Details
#foreground_command ⇒ Object
Last value written by Application’s foreground poller thread. nil when the shell itself is foreground (the common empty-prompt case) or when the lookup hasn’t run / couldn’t read. Renderer surfaces this in the pane title.
21 22 23 |
# File 'lib/muxr/pane.rb', line 21 def foreground_command @foreground_command end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
15 16 17 |
# File 'lib/muxr/pane.rb', line 15 def id @id end |
#process ⇒ Object (readonly)
Returns the value of attribute process.
15 16 17 |
# File 'lib/muxr/pane.rb', line 15 def process @process end |
#rect ⇒ Object
Returns the value of attribute rect.
16 17 18 |
# File 'lib/muxr/pane.rb', line 16 def rect @rect end |
#terminal ⇒ Object (readonly)
Returns the value of attribute terminal.
15 16 17 |
# File 'lib/muxr/pane.rb', line 15 def terminal @terminal end |
Instance Method Details
#alive? ⇒ Boolean
120 121 122 |
# File 'lib/muxr/pane.rb', line 120 def alive? @process.alive? end |
#close ⇒ Object
128 129 130 |
# File 'lib/muxr/pane.rb', line 128 def close @process.close end |
#cwd ⇒ Object
124 125 126 |
# File 'lib/muxr/pane.rb', line 124 def cwd @process.cwd || @initial_cwd end |
#drain_writes ⇒ Object
78 79 80 |
# File 'lib/muxr/pane.rb', line 78 def drain_writes @process.drain end |
#io ⇒ Object
66 67 68 |
# File 'lib/muxr/pane.rb', line 66 def io @process.io end |
#mark_private! ⇒ Object
54 55 56 |
# File 'lib/muxr/pane.rb', line 54 def mark_private! @private_flag = true end |
#mark_public! ⇒ Object
58 59 60 |
# File 'lib/muxr/pane.rb', line 58 def mark_public! @private_flag = false end |
#pending_write? ⇒ Boolean
74 75 76 |
# File 'lib/muxr/pane.rb', line 74 def pending_write? @process.pending_write? end |
#pid ⇒ Object
41 42 43 |
# File 'lib/muxr/pane.rb', line 41 def pid @process.pid end |
#private? ⇒ Boolean
Private panes are invisible to the MCP control surface — their cwd is stripped from panes.list and pane.read/send_input/run/subscribe/kill all refuse. Toggled by the human via Ctrl-a P or ‘:private`. Never settable from the control surface itself (so a misbehaving MCP client can’t unmark a pane it shouldn’t see).
50 51 52 |
# File 'lib/muxr/pane.rb', line 50 def private? @private_flag end |
#read_from_pty ⇒ Object
1 MiB
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/muxr/pane.rb', line 93 def read_from_pty total = 0 while total < READ_BUDGET chunk = @process.read_nonblock break unless chunk @terminal.feed(chunk) total += chunk.bytesize end # The emulator may owe the inner program a reply (DSR / CPR — see # Terminal#take_pending_replies!). Ship it back through the PTY's # input side as if it had been typed. Failure here is non-fatal: the # process can have exited between read and write. if (reply = @terminal.take_pending_replies!) begin @process.write(reply) rescue Errno::EIO, Errno::EPIPE end end total.positive? ? total : nil end |
#resize(rows, cols) ⇒ Object
114 115 116 117 118 |
# File 'lib/muxr/pane.rb', line 114 def resize(rows, cols) return if rows == @terminal.rows && cols == @terminal.cols @terminal.resize(rows, cols) @process.resize(rows, cols) end |
#toggle_private! ⇒ Object
62 63 64 |
# File 'lib/muxr/pane.rb', line 62 def toggle_private! @private_flag = !@private_flag end |
#write(data) ⇒ Object
82 83 84 |
# File 'lib/muxr/pane.rb', line 82 def write(data) @process.write(data) end |
#writer_io ⇒ Object
70 71 72 |
# File 'lib/muxr/pane.rb', line 70 def writer_io @process.writer_io end |