CLI UI
CLI UI is a small framework for generating nice command-line user interfaces
Installation
“sh gem install cli-ui
“
or add the following to your Gemfile:
“by gem ‘cli-ui’
“
In your code, simply add a require 'cli/ui'
. Most options assume CLI::UI::StdoutRouter.enable
has been called.
Features
This may not be an exhaustive list. Please check our documentation for more information.
Nested framing
To handle content flow (see example below)
“by CLI::UI::StdoutRouter.enable CLI::UI::Frame.open(‘Frame 1’) do CLI::UI::Frame.open(‘Frame 2’) { puts “inside frame 2” } puts “inside frame 1” end
“
Interactive Prompts
Prompt user with options and ask them to choose. Can answer using arrow keys, vim bindings (j
/k
), or numbers (or y/n for yes/no questions).
For large numbers of options, using e
, :
, or G
will toggle “line select” mode which allows numbers greater than 9 to be typed and f
or /
will allow the user to filter options using a free-form text input.
“by CLI::UI.ask(‘What language/framework do you use?’, options: %w(rails go ruby python))
“
Can also assign callbacks to each option
“by CLI::UI::Prompt.ask(‘What language/framework do you use?’) do |handler| handler.option(‘rails’) { |selection| selection } handler.option(‘go’) { |selection| selection } handler.option(‘ruby’) { |selection| selection } handler.option(‘python’) { |selection| selection } end
“
- Note that the two examples provided above are identical in functionality
Free form text prompts
“by CLI::UI.ask(‘Is CLI UI Awesome?’, default: ‘It is great!’)
“
Spinner groups
Handle many multi-threaded processes while suppressing output unless there is an issue. Can update title to show state.
“by CLI::UI::SpinGroup.new do |spin_group| spin_group.add(‘Title’) { |spinner| sleep 3.0 } spin_group.add(‘Title 2’) { |spinner| sleep 3.0; spinner.update_title(‘New Title’); sleep 3.0 } end
“
Text Color formatting
e.g. {{red:Red}} {{green:Green}}
“by puts CLI::UI.fmt “{red:Red} {green:Green}”
“
Symbol/Glyph Formatting
e.g. {{*}}
=> a yellow ⭑
“by puts CLI::UI.fmt “{<em>} {v} {?} {x}“
“
Status Widget
“by CLI::UI::Spinner.spin(“building packages: {@widget/status:1:2:3:4}”) do |spinner| # spinner.update_title(…) sleep(3) end
“
Progress Bar
Show progress of a process or operation.
“by CLI::UI::Progress.progress do |bar| 100.times do bar.tick end end
“
Frame Styles
Modify the appearance of CLI::UI both globally and on an individual frame level.
To set the default style:
“by CLI::UI.frame_style = :box
“
To style an individual frame:
“by CLI::UI.frame(‘New Style!’, frame_style: :bracket) { puts ‘It’s pretty cool!’ }
“
The default style - :box
- is what has been used up until now. The other style - :bracket
- looks like this:
“by CLI::UI.frame_style = :bracket CLI::UI::StdoutRouter.enable CLI::UI::Frame.open(‘Frame 1’) do CLI::UI::Frame.open(‘Frame 2’) { puts “inside frame 2” } puts “inside frame 1” end
“
Example Usage
The following code makes use of nested-framing, multi-threaded spinners, formatted text, and more.
“by require ‘cli/ui’
CLI::UI::StdoutRouter.enable
CLI::UI::Frame.open(‘{<em>} {bold:a}‘, color: :green) do CLI::UI::Frame.open(’{i} b’, color: :magenta) do CLI::UI::Frame.open(‘{?} c’, color: :cyan) do CLI::UI::SpinGroup.new do |sg| sg.add(‘wow’) do |spinner| sleep(2.5) spinner.update_title(‘second round!’) sleep (1.0) end sg.add(‘such spin’) { sleep(1.6) } sg.add(‘many glyph’) { sleep(2.0) } end end end CLI::UI::Frame.divider(‘{v} lol’) puts CLI::UI.fmt ‘{info:words} no!} {green:success!}’ CLI::UI::SpinGroup.new do |sg| sg.add(‘more spins’) { sleep(0.5) ; raise ‘oh no’ } end end
“
Output:
Development
- Run tests using
bundle exec rake test
. All code should be tested. - No code, outside of development and tests needs, should use dependencies. This is a self contained library
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/cli-ui.
License
The code is available as open source under the terms of the MIT License.