Module: RatatuiRuby::OutputGuard
- Included in:
- RatatuiRuby
- Defined in:
- lib/ratatui_ruby/output_guard.rb
Overview
Output protection for TUI sessions and batch/CLI mode.
This module provides mechanisms to prevent accidental output to stdout/stderr during TUI sessions and to support headless (batch/CLI) mode for applications that can run with or without a TUI.
Defined Under Namespace
Classes: NullIO
Instance Method Summary collapse
-
#guard_io ⇒ Object
Guards a block from stdout/stderr output.
-
#headless! ⇒ Object
Enables headless (batch/CLI) mode.
-
#is_headless? ⇒ Boolean
Whether headless (batch/pipeline/CLI) mode is enabled.
Instance Method Details
#guard_io ⇒ Object
Guards a block from stdout/stderr output.
During a TUI session, writes to $stdout or $stderr corrupt the display. Wrap code that might produce output (e.g., chatty gems) in this block.
This temporarily replaces $stdout and $stderr with a NullIO object that discards all output. The original streams are restored when the block exits, even if an exception occurs.
Behavior by mode
-
**TUI session active**: Output is swallowed (guarded)
-
**Headless mode**: Silent no-op (output flows normally)
-
Neither: Warns and yields (catches potential mistakes)
Example
– SPDX-SnippetBegin SPDX-FileCopyrightText: 2026 Kerrick Long SPDX-License-Identifier: MIT-0 ++
RatatuiRuby.run do |tui|
RatatuiRuby.guard_io do
SomeChattyGem.do_something # Any puts/warn calls are swallowed
end
end
– SPDX-SnippetEnd ++
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/ratatui_ruby/output_guard.rb', line 150 def guard_io # TUI active: guard the output if terminal_active? $stdout = NullIO.new $stderr = NullIO.new begin return yield ensure $stdout = Object::STDOUT $stderr = Object::STDERR end end # Headless mode: silent no-op return yield if is_headless? # Neither: warn about potential mistake warn "guard_io called outside TUI session. If this is intentional (batch/CLI mode), call RatatuiRuby.headless! at startup to silence this warning." yield end |
#headless! ⇒ Object
Enables headless (batch/CLI) mode.
Call this at app startup when running in batch/CLI mode (e.g., --no-tui). This tells RatatuiRuby that you intentionally don’t want a TUI session.
When headless mode is active:
-
#guard_io becomes a silent no-op (output flows normally)
-
TerminalLifecycle#init_terminal and TerminalLifecycle#run raise Error::Invariant
Headless mode and TUI sessions are mutually exclusive. Calling this while a TUI session is active raises Error::Invariant.
Why there is no exit_headless!
Headless mode is a startup-time decision for the entire app run. If you need to temporarily exit TUI mode for user interaction (like lazygit does when editing a commit message), use TerminalLifecycle#restore_terminal and TerminalLifecycle#init_terminal instead:
– SPDX-SnippetBegin SPDX-FileCopyrightText: 2026 Kerrick Long SPDX-License-Identifier: MIT-0 ++
RatatuiRuby.restore_terminal
puts "Press enter to continue..."
gets
RatatuiRuby.init_terminal
– SPDX-SnippetEnd ++
Example
– SPDX-SnippetBegin SPDX-FileCopyrightText: 2026 Kerrick Long SPDX-License-Identifier: MIT-0 ++
if ARGV.include?("--no-tui")
RatatuiRuby.headless!
process_batch_work # guard_io calls are silent no-ops
else
RatatuiRuby.run do |tui| # This branch only runs in TUI mode
# ... TUI code ...
end
end
– SPDX-SnippetEnd ++ Note: Calling TerminalLifecycle#run or TerminalLifecycle#init_terminal after #headless! raises Error::Invariant. The block is never executed.
110 111 112 113 114 115 |
# File 'lib/ratatui_ruby/output_guard.rb', line 110 def headless! if @tui_session_active raise Error::Invariant, "Cannot enable headless mode: TUI session already active" end @headless_mode = true end |
#is_headless? ⇒ Boolean
Whether headless (batch/pipeline/CLI) mode is enabled.
When headless mode is active:
-
#guard_io becomes a silent no-op (output is not swallowed)
-
TerminalLifecycle#init_terminal and TerminalLifecycle#run raise Error::Invariant
Use this when your app has a --no-tui or --batch flag and you want the same code to work in both TUI and non-TUI modes.
48 49 50 |
# File 'lib/ratatui_ruby/output_guard.rb', line 48 def is_headless? @headless_mode end |