term 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,64 @@
1
+ # cording: utf-8
2
+
3
+ require 'term/redio'
4
+
5
+ require 'term/color'
6
+
7
+ # @author {mailto:cuihaiqin@gmail.com cuihq}
8
+ class String
9
+
10
+ def ok?
11
+ print "#{self}? ".green
12
+ @begin_confirm_pos = IO.hide.pos
13
+ process_confirm_input
14
+ IO.show
15
+ @res
16
+ end
17
+
18
+ private
19
+
20
+ # print confirm.
21
+ def print_confirm(confirm, run)
22
+ IO.to @begin_confirm_pos
23
+ if @res = confirm
24
+ print '✔'.red
25
+ print ' ✖' if run
26
+ else
27
+ print '✔ ' if run
28
+ print '✖'.red
29
+ end
30
+ @confirm_loop = run
31
+ end
32
+
33
+ # process confirm input confirm event.
34
+ def process_confirm_input
35
+ print_confirm(true, true)
36
+ @confirm_loop = true
37
+ while @confirm_loop
38
+ input = IO.input
39
+ process_confirm_mouse_click input
40
+ process_confirm_keyboard_input input[:key]
41
+ end
42
+ end
43
+
44
+ # process confirm mouse confirm event.
45
+ def process_confirm_mouse_click(input)
46
+ if (input[:type] == :left_pressed) && (input[:pos][:y] == @begin_confirm_pos[:y])
47
+ if input[:pos][:x] == @begin_confirm_pos[:x]
48
+ print_confirm(true, false)
49
+ elsif input[:pos][:x] == @begin_confirm_pos[:x] + 2
50
+ print_confirm(false, false)
51
+ end
52
+ end
53
+ end
54
+
55
+ # process confirm keyboard confirm event.
56
+ def process_confirm_keyboard_input(key)
57
+ case key
58
+ when :enter then print_confirm(@res, false)
59
+ when :Y, :y then print_confirm(true, false)
60
+ when :N, :n then print_confirm(false, false)
61
+ when :tab, :down, :left, :space, :up, :right then print_confirm(!@res, true)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,177 @@
1
+ # coding: utf-8
2
+
3
+ require 'io/console'
4
+
5
+ # @author {mailto:cuihaiqin@gmail.com cuihq}
6
+ class IO
7
+ # move cursor to home position (0-0).
8
+ #
9
+ # @return [self] Term self.
10
+ def self.home
11
+ print "\e[H"
12
+ self
13
+ end
14
+
15
+ # save current cursor position & attrs.
16
+ #
17
+ # @return [Term] Term self.
18
+ def self.save
19
+ print "\e7"
20
+ self
21
+ end
22
+
23
+ # restore saved cursor position & attrs.
24
+ #
25
+ # @return [Term] Term self.
26
+ def self.restore
27
+ print "\e8"
28
+ self
29
+ end
30
+
31
+ # make cursor invisible.
32
+ #
33
+ # @return [Term] Term self.
34
+ def self.hide
35
+ print "\e[?25l"
36
+ self
37
+ end
38
+
39
+ # make cursor visible.
40
+ #
41
+ # @return [Term] Term self.
42
+ def self.show
43
+ print "\e[?25h"
44
+ self
45
+ end
46
+
47
+ # query cursor position.
48
+ #
49
+ # @return [Hash] pos cursor position.
50
+ def self.pos
51
+ $stdin.raw do
52
+ print "\e[6n"
53
+ y_axis, x_axis = $stdin.gets('R')[2..-2].split(';')
54
+ { x: x_axis.to_i - 1, y: y_axis.to_i - 1 }
55
+ end
56
+ end
57
+
58
+ # home-positioning to x and y coordinates.
59
+ # @param pos [Hash] opt the coordinates
60
+ # @option opt [Integer] x the x coordinates, default 0
61
+ # @option opt [Integer] y the y coordinates, default 0
62
+ # @return [Term] Term self.
63
+ def self.to(pos)
64
+ x_axis = pos[:x] || 0
65
+ y_axis = pos[:y] || 0
66
+ print "\e[#{y_axis + 1};#{x_axis + 1}H" # ANSI uses 1-1 as home
67
+ self
68
+ end
69
+
70
+ # moves the cursor up by num rows.
71
+ #
72
+ # @param num [Integer] the rows, the default num is 1.
73
+ # @return [Term] Term self.
74
+ def self.up(num = 1)
75
+ print "\e[#{num}A" # CUU
76
+ self
77
+ end
78
+
79
+ # moves the cursor down by num rows.
80
+ #
81
+ # @param num [Integer] the rows, the default num is 1.
82
+ # @return [Term] Term self.
83
+ def self.down(num = 1)
84
+ print "\e[#{num}B" # CUD
85
+ self
86
+ end
87
+
88
+ # moves the cursor forward by num columns.
89
+ #
90
+ # @param num [Integer] the columns, the default num is 1.
91
+ # @return [Term] Term self.
92
+ def self.forward(num = 1)
93
+ print "\e[#{num}C" # CUF
94
+ self
95
+ end
96
+
97
+ # moves the cursor backward by num columns.
98
+ #
99
+ # @param num [Integer] the columns, the default num is 1.
100
+ # @return [Term] Term self.
101
+ def self.backward(num = 1)
102
+ print "\e[#{num}D" # CUB
103
+ self
104
+ end
105
+
106
+ # cursor next line num times.
107
+ #
108
+ # @param num [Integer] the times, the default num is 1.
109
+ # @return [Term] Term self.
110
+ def self.next_line(num = 1)
111
+ print "\e[#{num}E"
112
+ self
113
+ end
114
+
115
+ # cursor preceding line num times.
116
+ #
117
+ # @param num [Integer] the times, the default num is 1.
118
+ # @return [Term] Term self.
119
+ def self.prev_line(num = 1)
120
+ print "\e[#{num}F"
121
+ self
122
+ end
123
+
124
+ # clear screen.
125
+ #
126
+ # @note cursor position unchanged
127
+ # @return [Term] Term self.
128
+ def self.clear
129
+ print "\e[2J"
130
+ self
131
+ end
132
+
133
+ # clear line from current cursor position to end of line.
134
+ #
135
+ # @note cursor position unchanged
136
+ # @return [Term] Term self.
137
+ def self.clear_forward
138
+ print "\e[K"
139
+ self
140
+ end
141
+
142
+ # clear line from beginning to current cursor position.
143
+ #
144
+ # @note cursor position unchanged
145
+ # @return [Term] Term self.
146
+ def self.clear_backward
147
+ print "\e[1K"
148
+ self
149
+ end
150
+
151
+ # clear whole line.
152
+ #
153
+ # @note cursor position unchanged
154
+ # @return [Term] Term self.
155
+ def self.clear_line
156
+ print "\e[2K"
157
+ self
158
+ end
159
+
160
+ # erase the screen from the current line up to the top of the screen.
161
+ #
162
+ # @note cursor position unchanged
163
+ # @return [Term] Term self.
164
+ def self.clear_up
165
+ print "\e[1J"
166
+ self
167
+ end
168
+
169
+ # erase the screen from the current line down to the top of the screen.
170
+ #
171
+ # @note cursor position unchanged
172
+ # @return [Term] Term self.
173
+ def self.clear_down
174
+ print "\e[J"
175
+ self
176
+ end
177
+ end
@@ -0,0 +1,23 @@
1
+ # cording: utf-8
2
+
3
+ require 'artii'
4
+
5
+ # @author {mailto:cuihaiqin@gmail.com cuihq}
6
+ class String
7
+ # string fonts builder cache hash.
8
+ class << self; attr_accessor :fonts end
9
+ @fonts = {}
10
+
11
+ # set the font.
12
+ #
13
+ # @note using `artii` gem.
14
+ # typing `artii -l` to see all fonts.
15
+ # @example
16
+ # puts "term".font('big')
17
+ # @param name [String] the font name
18
+ # @return [String] string with the font style.
19
+ def font(name)
20
+ font_builder = self.class.fonts[name.to_s] ||= Artii::Base.new(font: name)
21
+ font_builder.output self
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ # coding: utf-8
2
+
3
+ require 'term/cursor'
4
+
5
+ # @author {mailto:cuihaiqin@gmail.com cuihq}
6
+ class IO
7
+ # get keybord & mouse key.
8
+ #
9
+ # @return [Hash] keybord & mouse key
10
+ def self.input
11
+ $stdin.raw do
12
+ print "\e[?1000h" # DEC Private Mode Set
13
+ str = $stdin.readpartial(4096).force_encoding('utf-8')
14
+ print "\e[?1000l" # DEC Private Mode Reset
15
+ parse_key_str str
16
+ end
17
+ end
18
+
19
+ # keybord & mouse hash.
20
+ KEY = {
21
+ "\e[A" => :up,
22
+ "\e[B" => :down,
23
+ "\e[C" => :right,
24
+ "\e[D" => :left,
25
+ "\t" => :tab,
26
+ "\r" => :enter,
27
+ ' ' => :space,
28
+ "\e\[M" => :mouse
29
+ }.freeze
30
+
31
+ # parse key str
32
+ def self.parse_key_str(str)
33
+ key = KEY[str[0, 3]] || str.to_sym
34
+ if key == :mouse
35
+ type, mouse_x, mouse_y = str[3, 3].unpack('CCC')
36
+ type = %i(left_pressed scroll_down right_pressed released)[type & 0b11]
37
+ { key: key, type: type, pos: { x: mouse_x - 33, y: mouse_y - 33 } }
38
+ else
39
+ { key: key }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,63 @@
1
+ # coding: utf-8
2
+
3
+ require 'term/input'
4
+
5
+ # @author {mailto:cuihaiqin@gmail.com cuihq}
6
+ class IO
7
+ # get password.
8
+ #
9
+ # @return [String] password
10
+ def self.password
11
+ @begin_password_pos = IO.hide.pos
12
+ hide_password_text
13
+ process_password_input
14
+ IO.show
15
+ @password_text || ''
16
+ end
17
+
18
+ # process password input event.
19
+ def self.process_password_input
20
+ @redio_loop = true
21
+ while @redio_loop
22
+ input = IO.input
23
+ process_password_mouse_click input
24
+ process_password_keyboard_input input[:key]
25
+ end
26
+ end
27
+ private_class_method :process_password_input
28
+
29
+ # process keyboard input event.
30
+ def self.process_password_keyboard_input(key)
31
+ @password_text ||= ''
32
+ @password_text << key.to_s if key.size == 1
33
+ @redio_loop = false if key == :enter
34
+ end
35
+ private_class_method :process_password_keyboard_input
36
+
37
+ # process mouse click event.
38
+ def self.process_password_mouse_click(input)
39
+ type = input[:type]
40
+ pos = input[:pos]
41
+ if (type == :left_pressed) && (pos == @end_password_pos)
42
+ show_password_text
43
+ else
44
+ hide_password_text
45
+ end
46
+ end
47
+ private_class_method :process_password_mouse_click
48
+
49
+ # hide password text.
50
+ def self.hide_password_text
51
+ IO.to(@begin_password_pos).clear_forward
52
+ print '🔑 : ⚫ ⚫ ⚫ ⚫ ⚫ ⚫ ⚫ ⚫ 👁️'
53
+ @end_password_pos ||= IO.pos
54
+ end
55
+ private_class_method :hide_password_text
56
+
57
+ # show password text.
58
+ def self.show_password_text
59
+ IO.to(@begin_password_pos).clear_forward
60
+ print "🔑 : #{@password_text || ''}"
61
+ end
62
+ private_class_method :show_password_text
63
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+
3
+ require 'term/window'
4
+
5
+ # @author {mailto:cuihaiqin@gmail.com cuihq}
6
+ class Numeric
7
+ # get process bar.
8
+ #
9
+ # @example process bar
10
+ # print i.process_bar
11
+ # @param width [Integer] process width
12
+ # @return [String] process bar
13
+ def process_bar(width = IO.width - 8)
14
+ percent = format(' %3d%', self)
15
+ line = '-' * width
16
+ if self <= 0
17
+ "[#{line.insert(0, '🛫')}]#{percent}"
18
+ elsif self >= 100
19
+ "[#{line.insert(-1, '🛬')}]#{percent}"
20
+ else
21
+ "[#{line.insert((self / 100.0 * width).to_i, '✈️')}]#{percent}"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ # coding: utf-8
2
+
3
+ require 'rqrcode'
4
+
5
+ require 'term/color'
6
+
7
+ # @author {mailto:cuihaiqin@gmail.com cuihq}
8
+ class String
9
+ # get qrcode.
10
+ #
11
+ # @return [String] qrcode
12
+ def qrcode
13
+ RQRCode::QRCode.new(self).as_ansi(quiet_zone_size: 0)
14
+ end
15
+ end
@@ -0,0 +1,68 @@
1
+ # coding: utf-8
2
+
3
+ require 'term/cursor'
4
+ require 'term/input'
5
+
6
+ # @author {mailto:cuihaiqin@gmail.com cuihq}
7
+ module Enumerable
8
+ # the redio Component.
9
+ #
10
+ # @example redio
11
+ # ['a', 'b', 7].redio
12
+ # @return [Object] the redio val
13
+ def redio
14
+ size.times { print $/ }
15
+ @begin_pos = IO.up(size).hide.pos
16
+ process_input_redio
17
+ IO.show
18
+ @redio_res
19
+ end
20
+
21
+ private
22
+
23
+ # print redio.
24
+ def print_redio(index = 0)
25
+ IO.to @begin_pos
26
+ @redio_res = index.to_i % size
27
+ @item_ys = []
28
+ each_with_index do |item, num|
29
+ print_redio_item item, num
30
+ end
31
+ end
32
+
33
+ # print redio item.
34
+ def print_redio_item(item, num)
35
+ @item_ys[num] = IO.pos[:y]
36
+ print "#{@redio_res == num ? '🔘' : '⭕️'} #{num}. #{item}#{$/}"
37
+ end
38
+
39
+ # process redio input.
40
+ def process_input_redio
41
+ print_redio
42
+ @redio_loop = true
43
+ while @redio_loop
44
+ input = IO.input
45
+ process_redio_mouse_click input
46
+ process_redio_keyboard_input input[:key]
47
+ end
48
+ end
49
+
50
+ # process redio mouse click event.
51
+ def process_redio_mouse_click(input)
52
+ if input[:type] == :left_pressed
53
+ list_item = @item_ys.find_index input[:pos][:y]
54
+ print_redio list_item if list_item
55
+ @redio_loop = false
56
+ end
57
+ end
58
+
59
+ # process redio keyboard input event.
60
+ def process_redio_keyboard_input(key)
61
+ case key
62
+ when :enter then @redio_loop = false
63
+ when /\d/ then print_redio(key.to_s)
64
+ when :tab, :down, :left, :space then print_redio(@redio_res.succ)
65
+ when :up, :right then print_redio(@redio_res.pred)
66
+ end
67
+ end
68
+ end