tty-prompt 0.13.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +5 -4
- data/CHANGELOG.md +18 -0
- data/Gemfile +2 -2
- data/README.md +61 -14
- data/appveyor.yml +0 -4
- data/benchmarks/speed.rb +1 -1
- data/examples/ask.rb +1 -9
- data/examples/ask_valid.rb +12 -0
- data/examples/collect.rb +4 -2
- data/examples/echo.rb +2 -2
- data/examples/enum.rb +1 -1
- data/examples/enum_paged.rb +1 -1
- data/examples/enum_select.rb +1 -1
- data/examples/expand.rb +1 -1
- data/examples/in.rb +1 -1
- data/examples/inputs.rb +1 -1
- data/examples/key_events.rb +1 -1
- data/examples/keypress.rb +1 -1
- data/examples/mask.rb +1 -1
- data/examples/multi_select.rb +1 -1
- data/examples/multi_select_paged.rb +1 -1
- data/examples/multiline.rb +1 -1
- data/examples/pause.rb +1 -1
- data/examples/select.rb +1 -1
- data/examples/select_paginated.rb +1 -1
- data/examples/slider.rb +2 -2
- data/examples/validation.rb +1 -1
- data/examples/yes_no.rb +1 -1
- data/lib/tty/prompt.rb +9 -3
- data/lib/tty/prompt/converters.rb +2 -4
- data/lib/tty/prompt/enum_list.rb +5 -4
- data/lib/tty/prompt/enum_paginator.rb +2 -0
- data/lib/tty/prompt/keypress.rb +5 -2
- data/lib/tty/prompt/list.rb +14 -7
- data/lib/tty/prompt/mask_question.rb +4 -1
- data/lib/tty/prompt/multiline.rb +3 -2
- data/lib/tty/prompt/paginator.rb +11 -0
- data/lib/tty/prompt/question.rb +12 -11
- data/lib/tty/prompt/slider.rb +36 -27
- data/lib/tty/prompt/symbols.rb +4 -0
- data/lib/tty/prompt/version.rb +1 -1
- data/tty-prompt.gemspec +4 -2
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 914b91c8d5090e18ffa6da38c4e4ba7f26a7f50a
|
4
|
+
data.tar.gz: 0dea47a0af899dc93a532fc4371710807e8ef472
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9476326073c28e1c92c8b1a48fe66ce4769589ad44a15758ac376512a20f77065a5f78dc51a4b2c897f7825cf9d325d0c285700961c4a7f942c7a2bd8351bde8
|
7
|
+
data.tar.gz: 7206776eb52eb9451641be93db1de554bbbf94cdab014d8f5f21a4f46aa52acbd4cb50745806b6eb078f88eb863b97645483833d2df441cbb995245a64901912
|
data/.travis.yml
CHANGED
@@ -2,17 +2,18 @@
|
|
2
2
|
language: ruby
|
3
3
|
sudo: false
|
4
4
|
cache: bundler
|
5
|
+
before_install: "gem update bundler"
|
5
6
|
bundler_args: --without tools
|
6
7
|
script: "bundle exec rake ci"
|
7
8
|
rvm:
|
8
|
-
- 1.9.3
|
9
9
|
- 2.0.0
|
10
10
|
- 2.1.10
|
11
|
-
- 2.2.
|
12
|
-
- 2.3.
|
13
|
-
- 2.4.
|
11
|
+
- 2.2.8
|
12
|
+
- 2.3.6
|
13
|
+
- 2.4.3
|
14
14
|
- ruby-head
|
15
15
|
- jruby-9000
|
16
|
+
- jruby-9.1.1.0
|
16
17
|
- jruby-head
|
17
18
|
matrix:
|
18
19
|
allow_failures:
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## [v0.14.0] - 2018-01-01
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add :cycle option to #select, #multi_select & #enum_select prompts to allow toggling between infinite and bounded list by Jonas Müller(@muellerj)
|
7
|
+
|
8
|
+
### Changed
|
9
|
+
* Change #multi_selct, #select & #enum_select to stop cycling options by default by Jona Müller(@muellerj)
|
10
|
+
* Change gemspec to require ruby >= 2.0.0
|
11
|
+
* Change #slider prompt to display slider next to query and help underneath
|
12
|
+
* Change to use tty-reader v0.2.0 with new line editing features for processing long inputs
|
13
|
+
|
14
|
+
### Fixed
|
15
|
+
* Fix Paginator & EnumPaginator to allow only positive integer values by Andy Brody(@ab)
|
16
|
+
* Fix EnumSelect to report on default option out of range and raise correctly
|
17
|
+
* Fix #ask :file & :path converters to correctly locate the files
|
18
|
+
* Fix #ask, #multiline to correctly handle long strings that wrap around screen
|
19
|
+
* Fix #slider prompt to correctly scale sliding
|
20
|
+
|
3
21
|
## [v0.13.2] - 2017-08-30
|
4
22
|
|
5
23
|
### Changed
|
data/Gemfile
CHANGED
@@ -6,7 +6,7 @@ gemspec
|
|
6
6
|
# gem 'tty-reader', git: 'https://github.com/piotrmurach/tty-reader'
|
7
7
|
|
8
8
|
group :test do
|
9
|
-
gem 'benchmark-ips', '~> 2.
|
9
|
+
gem 'benchmark-ips', '~> 2.7.2'
|
10
10
|
gem 'simplecov', '~> 0.10.0'
|
11
11
|
gem 'coveralls', '~> 0.8.2'
|
12
12
|
gem 'term-ansicolor', '=1.3.2'
|
@@ -17,6 +17,6 @@ group :tools do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
group :metrics do
|
20
|
-
gem 'yard', '~> 0.
|
20
|
+
gem 'yard', '~> 0.9.12'
|
21
21
|
gem 'yardstick', '~> 0.9.9'
|
22
22
|
end
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# TTY::Prompt [][gitter]
|
2
|
+
|
2
3
|
[][gem]
|
3
4
|
[][travis]
|
4
5
|
[][appveyor]
|
@@ -25,6 +26,17 @@
|
|
25
26
|
* User friendly error feedback
|
26
27
|
* Intuitive DSL for creating complex menus
|
27
28
|
* Ability to page long menus
|
29
|
+
* Support for Linux, OS X, FreeBSD and Windows systems
|
30
|
+
|
31
|
+
## Windows support
|
32
|
+
|
33
|
+
`tty-prompt` works across all Unix and Windows systems in the "best possible" way. On Windows, it uses Win32 API in place of terminal device to provide matching functionality.
|
34
|
+
|
35
|
+
Since Unix terminals provide richer set of features than Windows PowerShell consoles, expect to have a better experience on Unix-like platform.
|
36
|
+
|
37
|
+
Some features like `select` or `multi_select` menus may not work on Windows when run from Git Bash. See GitHub suggested [fixes](https://github.com/git-for-windows/git/wiki/FAQ#some-native-console-programs-dont-work-when-run-from-git-bash-how-to-fix-it).
|
38
|
+
|
39
|
+
For Windows, consider installing [ConEmu](https://conemu.github.io/), [cmder](http://cmder.net/) or [PowerCmd](http://www.powercmd.com/).
|
28
40
|
|
29
41
|
## Installation
|
30
42
|
|
@@ -362,7 +374,7 @@ prompt.keypress("Press key ?")
|
|
362
374
|
By default any key is accepted but you can limit keys by using `:keys` option. Any key event names such as `:space` or `:ctrl_k` are valid:
|
363
375
|
|
364
376
|
```ruby
|
365
|
-
prompt.keypress("Press space or enter to continue, keys: [:space, :return])
|
377
|
+
prompt.keypress("Press space or enter to continue", keys: [:space, :return])
|
366
378
|
```
|
367
379
|
|
368
380
|
#### 2.2.1 timeout
|
@@ -564,6 +576,17 @@ end
|
|
564
576
|
# ‣ Jax
|
565
577
|
```
|
566
578
|
|
579
|
+
You can navigate the choices using the arrow keys or define your own keymappings (see [keyboard events](#212-keyboard-events). When reaching the top/bottom of the list, the selection does not cycle around by default. If you wish to enable cycling, you can pass `cycle: true` to `select` and `mutli_select`:
|
580
|
+
|
581
|
+
```ruby
|
582
|
+
prompt.select("Choose your destiny?", %w(Scorpion Kano Jax), cycle: true)
|
583
|
+
# =>
|
584
|
+
# Choose your destiny? (Use arrow keys, press Enter to select)
|
585
|
+
# ‣ Scorpion
|
586
|
+
# Kano
|
587
|
+
# Jax
|
588
|
+
```
|
589
|
+
|
567
590
|
For ordered choices set `enum` to any delimiter String. In that way, you can use arrows keys and numbers (0-9) to select the item.
|
568
591
|
|
569
592
|
```ruby
|
@@ -704,6 +727,12 @@ And when you press enter you will see the following selected:
|
|
704
727
|
# => [{score: 20}, {score: 50}]
|
705
728
|
```
|
706
729
|
|
730
|
+
Also like, `select`, the method takes an option `cycle` (which defaults to `false`), which lets you configure whether the selection should cycle around when reaching the top/bottom of the list when navigating:
|
731
|
+
|
732
|
+
```ruby
|
733
|
+
prompt.multi_select("Select drinks?", %w(vodka beer wine), cycle: true)
|
734
|
+
```
|
735
|
+
|
707
736
|
You can configure help message and/or marker like so
|
708
737
|
|
709
738
|
```ruby
|
@@ -933,29 +962,47 @@ prompt.suggest('b', possible, indent: 4, single_text: 'Perhaps you meant?')
|
|
933
962
|
|
934
963
|
### 2.10 slider
|
935
964
|
|
936
|
-
If you have constrained range of numbers for user to choose from you may consider using `slider`.
|
965
|
+
If you have constrained range of numbers for user to choose from you may consider using `slider`.
|
966
|
+
|
967
|
+
The slider provides easy visual way of picking a value marked by `O` marker. You can set `:min`(defaults to 0), `:max` and `:step`(defaults to 1) options to configure slider range:
|
937
968
|
|
938
969
|
```ruby
|
939
|
-
prompt.slider('
|
970
|
+
prompt.slider('Volume', max: 100, step: 5)
|
940
971
|
# =>
|
941
|
-
#
|
942
|
-
#
|
943
|
-
|
972
|
+
# Volume ──────────O────────── 50
|
973
|
+
# (User arrow keys, press Enter to select)
|
974
|
+
```
|
975
|
+
|
976
|
+
By default the slider is configured to pick middle of the range as a start value, you can change this by using the `:default` option:
|
977
|
+
|
978
|
+
```ruby
|
979
|
+
prompt.slider('Volume', max: 100, step: 5, default: 75)
|
980
|
+
# =>
|
981
|
+
# Volume ───────────────O───── 75
|
982
|
+
# (Use arrow keys, press Enter to select)
|
983
|
+
```
|
984
|
+
|
985
|
+
You can also change the default slider formatting using the `:format`. The value must contain the `:slider` token for placing the actual animation and any `sprintf` compatible flag for number display, in our case `%d`:
|
986
|
+
|
987
|
+
```ruby
|
988
|
+
prompt.slider('Volume', max: 100, step: 5, default: 75, format: "|:slider| %d%")
|
989
|
+
# =>
|
990
|
+
# Volume |───────────────O─────| 75%
|
991
|
+
# (Use arrow keys, press Enter to select)
|
944
992
|
```
|
945
993
|
|
946
994
|
Slider can be configured through DSL as well:
|
947
995
|
|
948
996
|
```ruby
|
949
997
|
prompt.slider('What size?') do |range|
|
950
|
-
range.
|
951
|
-
range.
|
952
|
-
range.
|
953
|
-
range.
|
998
|
+
range.max 100
|
999
|
+
range.step 5
|
1000
|
+
range.default 75
|
1001
|
+
range.format "|:slider| %d%"
|
954
1002
|
end
|
955
1003
|
# =>
|
956
|
-
#
|
957
|
-
#
|
958
|
-
# |--O-------| 4
|
1004
|
+
# Volume |───────────────O─────| 75%
|
1005
|
+
# (Use arrow keys, press Enter to select)
|
959
1006
|
```
|
960
1007
|
|
961
1008
|
### 2.11 say
|
@@ -1129,4 +1176,4 @@ This project is intended to be a safe, welcoming space for collaboration, and co
|
|
1129
1176
|
|
1130
1177
|
## Copyright
|
1131
1178
|
|
1132
|
-
Copyright (c) 2015-
|
1179
|
+
Copyright (c) 2015-2018 Piotr Murach. See LICENSE for further details.
|
data/appveyor.yml
CHANGED
@@ -9,7 +9,6 @@ test_script:
|
|
9
9
|
- bundle exec rake ci
|
10
10
|
environment:
|
11
11
|
matrix:
|
12
|
-
- ruby_version: "193"
|
13
12
|
- ruby_version: "200"
|
14
13
|
- ruby_version: "200-x64"
|
15
14
|
- ruby_version: "21"
|
@@ -20,6 +19,3 @@ environment:
|
|
20
19
|
- ruby_version: "23-x64"
|
21
20
|
- ruby_version: "24"
|
22
21
|
- ruby_version: "24-x64"
|
23
|
-
matrix:
|
24
|
-
allow_failures:
|
25
|
-
- ruby_version: "193"
|
data/benchmarks/speed.rb
CHANGED
data/examples/ask.rb
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "../lib/tty-prompt"
|
4
4
|
|
5
5
|
prompt = TTY::Prompt.new
|
6
6
|
|
7
7
|
prompt.ask('What is your name?', default: ENV['USER'])
|
8
|
-
|
9
|
-
prompt.ask('Folder name?') do |q|
|
10
|
-
q.required(true)
|
11
|
-
q.validate ->(v) { return !Dir.exist?(v) }
|
12
|
-
q.messages[:valid?] = 'Folder already exists?'
|
13
|
-
q.messages[:required?] = 'Folder name must not be empty'
|
14
|
-
end
|
15
|
-
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative "../lib/tty-prompt"
|
4
|
+
|
5
|
+
prompt = TTY::Prompt.new
|
6
|
+
|
7
|
+
prompt.ask('Folder name?') do |q|
|
8
|
+
q.required(true)
|
9
|
+
q.validate ->(v) { return !Dir.exist?(v) }
|
10
|
+
q.messages[:valid?] = 'Folder already exists?'
|
11
|
+
q.messages[:required?] = 'Folder name must not be empty'
|
12
|
+
end
|
data/examples/collect.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require_relative "../lib/tty-prompt"
|
4
6
|
|
5
7
|
prompt = TTY::Prompt.new(prefix: '[?] ')
|
6
8
|
|
@@ -16,4 +18,4 @@ result = prompt.collect do
|
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
|
-
puts result
|
21
|
+
puts JSON.pretty_generate(result)
|
data/examples/echo.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "../lib/tty-prompt"
|
4
4
|
|
5
5
|
prompt = TTY::Prompt.new
|
6
6
|
|
@@ -8,4 +8,4 @@ answer = prompt.ask('Password?', echo: false) do |q|
|
|
8
8
|
q.validate(/^[^\.]+\.[^\.]+/)
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
puts "Password: #{answer}"
|
data/examples/enum.rb
CHANGED
data/examples/enum_paged.rb
CHANGED
data/examples/enum_select.rb
CHANGED
data/examples/expand.rb
CHANGED
data/examples/in.rb
CHANGED
data/examples/inputs.rb
CHANGED
data/examples/key_events.rb
CHANGED
data/examples/keypress.rb
CHANGED
data/examples/mask.rb
CHANGED
data/examples/multi_select.rb
CHANGED
data/examples/multiline.rb
CHANGED
data/examples/pause.rb
CHANGED
data/examples/select.rb
CHANGED
data/examples/slider.rb
CHANGED
data/examples/validation.rb
CHANGED
data/examples/yes_no.rb
CHANGED
data/lib/tty/prompt.rb
CHANGED
@@ -75,7 +75,8 @@ module TTY
|
|
75
75
|
:show, :hide
|
76
76
|
|
77
77
|
def_delegators :@reader, :read_char, :read_line, :read_keypress,
|
78
|
-
:read_multiline, :on, :subscribe, :trigger
|
78
|
+
:read_multiline, :on, :subscribe, :trigger,
|
79
|
+
:count_screen_lines
|
79
80
|
|
80
81
|
def_delegators :@output, :print, :puts, :flush
|
81
82
|
|
@@ -127,8 +128,13 @@ module TTY
|
|
127
128
|
|
128
129
|
@cursor = TTY::Cursor
|
129
130
|
@pastel = Pastel.new(@enabled_color.nil? ? {} : { enabled: @enabled_color })
|
130
|
-
@reader = TTY::Reader.new(
|
131
|
-
|
131
|
+
@reader = TTY::Reader.new(
|
132
|
+
input: @input,
|
133
|
+
output: @output,
|
134
|
+
interrupt: @interrupt,
|
135
|
+
track_history: @track_history,
|
136
|
+
env: @env
|
137
|
+
)
|
132
138
|
end
|
133
139
|
|
134
140
|
# Invoke a question type of prompt
|
@@ -60,13 +60,11 @@ module TTY
|
|
60
60
|
end
|
61
61
|
|
62
62
|
converter(:file) do |input|
|
63
|
-
|
64
|
-
::File.open(::File.join(directory, input))
|
63
|
+
::File.open(::File.join(Dir.pwd, input))
|
65
64
|
end
|
66
65
|
|
67
66
|
converter(:path) do |input|
|
68
|
-
|
69
|
-
Pathname.new(::File.join(directory, input))
|
67
|
+
Pathname.new(::File.join(Dir.pwd, input))
|
70
68
|
end
|
71
69
|
|
72
70
|
converter(:char) do |input|
|
data/lib/tty/prompt/enum_list.rb
CHANGED
@@ -24,6 +24,7 @@ module TTY
|
|
24
24
|
@active_color = options.fetch(:active_color) { @prompt.active_color }
|
25
25
|
@help_color = options.fetch(:help_color) { @prompt.help_color }
|
26
26
|
@error_color = options.fetch(:error_color) { @prompt.error_color }
|
27
|
+
@cycle = options.fetch(:cycle) { false }
|
27
28
|
@input = nil
|
28
29
|
@done = false
|
29
30
|
@first_render = true
|
@@ -139,7 +140,7 @@ module TTY
|
|
139
140
|
def keyright(*)
|
140
141
|
if (@page_active + page_size) <= @choices.size
|
141
142
|
@page_active += page_size
|
142
|
-
|
143
|
+
elsif @cycle
|
143
144
|
@page_active = 1
|
144
145
|
end
|
145
146
|
end
|
@@ -148,7 +149,7 @@ module TTY
|
|
148
149
|
def keyleft(*)
|
149
150
|
if (@page_active - page_size) >= 0
|
150
151
|
@page_active -= page_size
|
151
|
-
|
152
|
+
elsif @cycle
|
152
153
|
@page_active = @choices.size - 1
|
153
154
|
end
|
154
155
|
end
|
@@ -174,8 +175,8 @@ module TTY
|
|
174
175
|
# @api private
|
175
176
|
def validate_defaults
|
176
177
|
return if @default >= 1 && @default <= @choices.size
|
177
|
-
raise
|
178
|
-
"default index `#{
|
178
|
+
raise ConfigurationError,
|
179
|
+
"default index `#{@default}` out of range (1 - #{@choices.size})"
|
179
180
|
end
|
180
181
|
|
181
182
|
# Setup default option and active selection
|
data/lib/tty/prompt/keypress.rb
CHANGED
@@ -25,7 +25,9 @@ module TTY
|
|
25
25
|
@interval_handler = proc { |time|
|
26
26
|
unless @done
|
27
27
|
question = render_question
|
28
|
-
|
28
|
+
line_size = question.size
|
29
|
+
total_lines = @prompt.count_screen_lines(line_size)
|
30
|
+
@prompt.print(refresh(question.lines.count, total_lines))
|
29
31
|
countdown(time)
|
30
32
|
@prompt.print(render_question)
|
31
33
|
end
|
@@ -70,6 +72,7 @@ module TTY
|
|
70
72
|
|
71
73
|
def process_input(question)
|
72
74
|
time do
|
75
|
+
@prompt.print(render_question)
|
73
76
|
until @done
|
74
77
|
@input = @prompt.read_keypress(nonblock: true)
|
75
78
|
end
|
@@ -77,7 +80,7 @@ module TTY
|
|
77
80
|
@evaluator.(@input)
|
78
81
|
end
|
79
82
|
|
80
|
-
def refresh(lines)
|
83
|
+
def refresh(lines, lines_to_clear)
|
81
84
|
@prompt.clear_lines(lines)
|
82
85
|
end
|
83
86
|
|
data/lib/tty/prompt/list.rb
CHANGED
@@ -41,6 +41,7 @@ module TTY
|
|
41
41
|
@active_color = options.fetch(:active_color) { @prompt.active_color }
|
42
42
|
@help_color = options.fetch(:help_color) { @prompt.help_color }
|
43
43
|
@marker = options.fetch(:marker) { symbols[:pointer] }
|
44
|
+
@cycle = options.fetch(:cycle) { false }
|
44
45
|
@help = options[:help]
|
45
46
|
@first_render = true
|
46
47
|
@done = false
|
@@ -169,20 +170,26 @@ module TTY
|
|
169
170
|
@active = value
|
170
171
|
end
|
171
172
|
|
172
|
-
def
|
173
|
-
@done = true
|
174
|
-
end
|
175
|
-
|
176
|
-
def keyreturn(*)
|
173
|
+
def keyenter(*)
|
177
174
|
@done = true
|
178
175
|
end
|
176
|
+
alias keyreturn keyenter
|
177
|
+
alias keyspace keyenter
|
179
178
|
|
180
179
|
def keyup(*)
|
181
|
-
|
180
|
+
if @active == 1
|
181
|
+
@active = @choices.length if @cycle
|
182
|
+
else
|
183
|
+
@active -= 1
|
184
|
+
end
|
182
185
|
end
|
183
186
|
|
184
187
|
def keydown(*)
|
185
|
-
|
188
|
+
if @active == @choices.length
|
189
|
+
@active = 1 if @cycle
|
190
|
+
else
|
191
|
+
@active += 1
|
192
|
+
end
|
186
193
|
end
|
187
194
|
alias keytab keydown
|
188
195
|
|
@@ -78,9 +78,12 @@ module TTY
|
|
78
78
|
@done_masked = false
|
79
79
|
@failure = false
|
80
80
|
@input = ''
|
81
|
+
@prompt.print(question)
|
81
82
|
until @done_masked
|
82
83
|
@prompt.read_keypress
|
83
|
-
|
84
|
+
question = render_question
|
85
|
+
total_lines = @prompt.count_screen_lines(question)
|
86
|
+
@prompt.print(@prompt.clear_lines(total_lines))
|
84
87
|
@prompt.print(render_question)
|
85
88
|
end
|
86
89
|
@prompt.puts
|
data/lib/tty/prompt/multiline.rb
CHANGED
@@ -54,6 +54,7 @@ module TTY
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def process_input(question)
|
57
|
+
@prompt.print(question)
|
57
58
|
@lines = read_input
|
58
59
|
@input = "#{@lines.first.strip} ..." unless @lines.first.to_s.empty?
|
59
60
|
if Utils.blank?(@input)
|
@@ -62,8 +63,8 @@ module TTY
|
|
62
63
|
@evaluator.(@lines)
|
63
64
|
end
|
64
65
|
|
65
|
-
def refresh(lines)
|
66
|
-
size = @lines_count +
|
66
|
+
def refresh(lines, lines_to_clear)
|
67
|
+
size = @lines_count + lines_to_clear + 1
|
67
68
|
@prompt.clear_lines(size)
|
68
69
|
end
|
69
70
|
end # Multiline
|
data/lib/tty/prompt/paginator.rb
CHANGED
@@ -24,6 +24,15 @@ module TTY
|
|
24
24
|
@lower_index + @per_page - 1
|
25
25
|
end
|
26
26
|
|
27
|
+
# Check if page size is valid
|
28
|
+
#
|
29
|
+
# @raise [InvalidArgument]
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
def check_page_size!
|
33
|
+
raise InvalidArgument, 'per_page must be > 0' if @per_page < 1
|
34
|
+
end
|
35
|
+
|
27
36
|
# Paginate collection given an active index
|
28
37
|
#
|
29
38
|
# @param [Array[Choice]] list
|
@@ -43,6 +52,8 @@ module TTY
|
|
43
52
|
@lower_index ||= current_index
|
44
53
|
@upper_index ||= max_index
|
45
54
|
|
55
|
+
check_page_size!
|
56
|
+
|
46
57
|
# Don't paginate short lists
|
47
58
|
if list.size <= @per_page
|
48
59
|
@lower_index = 0
|
data/lib/tty/prompt/question.rb
CHANGED
@@ -107,16 +107,17 @@ module TTY
|
|
107
107
|
def render
|
108
108
|
@errors = []
|
109
109
|
until @done
|
110
|
-
|
111
|
-
@prompt.print(question)
|
112
|
-
result = process_input(question)
|
110
|
+
result = process_input(render_question)
|
113
111
|
if result.failure?
|
114
112
|
@errors = result.errors
|
115
113
|
@prompt.print(render_error(result.errors))
|
116
114
|
else
|
117
115
|
@done = true
|
118
116
|
end
|
119
|
-
|
117
|
+
question = render_question
|
118
|
+
input_line = question + result.value.to_s
|
119
|
+
total_lines = @prompt.count_screen_lines(input_line)
|
120
|
+
@prompt.print(refresh(question.lines.count, total_lines))
|
120
121
|
end
|
121
122
|
@prompt.print(render_question)
|
122
123
|
convert_result(result.value)
|
@@ -164,11 +165,10 @@ module TTY
|
|
164
165
|
#
|
165
166
|
# @api private
|
166
167
|
def render_error(errors)
|
167
|
-
errors.reduce(
|
168
|
-
|
169
|
-
acc << newline + @prompt.decorate('>>', :red) + ' ' + err
|
168
|
+
errors.reduce([]) do |acc, err|
|
169
|
+
acc << @prompt.decorate('>>', :red) + ' ' + err
|
170
170
|
acc
|
171
|
-
end
|
171
|
+
end.join("\n")
|
172
172
|
end
|
173
173
|
|
174
174
|
# Determine area of the screen to clear
|
@@ -179,18 +179,19 @@ module TTY
|
|
179
179
|
# @return [String]
|
180
180
|
#
|
181
181
|
# @api private
|
182
|
-
def refresh(lines)
|
182
|
+
def refresh(lines, lines_to_clear)
|
183
183
|
output = ''
|
184
184
|
if @done
|
185
|
-
if @errors.count.zero?
|
185
|
+
if @errors.count.zero?
|
186
186
|
output << @prompt.cursor.up(lines)
|
187
187
|
else
|
188
188
|
lines += @errors.count
|
189
|
+
lines_to_clear += @errors.count
|
189
190
|
end
|
190
191
|
else
|
191
192
|
output << @prompt.cursor.up(lines)
|
192
193
|
end
|
193
|
-
output + @prompt.clear_lines(
|
194
|
+
output + @prompt.clear_lines(lines_to_clear)
|
194
195
|
end
|
195
196
|
|
196
197
|
# Convert value to expected type
|
data/lib/tty/prompt/slider.rb
CHANGED
@@ -13,8 +13,19 @@ module TTY
|
|
13
13
|
|
14
14
|
HELP = '(Use arrow keys, press Enter to select)'.freeze
|
15
15
|
|
16
|
+
FORMAT = ':slider %d'.freeze
|
17
|
+
|
16
18
|
# Initailize a Slider
|
17
19
|
#
|
20
|
+
# @param [Prompt] prompt
|
21
|
+
# the prompt
|
22
|
+
# @param [Hash] options
|
23
|
+
# the options to configure this slider
|
24
|
+
# @option options [Integer] :min The minimum value
|
25
|
+
# @option options [Integer] :max The maximum value
|
26
|
+
# @option options [Integer] :step The step value
|
27
|
+
# @option options [String] :format The display format
|
28
|
+
#
|
18
29
|
# @api public
|
19
30
|
def initialize(prompt, options = {})
|
20
31
|
@prompt = prompt
|
@@ -25,6 +36,7 @@ module TTY
|
|
25
36
|
@default = options[:default]
|
26
37
|
@active_color = options.fetch(:active_color) { @prompt.active_color }
|
27
38
|
@help_color = options.fetch(:help_color) { @prompt.help_color }
|
39
|
+
@format = options.fetch(:format) { FORMAT }
|
28
40
|
@first_render = true
|
29
41
|
@done = false
|
30
42
|
|
@@ -73,6 +85,10 @@ module TTY
|
|
73
85
|
@step = value
|
74
86
|
end
|
75
87
|
|
88
|
+
def format(value)
|
89
|
+
@format = value
|
90
|
+
end
|
91
|
+
|
76
92
|
# Call the slider by passing question
|
77
93
|
#
|
78
94
|
# @param [String] question
|
@@ -89,17 +105,18 @@ module TTY
|
|
89
105
|
def keyleft(*)
|
90
106
|
@active -= 1 if @active > 0
|
91
107
|
end
|
92
|
-
|
108
|
+
alias keydown keyleft
|
93
109
|
|
94
110
|
def keyright(*)
|
95
|
-
@active += 1 if (@active +
|
111
|
+
@active += 1 if (@active + 1) < range.size
|
96
112
|
end
|
97
|
-
|
113
|
+
alias keyup keyright
|
98
114
|
|
99
115
|
def keyreturn(*)
|
100
116
|
@done = true
|
101
117
|
end
|
102
|
-
|
118
|
+
alias keyspace keyreturn
|
119
|
+
alias keyenter keyreturn
|
103
120
|
|
104
121
|
private
|
105
122
|
|
@@ -143,23 +160,18 @@ module TTY
|
|
143
160
|
#
|
144
161
|
# @api private
|
145
162
|
def render_question
|
146
|
-
header = "#{@prefix}#{@question}
|
147
|
-
@first_render = false
|
148
|
-
header << render_slider unless @done
|
149
|
-
header
|
150
|
-
end
|
151
|
-
|
152
|
-
# Render actual answer or help
|
153
|
-
#
|
154
|
-
# @return [String]
|
155
|
-
#
|
156
|
-
# @api private
|
157
|
-
def render_header
|
163
|
+
header = "#{@prefix}#{@question} "
|
158
164
|
if @done
|
159
|
-
@prompt.decorate(answer.to_s, @active_color)
|
160
|
-
|
161
|
-
|
165
|
+
header << @prompt.decorate(answer.to_s, @active_color)
|
166
|
+
header << "\n"
|
167
|
+
else
|
168
|
+
header << render_slider
|
169
|
+
end
|
170
|
+
if @first_render
|
171
|
+
header << "\n" + @prompt.decorate(HELP, @help_color)
|
172
|
+
@first_render = false
|
162
173
|
end
|
174
|
+
header
|
163
175
|
end
|
164
176
|
|
165
177
|
# Render slider representation
|
@@ -168,14 +180,11 @@ module TTY
|
|
168
180
|
#
|
169
181
|
# @api private
|
170
182
|
def render_slider
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
output << symbols[:pipe]
|
177
|
-
output << " #{range[@active]}"
|
178
|
-
output
|
183
|
+
slider = (symbols[:line] * @active) +
|
184
|
+
@prompt.decorate(symbols[:handle], @active_color) +
|
185
|
+
(symbols[:line] * (range.size - @active - 1))
|
186
|
+
value = " #{range[@active]}"
|
187
|
+
@format.gsub(':slider', slider) % [value]
|
179
188
|
end
|
180
189
|
end # Slider
|
181
190
|
end # Prompt
|
data/lib/tty/prompt/symbols.rb
CHANGED
@@ -10,6 +10,8 @@ module TTY
|
|
10
10
|
tick: '✓',
|
11
11
|
cross: '✘',
|
12
12
|
star: '★',
|
13
|
+
square: '◼',
|
14
|
+
square_empty: '◻',
|
13
15
|
dot: '•',
|
14
16
|
pointer: '‣',
|
15
17
|
line: '─',
|
@@ -28,6 +30,8 @@ module TTY
|
|
28
30
|
tick: '√',
|
29
31
|
cross: '×',
|
30
32
|
star: '*',
|
33
|
+
square: '[█]',
|
34
|
+
square_empty: '[ ]',
|
31
35
|
dot: '.',
|
32
36
|
pointer: '>',
|
33
37
|
line: '-',
|
data/lib/tty/prompt/version.rb
CHANGED
data/tty-prompt.gemspec
CHANGED
@@ -20,13 +20,15 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
+
spec.required_ruby_version = '>= 2.0.0'
|
24
|
+
|
23
25
|
spec.add_dependency 'necromancer', '~> 0.4.0'
|
24
26
|
spec.add_dependency 'pastel', '~> 0.7.0'
|
25
27
|
spec.add_dependency 'timers', '~> 4.1.2'
|
26
28
|
spec.add_dependency 'tty-cursor', '~> 0.5.0'
|
27
|
-
spec.add_dependency 'tty-reader', '~> 0.
|
29
|
+
spec.add_dependency 'tty-reader', '~> 0.2.0'
|
28
30
|
|
29
31
|
spec.add_development_dependency 'bundler', '>= 1.5.0', '< 2.0'
|
30
32
|
spec.add_development_dependency 'rake'
|
31
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
33
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
32
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tty-prompt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: necromancer
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: 0.2.0
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
82
|
+
version: 0.2.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: bundler
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,14 +120,14 @@ dependencies:
|
|
120
120
|
requirements:
|
121
121
|
- - "~>"
|
122
122
|
- !ruby/object:Gem::Version
|
123
|
-
version: 3.
|
123
|
+
version: '3.0'
|
124
124
|
type: :development
|
125
125
|
prerelease: false
|
126
126
|
version_requirements: !ruby/object:Gem::Requirement
|
127
127
|
requirements:
|
128
128
|
- - "~>"
|
129
129
|
- !ruby/object:Gem::Version
|
130
|
-
version: 3.
|
130
|
+
version: '3.0'
|
131
131
|
description: A beautiful and powerful interactive command line prompt with a robust
|
132
132
|
API for getting and validating complex inputs.
|
133
133
|
email:
|
@@ -148,6 +148,7 @@ files:
|
|
148
148
|
- appveyor.yml
|
149
149
|
- benchmarks/speed.rb
|
150
150
|
- examples/ask.rb
|
151
|
+
- examples/ask_valid.rb
|
151
152
|
- examples/collect.rb
|
152
153
|
- examples/echo.rb
|
153
154
|
- examples/enum.rb
|
@@ -217,7 +218,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
217
218
|
requirements:
|
218
219
|
- - ">="
|
219
220
|
- !ruby/object:Gem::Version
|
220
|
-
version:
|
221
|
+
version: 2.0.0
|
221
222
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
222
223
|
requirements:
|
223
224
|
- - ">="
|
@@ -230,4 +231,3 @@ signing_key:
|
|
230
231
|
specification_version: 4
|
231
232
|
summary: A beautiful and powerful interactive command line prompt.
|
232
233
|
test_files: []
|
233
|
-
has_rdoc:
|