inquirer.rb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|