Module: CLI::UI::Frame
- Defined in:
- lib/cli/ui/frame.rb,
lib/cli/ui/frame/frame_stack.rb,
lib/cli/ui/frame/frame_style.rb,
lib/cli/ui/frame/frame_style/box.rb,
lib/cli/ui/frame/frame_style/bracket.rb
Defined Under Namespace
Modules: FrameStack, FrameStyle Classes: UnnestedFrameException
Constant Summary collapse
- DEFAULT_FRAME_COLOR =
CLI::UI.resolve_color(:cyan)
Class Method Summary collapse
-
.close(text, color: nil, elapsed: nil, frame_style: nil, to: $stdout) ⇒ Object
Closes a frame Automatically called for a block-form
open. -
.divider(text, color: nil, frame_style: nil, to: $stdout) ⇒ Object
Adds a divider in a frame Used to separate information within a single frame.
-
.frame_style ⇒ Object
: -> FrameStyle.
-
.frame_style=(frame_style) ⇒ Object
Set the default frame style.
-
.open(text, color: DEFAULT_FRAME_COLOR, failure_text: nil, success_text: nil, timing: block_given?, , frame_style: self.frame_style, to: $stdout, &block) ⇒ Object
Opens a new frame.
-
.prefix(color: Thread.current[:cliui_frame_color_override]) ⇒ Object
Determines the prefix of a frame entry taking multi-nested frames into account.
-
.prefix_width ⇒ Object
The width of a prefix given the number of Frames in the stack : -> Integer.
-
.with_frame_color_override(color, &block) ⇒ Object
Override a color for a given thread.
Class Method Details
.close(text, color: nil, elapsed: nil, frame_style: nil, to: $stdout) ⇒ Object
Closes a frame Automatically called for a block-form open
Attributes
-
text- (required) the text/title to output in the frame
Options
-
:color- The color of the frame. Defaults to nil -
:elapsed- How long did the frame take? Defaults to nil -
frame_style- The frame style to use for this frame. Defaults to nil -
:to- Target stream, like $stdout or $stderr. Can be anything with print and puts methods, or under Sorbet, IO or StringIO. Defaults to $stdout.
Example
CLI::UI::Frame.close('Close')
Default Output:
┗━━ Close ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Raises
MUST be inside an open frame or it raises a UnnestedFrameException
: (String? text, ?color: colorable?, ?elapsed: Numeric?, ?frame_style: frame_stylable?, ?to: io_like) -> void
202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/cli/ui/frame.rb', line 202 def close(text, color: nil, elapsed: nil, frame_style: nil, to: $stdout) fs_item = FrameStack.pop raise UnnestedFrameException, 'No frame nesting to unnest' unless fs_item close_color = CLI::UI.resolve_color(color || fs_item.color) frame_style = CLI::UI.resolve_style(frame_style || fs_item.frame_style) elapsed_string = elapsed ? "(#{elapsed.round(2)}s)" : nil CLI::UI.raw do to.print(prefix.chop) to.puts(frame_style.close(text.to_s, color: close_color, right_text: elapsed_string)) end end |
.divider(text, color: nil, frame_style: nil, to: $stdout) ⇒ Object
Adds a divider in a frame Used to separate information within a single frame
Attributes
-
text- (required) the text/title to output in the frame
Options
-
:color- The color of the frame. Defaults toDEFAULT_FRAME_COLOR -
frame_style- The frame style to use for this frame -
:to- Target stream, like $stdout or $stderr. Can be anything with print and puts methods, or under Sorbet, IO or StringIO. Defaults to $stdout.
Example
CLI::UI::Frame.open('Open') { CLI::UI::Frame.divider('Divider') }
Default Output:
┏━━ Open ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┣━━ Divider ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Raises
MUST be inside an open frame or it raises a UnnestedFrameException
: (String? text, ?color: colorable?, ?frame_style: frame_stylable?, ?to: io_like) -> void
160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/cli/ui/frame.rb', line 160 def divider(text, color: nil, frame_style: nil, to: $stdout) fs_item = FrameStack.pop raise UnnestedFrameException, 'No frame nesting to unnest' unless fs_item divider_color = CLI::UI.resolve_color(color || fs_item.color) frame_style = CLI::UI.resolve_style(frame_style || fs_item.frame_style) CLI::UI.raw do to.print(prefix.chop) to.puts(frame_style.divider(text.to_s, color: divider_color)) end FrameStack.push(fs_item) end |
.frame_style ⇒ Object
: -> FrameStyle
15 16 17 |
# File 'lib/cli/ui/frame.rb', line 15 def frame_style @frame_style ||= FrameStyle::Box end |
.frame_style=(frame_style) ⇒ Object
Set the default frame style.
Raises ArgumentError if frame_style is not valid
Attributes
-
symbolorFrameStyle- the default frame style to use for frames
: (frame_stylable frame_style) -> void
28 29 30 |
# File 'lib/cli/ui/frame.rb', line 28 def frame_style=(frame_style) @frame_style = CLI::UI.resolve_style(frame_style) end |
.open(text, color: DEFAULT_FRAME_COLOR, failure_text: nil, success_text: nil, timing: block_given?, , frame_style: self.frame_style, to: $stdout, &block) ⇒ Object
Opens a new frame. Can be nested Can be invoked in two ways: block and blockless
-
In block form, the frame is closed automatically when the block returns
-
In blockless form, caller MUST call
Frame.closewhen the frame is logically done -
Blockless form is strongly discouraged in cases where block form can be made to work

The return value of the block determines if the block is a “success” or a “failure”
Attributes
-
text- (required) the text/title to output in the frame
Options
-
:color- The color of the frame. Defaults toDEFAULT_FRAME_COLOR -
:failure_text- If the block failed, what do we output? Defaults to nil -
:success_text- If the block succeeds, what do we output? Defaults to nil -
:timing- How long did the frame content take? Invalid for blockless. Defaults to true for the block form -
frame_style- The frame style to use for this frame -
:to- Target stream, like $stdout or $stderr. Can be anything with print and puts methods, or under Sorbet, IO or StringIO. Defaults to $stdout.
Example
Block Form (Assumes CLI::UI::StdoutRouter.enable has been called)
CLI::UI::Frame.open('Open') { puts 'hi' }
Default Output:
┏━━ Open ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┃ hi
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ (0.0s) ━━
Blockless Form
CLI::UI::Frame.open('Open')
Default Output:
┏━━ Open ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
: [T] (String text, ?color: colorable, ?failure_text: String?, ?success_text: String?, ?timing: (Numeric | bool), ?frame_style: frame_stylable, ?to: io_like) ?{ -> T } -> T?
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/cli/ui/frame.rb', line 76 def open( text, color: DEFAULT_FRAME_COLOR, failure_text: nil, success_text: nil, timing: block_given?, frame_style: self.frame_style, to: $stdout, &block ) frame_style = CLI::UI.resolve_style(frame_style) color = CLI::UI.resolve_color(color) unless block_given? if failure_text raise ArgumentError, 'failure_text is not compatible with blockless invocation' elsif success_text raise ArgumentError, 'success_text is not compatible with blockless invocation' elsif timing raise ArgumentError, 'timing is not compatible with blockless invocation' end end t_start = Time.now CLI::UI.raw do to.print(prefix.chop) to.puts(frame_style.start(text, color: color)) end FrameStack.push(color: color, style: frame_style) return unless block_given? closed = false begin success = false #: untyped success = yield rescue closed = true t_diff = elapsed(t_start, timing) close(failure_text, color: :red, elapsed: t_diff, to: to) raise else success ensure unless closed t_diff = elapsed(t_start, timing) success_bool = success #: as untyped if success_bool != false close(success_text, color: color, elapsed: t_diff, to: to) else close(failure_text, color: :red, elapsed: t_diff, to: to) end end end end |
.prefix(color: Thread.current[:cliui_frame_color_override]) ⇒ Object
Determines the prefix of a frame entry taking multi-nested frames into account
Options
-
:color- The color of the prefix. Defaults toThread.current[:cliui_frame_color_override]
: (?color: colorable?) -> String
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/cli/ui/frame.rb', line 223 def prefix(color: Thread.current[:cliui_frame_color_override]) (+'').tap do |output| items = FrameStack.items items[0..-2].to_a.each do |item| output << item.color.code if CLI::UI.enable_color? output << item.frame_style.prefix output << CLI::UI::Color::RESET.code if CLI::UI.enable_color? end if (item = items.last) final_color = color || item.color output << CLI::UI.resolve_color(final_color).code if CLI::UI.enable_color? output << item.frame_style.prefix output << CLI::UI::Color::RESET.code if CLI::UI.enable_color? output << ' ' end end end |
.prefix_width ⇒ Object
The width of a prefix given the number of Frames in the stack : -> Integer
245 246 247 248 249 250 251 |
# File 'lib/cli/ui/frame.rb', line 245 def prefix_width w = FrameStack.items.reduce(0) do |width, item| width + item.frame_style.prefix_width end w.zero? ? w : w + 1 end |
.with_frame_color_override(color, &block) ⇒ Object
Override a color for a given thread.
Attributes
-
color- The color to override to
: [T] (colorable color) { -> T } -> T
260 261 262 263 264 265 266 |
# File 'lib/cli/ui/frame.rb', line 260 def with_frame_color_override(color, &block) prev = Thread.current[:cliui_frame_color_override] Thread.current[:cliui_frame_color_override] = color yield ensure Thread.current[:cliui_frame_color_override] = prev end |