yap-rawline 0.4.1 → 0.5.0
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/rawline/editor.rb +17 -6
- data/lib/rawline/event_loop.rb +4 -0
- data/lib/rawline/keycode_parser.rb +27 -34
- data/lib/rawline/non_blocking_input.rb +7 -2
- data/lib/rawline/renderer.rb +21 -2
- data/lib/rawline/terminal.rb +9 -2
- data/lib/rawline/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13e2947b290e867550d30cacb28b8cf70896b796
|
4
|
+
data.tar.gz: 7e29e206c43dca81525e1aee74015b8e85b234e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00af0143953fe8b96f103ddd0cdf07660a60883e29d873e7deff86ffe04134cede9f68b4c10af219156926da6581eaf06c5bae7bc133aad55b55efd0a840e2e2
|
7
|
+
data.tar.gz: 646ec77535f43e27d829a38f8b98f5efe1c2f67f1b83a940714f6370cb4ca3dfd3c5a0e2d7b5aeef773f54031481836affb58064e16edb83c06a6b97021c3901
|
data/lib/rawline/editor.rb
CHANGED
@@ -252,22 +252,32 @@ module RawLine
|
|
252
252
|
|
253
253
|
def read_bytes(bytes)
|
254
254
|
return unless bytes.any?
|
255
|
+
@renderer.pause
|
256
|
+
|
257
|
+
Treefell['editor'].puts "read_bytes #{bytes.inspect}"
|
255
258
|
old_position = @line.position
|
256
259
|
|
257
260
|
key_code_sequences = parse_key_code_sequences(bytes)
|
261
|
+
|
262
|
+
Treefell['editor'].puts "key code sequences: #{key_code_sequences.inspect}"
|
258
263
|
key_code_sequences.each do |sequence|
|
259
264
|
@char = sequence
|
260
265
|
if @char == @terminal.keys[:enter] || !@char
|
266
|
+
Treefell['editor'].puts "processing line: #{@line.text.inspect}"
|
267
|
+
@renderer.pause
|
261
268
|
process_line
|
269
|
+
@renderer.unpause
|
262
270
|
else
|
263
271
|
process_character
|
264
272
|
new_position = @line.position
|
265
273
|
end
|
266
274
|
end
|
275
|
+
ensure
|
276
|
+
@renderer.unpause
|
267
277
|
end
|
268
278
|
|
269
279
|
def process_line
|
270
|
-
@event_loop.
|
280
|
+
@event_loop.immediately(name: "process_line", source: self) do
|
271
281
|
add_to_history
|
272
282
|
|
273
283
|
@terminal.snapshot_tty_attrs
|
@@ -276,13 +286,14 @@ module RawLine
|
|
276
286
|
@terminal.move_to_beginning_of_row
|
277
287
|
@terminal.puts
|
278
288
|
end
|
279
|
-
|
280
|
-
@event_loop.
|
281
|
-
|
289
|
+
@event_loop.immediately(name: "line_read", source: self, payload: { line: @line.text.without_ansi.dup })
|
290
|
+
@event_loop.immediately(name: "prepare_new_line", source: self) do
|
291
|
+
history.clear_position
|
292
|
+
reset_line
|
282
293
|
move_to_beginning_of_input
|
283
294
|
end
|
284
|
-
@event_loop.
|
285
|
-
@event_loop.
|
295
|
+
@event_loop.immediately(name: "restore_tty_attrs", source: self) { @terminal.restore_tty_attrs }
|
296
|
+
@event_loop.immediately(name: "render", source: self, payload: { reset: true })
|
286
297
|
end
|
287
298
|
|
288
299
|
#
|
data/lib/rawline/event_loop.rb
CHANGED
@@ -2,6 +2,7 @@ module RawLine
|
|
2
2
|
class KeycodeParser
|
3
3
|
def initialize(keymap)
|
4
4
|
@keymap = keymap
|
5
|
+
@inverted_keymap = @keymap.invert
|
5
6
|
@escape_code = keymap[:escape]
|
6
7
|
end
|
7
8
|
|
@@ -41,45 +42,37 @@ module RawLine
|
|
41
42
|
bytes.pack('C*').force_encoding('UTF-8')
|
42
43
|
end
|
43
44
|
|
44
|
-
def parse_bytes
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
results
|
53
|
-
|
54
|
-
|
55
|
-
results << byte.ord
|
56
|
-
i += 1
|
45
|
+
def parse_bytes bytes
|
46
|
+
if bytes.empty?
|
47
|
+
[]
|
48
|
+
elsif bytes.any?
|
49
|
+
results = []
|
50
|
+
index = 0
|
51
|
+
loop do
|
52
|
+
sequence = byte_sequence_for(bytes[index..-1])
|
53
|
+
results.concat sequence
|
54
|
+
index += sequence.first.is_a?(Array) ? sequence.first.length : sequence.length
|
55
|
+
break if index >= bytes.length
|
57
56
|
end
|
58
|
-
|
59
|
-
break if i >= bytes.length
|
57
|
+
results
|
60
58
|
end
|
61
|
-
results
|
62
59
|
end
|
63
60
|
|
64
|
-
|
65
|
-
|
66
|
-
#
|
67
|
-
# [27,
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
79
|
-
break if i >= bytes.length
|
61
|
+
# This returns the longer possible known byte sequence for the given
|
62
|
+
# bytes. It returns every sequence wrapped in an array so if it knows
|
63
|
+
# about a multi-byte sequence like :left_arrow then it will return
|
64
|
+
# [[27,91,68]]. If it does not have a matching byte sequence it will
|
65
|
+
# return a single element array, e.g. [12].
|
66
|
+
def byte_sequence_for(bytes)
|
67
|
+
if @inverted_keymap[bytes]
|
68
|
+
[bytes]
|
69
|
+
elsif bytes.length == 1
|
70
|
+
bytes
|
71
|
+
elsif bytes.length == 0
|
72
|
+
fail "Bytes cannot be zero length"
|
73
|
+
else
|
74
|
+
byte_sequence_for(bytes[0..-2])
|
80
75
|
end
|
81
|
-
|
82
|
-
sequence.any? ? sequence : nil
|
83
76
|
end
|
84
77
|
end
|
85
78
|
end
|
@@ -18,8 +18,13 @@ module RawLine
|
|
18
18
|
begin
|
19
19
|
file_descriptor_flags = @input.fcntl(Fcntl::F_GETFL, 0)
|
20
20
|
loop do
|
21
|
-
|
22
|
-
|
21
|
+
begin
|
22
|
+
string = @input.read_nonblock(4096)
|
23
|
+
bytes.concat string.bytes
|
24
|
+
rescue EOFError
|
25
|
+
sleep 0.1
|
26
|
+
retry
|
27
|
+
end
|
23
28
|
end
|
24
29
|
rescue IO::WaitReadable
|
25
30
|
# reset flags so O_NONBLOCK is turned off on the file descriptor
|
data/lib/rawline/renderer.rb
CHANGED
@@ -12,9 +12,28 @@ module RawLine
|
|
12
12
|
)
|
13
13
|
end
|
14
14
|
|
15
|
+
def pause
|
16
|
+
@paused = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def unpause
|
20
|
+
@paused = false
|
21
|
+
if @render_on_unpause_kwargs
|
22
|
+
render(**@render_on_unpause_kwargs)
|
23
|
+
@render_on_unpause = nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
15
27
|
def render(reset: false)
|
16
|
-
|
17
|
-
@
|
28
|
+
Treefell['editor'].puts "#{self.class}##{__callee__} reset=#{reset}"
|
29
|
+
if @paused
|
30
|
+
Treefell['editor'].puts " paused"
|
31
|
+
@render_on_unpause_kwargs = {reset: reset}
|
32
|
+
else
|
33
|
+
Treefell['editor'].puts " unpaused"
|
34
|
+
@render_tree.layout
|
35
|
+
@renderer.render(@render_tree, reset: reset)
|
36
|
+
end
|
18
37
|
end
|
19
38
|
|
20
39
|
def render_cursor
|
data/lib/rawline/terminal.rb
CHANGED
@@ -80,18 +80,21 @@ module RawLine
|
|
80
80
|
CursorPosition = Struct.new(:column, :row)
|
81
81
|
|
82
82
|
def raw!
|
83
|
+
return unless @input.isatty
|
83
84
|
@input.raw!
|
84
85
|
end
|
85
86
|
|
86
87
|
def cooked!
|
88
|
+
return unless @input.isatty
|
87
89
|
@input.cooked!
|
88
90
|
end
|
89
91
|
|
90
92
|
def pseudo_cooked!
|
93
|
+
return unless @input.isatty
|
94
|
+
|
91
95
|
old_tty_attrs = Termios.tcgetattr(@input)
|
92
96
|
new_tty_attrs = old_tty_attrs.dup
|
93
97
|
|
94
|
-
|
95
98
|
new_tty_attrs.cflag |= Termios::BRKINT | Termios::ISTRIP | Termios::ICRNL | Termios::IXON
|
96
99
|
|
97
100
|
new_tty_attrs.iflag |= Termios::ICRNL | Termios::IGNBRK
|
@@ -105,10 +108,12 @@ module RawLine
|
|
105
108
|
end
|
106
109
|
|
107
110
|
def snapshot_tty_attrs
|
111
|
+
return unless @input.isatty
|
108
112
|
@snapshotted_tty_attrs << Termios.tcgetattr(@input)
|
109
113
|
end
|
110
114
|
|
111
115
|
def restore_tty_attrs
|
116
|
+
return unless @input.isatty
|
112
117
|
Termios::tcsetattr(@input, Termios::TCSANOW, @snapshotted_tty_attrs.pop)
|
113
118
|
end
|
114
119
|
|
@@ -182,7 +187,9 @@ module RawLine
|
|
182
187
|
end
|
183
188
|
|
184
189
|
def puts(*args)
|
185
|
-
@output.
|
190
|
+
if @output.isatty
|
191
|
+
@output.cooked { @output.puts(*args) }
|
192
|
+
else
|
186
193
|
@output.puts(*args)
|
187
194
|
end
|
188
195
|
end
|
data/lib/rawline/version.rb
CHANGED