term 0.9.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.
@@ -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