tty-prompt 0.13.2 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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](https://badges.gitter.im/Join%20Chat.svg)][gitter]
|
2
|
+
|
2
3
|
[![Gem Version](https://badge.fury.io/rb/tty-prompt.svg)][gem]
|
3
4
|
[![Build Status](https://secure.travis-ci.org/piotrmurach/tty-prompt.svg?branch=master)][travis]
|
4
5
|
[![Build status](https://ci.appveyor.com/api/projects/status/4cguoiah5dprbq7n?svg=true)][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:
|