module CLI::UI::Frame
Constants
- DEFAULT_FRAME_COLOR
Public Class Methods
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
Example¶ ↑
CLI::UI::Frame.close('Close')
Default Output:
┗━━ Close ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Raises¶ ↑
MUST be inside an open frame or it raises a UnnestedFrameException
# File lib/cli/ui/frame.rb, line 187 def close(text, color: nil, elapsed: nil, frame_style: nil) fs_item = FrameStack.pop raise UnnestedFrameException, 'No frame nesting to unnest' unless fs_item color = CLI::UI.resolve_color(color) || fs_item.color frame_style = CLI::UI.resolve_style(frame_style) || fs_item.frame_style kwargs = {} if elapsed kwargs[:right_text] = "(#{elapsed.round(2)}s)" end CLI::UI.raw do print(prefix.chop) puts frame_style.close(text, color: color, **kwargs) end end
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
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
# File lib/cli/ui/frame.rb, line 148 def divider(text, color: nil, frame_style: nil) fs_item = FrameStack.pop raise UnnestedFrameException, 'No frame nesting to unnest' unless fs_item 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 print(prefix.chop) puts frame_style.divider(text, color: color) end FrameStack.push(fs_item) end
# File lib/cli/ui/frame.rb, line 13 def frame_style @frame_style ||= FrameStyle::Box end
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.close
when 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
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 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# File lib/cli/ui/frame.rb, line 70 def open( text, color: DEFAULT_FRAME_COLOR, failure_text: nil, success_text: nil, timing: nil, frame_style: self.frame_style ) 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 print(prefix.chop) puts frame_style.open(text, color: color) end FrameStack.push(color: color, style: frame_style) return unless block_given? closed = false begin success = false success = yield rescue closed = true t_diff = elasped(t_start, timing) close(failure_text, color: :red, elapsed: t_diff) raise else success ensure unless closed t_diff = elasped(t_start, timing) if success != false close(success_text, color: color, elapsed: t_diff) else close(failure_text, color: :red, elapsed: t_diff) end end end end
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]
# File lib/cli/ui/frame.rb, line 211 def prefix(color: Thread.current[:cliui_frame_color_override]) +''.tap do |output| items = FrameStack.items items[0..-2].each do |item| output << item.color.code << item.frame_style.prefix end if (item = items.last) final_color = color || item.color output << CLI::UI.resolve_color(final_color).code \ << item.frame_style.prefix \ << ' ' \ << CLI::UI::Color::RESET.code end end end
The width of a prefix given the number of Frames in the stack
# File lib/cli/ui/frame.rb, line 230 def prefix_width w = FrameStack.items.reduce(0) do |width, item| width + item.frame_style.prefix_width end w.zero? ? w : w + 1 end
Override a color for a given thread.
Attributes¶ ↑
-
color
- The color to override to
# File lib/cli/ui/frame.rb, line 244 def with_frame_color_override(color) prev = Thread.current[:cliui_frame_color_override] Thread.current[:cliui_frame_color_override] = color yield ensure Thread.current[:cliui_frame_color_override] = prev end
Private Class Methods
If timing is:
Numeric: return it false: return nil true or nil: defaults to Time.new Time: return the difference with start
# File lib/cli/ui/frame.rb, line 259 def elasped(start, timing) return timing if timing.is_a?(Numeric) return if timing.is_a?(FalseClass) timing = Time.new if timing.is_a?(TrueClass) || timing.nil? timing - start end