cli-ui 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -2
- data/.travis.yml +1 -1
- data/Gemfile +3 -2
- data/Gemfile.lock +22 -18
- data/Rakefile +1 -1
- data/bin/console +3 -3
- data/cli-ui.gemspec +11 -11
- data/lib/cli/ui.rb +19 -14
- data/lib/cli/ui/ansi.rb +7 -9
- data/lib/cli/ui/frame.rb +5 -5
- data/lib/cli/ui/frame/frame_stack.rb +2 -2
- data/lib/cli/ui/frame/frame_style.rb +1 -1
- data/lib/cli/ui/glyph.rb +1 -0
- data/lib/cli/ui/os.rb +8 -4
- data/lib/cli/ui/printer.rb +15 -3
- data/lib/cli/ui/prompt.rb +21 -6
- data/lib/cli/ui/prompt/interactive_options.rb +11 -18
- data/lib/cli/ui/spinner/spin_group.rb +2 -2
- data/lib/cli/ui/stdout_router.rb +1 -1
- data/lib/cli/ui/truncater.rb +1 -1
- data/lib/cli/ui/version.rb +1 -1
- data/lib/cli/ui/wrap.rb +56 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8de8c1fd6c855f812125e71e85dbfc12163dfd504215fab462d56ad5f4d2cc7e
|
4
|
+
data.tar.gz: 404f164084fd9cf85aa382a5d5f93b77b08ea4bc529840ebfe230e1b5ea7c620
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f737c534e372589165a3263854d3a90f024181f632f6ae918fcb7aafea69abad27f50246d35c2957c238447a74871f4705add26d1bf272ad58f4fcc52d31ae6
|
7
|
+
data.tar.gz: 56c449900c817637b97d0e99b05ac01375bbde1458db3f2d5e7122027cdd525e0b8aaf9b9d5290cc2f1fa8cae314efb1365ac46ab277629f5cebf5d113e39b0d
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
-
|
1
|
+
inherit_gem:
|
2
|
+
rubocop-shopify: rubocop-cli.yml
|
3
3
|
|
4
4
|
AllCops:
|
5
5
|
Exclude:
|
@@ -36,3 +36,6 @@ Style/MultilineBlockChain:
|
|
36
36
|
# we prefer rescue to align with the beginning of the line containing begin, not begin itself
|
37
37
|
Layout/RescueEnsureAlignment:
|
38
38
|
Enabled: false
|
39
|
+
|
40
|
+
Style/StringLiterals:
|
41
|
+
EnforcedStyle: single_quotes
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# NOTE: These are development-only dependencies
|
2
|
-
source
|
2
|
+
source 'https://rubygems.org'
|
3
3
|
|
4
4
|
gemspec
|
5
5
|
|
6
6
|
group :development, :test do
|
7
7
|
gem 'rubocop'
|
8
|
-
gem '
|
8
|
+
gem 'rubocop-shopify'
|
9
|
+
gem 'byebug', platforms: [:mri]
|
9
10
|
gem 'method_source'
|
10
11
|
end
|
11
12
|
|
data/Gemfile.lock
CHANGED
@@ -1,45 +1,48 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cli-ui (1.
|
4
|
+
cli-ui (1.5.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
ansi (1.5.0)
|
10
|
-
ast (2.4.
|
10
|
+
ast (2.4.2)
|
11
11
|
builder (3.2.4)
|
12
12
|
byebug (11.1.3)
|
13
13
|
method_source (1.0.0)
|
14
|
-
minitest (5.14.
|
15
|
-
minitest-reporters (1.4.
|
14
|
+
minitest (5.14.4)
|
15
|
+
minitest-reporters (1.4.3)
|
16
16
|
ansi
|
17
17
|
builder
|
18
18
|
minitest (>= 5.0)
|
19
19
|
ruby-progressbar
|
20
|
-
mocha (1.
|
21
|
-
parallel (1.
|
22
|
-
parser (
|
20
|
+
mocha (1.12.0)
|
21
|
+
parallel (1.20.1)
|
22
|
+
parser (3.0.0.0)
|
23
23
|
ast (~> 2.4.1)
|
24
24
|
rainbow (3.0.0)
|
25
|
-
rake (13.0.
|
26
|
-
regexp_parser (1.
|
27
|
-
rexml (3.2.
|
28
|
-
rubocop (1.1
|
25
|
+
rake (13.0.3)
|
26
|
+
regexp_parser (2.1.1)
|
27
|
+
rexml (3.2.5)
|
28
|
+
rubocop (1.12.1)
|
29
29
|
parallel (~> 1.10)
|
30
|
-
parser (>=
|
30
|
+
parser (>= 3.0.0.0)
|
31
31
|
rainbow (>= 2.2.2, < 4.0)
|
32
|
-
regexp_parser (>= 1.8)
|
32
|
+
regexp_parser (>= 1.8, < 3.0)
|
33
33
|
rexml
|
34
|
-
rubocop-ast (>= 1.0.
|
34
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
35
35
|
ruby-progressbar (~> 1.7)
|
36
|
-
unicode-display_width (>= 1.4.0, <
|
37
|
-
rubocop-ast (1.1
|
36
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
37
|
+
rubocop-ast (1.4.1)
|
38
38
|
parser (>= 2.7.1.5)
|
39
|
-
|
40
|
-
|
39
|
+
rubocop-shopify (2.0.1)
|
40
|
+
rubocop (~> 1.11)
|
41
|
+
ruby-progressbar (1.11.0)
|
42
|
+
unicode-display_width (2.0.0)
|
41
43
|
|
42
44
|
PLATFORMS
|
45
|
+
java
|
43
46
|
ruby
|
44
47
|
|
45
48
|
DEPENDENCIES
|
@@ -51,6 +54,7 @@ DEPENDENCIES
|
|
51
54
|
mocha
|
52
55
|
rake (~> 13.0)
|
53
56
|
rubocop
|
57
|
+
rubocop-shopify
|
54
58
|
|
55
59
|
BUNDLED WITH
|
56
60
|
2.1.0
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'cli/ui'
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +10,5 @@ require "cli/ui"
|
|
10
10
|
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require
|
13
|
+
require 'irb'
|
14
14
|
IRB.start(__FILE__)
|
data/cli-ui.gemspec
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require 'cli/ui/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'cli-ui'
|
8
8
|
spec.version = CLI::UI::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['Burke Libbey', 'Julian Nadeau', 'Lisa Ugray']
|
10
|
+
spec.email = ['burke.libbey@shopify.com', 'julian.nadeau@shopify.com', 'lisa.ugray@shopify.com']
|
11
11
|
|
12
12
|
spec.summary = 'Terminal UI framework'
|
13
13
|
spec.description = 'Terminal UI framework'
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
14
|
+
spec.homepage = 'https://github.com/shopify/cli-ui'
|
15
|
+
spec.license = 'MIT'
|
16
16
|
|
17
17
|
spec.files = %x(git ls-files -z).split("\x0").reject do |f|
|
18
18
|
f.match(%r{^(test|spec|features)/})
|
19
19
|
end
|
20
|
-
spec.bindir =
|
20
|
+
spec.bindir = 'exe'
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
-
spec.require_paths = [
|
22
|
+
spec.require_paths = ['lib']
|
23
23
|
|
24
24
|
# spec.add_development_dependency "bundler", "~> 2.0"
|
25
|
-
spec.add_development_dependency(
|
26
|
-
spec.add_development_dependency(
|
25
|
+
spec.add_development_dependency('rake', '~> 13.0')
|
26
|
+
spec.add_development_dependency('minitest', '~> 5.0')
|
27
27
|
end
|
data/lib/cli/ui.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
module CLI
|
2
2
|
module UI
|
3
|
-
autoload :ANSI,
|
4
|
-
autoload :Glyph,
|
5
|
-
autoload :Color,
|
6
|
-
autoload :Frame,
|
7
|
-
autoload :OS,
|
8
|
-
autoload :Printer,
|
9
|
-
autoload :Progress,
|
10
|
-
autoload :Prompt,
|
11
|
-
autoload :Terminal,
|
12
|
-
autoload :Truncater,
|
13
|
-
autoload :Formatter,
|
14
|
-
autoload :Spinner,
|
15
|
-
autoload :Widgets,
|
3
|
+
autoload :ANSI, 'cli/ui/ansi'
|
4
|
+
autoload :Glyph, 'cli/ui/glyph'
|
5
|
+
autoload :Color, 'cli/ui/color'
|
6
|
+
autoload :Frame, 'cli/ui/frame'
|
7
|
+
autoload :OS, 'cli/ui/os'
|
8
|
+
autoload :Printer, 'cli/ui/printer'
|
9
|
+
autoload :Progress, 'cli/ui/progress'
|
10
|
+
autoload :Prompt, 'cli/ui/prompt'
|
11
|
+
autoload :Terminal, 'cli/ui/terminal'
|
12
|
+
autoload :Truncater, 'cli/ui/truncater'
|
13
|
+
autoload :Formatter, 'cli/ui/formatter'
|
14
|
+
autoload :Spinner, 'cli/ui/spinner'
|
15
|
+
autoload :Widgets, 'cli/ui/widgets'
|
16
|
+
autoload :Wrap, 'cli/ui/wrap'
|
16
17
|
|
17
18
|
# Convenience accessor to +CLI::UI::Spinner::SpinGroup+
|
18
19
|
SpinGroup = Spinner::SpinGroup
|
@@ -113,6 +114,10 @@ module CLI
|
|
113
114
|
CLI::UI::Formatter.new(input).format(enable_color: enable_color)
|
114
115
|
end
|
115
116
|
|
117
|
+
def self.wrap(input)
|
118
|
+
CLI::UI::Wrap.new(input).wrap
|
119
|
+
end
|
120
|
+
|
116
121
|
# Convenience Method for +CLI::UI::Printer.puts+
|
117
122
|
#
|
118
123
|
# ==== Attributes
|
@@ -165,7 +170,7 @@ module CLI
|
|
165
170
|
#
|
166
171
|
def self.log_output_to(path)
|
167
172
|
if CLI::UI::StdoutRouter.duplicate_output_to
|
168
|
-
raise
|
173
|
+
raise 'multiple logs not allowed'
|
169
174
|
end
|
170
175
|
CLI::UI::StdoutRouter.duplicate_output_to = File.open(path, 'w')
|
171
176
|
yield
|
data/lib/cli/ui/ansi.rb
CHANGED
@@ -21,6 +21,8 @@ module CLI
|
|
21
21
|
when 0x200d # zero-width joiner
|
22
22
|
zwj = true
|
23
23
|
acc
|
24
|
+
when "\n"
|
25
|
+
acc
|
24
26
|
else
|
25
27
|
acc + 1
|
26
28
|
end
|
@@ -45,7 +47,7 @@ module CLI
|
|
45
47
|
# - +cmd+ - ANSI control sequence Command
|
46
48
|
#
|
47
49
|
def self.control(args, cmd)
|
48
|
-
ESC +
|
50
|
+
ESC + '[' + args + cmd
|
49
51
|
end
|
50
52
|
|
51
53
|
# https://en.wikipedia.org/wiki/ANSI_escape_code#graphics
|
@@ -114,13 +116,13 @@ module CLI
|
|
114
116
|
# Show the cursor
|
115
117
|
#
|
116
118
|
def self.show_cursor
|
117
|
-
control('',
|
119
|
+
control('', '?25h')
|
118
120
|
end
|
119
121
|
|
120
122
|
# Hide the cursor
|
121
123
|
#
|
122
124
|
def self.hide_cursor
|
123
|
-
control('',
|
125
|
+
control('', '?25l')
|
124
126
|
end
|
125
127
|
|
126
128
|
# Save the cursor position
|
@@ -138,17 +140,13 @@ module CLI
|
|
138
140
|
# Move to the next line
|
139
141
|
#
|
140
142
|
def self.next_line
|
141
|
-
|
142
|
-
cmd += control('1', 'D') if CLI::UI::OS.current.shift_cursor_on_line_reset?
|
143
|
-
cmd
|
143
|
+
cursor_down + cursor_horizontal_absolute
|
144
144
|
end
|
145
145
|
|
146
146
|
# Move to the previous line
|
147
147
|
#
|
148
148
|
def self.previous_line
|
149
|
-
|
150
|
-
cmd += control('1', 'D') if CLI::UI::OS.current.shift_cursor_on_line_reset?
|
151
|
-
cmd
|
149
|
+
cursor_up + cursor_horizontal_absolute
|
152
150
|
end
|
153
151
|
|
154
152
|
def self.clear_to_end_of_line
|
data/lib/cli/ui/frame.rb
CHANGED
@@ -80,11 +80,11 @@ module CLI
|
|
80
80
|
|
81
81
|
unless block_given?
|
82
82
|
if failure_text
|
83
|
-
raise ArgumentError,
|
83
|
+
raise ArgumentError, 'failure_text is not compatible with blockless invocation'
|
84
84
|
elsif success_text
|
85
|
-
raise ArgumentError,
|
85
|
+
raise ArgumentError, 'success_text is not compatible with blockless invocation'
|
86
86
|
elsif timing
|
87
|
-
raise ArgumentError,
|
87
|
+
raise ArgumentError, 'timing is not compatible with blockless invocation'
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
@@ -147,7 +147,7 @@ module CLI
|
|
147
147
|
#
|
148
148
|
def divider(text, color: nil, frame_style: nil)
|
149
149
|
fs_item = FrameStack.pop
|
150
|
-
raise UnnestedFrameException,
|
150
|
+
raise UnnestedFrameException, 'No frame nesting to unnest' unless fs_item
|
151
151
|
|
152
152
|
color = CLI::UI.resolve_color(color) || fs_item.color
|
153
153
|
frame_style = CLI::UI.resolve_style(frame_style) || fs_item.frame_style
|
@@ -186,7 +186,7 @@ module CLI
|
|
186
186
|
#
|
187
187
|
def close(text, color: nil, elapsed: nil, frame_style: nil)
|
188
188
|
fs_item = FrameStack.pop
|
189
|
-
raise UnnestedFrameException,
|
189
|
+
raise UnnestedFrameException, 'No frame nesting to unnest' unless fs_item
|
190
190
|
|
191
191
|
color = CLI::UI.resolve_color(color) || fs_item.color
|
192
192
|
frame_style = CLI::UI.resolve_style(frame_style) || fs_item.frame_style
|
@@ -46,11 +46,11 @@ module CLI
|
|
46
46
|
def push(item = nil, color: nil, style: nil)
|
47
47
|
unless item.nil?
|
48
48
|
unless item.is_a?(StackItem)
|
49
|
-
raise ArgumentError,
|
49
|
+
raise ArgumentError, 'item must be a StackItem'
|
50
50
|
end
|
51
51
|
|
52
52
|
unless color.nil? && style.nil?
|
53
|
-
raise ArgumentError,
|
53
|
+
raise ArgumentError, 'Must give one of item or color: and style:'
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -39,7 +39,7 @@ module CLI
|
|
39
39
|
def message
|
40
40
|
keys = FrameStyle.loaded_styles.map(&:inspect).join(',')
|
41
41
|
"invalid frame style: #{@name.inspect}" \
|
42
|
-
|
42
|
+
' -- must be one of CLI::UI::Frame::FrameStyle.loaded_styles ' \
|
43
43
|
"(#{keys})"
|
44
44
|
end
|
45
45
|
end
|
data/lib/cli/ui/glyph.rb
CHANGED
@@ -57,6 +57,7 @@ module CLI
|
|
57
57
|
BUG = new('b', 0x1f41b, '!', Color::WHITE) # Bug emoji (🐛)
|
58
58
|
CHEVRON = new('>', 0xbb, '»', Color::YELLOW) # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (»)
|
59
59
|
HOURGLASS = new('H', [0x231b, 0xfe0e], 'H', Color::BLUE) # HOURGLASS + VARIATION SELECTOR 15 (⌛︎)
|
60
|
+
WARNING = new('!', [0x26a0, 0xfe0f], '!', Color::YELLOW) # WARNING SIGN + VARIATION SELECTOR 16 (⚠️ )
|
60
61
|
|
61
62
|
# Looks up a glyph by name
|
62
63
|
#
|
data/lib/cli/ui/os.rb
CHANGED
@@ -1,18 +1,22 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
1
3
|
module CLI
|
2
4
|
module UI
|
3
5
|
module OS
|
4
6
|
# Determines which OS is currently running the UI, to make it easier to
|
5
7
|
# adapt its behaviour to the features of the OS.
|
6
8
|
def self.current
|
7
|
-
@current_os ||= case
|
9
|
+
@current_os ||= case RbConfig::CONFIG['host_os']
|
8
10
|
when /darwin/
|
9
11
|
Mac
|
10
12
|
when /linux/
|
11
13
|
Linux
|
12
|
-
when /mingw32/
|
13
|
-
Windows
|
14
14
|
else
|
15
|
-
|
15
|
+
if RUBY_PLATFORM !~ /cygwin/ && ENV['OS'] == 'Windows_NT'
|
16
|
+
Windows
|
17
|
+
else
|
18
|
+
raise "Could not determine OS from host_os #{RbConfig::CONFIG["host_os"]}"
|
19
|
+
end
|
16
20
|
end
|
17
21
|
end
|
18
22
|
|
data/lib/cli/ui/printer.rb
CHANGED
@@ -18,6 +18,7 @@ module CLI
|
|
18
18
|
# * +:encoding+ - Force the output to be in a certain encoding. Defaults to UTF-8.
|
19
19
|
# * +:format+ - Whether to format the string using CLI::UI.fmt. Defaults to true.
|
20
20
|
# * +:graceful+ - Whether to gracefully ignore common I/O errors. Defaults to true.
|
21
|
+
# * +:wrap+ - Whether to wrap text at word boundaries to terminal width. Defaults to true.
|
21
22
|
#
|
22
23
|
# ==== Returns
|
23
24
|
# Returns whether the message was successfully printed,
|
@@ -25,11 +26,22 @@ module CLI
|
|
25
26
|
#
|
26
27
|
# ==== Example
|
27
28
|
#
|
28
|
-
# CLI::UI::Printer.puts('{x} Ouch',
|
29
|
-
#
|
30
|
-
def self.puts(
|
29
|
+
# CLI::UI::Printer.puts('{{x}} Ouch', to: $stderr)
|
30
|
+
#
|
31
|
+
def self.puts(
|
32
|
+
msg,
|
33
|
+
frame_color:
|
34
|
+
nil,
|
35
|
+
to:
|
36
|
+
$stdout,
|
37
|
+
encoding: Encoding::UTF_8,
|
38
|
+
format: true,
|
39
|
+
graceful: true,
|
40
|
+
wrap: true
|
41
|
+
)
|
31
42
|
msg = (+msg).force_encoding(encoding) if encoding
|
32
43
|
msg = CLI::UI.fmt(msg) if format
|
44
|
+
msg = CLI::UI.wrap(msg) if wrap
|
33
45
|
|
34
46
|
if frame_color
|
35
47
|
CLI::UI::Frame.with_frame_color_override(frame_color) { to.puts(msg) }
|
data/lib/cli/ui/prompt.rb
CHANGED
@@ -2,6 +2,21 @@
|
|
2
2
|
require 'cli/ui'
|
3
3
|
require 'readline'
|
4
4
|
|
5
|
+
module Readline
|
6
|
+
unless const_defined?(:FILENAME_COMPLETION_PROC)
|
7
|
+
FILENAME_COMPLETION_PROC = proc do |input|
|
8
|
+
directory = input[-1] == '/' ? input : File.dirname(input)
|
9
|
+
filename = input[-1] == '/' ? '' : File.basename(input)
|
10
|
+
|
11
|
+
(Dir.entries(directory).select do |fp|
|
12
|
+
fp.start_with?(filename)
|
13
|
+
end - (input[-1] == '.' ? [] : ['.', '..'])).map do |fp|
|
14
|
+
File.join(directory, fp).gsub(/\A\.\//, '')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
5
20
|
module CLI
|
6
21
|
module UI
|
7
22
|
module Prompt
|
@@ -191,12 +206,12 @@ module CLI
|
|
191
206
|
|
192
207
|
raise(ArgumentError, 'insufficient options') if options.nil? || options.empty?
|
193
208
|
navigate_text = if CLI::UI::OS.current.supports_arrow_keys?
|
194
|
-
|
209
|
+
'Choose with ↑ ↓ ⏎'
|
195
210
|
else
|
196
211
|
"Navigate up with 'k' and down with 'j', press Enter to select"
|
197
212
|
end
|
198
213
|
|
199
|
-
instructions = (multiple ?
|
214
|
+
instructions = (multiple ? 'Toggle options. ' : '') + navigate_text
|
200
215
|
instructions += ", filter with 'f'" if filter_ui
|
201
216
|
instructions += ", enter option with 'e'" if select_ui && (options.size > 9)
|
202
217
|
puts_question("#{question} {{yellow:(#{instructions})}}")
|
@@ -212,9 +227,9 @@ module CLI
|
|
212
227
|
if multiple
|
213
228
|
resp_text = case resp.size
|
214
229
|
when 0
|
215
|
-
|
230
|
+
'<nothing>'
|
216
231
|
when 1..2
|
217
|
-
resp.join(
|
232
|
+
resp.join(' and ')
|
218
233
|
else
|
219
234
|
"#{resp.size} items"
|
220
235
|
end
|
@@ -251,10 +266,10 @@ module CLI
|
|
251
266
|
def readline(is_file: false)
|
252
267
|
if is_file
|
253
268
|
Readline.completion_proc = Readline::FILENAME_COMPLETION_PROC
|
254
|
-
Readline.completion_append_character =
|
269
|
+
Readline.completion_append_character = ''
|
255
270
|
else
|
256
271
|
Readline.completion_proc = proc { |*| nil }
|
257
|
-
Readline.completion_append_character =
|
272
|
+
Readline.completion_append_character = ' '
|
258
273
|
end
|
259
274
|
|
260
275
|
# because Readline is a C library, CLI::UI's hooks into $stdout don't
|
@@ -5,8 +5,8 @@ module CLI
|
|
5
5
|
module UI
|
6
6
|
module Prompt
|
7
7
|
class InteractiveOptions
|
8
|
-
DONE =
|
9
|
-
CHECKBOX_ICON = { false =>
|
8
|
+
DONE = 'Done'
|
9
|
+
CHECKBOX_ICON = { false => '☐', true => '☑' }
|
10
10
|
|
11
11
|
# Prompts the user with options
|
12
12
|
# Uses an interactive session to allow the user to pick an answer
|
@@ -267,7 +267,7 @@ module CLI
|
|
267
267
|
when 'f', '/' ; start_filter
|
268
268
|
when ('0'..max_digit) ; select_n(char.to_i)
|
269
269
|
when 'y', 'n' ; select_bool(char)
|
270
|
-
when
|
270
|
+
when ' ', "\r", "\n" ; select_current # <enter>
|
271
271
|
end
|
272
272
|
when :filter
|
273
273
|
case char
|
@@ -334,22 +334,15 @@ module CLI
|
|
334
334
|
end
|
335
335
|
|
336
336
|
def read_char
|
337
|
-
|
338
|
-
|
339
|
-
|
337
|
+
if $stdin.tty? && !ENV['TEST']
|
338
|
+
$stdin.getch # raw mode for tty
|
339
|
+
else
|
340
|
+
$stdin.getc
|
340
341
|
end
|
341
342
|
rescue IOError
|
342
343
|
"\e"
|
343
344
|
end
|
344
345
|
|
345
|
-
def raw_tty!
|
346
|
-
if ENV['TEST'] || !$stdin.tty?
|
347
|
-
yield
|
348
|
-
else
|
349
|
-
$stdin.raw { yield }
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
346
|
def presented_options(recalculate: false)
|
354
347
|
return @presented_options unless recalculate
|
355
348
|
|
@@ -411,11 +404,11 @@ module CLI
|
|
411
404
|
end
|
412
405
|
|
413
406
|
def ensure_last_item_is_continuation_marker
|
414
|
-
@presented_options.push([
|
407
|
+
@presented_options.push(['...', nil]) if @presented_options.last.last
|
415
408
|
end
|
416
409
|
|
417
410
|
def ensure_first_item_is_continuation_marker
|
418
|
-
@presented_options.unshift([
|
411
|
+
@presented_options.unshift(['...', nil]) if @presented_options.first.last
|
419
412
|
end
|
420
413
|
|
421
414
|
def max_lines
|
@@ -453,9 +446,9 @@ module CLI
|
|
453
446
|
is_chosen = @multiple && num && @chosen[num - 1] && num != 0
|
454
447
|
|
455
448
|
padding = ' ' * (max_num_length - num.to_s.length)
|
456
|
-
message = " #{num}#{num ?
|
449
|
+
message = " #{num}#{num ? "." : " "}#{padding}"
|
457
450
|
|
458
|
-
format =
|
451
|
+
format = '%s'
|
459
452
|
# If multiple, bold only selected. If not multiple, bold everything
|
460
453
|
format = "{{bold:#{format}}}" if !@multiple || is_chosen
|
461
454
|
format = "{{cyan:#{format}}}" if @multiple && is_chosen && num != @active
|
@@ -246,11 +246,11 @@ module CLI
|
|
246
246
|
end
|
247
247
|
|
248
248
|
CLI::UI::Frame.divider('STDOUT')
|
249
|
-
out =
|
249
|
+
out = '(empty)' if out.nil? || out.strip.empty?
|
250
250
|
puts out
|
251
251
|
|
252
252
|
CLI::UI::Frame.divider('STDERR')
|
253
|
-
err =
|
253
|
+
err = '(empty)' if err.nil? || err.strip.empty?
|
254
254
|
puts err
|
255
255
|
end
|
256
256
|
end
|
data/lib/cli/ui/stdout_router.rb
CHANGED
data/lib/cli/ui/truncater.rb
CHANGED
data/lib/cli/ui/version.rb
CHANGED
data/lib/cli/ui/wrap.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'cli/ui'
|
3
|
+
require 'cli/ui/frame/frame_stack'
|
4
|
+
require 'cli/ui/frame/frame_style'
|
5
|
+
|
6
|
+
module CLI
|
7
|
+
module UI
|
8
|
+
class Wrap
|
9
|
+
def initialize(input)
|
10
|
+
@input = input
|
11
|
+
end
|
12
|
+
|
13
|
+
def wrap
|
14
|
+
max_width = Terminal.width - Frame.prefix_width
|
15
|
+
width = 0
|
16
|
+
final = []
|
17
|
+
# Create an alternation of format codes of parameter lengths 1-20, since + and {1,n} not allowed in lookbehind
|
18
|
+
format_codes = (1..20).map { |n| /\x1b\[[\d;]{#{n}}m/ }.join('|')
|
19
|
+
codes = ''
|
20
|
+
@input.split(/(?=\s|\x1b\[[\d;]+m|\r)|(?<=\s|#{format_codes})/).each do |token|
|
21
|
+
case token
|
22
|
+
when '\x1B[0?m'
|
23
|
+
codes = ''
|
24
|
+
final << token
|
25
|
+
when /\x1b\[[\d;]+m/
|
26
|
+
codes += token # Track in use format codes so that they are resent after frame coloring
|
27
|
+
final << token
|
28
|
+
when "\n"
|
29
|
+
final << "\n#{codes}"
|
30
|
+
width = 0
|
31
|
+
when /\s/
|
32
|
+
token_width = ANSI.printing_width(token)
|
33
|
+
if width + token_width <= max_width
|
34
|
+
final << token
|
35
|
+
width += token_width
|
36
|
+
else
|
37
|
+
final << "\n#{codes}"
|
38
|
+
width = 0
|
39
|
+
end
|
40
|
+
else
|
41
|
+
token_width = ANSI.printing_width(token)
|
42
|
+
if width + token_width <= max_width
|
43
|
+
final << token
|
44
|
+
width += token_width
|
45
|
+
else
|
46
|
+
final << "\n#{codes}"
|
47
|
+
final << token
|
48
|
+
width = token_width
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
final.join
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cli-ui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Burke Libbey
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2021-04-14 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake
|
@@ -89,6 +89,7 @@ files:
|
|
89
89
|
- lib/cli/ui/widgets.rb
|
90
90
|
- lib/cli/ui/widgets/base.rb
|
91
91
|
- lib/cli/ui/widgets/status.rb
|
92
|
+
- lib/cli/ui/wrap.rb
|
92
93
|
homepage: https://github.com/shopify/cli-ui
|
93
94
|
licenses:
|
94
95
|
- MIT
|