class Riffer::Rig::Terminal::Repl
Public Class Methods
(console: Riffer::Rig::Terminal::Console, frame: Riffer::Rig::Terminal::Frame, keys: Thread::Queue[Riffer::Rig::Terminal::Key], asks: Thread::Queue[Riffer::Rig::Terminal::Key], prompter: Riffer::Rig::Terminal::FramePrompter, peek: Riffer::Rig::Terminal::Peek, interrupt: ^() → void, builtins: Array[Riffer::Rig::Terminal::Autocomplete::_Entry]) → void
Source
# File lib/riffer/rig/terminal/repl.rb, line 33 def initialize(console:, frame:, keys:, asks:, prompter:, peek:, interrupt:, builtins:) @console = console @frame = frame @keys = keys @asks = asks @prompter = prompter @peek = peek @interrupt = interrupt @builtins = builtins @reader = nil @runtime = nil @completion = Riffer::Rig::Terminal::Autocomplete.new(commands: []) @queue = Riffer::Rig::Terminal::MessageQueue.new @asking = false @armed = false @woken = false @busy = false @closed = false @mutex = Mutex.new @arrival = ConditionVariable.new end
@rbs console: Riffer::Rig::Terminal::Console @rbs frame: Riffer::Rig::Terminal::Frame @rbs keys: Thread::Queue @rbs asks: Thread::Queue @rbs prompter: Riffer::Rig::Terminal::FramePrompter @rbs peek: Riffer::Rig::Terminal::Peek @rbs interrupt: ^() -> void @rbs builtins: Array @rbs return: void
Public Instance Methods
() → bool
Source
# File lib/riffer/rig/terminal/repl.rb, line 128 def arm @mutex.synchronize do return false if @armed @armed = true @frame.status(Riffer::Rig::Terminal::EXIT_HINT) true end end
Records a Ctrl-C for the idle prompt: the first one arms the exit hint, a second one while armed ends the session. @rbs return: bool
(String? question, options: Array[String]?, secret: bool) → String?
Source
# File lib/riffer/rig/terminal/repl.rb, line 90 def ask(question, options:, secret:) @mutex.synchronize do @asking = true @frame.input(Riffer::Rig::Terminal::LineEditor.new) end @prompter.ask(question, options: options, secret: secret) rescue Interrupt # A Ctrl-C leaves the question unanswered and is then sent on as the # signal, which lands where one at the input line would: on the trap of # a running turn, which cancels it, or, for whatever asked outside one, # as an Interrupt raised right here. @interrupt.call nil ensure @mutex.synchronize do @asking = false # A key typed behind the answer reached the ask before it returned. Array.new(@asks.size) { @asks.pop }.compact.each { |key| press(key) } @frame.complete(@completion) end end
@rbs question: String? @rbs options: Array? @rbs secret: bool @rbs return: String?
(Array[Riffer::Rig::Terminal::Replay::_Recorded] recorded, theme: Riffer::Rig::Terminal::Theme) → void
Source
# File lib/riffer/rig/terminal/repl.rb, line 81 def replay(recorded, theme:) width = @frame.measure&.last @console.print(Riffer::Rig::Terminal::Replay.call(recorded, theme: theme, width: width)) end
@rbs recorded: Array @rbs theme: Riffer::Rig::Terminal::Theme @rbs return: void
() { (String | :job_exit) → void } → void
Source
# File lib/riffer/rig/terminal/repl.rb, line 114 def run while (entry = take) yield entry end rescue Interrupt # The turn's own trap covers the turn, but a Ctrl-C can still be delivered # in the glue around it (the report, the echo, the dispatch); there it acts # as one at the idle prompt. retry if arm end
@rbs &block: (String | :job_exit) -> void @rbs return: void
() → void
Source
# File lib/riffer/rig/terminal/repl.rb, line 56 def start @console.start # Turns and asks stay on the calling thread, where the Interrupt of a # Ctrl-C is raised, so the keys are read on one of their own. @reader = Thread.new { read } end
@rbs return: void
() → void
Source
# File lib/riffer/rig/terminal/repl.rb, line 64 def stop @reader&.kill @reader&.join @console.stop end
@rbs return: void
(Riffer::Rig::Runtime runtime) → void
Source
# File lib/riffer/rig/terminal/repl.rb, line 72 def watch(runtime) @mutex.synchronize { @runtime = runtime } @frame.session(tally: -> { runtime.tally }, reasoning: -> { runtime.reasoning }) runtime.on_job_exit { wake } end
@rbs runtime: Riffer::Rig::Runtime @rbs return: void