inquirer.rb 0.0.1
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 +7 -0
- data/.gitignore +9 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +197 -0
- data/Rakefile +2 -0
- data/examples/checkbox.rb +203 -0
- data/examples/confirm.rb +63 -0
- data/examples/input.rb +67 -0
- data/examples/list.rb +185 -0
- data/examples/password.rb +63 -0
- data/inquirer.gemspec +34 -0
- data/lib/inquirer.rb +86 -0
- data/lib/inquirer/prompts/checkbox.rb +165 -0
- data/lib/inquirer/prompts/confirm.rb +89 -0
- data/lib/inquirer/prompts/input.rb +138 -0
- data/lib/inquirer/prompts/list.rb +116 -0
- data/lib/inquirer/prompts/password.rb +15 -0
- data/lib/inquirer/style.rb +51 -0
- data/lib/inquirer/style/checkbox.rb +16 -0
- data/lib/inquirer/style/confirm.rb +15 -0
- data/lib/inquirer/style/input.rb +13 -0
- data/lib/inquirer/style/list.rb +16 -0
- data/lib/inquirer/style/password.rb +12 -0
- data/lib/inquirer/utils/iochar.rb +32 -0
- data/lib/inquirer/utils/iohelper.rb +123 -0
- data/lib/inquirer/utils/paginator.rb +37 -0
- data/lib/inquirer/version.rb +3 -0
- data/screenshots/checkbox.png +0 -0
- data/screenshots/confirm.png +0 -0
- data/screenshots/input.png +0 -0
- data/screenshots/list.png +0 -0
- data/screenshots/password.png +0 -0
- metadata +121 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'inquirer/prompts/input'
|
2
|
+
require 'inquirer/style/password'
|
3
|
+
|
4
|
+
module Password
|
5
|
+
|
6
|
+
extend Input
|
7
|
+
extend self
|
8
|
+
|
9
|
+
# this function is necessary to reduce code
|
10
|
+
# duplication of the password promt engine
|
11
|
+
# to a minimum
|
12
|
+
def display_value
|
13
|
+
Inquirer::Style::Password.placeholder_char * @value.size
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'term/ansicolor'
|
3
|
+
|
4
|
+
module Inquirer
|
5
|
+
class Style
|
6
|
+
|
7
|
+
@@color = Term::ANSIColor
|
8
|
+
|
9
|
+
@@question_prefix = @@color.green('?') + ' '
|
10
|
+
@@seperator = '--------'
|
11
|
+
|
12
|
+
@@question = '%s '
|
13
|
+
@@response = @@color.cyan('%s')
|
14
|
+
|
15
|
+
@@selector = @@color.cyan('‣')
|
16
|
+
@@checkbox_on = @@color.green('◉')
|
17
|
+
@@checkbox_off = '◯'
|
18
|
+
|
19
|
+
@@pagiator_text = '(Move up and down to reveal more choices)'
|
20
|
+
|
21
|
+
@@error_message = @@color.red('>>') + ' %s'
|
22
|
+
@@error_message_invalid_value = 'The entered value is not valid'
|
23
|
+
|
24
|
+
@@endless_repeat = @@color.yellow('#%s')
|
25
|
+
@@limited_repeat = @@color.yellow('#%s of %s')
|
26
|
+
|
27
|
+
# http://blog.marc-seeger.de/2011/04/06/attr_reader-for-class-variables-in-ruby/
|
28
|
+
def self.activate_getter_setter
|
29
|
+
# this creates the methods when the class is loaded
|
30
|
+
self.class_variables.each{ |sym|
|
31
|
+
|
32
|
+
# build the meta syntax
|
33
|
+
class_variable_getter_and_setter = <<EVALME
|
34
|
+
|
35
|
+
# getter
|
36
|
+
def self.#{sym.to_s.gsub('@@','')}
|
37
|
+
#{sym}
|
38
|
+
end
|
39
|
+
|
40
|
+
# setter
|
41
|
+
def self.#{sym.to_s.gsub('@@','')}=(value)
|
42
|
+
#{sym} = value
|
43
|
+
end;
|
44
|
+
EVALME
|
45
|
+
class_eval(class_variable_getter_and_setter)
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
self.activate_getter_setter
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'inquirer/utils/iochar'
|
2
|
+
require 'inquirer/style'
|
3
|
+
|
4
|
+
module Inquirer
|
5
|
+
class Style
|
6
|
+
class Checkbox < Inquirer::Style
|
7
|
+
|
8
|
+
@@item = "%s#{IOChar.newline}"
|
9
|
+
@@checked_item = "%s#{IOChar.newline}"
|
10
|
+
|
11
|
+
@@selection_help = '(Press <space> to select)'
|
12
|
+
|
13
|
+
self.activate_getter_setter
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'inquirer/utils/iochar'
|
2
|
+
require 'inquirer/style'
|
3
|
+
|
4
|
+
module Inquirer
|
5
|
+
class Style
|
6
|
+
class Confirm < Inquirer::Style
|
7
|
+
|
8
|
+
@@options = '(%s/%s)'
|
9
|
+
@@option_true = 'Yes'
|
10
|
+
@@option_false = 'No'
|
11
|
+
|
12
|
+
self.activate_getter_setter
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'inquirer/utils/iochar'
|
2
|
+
require 'inquirer/style'
|
3
|
+
|
4
|
+
module Inquirer
|
5
|
+
class Style
|
6
|
+
class List < Inquirer::Style
|
7
|
+
|
8
|
+
@@item = "%s#{IOChar.newline}"
|
9
|
+
@@selected_item = @@color.cyan('%s') + IOChar.newline
|
10
|
+
|
11
|
+
@@selection_help = '(Use arrow keys)'
|
12
|
+
|
13
|
+
self.activate_getter_setter
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'io/console'
|
2
|
+
|
3
|
+
module IOChar
|
4
|
+
extend self
|
5
|
+
|
6
|
+
KEYS = {
|
7
|
+
' ' => 'space',
|
8
|
+
"\t" => 'tab',
|
9
|
+
"\r" => 'return',
|
10
|
+
"\n" => 'linefeed',
|
11
|
+
"\e" => 'escape',
|
12
|
+
"\e[A" => 'up',
|
13
|
+
"\e[B" => 'down',
|
14
|
+
"\e[C" => 'right',
|
15
|
+
"\e[D" => 'left',
|
16
|
+
"\177" => 'backspace',
|
17
|
+
"\003" => 'ctrl-c',
|
18
|
+
"\004" => 'ctrl-d',
|
19
|
+
}
|
20
|
+
|
21
|
+
def char_to_key char
|
22
|
+
KEYS.fetch char, char
|
23
|
+
end
|
24
|
+
|
25
|
+
def newline; "\n" end
|
26
|
+
def carriage_return; "\r" end
|
27
|
+
def cursor_up; "\e[A" end
|
28
|
+
def cursor_down; "\e[B" end
|
29
|
+
def cursor_right; "\e[C" end
|
30
|
+
def cursor_left; "\e[D" end
|
31
|
+
def clear_line; "\e[0K" end
|
32
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'io/console'
|
2
|
+
require 'inquirer/utils/iochar'
|
3
|
+
|
4
|
+
module IOHelper
|
5
|
+
extend self
|
6
|
+
|
7
|
+
@rendered = ''
|
8
|
+
@bottomline = nil
|
9
|
+
|
10
|
+
# Get each key the user presses and hand it one by one to the block. Do this
|
11
|
+
# as long as the block returns truthy
|
12
|
+
# Params:
|
13
|
+
# +&block+:: +Proc+ a block that receives a user key and returns truthy or falsy
|
14
|
+
def read_char &block
|
15
|
+
STDIN.noecho do
|
16
|
+
# as long as the block doen't return falsy,
|
17
|
+
# read the user input key and sned it to the block
|
18
|
+
while block.( IOHelper.get_char )
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# read a character the user enters on console. This call is synchronous blocking.
|
24
|
+
# this is taken from: http://www.alecjacobson.com/weblog/?p=75
|
25
|
+
# and: https://gist.github.com/acook/4190379
|
26
|
+
def get_char
|
27
|
+
begin
|
28
|
+
# save previous state of stty
|
29
|
+
old_state = `stty -g`
|
30
|
+
# disable echoing and enable raw (not having to press enter)
|
31
|
+
system 'stty raw -echo'
|
32
|
+
char = STDIN.getc.chr
|
33
|
+
# gather next two characters of special keys
|
34
|
+
if char == "\e"
|
35
|
+
char << STDIN.read_nonblock(3) rescue nil
|
36
|
+
char << STDIN.read_nonblock(2) rescue nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# restore previous state of stty
|
40
|
+
system "stty #{old_state}"
|
41
|
+
end
|
42
|
+
|
43
|
+
key = IOChar.char_to_key(char)
|
44
|
+
|
45
|
+
if key == 'ctrl-c' or key == 'ctrl-d'
|
46
|
+
raise Interrupt
|
47
|
+
end
|
48
|
+
|
49
|
+
char
|
50
|
+
end
|
51
|
+
|
52
|
+
def winsize
|
53
|
+
STDIN.winsize
|
54
|
+
end
|
55
|
+
|
56
|
+
# render a text to the prompt
|
57
|
+
def render prompt, bottomline = nil
|
58
|
+
@rendered = wrap(prompt)
|
59
|
+
@bottomline = bottomline
|
60
|
+
|
61
|
+
# determine how many lines to move up
|
62
|
+
lines = @rendered.scan(/\n/).size + 1
|
63
|
+
|
64
|
+
if @bottomline
|
65
|
+
print IOChar.newline * lines + @bottomline + IOChar.cursor_left * @bottomline.size + IOChar.cursor_up * lines
|
66
|
+
end
|
67
|
+
print @rendered
|
68
|
+
end
|
69
|
+
|
70
|
+
# clear the console based on the last text rendered
|
71
|
+
def clear
|
72
|
+
# determine how many lines to move up
|
73
|
+
lines = @rendered.scan(/\n/).length
|
74
|
+
|
75
|
+
if @bottomline
|
76
|
+
print IOChar.cursor_down + IOChar.carriage_return + IOChar.clear_line + IOChar.cursor_up
|
77
|
+
end
|
78
|
+
|
79
|
+
# jump back to the first position and clear the line
|
80
|
+
print IOChar.cursor_down + IOChar.carriage_return + IOChar.clear_line + IOChar.cursor_up + IOChar.clear_line + IOChar.carriage_return + ( IOChar.cursor_up + IOChar.clear_line ) * lines + IOChar.clear_line
|
81
|
+
end
|
82
|
+
|
83
|
+
# hides the cursor and ensure the curso be visible at the end
|
84
|
+
def without_cursor
|
85
|
+
# tell the terminal to hide the cursor
|
86
|
+
print `tput civis`
|
87
|
+
begin
|
88
|
+
# run the block
|
89
|
+
yield
|
90
|
+
ensure
|
91
|
+
# tell the terminal to show the cursor
|
92
|
+
print `tput cnorm`
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# inspired by http://apidock.com/rails/ActionView/Helpers/TextHelper/word_wrap
|
97
|
+
# maybe interesting: https://www.safaribooksonline.com/library/view/ruby-cookbook/0596523696/ch01s15.html
|
98
|
+
def wrap(string)
|
99
|
+
|
100
|
+
height, width = IOHelper.winsize
|
101
|
+
|
102
|
+
keep_trailing_newline = false
|
103
|
+
if string[-1, 1] == IOChar.newline
|
104
|
+
keep_trailing_newline = true
|
105
|
+
end
|
106
|
+
|
107
|
+
result = string.split(IOChar.newline).collect! do |line|
|
108
|
+
if line.length > width
|
109
|
+
line.gsub(/(.{1,#{width}})(\s+|$)/, "\\1#{ IOChar.newline }")
|
110
|
+
else
|
111
|
+
line
|
112
|
+
end
|
113
|
+
end * IOChar.newline
|
114
|
+
|
115
|
+
if keep_trailing_newline
|
116
|
+
result += IOChar.newline
|
117
|
+
else
|
118
|
+
result.chomp!
|
119
|
+
end
|
120
|
+
|
121
|
+
result + IOChar.clear_line
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'inquirer/utils/iochar'
|
2
|
+
|
3
|
+
class Paginator
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@pointer = 0
|
7
|
+
@last_index = 0
|
8
|
+
@page_size = 7
|
9
|
+
end
|
10
|
+
|
11
|
+
def paginate(content, current_position)
|
12
|
+
|
13
|
+
lines_list = content.lines
|
14
|
+
|
15
|
+
# Make sure there's enough lines to paginate
|
16
|
+
return content if lines_list.count < (@page_size + 2)
|
17
|
+
|
18
|
+
promt_question = lines_list.shift
|
19
|
+
lines_count = lines_list.count
|
20
|
+
infinite = lines_list * 3
|
21
|
+
|
22
|
+
# Move the pos only when the user go down and limit it to 3
|
23
|
+
if @pointer < 3 && @last_index < current_position && current_position - @last_index < 9
|
24
|
+
@pointer = [3, @pointer + current_position - @last_index].min
|
25
|
+
end
|
26
|
+
@last_index = current_position
|
27
|
+
|
28
|
+
top_index = [0, current_position + lines_count - @pointer].max
|
29
|
+
section = infinite.slice(top_index, @page_size).join
|
30
|
+
|
31
|
+
[
|
32
|
+
promt_question,
|
33
|
+
section,
|
34
|
+
Inquirer::Style.pagiator_text + IOChar.newline
|
35
|
+
].join(IOChar.newline)
|
36
|
+
end
|
37
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: inquirer.rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Thorsten Eckel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.11'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: term-ansicolor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
description: A collection of common interactive command line user interfaces. A (not
|
56
|
+
yet compleded) clone of the great Inquirer.js (https://github.com/SBoudrias/Inquirer.js)
|
57
|
+
and strongly inspired by the similar inquirer.rb (https://github.com/arlimus/inquirer.rb).
|
58
|
+
email:
|
59
|
+
- te@znuny.com
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- ".gitignore"
|
65
|
+
- CODE_OF_CONDUCT.md
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE.txt
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- examples/checkbox.rb
|
71
|
+
- examples/confirm.rb
|
72
|
+
- examples/input.rb
|
73
|
+
- examples/list.rb
|
74
|
+
- examples/password.rb
|
75
|
+
- inquirer.gemspec
|
76
|
+
- lib/inquirer.rb
|
77
|
+
- lib/inquirer/prompts/checkbox.rb
|
78
|
+
- lib/inquirer/prompts/confirm.rb
|
79
|
+
- lib/inquirer/prompts/input.rb
|
80
|
+
- lib/inquirer/prompts/list.rb
|
81
|
+
- lib/inquirer/prompts/password.rb
|
82
|
+
- lib/inquirer/style.rb
|
83
|
+
- lib/inquirer/style/checkbox.rb
|
84
|
+
- lib/inquirer/style/confirm.rb
|
85
|
+
- lib/inquirer/style/input.rb
|
86
|
+
- lib/inquirer/style/list.rb
|
87
|
+
- lib/inquirer/style/password.rb
|
88
|
+
- lib/inquirer/utils/iochar.rb
|
89
|
+
- lib/inquirer/utils/iohelper.rb
|
90
|
+
- lib/inquirer/utils/paginator.rb
|
91
|
+
- lib/inquirer/version.rb
|
92
|
+
- screenshots/checkbox.png
|
93
|
+
- screenshots/confirm.png
|
94
|
+
- screenshots/input.png
|
95
|
+
- screenshots/list.png
|
96
|
+
- screenshots/password.png
|
97
|
+
homepage: https://github.com/thorsteneckel/inquirer
|
98
|
+
licenses:
|
99
|
+
- MIT
|
100
|
+
metadata: {}
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 2.4.8
|
118
|
+
signing_key:
|
119
|
+
specification_version: 4
|
120
|
+
summary: A collection of common interactive command line user interfaces.
|
121
|
+
test_files: []
|