Module: Chamomile::Commands

Included in:
Application
Defined in:
lib/chamomile/commands.rb

Overview

Helper methods for creating command lambdas (quit, batch, tick, etc.).

Class Method Summary collapse

Class Method Details

.batch(*cmds) ⇒ Object



77
78
79
80
81
82
# File 'lib/chamomile/commands.rb', line 77

def batch(*cmds)
  valid = cmds.flatten.compact
  return nil if valid.empty?

  -> { valid }
end

.cancel(token) ⇒ Object

Returns a command that cancels a running token.



145
146
147
# File 'lib/chamomile/commands.rb', line 145

def cancel(token)
  -> { CancelCommand.new(token: token) }
end

.cancellable(&block) ⇒ Object

Creates a cancel token and returns [token, command_wrapper]. The block receives the token for cooperative cancellation checking.



134
135
136
137
138
139
140
141
142
# File 'lib/chamomile/commands.rb', line 134

def cancellable(&block)
  token = CancelToken.new
  wrapped = -> {
    return nil if token.cancelled?

    block.call(token)
  }
  [token, wrapped]
end

.clear_screenObject



250
251
252
# File 'lib/chamomile/commands.rb', line 250

def clear_screen
  -> { ClearScreenMsg.new }
end

.cmd(callable) ⇒ Object



113
114
115
# File 'lib/chamomile/commands.rb', line 113

def cmd(callable)
  -> { callable.call }
end

.cursor_position(row, col) ⇒ Object



188
189
190
# File 'lib/chamomile/commands.rb', line 188

def cursor_position(row, col)
  -> { CursorPositionCommand.new(row: row, col: col) }
end

.cursor_shape(shape) ⇒ Object



192
193
194
# File 'lib/chamomile/commands.rb', line 192

def cursor_shape(shape)
  -> { CursorShapeCommand.new(shape: shape) }
end

.deliver(msg) ⇒ Object

Posts a message directly to the event queue — no thread, no async.



118
119
120
# File 'lib/chamomile/commands.rb', line 118

def deliver(msg)
  -> { msg }
end

.disable_bracketed_pasteObject



238
239
240
# File 'lib/chamomile/commands.rb', line 238

def disable_bracketed_paste
  -> { DisableBracketedPasteMsg.new }
end

.disable_mouseObject



230
231
232
# File 'lib/chamomile/commands.rb', line 230

def disable_mouse
  -> { DisableMouseMsg.new }
end

.disable_report_focusObject



246
247
248
# File 'lib/chamomile/commands.rb', line 246

def disable_report_focus
  -> { DisableReportFocusMsg.new }
end

.enable_bracketed_pasteObject



234
235
236
# File 'lib/chamomile/commands.rb', line 234

def enable_bracketed_paste
  -> { EnableBracketedPasteMsg.new }
end

.enable_mouse_all_motionObject



226
227
228
# File 'lib/chamomile/commands.rb', line 226

def enable_mouse_all_motion
  -> { EnableMouseAllMotionMsg.new }
end

.enable_mouse_cell_motionObject



222
223
224
# File 'lib/chamomile/commands.rb', line 222

def enable_mouse_cell_motion
  -> { EnableMouseCellMotionMsg.new }
end

.enable_report_focusObject



242
243
244
# File 'lib/chamomile/commands.rb', line 242

def enable_report_focus
  -> { EnableReportFocusMsg.new }
end

.enter_alt_screenObject

Runtime mode toggles — return these as commands from update



214
215
216
# File 'lib/chamomile/commands.rb', line 214

def enter_alt_screen
  -> { EnterAltScreenMsg.new }
end

.every(duration, &block) ⇒ Object



104
105
106
107
108
109
110
111
# File 'lib/chamomile/commands.rb', line 104

def every(duration, &block)
  -> {
    now = Time.now
    next_tick = (now + duration) - (now.to_f % duration)
    sleep(next_tick - Time.now)
    block ? block.call : TickEvent.new(time: Time.now)
  }
end

.exec(command, *args, &callback) ⇒ Object



204
205
206
# File 'lib/chamomile/commands.rb', line 204

def exec(command, *args, &callback)
  -> { ExecCommand.new(command: command, args: args, callback: callback) }
end

.exit_alt_screenObject



218
219
220
# File 'lib/chamomile/commands.rb', line 218

def exit_alt_screen
  -> { ExitAltScreenMsg.new }
end

.hide_cursorObject



200
201
202
# File 'lib/chamomile/commands.rb', line 200

def hide_cursor
  -> { CursorVisibilityCommand.new(visible: false) }
end

.map(cmd, &transform) ⇒ Object

Transforms a command's result before it reaches update.



123
124
125
126
127
128
129
130
# File 'lib/chamomile/commands.rb', line 123

def map(cmd, &transform)
  return nil if cmd.nil?

  -> {
    result = cmd.call
    result ? transform.call(result) : nil
  }
end

.noneObject



73
74
75
# File 'lib/chamomile/commands.rb', line 73

def none
  nil
end

.parallelObject

Run commands concurrently (Ruby-idiomatic alias for batch)



92
93
94
95
96
97
# File 'lib/chamomile/commands.rb', line 92

def batch(*cmds)
  valid = cmds.flatten.compact
  return nil if valid.empty?

  -> { valid }
end

.println(text) ⇒ Object

Print a line above the rendered TUI area



209
210
211
# File 'lib/chamomile/commands.rb', line 209

def println(text)
  -> { PrintlnCommand.new(text: text) }
end

.quitObject



69
70
71
# File 'lib/chamomile/commands.rb', line 69

def quit
  -> { QuitEvent.new }
end

.request_window_sizeObject



254
255
256
# File 'lib/chamomile/commands.rb', line 254

def request_window_size
  -> { RequestWindowSizeMsg.new }
end

.sequence(*cmds) ⇒ Object



84
85
86
87
88
89
# File 'lib/chamomile/commands.rb', line 84

def sequence(*cmds)
  valid = cmds.flatten.compact
  return nil if valid.empty?

  -> { [:sequence, *valid] }
end

.serialObject

Run commands in order (Ruby-idiomatic alias for sequence)



95
96
97
98
99
100
# File 'lib/chamomile/commands.rb', line 95

def sequence(*cmds)
  valid = cmds.flatten.compact
  return nil if valid.empty?

  -> { [:sequence, *valid] }
end

.shell(command, envelope:, dir: Dir.pwd, env: {}) ⇒ Object

Run a shell command and return a ShellResult message with the given envelope name.



163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/chamomile/commands.rb', line 163

def shell(command, envelope:, dir: Dir.pwd, env: {})
  -> {
    stdout, stderr, status = Open3.capture3(env, command, chdir: dir)
    ShellResult.new(
      envelope: envelope,
      stdout: stdout.force_encoding("UTF-8"),
      stderr: stderr.force_encoding("UTF-8"),
      status: status.exitstatus,
      success: status.success?
    )
  }
end

.show_cursorObject



196
197
198
# File 'lib/chamomile/commands.rb', line 196

def show_cursor
  -> { CursorVisibilityCommand.new(visible: true) }
end

.stream(&block) ⇒ Object

A streaming command that emits multiple messages over time. The block receives a push callable and a token for cancellation. Returns [cancel_token, command].



152
153
154
155
156
157
158
159
160
# File 'lib/chamomile/commands.rb', line 152

def stream(&block)
  token = CancelToken.new
  cmd = -> {
    return nil if token.cancelled?

    StreamCommand.new(token: token, producer: block)
  }
  [token, cmd]
end

.tick(duration, &block) ⇒ Object



97
98
99
100
101
102
# File 'lib/chamomile/commands.rb', line 97

def tick(duration, &block)
  -> {
    sleep(duration)
    block ? block.call : TickEvent.new(time: Time.now)
  }
end

.timer(duration, envelope:) ⇒ Object

Fire a timer message with a typed envelope.



177
178
179
180
181
182
# File 'lib/chamomile/commands.rb', line 177

def timer(duration, envelope:)
  -> {
    sleep(duration)
    TimerTick.new(envelope: envelope, time: Time.now)
  }
end

.window_title(title) ⇒ Object



184
185
186
# File 'lib/chamomile/commands.rb', line 184

def window_title(title)
  -> { WindowTitleCommand.new(title: title) }
end