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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8d1c07d4414b6e996e693a064efac3449068024e
4
- data.tar.gz: 5425b7db921aad04459051ec8a237c44aff88645
3
+ metadata.gz: 13e2947b290e867550d30cacb28b8cf70896b796
4
+ data.tar.gz: 7e29e206c43dca81525e1aee74015b8e85b234e5
5
5
  SHA512:
6
- metadata.gz: cf302b38f21ca604e5da6d58f98caf63eaf2d1cf23f7f2971153fca6c1dd39b8bb6d43caf64f7bbae35511786478a0fab3645f6e9f561580d0694550efa7f988
7
- data.tar.gz: 1d40fa9b080716cb5d1b09ce43dba8f1343a2ded4578bfae8a995167c14064cbf00a8a76214f592e5992a487036791fa0f6cd6ba8a438c1bf84494d003c98ecd
6
+ metadata.gz: 00af0143953fe8b96f103ddd0cdf07660a60883e29d873e7deff86ffe04134cede9f68b4c10af219156926da6581eaf06c5bae7bc133aad55b55efd0a840e2e2
7
+ data.tar.gz: 646ec77535f43e27d829a38f8b98f5efe1c2f67f1b83a940714f6370cb4ca3dfd3c5a0e2d7b5aeef773f54031481836affb58064e16edb83c06a6b97021c3901
@@ -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.add_event(name: "process_line", source: self) do
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.add_event(name: "line_read", source: self, payload: { line: @line.text.without_ansi.dup })
281
- @event_loop.add_event(name: "prepare_new_line", source: self) do
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.add_event(name: "restore_tty_attrs", source: self) { @terminal.restore_tty_attrs }
285
- @event_loop.add_event(name: "render", source: self, payload: { reset: true })
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
  #
@@ -38,6 +38,10 @@ module RawLine
38
38
  @events = @events.reject { |event| event[:_event_id] == event_id }
39
39
  end
40
40
 
41
+ def immediately(**event_kwargs, &blk)
42
+ dispatch_event(event_kwargs.merge(_event_callback: blk))
43
+ end
44
+
41
45
  def reset
42
46
  @events.clear
43
47
  @counter = 0
@@ -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(bytes)
45
- i = 0
46
- results = []
47
- loop do
48
- byte = bytes[i]
49
-
50
- keycode = find_keycode_for_multi_byte_sequence(bytes[i..-1])
51
- if keycode
52
- results << keycode
53
- i += keycode.length
54
- else
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
- private
65
-
66
- # {:left_arrow=>[27, 91, 68]}
67
- # [27, 91, 68]
68
- def find_keycode_for_multi_byte_sequence(bytes)
69
- i = 0
70
- sequence = []
71
- loop do
72
- byte = bytes[i]
73
- if @keymap.values.any?{ |arr| arr[i] == byte }
74
- sequence << byte
75
- i += 1
76
- else
77
- break
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
- string = @input.read_nonblock(4096)
22
- bytes.concat string.bytes
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
@@ -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
- @render_tree.layout
17
- @renderer.render(@render_tree, reset: reset)
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
@@ -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.cooked do
190
+ if @output.isatty
191
+ @output.cooked { @output.puts(*args) }
192
+ else
186
193
  @output.puts(*args)
187
194
  end
188
195
  end
@@ -1,3 +1,3 @@
1
1
  module RawLine
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yap-rawline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabio Cevasco