terminal_rb 0.17.0 → 0.17.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 +4 -4
- data/lib/terminal/input.rb +34 -17
- data/lib/terminal/shell.rb +53 -72
- data/lib/terminal/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3ccb3312146fca100bd13e4c079e5cf6f4a33e73ef9eb526765df1309ae5168e
|
|
4
|
+
data.tar.gz: ce4f5679183067ac7f7d84196db0ad9a06a22878fda79ec302fbacc8047699fa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8a898bce2dc22f5b1d873ace6cef5ea53046318d68bc80062898ec7be43553acde5a7709c1b1043666533e91fbecec3e66dd0372c0adb1642803b4273f0c91d0
|
|
7
|
+
data.tar.gz: d9a06bd5ef76f97a0331bb2e05681fae5103dbe69a21c8e5ac0b97cb7342a6569d0e595b90b00744f22ed9253fc858fdbcd8e81e37ce595bfd1bb830c5cea2b9
|
data/lib/terminal/input.rb
CHANGED
|
@@ -49,14 +49,16 @@ module Terminal
|
|
|
49
49
|
# @return [KeyEvent] next event
|
|
50
50
|
# @return [nil] in error case
|
|
51
51
|
def read_key_event
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
prevent_input_recursion do
|
|
53
|
+
case input_mode
|
|
54
|
+
when :dumb
|
|
55
|
+
raw = read_dumb or return
|
|
56
|
+
opts = @dumb_keys[raw.ord] if raw.size == 1
|
|
57
|
+
KeyEvent.new(raw, *opts)
|
|
58
|
+
when :csi_u, :legacy
|
|
59
|
+
raw = read_tty or return
|
|
60
|
+
KeyEvent[raw]
|
|
61
|
+
end
|
|
60
62
|
end
|
|
61
63
|
end
|
|
62
64
|
|
|
@@ -80,20 +82,33 @@ module Terminal
|
|
|
80
82
|
# when no block was given
|
|
81
83
|
def on_key_event(mouse: false, mouse_move: false, focus: false, &block)
|
|
82
84
|
return unless block
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
85
|
+
prevent_input_recursion do
|
|
86
|
+
case input_mode
|
|
87
|
+
when :dumb
|
|
88
|
+
on_bumb_key_event(&block)
|
|
89
|
+
true
|
|
90
|
+
when :csi_u, :legacy
|
|
91
|
+
on_tty_key_event(mouse_option(mouse, mouse_move, focus), &block)
|
|
92
|
+
true
|
|
93
|
+
else
|
|
94
|
+
false
|
|
95
|
+
end
|
|
92
96
|
end
|
|
93
97
|
end
|
|
94
98
|
|
|
95
99
|
private
|
|
96
100
|
|
|
101
|
+
def prevent_input_recursion
|
|
102
|
+
if (@key_event += 1) != 1
|
|
103
|
+
raise(RuntimeError, 'already reading key events', caller(2))
|
|
104
|
+
end
|
|
105
|
+
begin
|
|
106
|
+
yield
|
|
107
|
+
ensure
|
|
108
|
+
@key_event -= 1
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
97
112
|
def mouse_option(mouse, mouse_move, focus)
|
|
98
113
|
opts = +(mouse ? '1000' : '')
|
|
99
114
|
# highlight: '1001'
|
|
@@ -189,5 +204,7 @@ module Terminal
|
|
|
189
204
|
0x1b => :Esc
|
|
190
205
|
}.compare_by_identity.freeze
|
|
191
206
|
|
|
207
|
+
@key_event = 0
|
|
208
|
+
|
|
192
209
|
autoload :KeyEvent, "#{__dir__}/input/key_event.rb"
|
|
193
210
|
end
|
data/lib/terminal/shell.rb
CHANGED
|
@@ -5,50 +5,43 @@ module Terminal
|
|
|
5
5
|
class << self
|
|
6
6
|
def exec(cmd, env: {}, shell: false, input: nil, **options)
|
|
7
7
|
options = options.except(:in, :out, :err)
|
|
8
|
-
if shell
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
cmd = cmd[0]
|
|
12
|
-
end
|
|
8
|
+
cmd = cmd.map! { _escape(_1) }.join(' ') if shell
|
|
9
|
+
input = Input[input]
|
|
10
|
+
thread = nil
|
|
13
11
|
|
|
14
|
-
input = Input.for(input)
|
|
15
|
-
ret = nil
|
|
16
12
|
with_io(options, input) do |cio, out_r, err_r, in_w|
|
|
17
13
|
thread = Process.detach(Process.spawn(env, *cmd, options))
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
read.delete(out_r)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
if rr.include?(err_r)
|
|
32
|
-
begin
|
|
33
|
-
yield(err_r.readline(chomp: true), :error)
|
|
34
|
-
rescue SystemCallError, IOError
|
|
35
|
-
read.delete(err_r)
|
|
36
|
-
end
|
|
14
|
+
cio.each(&:close)
|
|
15
|
+
read = [out_r, err_r]
|
|
16
|
+
write = [in_w] if in_w
|
|
17
|
+
until read.empty? && write.nil?
|
|
18
|
+
rr, wr, = IO.select(read, write)
|
|
19
|
+
if rr.include?(out_r)
|
|
20
|
+
begin
|
|
21
|
+
yield(out_r.readline(chomp: true), :output)
|
|
22
|
+
rescue SystemCallError, IOError
|
|
23
|
+
read.delete(out_r)
|
|
37
24
|
end
|
|
38
|
-
|
|
25
|
+
end
|
|
26
|
+
if rr.include?(err_r)
|
|
39
27
|
begin
|
|
40
|
-
|
|
41
|
-
in_w.close
|
|
42
|
-
write = nil
|
|
28
|
+
yield(err_r.readline(chomp: true), :error)
|
|
43
29
|
rescue SystemCallError, IOError
|
|
44
|
-
|
|
30
|
+
read.delete(err_r)
|
|
45
31
|
end
|
|
46
32
|
end
|
|
47
|
-
|
|
48
|
-
|
|
33
|
+
next if wr.empty?
|
|
34
|
+
begin
|
|
35
|
+
next if input.call(in_w)
|
|
36
|
+
in_w.close
|
|
37
|
+
write = nil
|
|
38
|
+
rescue SystemCallError, IOError
|
|
39
|
+
write = nil
|
|
40
|
+
end
|
|
49
41
|
end
|
|
50
42
|
end
|
|
51
|
-
|
|
43
|
+
|
|
44
|
+
thread.join.value if thread
|
|
52
45
|
rescue SystemCallError, IOError
|
|
53
46
|
nil
|
|
54
47
|
end
|
|
@@ -70,58 +63,46 @@ module Terminal
|
|
|
70
63
|
end
|
|
71
64
|
|
|
72
65
|
def _escape(str)
|
|
73
|
-
return
|
|
74
|
-
str
|
|
75
|
-
str.gsub!(%r{[^A-Za-z0-9_\-.,:+/@\n]}, "\\\\\\&")
|
|
76
|
-
str.gsub!("\n", "'\n'")
|
|
77
|
-
str
|
|
66
|
+
return "''" if str.empty?
|
|
67
|
+
str.gsub(%r{[^A-Za-z0-9_\-.,:+/@\n]}, "\\\\\\&").gsub("\n", "'\n'")
|
|
78
68
|
end
|
|
79
69
|
end
|
|
80
70
|
|
|
81
71
|
module Input
|
|
82
|
-
def self.
|
|
72
|
+
def self.[](obj)
|
|
83
73
|
return unless obj
|
|
84
|
-
return
|
|
85
|
-
return
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
74
|
+
return copy_writer(obj) if obj.respond_to?(:readpartial)
|
|
75
|
+
return copy_writer(obj.to_io) if obj.respond_to?(:to_io)
|
|
76
|
+
return array_writer(obj) if obj.is_a?(Array)
|
|
77
|
+
if obj.respond_to?(:each)
|
|
78
|
+
return enum_writer(obj.enum_for(:each)) if obj.respond_to?(:enum_for)
|
|
79
|
+
return enum_writer(Enumerator.new { |y| obj.each { y << _1 } })
|
|
80
|
+
end
|
|
81
|
+
return array_writer(obj.to_a) if obj.respond_to?(:to_a)
|
|
82
|
+
proc do |io|
|
|
83
|
+
io.write(obj)
|
|
84
|
+
nil
|
|
85
|
+
end
|
|
96
86
|
end
|
|
97
87
|
|
|
98
|
-
|
|
99
|
-
|
|
88
|
+
def self.copy_writer(src)
|
|
89
|
+
proc do |trg|
|
|
90
|
+
IO.copy_stream(src, trg)
|
|
91
|
+
nil
|
|
92
|
+
end
|
|
100
93
|
end
|
|
101
94
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
def initialize(ary)
|
|
106
|
-
@ry = ary
|
|
107
|
-
@idx = -1
|
|
108
|
-
end
|
|
95
|
+
def self.array_writer(array, idx = -1)
|
|
96
|
+
proc { _1.write(array[idx += 1] || next) }
|
|
109
97
|
end
|
|
110
98
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
io.write(
|
|
99
|
+
def self.enum_writer(enum)
|
|
100
|
+
proc do |io|
|
|
101
|
+
io.write(enum.next)
|
|
114
102
|
rescue StopIteration
|
|
115
|
-
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def initialize(enum)
|
|
119
|
-
return @enum = enum.enum_for(:each) if enum.respond_to?(:enum_for)
|
|
120
|
-
@enum = Enumerator.new { |y| enum.each { y << _1 } }
|
|
103
|
+
nil
|
|
121
104
|
end
|
|
122
105
|
end
|
|
123
|
-
|
|
124
|
-
private_constant :Writer, :CopyWriter, :ArrayWriter, :EnumerableWriter
|
|
125
106
|
end
|
|
126
107
|
|
|
127
108
|
private_constant :Input
|
data/lib/terminal/version.rb
CHANGED