yap-rawline 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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