inquirer.rb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,13 @@
1
+ require 'inquirer/style'
2
+
3
+ module Inquirer
4
+ class Style
5
+ class Input < Inquirer::Style
6
+
7
+ @@default = '(%s) '
8
+ @@value = '%s'
9
+
10
+ self.activate_getter_setter
11
+ end
12
+ end
13
+ 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,12 @@
1
+ require 'inquirer/style'
2
+
3
+ module Inquirer
4
+ class Style
5
+ class Password < Inquirer::Style::Input
6
+
7
+ @@placeholder_char = '*'
8
+
9
+ self.activate_getter_setter
10
+ end
11
+ end
12
+ 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
@@ -0,0 +1,3 @@
1
+ module Inquirer
2
+ VERSION = '0.0.1'
3
+ 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: []