reline 0.3.0 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
data/lib/reline.rb CHANGED
@@ -11,12 +11,13 @@ require 'reline/terminfo'
11
11
  require 'rbconfig'
12
12
 
13
13
  module Reline
14
+ # NOTE: For making compatible with the rb-readline gem
14
15
  FILENAME_COMPLETION_PROC = nil
15
16
  USERNAME_COMPLETION_PROC = nil
16
17
 
17
18
  class ConfigEncodingConversionError < StandardError; end
18
19
 
19
- Key = Struct.new('Key', :char, :combined_char, :with_meta) do
20
+ Key = Struct.new(:char, :combined_char, :with_meta) do
20
21
  def match?(other)
21
22
  case other
22
23
  when Reline::Key
@@ -33,7 +34,18 @@ module Reline
33
34
  alias_method :==, :match?
34
35
  end
35
36
  CursorPos = Struct.new(:x, :y)
36
- DialogRenderInfo = Struct.new(:pos, :contents, :bg_color, :width, :height, :scrollbar, keyword_init: true)
37
+ DialogRenderInfo = Struct.new(
38
+ :pos,
39
+ :contents,
40
+ :bg_color,
41
+ :pointer_bg_color,
42
+ :fg_color,
43
+ :pointer_fg_color,
44
+ :width,
45
+ :height,
46
+ :scrollbar,
47
+ keyword_init: true
48
+ )
37
49
 
38
50
  class Core
39
51
  ATTR_READER_NAMES = %i(
@@ -58,6 +70,11 @@ module Reline
58
70
  attr_accessor :last_incremental_search
59
71
  attr_reader :output
60
72
 
73
+ extend Forwardable
74
+ def_delegators :config,
75
+ :autocompletion,
76
+ :autocompletion=
77
+
61
78
  def initialize
62
79
  self.output = STDOUT
63
80
  @dialog_proc_list = {}
@@ -66,44 +83,48 @@ module Reline
66
83
  @bracketed_paste_finished = false
67
84
  end
68
85
 
86
+ def io_gate
87
+ Reline::IOGate
88
+ end
89
+
69
90
  def encoding
70
- Reline::IOGate.encoding
91
+ io_gate.encoding
71
92
  end
72
93
 
73
94
  def completion_append_character=(val)
74
95
  if val.nil?
75
96
  @completion_append_character = nil
76
97
  elsif val.size == 1
77
- @completion_append_character = val.encode(Reline::IOGate.encoding)
98
+ @completion_append_character = val.encode(encoding)
78
99
  elsif val.size > 1
79
- @completion_append_character = val[0].encode(Reline::IOGate.encoding)
100
+ @completion_append_character = val[0].encode(encoding)
80
101
  else
81
102
  @completion_append_character = nil
82
103
  end
83
104
  end
84
105
 
85
106
  def basic_word_break_characters=(v)
86
- @basic_word_break_characters = v.encode(Reline::IOGate.encoding)
107
+ @basic_word_break_characters = v.encode(encoding)
87
108
  end
88
109
 
89
110
  def completer_word_break_characters=(v)
90
- @completer_word_break_characters = v.encode(Reline::IOGate.encoding)
111
+ @completer_word_break_characters = v.encode(encoding)
91
112
  end
92
113
 
93
114
  def basic_quote_characters=(v)
94
- @basic_quote_characters = v.encode(Reline::IOGate.encoding)
115
+ @basic_quote_characters = v.encode(encoding)
95
116
  end
96
117
 
97
118
  def completer_quote_characters=(v)
98
- @completer_quote_characters = v.encode(Reline::IOGate.encoding)
119
+ @completer_quote_characters = v.encode(encoding)
99
120
  end
100
121
 
101
122
  def filename_quote_characters=(v)
102
- @filename_quote_characters = v.encode(Reline::IOGate.encoding)
123
+ @filename_quote_characters = v.encode(encoding)
103
124
  end
104
125
 
105
126
  def special_prefixes=(v)
106
- @special_prefixes = v.encode(Reline::IOGate.encoding)
127
+ @special_prefixes = v.encode(encoding)
107
128
  end
108
129
 
109
130
  def completion_case_fold=(v)
@@ -123,14 +144,6 @@ module Reline
123
144
  @completion_proc = p
124
145
  end
125
146
 
126
- def autocompletion
127
- @config.autocompletion
128
- end
129
-
130
- def autocompletion=(val)
131
- @config.autocompletion = val
132
- end
133
-
134
147
  def output_modifier_proc=(p)
135
148
  raise ArgumentError unless p.respond_to?(:call) or p.nil?
136
149
  @output_modifier_proc = p
@@ -157,9 +170,13 @@ module Reline
157
170
 
158
171
  DialogProc = Struct.new(:dialog_proc, :context)
159
172
  def add_dialog_proc(name_sym, p, context = nil)
160
- raise ArgumentError unless p.respond_to?(:call) or p.nil?
161
173
  raise ArgumentError unless name_sym.instance_of?(Symbol)
162
- @dialog_proc_list[name_sym] = DialogProc.new(p, context)
174
+ if p.nil?
175
+ @dialog_proc_list.delete(name_sym)
176
+ else
177
+ raise ArgumentError unless p.respond_to?(:call)
178
+ @dialog_proc_list[name_sym] = DialogProc.new(p, context)
179
+ end
163
180
  end
164
181
 
165
182
  def dialog_proc(name_sym)
@@ -168,20 +185,16 @@ module Reline
168
185
 
169
186
  def input=(val)
170
187
  raise TypeError unless val.respond_to?(:getc) or val.nil?
171
- if val.respond_to?(:getc)
172
- if defined?(Reline::ANSI) and Reline::IOGate == Reline::ANSI
173
- Reline::ANSI.input = val
174
- elsif Reline::IOGate == Reline::GeneralIO
175
- Reline::GeneralIO.input = val
176
- end
188
+ if val.respond_to?(:getc) && io_gate.respond_to?(:input=)
189
+ io_gate.input = val
177
190
  end
178
191
  end
179
192
 
180
193
  def output=(val)
181
194
  raise TypeError unless val.respond_to?(:write) or val.nil?
182
195
  @output = val
183
- if defined?(Reline::ANSI) and Reline::IOGate == Reline::ANSI
184
- Reline::ANSI.output = val
196
+ if io_gate.respond_to?(:output=)
197
+ io_gate.output = val
185
198
  end
186
199
  end
187
200
 
@@ -204,7 +217,7 @@ module Reline
204
217
  end
205
218
 
206
219
  def get_screen_size
207
- Reline::IOGate.get_screen_size
220
+ io_gate.get_screen_size
208
221
  end
209
222
 
210
223
  Reline::DEFAULT_DIALOG_PROC_AUTOCOMPLETE = ->() {
@@ -243,27 +256,40 @@ module Reline
243
256
  context.push(cursor_pos_to_render, result, pointer, dialog)
244
257
  end
245
258
  dialog.pointer = pointer
246
- DialogRenderInfo.new(pos: cursor_pos_to_render, contents: result, scrollbar: true, height: 15)
259
+ DialogRenderInfo.new(
260
+ pos: cursor_pos_to_render,
261
+ contents: result,
262
+ scrollbar: true,
263
+ height: [15, preferred_dialog_height].min,
264
+ bg_color: 46,
265
+ pointer_bg_color: 45,
266
+ fg_color: 37,
267
+ pointer_fg_color: 37
268
+ )
247
269
  }
248
270
  Reline::DEFAULT_DIALOG_CONTEXT = Array.new
249
271
 
250
272
  def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
251
- unless confirm_multiline_termination
252
- raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
253
- end
254
- inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
273
+ Reline.update_iogate
274
+ io_gate.with_raw_input do
275
+ unless confirm_multiline_termination
276
+ raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
277
+ end
278
+ inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
255
279
 
256
- whole_buffer = line_editor.whole_buffer.dup
257
- whole_buffer.taint if RUBY_VERSION < '2.7'
258
- if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0
259
- Reline::HISTORY << whole_buffer
260
- end
280
+ whole_buffer = line_editor.whole_buffer.dup
281
+ whole_buffer.taint if RUBY_VERSION < '2.7'
282
+ if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0
283
+ Reline::HISTORY << whole_buffer
284
+ end
261
285
 
262
- line_editor.reset_line if line_editor.whole_buffer.nil?
263
- whole_buffer
286
+ line_editor.reset_line if line_editor.whole_buffer.nil?
287
+ whole_buffer
288
+ end
264
289
  end
265
290
 
266
291
  def readline(prompt = '', add_hist = false)
292
+ Reline.update_iogate
267
293
  inner_readline(prompt, add_hist, false)
268
294
 
269
295
  line = line_editor.line.dup
@@ -278,7 +304,7 @@ module Reline
278
304
 
279
305
  private def inner_readline(prompt, add_hist, multiline, &confirm_multiline_termination)
280
306
  if ENV['RELINE_STDERR_TTY']
281
- if Reline::IOGate.win?
307
+ if io_gate.win?
282
308
  $stderr = File.open(ENV['RELINE_STDERR_TTY'], 'a')
283
309
  else
284
310
  $stderr.reopen(ENV['RELINE_STDERR_TTY'], 'w')
@@ -286,10 +312,10 @@ module Reline
286
312
  $stderr.sync = true
287
313
  $stderr.puts "Reline is used by #{Process.pid}"
288
314
  end
289
- otio = Reline::IOGate.prep
315
+ otio = io_gate.prep
290
316
 
291
317
  may_req_ambiguous_char_width
292
- line_editor.reset(prompt, encoding: Reline::IOGate.encoding)
318
+ line_editor.reset(prompt, encoding: encoding)
293
319
  if multiline
294
320
  line_editor.multiline_on
295
321
  if block_given?
@@ -313,7 +339,7 @@ module Reline
313
339
  unless config.test_mode
314
340
  config.read
315
341
  config.reset_default_key_bindings
316
- Reline::IOGate.set_default_key_bindings(config)
342
+ io_gate.set_default_key_bindings(config)
317
343
  end
318
344
 
319
345
  line_editor.rerender
@@ -322,9 +348,9 @@ module Reline
322
348
  line_editor.set_signal_handlers
323
349
  prev_pasting_state = false
324
350
  loop do
325
- prev_pasting_state = Reline::IOGate.in_pasting?
351
+ prev_pasting_state = io_gate.in_pasting?
326
352
  read_io(config.keyseq_timeout) { |inputs|
327
- line_editor.set_pasting_state(Reline::IOGate.in_pasting?)
353
+ line_editor.set_pasting_state(io_gate.in_pasting?)
328
354
  inputs.each { |c|
329
355
  line_editor.input_key(c)
330
356
  line_editor.rerender
@@ -334,29 +360,29 @@ module Reline
334
360
  @bracketed_paste_finished = false
335
361
  end
336
362
  }
337
- if prev_pasting_state == true and not Reline::IOGate.in_pasting? and not line_editor.finished?
363
+ if prev_pasting_state == true and not io_gate.in_pasting? and not line_editor.finished?
338
364
  line_editor.set_pasting_state(false)
339
365
  prev_pasting_state = false
340
366
  line_editor.rerender_all
341
367
  end
342
368
  break if line_editor.finished?
343
369
  end
344
- Reline::IOGate.move_cursor_column(0)
370
+ io_gate.move_cursor_column(0)
345
371
  rescue Errno::EIO
346
372
  # Maybe the I/O has been closed.
347
373
  rescue StandardError => e
348
374
  line_editor.finalize
349
- Reline::IOGate.deprep(otio)
375
+ io_gate.deprep(otio)
350
376
  raise e
351
377
  rescue Exception
352
378
  # Including Interrupt
353
379
  line_editor.finalize
354
- Reline::IOGate.deprep(otio)
380
+ io_gate.deprep(otio)
355
381
  raise
356
382
  end
357
383
 
358
384
  line_editor.finalize
359
- Reline::IOGate.deprep(otio)
385
+ io_gate.deprep(otio)
360
386
  end
361
387
 
362
388
  # GNU Readline waits for "keyseq-timeout" milliseconds to see if the ESC
@@ -371,7 +397,7 @@ module Reline
371
397
  private def read_io(keyseq_timeout, &block)
372
398
  buffer = []
373
399
  loop do
374
- c = Reline::IOGate.getc
400
+ c = io_gate.getc
375
401
  if c == -1
376
402
  result = :unmatched
377
403
  @bracketed_paste_finished = true
@@ -411,7 +437,7 @@ module Reline
411
437
  begin
412
438
  succ_c = nil
413
439
  Timeout.timeout(keyseq_timeout / 1000.0) {
414
- succ_c = Reline::IOGate.getc
440
+ succ_c = io_gate.getc
415
441
  }
416
442
  rescue Timeout::Error # cancel matching only when first byte
417
443
  block.([Reline::Key.new(c, c, false)])
@@ -426,7 +452,7 @@ module Reline
426
452
  end
427
453
  return :break
428
454
  when :matching
429
- Reline::IOGate.ungetc(succ_c)
455
+ io_gate.ungetc(succ_c)
430
456
  return :next
431
457
  when :matched
432
458
  buffer << succ_c
@@ -443,7 +469,7 @@ module Reline
443
469
  begin
444
470
  escaped_c = nil
445
471
  Timeout.timeout(keyseq_timeout / 1000.0) {
446
- escaped_c = Reline::IOGate.getc
472
+ escaped_c = io_gate.getc
447
473
  }
448
474
  rescue Timeout::Error # independent ESC
449
475
  block.([Reline::Key.new(c, c, false)])
@@ -466,19 +492,19 @@ module Reline
466
492
  end
467
493
 
468
494
  private def may_req_ambiguous_char_width
469
- @ambiguous_width = 2 if Reline::IOGate == Reline::GeneralIO or STDOUT.is_a?(File)
495
+ @ambiguous_width = 2 if io_gate == Reline::GeneralIO or !STDOUT.tty?
470
496
  return if defined? @ambiguous_width
471
- Reline::IOGate.move_cursor_column(0)
497
+ io_gate.move_cursor_column(0)
472
498
  begin
473
499
  output.write "\u{25bd}"
474
500
  rescue Encoding::UndefinedConversionError
475
501
  # LANG=C
476
502
  @ambiguous_width = 1
477
503
  else
478
- @ambiguous_width = Reline::IOGate.cursor_pos.x
504
+ @ambiguous_width = io_gate.cursor_pos.x
479
505
  end
480
- Reline::IOGate.move_cursor_column(0)
481
- Reline::IOGate.erase_after_cursor
506
+ io_gate.move_cursor_column(0)
507
+ io_gate.erase_after_cursor
482
508
  end
483
509
  end
484
510
 
@@ -541,7 +567,7 @@ module Reline
541
567
  @core ||= Core.new { |core|
542
568
  core.config = Reline::Config.new
543
569
  core.key_stroke = Reline::KeyStroke.new(core.config)
544
- core.line_editor = Reline::LineEditor.new(core.config, Reline::IOGate.encoding)
570
+ core.line_editor = Reline::LineEditor.new(core.config, core.encoding)
545
571
 
546
572
  core.basic_word_break_characters = " \t\n`><=;|&{("
547
573
  core.completer_word_break_characters = " \t\n`><=;|&{("
@@ -554,33 +580,42 @@ module Reline
554
580
  end
555
581
 
556
582
  def self.ungetc(c)
557
- Reline::IOGate.ungetc(c)
583
+ core.io_gate.ungetc(c)
558
584
  end
559
585
 
560
586
  def self.line_editor
561
587
  core.line_editor
562
588
  end
563
- end
564
589
 
565
- require 'reline/general_io'
566
- if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
567
- require 'reline/windows'
568
- if Reline::Windows.msys_tty?
569
- Reline::IOGate = if ENV['TERM'] == 'dumb'
570
- Reline::GeneralIO
571
- else
590
+ def self.update_iogate
591
+ return if core.config.test_mode
592
+
593
+ # Need to change IOGate when `$stdout.tty?` change from false to true by `$stdout.reopen`
594
+ # Example: rails/spring boot the application in non-tty, then run console in tty.
595
+ if ENV['TERM'] != 'dumb' && core.io_gate == Reline::GeneralIO && $stdout.tty?
572
596
  require 'reline/ansi'
573
- Reline::ANSI
597
+ remove_const(:IOGate)
598
+ const_set(:IOGate, Reline::ANSI)
574
599
  end
575
- else
576
- Reline::IOGate = Reline::Windows
577
600
  end
578
- else
579
- Reline::IOGate = if $stdout.isatty
580
- require 'reline/ansi'
581
- Reline::ANSI
601
+ end
602
+
603
+ require 'reline/general_io'
604
+ io = Reline::GeneralIO
605
+ unless ENV['TERM'] == 'dumb'
606
+ case RbConfig::CONFIG['host_os']
607
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
608
+ require 'reline/windows'
609
+ tty = (io = Reline::Windows).msys_tty?
582
610
  else
583
- Reline::GeneralIO
611
+ tty = $stdout.tty?
584
612
  end
585
613
  end
614
+ Reline::IOGate = if tty
615
+ require 'reline/ansi'
616
+ Reline::ANSI
617
+ else
618
+ io
619
+ end
620
+
586
621
  Reline::HISTORY = Reline::History.new(Reline.core.config)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-24 00:00:00.000000000 Z
11
+ date: 2023-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: io-console
@@ -47,7 +47,6 @@ files:
47
47
  - lib/reline/key_stroke.rb
48
48
  - lib/reline/kill_ring.rb
49
49
  - lib/reline/line_editor.rb
50
- - lib/reline/sibori.rb
51
50
  - lib/reline/terminfo.rb
52
51
  - lib/reline/unicode.rb
53
52
  - lib/reline/unicode/east_asian_width.rb
@@ -66,14 +65,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
66
65
  requirements:
67
66
  - - ">="
68
67
  - !ruby/object:Gem::Version
69
- version: '2.5'
68
+ version: '2.6'
70
69
  required_rubygems_version: !ruby/object:Gem::Requirement
71
70
  requirements:
72
71
  - - ">="
73
72
  - !ruby/object:Gem::Version
74
73
  version: '0'
75
74
  requirements: []
76
- rubygems_version: 3.2.22
75
+ rubygems_version: 3.4.13
77
76
  signing_key:
78
77
  specification_version: 4
79
78
  summary: Alternative GNU Readline or Editline implementation by pure Ruby.
data/lib/reline/sibori.rb DELETED
@@ -1,170 +0,0 @@
1
- require 'reline/unicode'
2
-
3
- =begin
4
-
5
- \ |
6
- \ | <--- whipped cream
7
- \ |
8
- \ |
9
- \-~~|
10
- \ | <--- shibori kutigane (piping nozzle in Japanese)
11
- \Ml
12
- (\ __ __
13
- ( \--( ) )
14
- (__(__)__) <--- compressed whipped cream
15
- =end
16
-
17
- class Sibori
18
- attr_writer :output
19
-
20
- def initialize(width, height, cursor_pos)
21
- @width = width
22
- @height = height
23
- @cursor_pos = cursor_pos
24
- @screen = [String.new]
25
- @line_index = 0
26
- @byte_pointer_in_line = 0
27
- @cleared = false
28
- clone_screen
29
- end
30
-
31
- def clone_screen
32
- @prev_screen = @screen.map { |line|
33
- line.dup
34
- }
35
- @prev_cursor_pos = @cursor_pos.dup
36
- @prev_line_index = @line_index
37
- end
38
-
39
- def print(str)
40
- #$stderr.puts "print #{str.inspect}"
41
- line = @screen[@line_index]
42
- before = line.byteslice(0, @byte_pointer_in_line)
43
- str_width = Reline::Unicode.calculate_width(str, true)
44
- after_cursor = line.byteslice(@byte_pointer_in_line..-1)
45
- after_cursor_width = Reline::Unicode.calculate_width(after_cursor, true)
46
- rest = ''
47
- if after_cursor_width > str_width
48
- rest_byte_pointer = @byte_pointer_in_line + width_to_bytesize(after_cursor, str_width)
49
- rest = line.byteslice(rest_byte_pointer..-1)
50
- end
51
- @screen[@line_index] = before + str + rest
52
- @byte_pointer_in_line += str.bytesize
53
- @cursor_pos.x += Reline::Unicode.calculate_width(str, true)
54
- end
55
-
56
- def move_cursor_column(col)
57
- #$stderr.puts "move_cursor_column(#{col})"
58
- @byte_pointer_in_line = width_to_bytesize(@screen[@line_index], col)
59
- @cursor_pos.x = col
60
- end
61
-
62
- def move_cursor_up(val)
63
- #$stderr.puts "move_cursor_up(#{val})"
64
- if @line_index.positive?
65
- @line_index -= val
66
- @byte_pointer_in_line = width_to_bytesize(@screen[@line_index], @cursor_pos.x)
67
- @cursor_pos.y -= val
68
- end
69
- end
70
-
71
- def move_cursor_down(val)
72
- #$stderr.puts "move_cursor_down(#{val})"
73
- if @line_index < @height - 1
74
- #$stderr.puts "@line_index #{@line_index} @screen.size #{@screen.size} @height #{@height}"
75
- #$stderr.puts @screen.inspect
76
- @line_index += val
77
- @screen[@line_index] = String.new if @line_index == @screen.size
78
- @byte_pointer_in_line = width_to_bytesize(@screen[@line_index], @cursor_pos.x)
79
- @cursor_pos.y += val
80
- end
81
- end
82
-
83
- def scroll_down(val)
84
- #$stderr.puts "scroll_down(#{val})"
85
- if val >= @height
86
- clear_screen
87
- @line_index = @screen.size - 1
88
- return
89
- end
90
- @screen.size.times do |n|
91
- if n < @screen.size - val
92
- #$stderr.puts "A @screen[#{val} + #{n}] (#{@screen[val + n].inspect}) to @screen[#{n}]"
93
- @screen[n] = @screen[val + n]
94
- else
95
- #$stderr.puts "B String.new to @screen[#{n}]"
96
- @screen[n] = String.new
97
- end
98
- end
99
- @line_index += val
100
- end
101
-
102
- def erase_after_cursor
103
- #$stderr.puts "erase_after_cursor"
104
- @screen[@line_index] = @screen[@line_index].byteslice(0, @byte_pointer_in_line)
105
- end
106
-
107
- def clear_screen
108
- #$stderr.puts "clear_screen"
109
- @screen = [String.new]
110
- @line_index = 0
111
- @byte_pointer_in_line = 0
112
- @cursor_pos.x = @cursor_pos.y = 0
113
- @cleared = true
114
- Reline::IOGate.clear_screen
115
- end
116
-
117
- private def width_to_bytesize(str, width)
118
- lines, _ = Reline::Unicode.split_by_width(str, width)
119
- lines.first.bytesize
120
- end
121
-
122
- def render
123
- #$stderr.puts ?* * 100
124
- Reline::IOGate.move_cursor_up(@prev_line_index) if @prev_line_index.positive?
125
- #$stderr.puts "! move_cursor_up(#{@prev_line_index})" if @prev_line_index.positive?
126
- #$stderr.puts "@prev_line_index #{@prev_line_index} @line_index #{@line_index}"
127
- if @screen.size > @prev_screen.size
128
- #$stderr.puts ?a * 100
129
- down = @screen.size - @prev_screen.size
130
- #$stderr.puts "#{@prev_cursor_pos.y} #{down} #{@height}"
131
- if @prev_cursor_pos.y + down > (@height - 1)
132
- #$stderr.puts ?b * 100
133
- scroll = (@prev_cursor_pos.y + down) - (@height - 1)
134
- Reline::IOGate.scroll_down(scroll)
135
- #$stderr.puts "! scroll_down(#{scroll})"
136
- #$stderr.puts "down #{down}"
137
- Reline::IOGate.move_cursor_up(@screen.size - 1 - scroll)
138
- #$stderr.puts "! move_cursor_up(#{@screen.size - 1})"
139
- else
140
- #$stderr.puts ?c * 100
141
- end
142
- end
143
- @screen.size.times do |n|
144
- Reline::IOGate.move_cursor_column(0)
145
- #$stderr.puts "! move_cursor_column(0)"
146
- @output.write @screen[n]
147
- #$stderr.puts "! print #{@screen[n].inspect}"
148
- Reline::IOGate.erase_after_cursor
149
- #$stderr.puts "! erase_after_cursor"
150
- Reline::IOGate.move_cursor_down(1) if n != (@screen.size - 1)
151
- #$stderr.puts "! move_cursor_down(1)" if n != (@screen.size - 1)
152
- end
153
- up = @screen.size - 1 - @line_index
154
- Reline::IOGate.move_cursor_up(up) if up.positive?
155
- #$stderr.puts "! move_cursor_up(#{up})" if up.positive?
156
- column = Reline::Unicode.calculate_width(@screen[@line_index].byteslice(0, @byte_pointer_in_line), true)
157
- Reline::IOGate.move_cursor_column(column)
158
- #$stderr.puts "! move_cursor_column(#{column}) #{@byte_pointer_in_line}"
159
- clone_screen
160
- #$stderr.puts ?- * 10
161
- end
162
-
163
- def prep
164
- Reline::IOGate.prep
165
- end
166
-
167
- def deprep
168
- Reline::IOGate.deprep
169
- end
170
- end