reline 0.5.9 → 0.5.10

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
  SHA256:
3
- metadata.gz: 28ee53a9963a33e9eb1159bea507695d94cc4f67b05ce005175808b7ec2d5175
4
- data.tar.gz: c165de2edcc223bc4e3e149208fe29994063445ea0cf02b93658010a245df5e4
3
+ metadata.gz: 402ac8415b342c58b741ab1ae942818c44f092d43665d9546fde986572ce2bcf
4
+ data.tar.gz: 0a54115c2e2b02720e67a7870edc77430493b3d2fa89c033046d817b5b984b13
5
5
  SHA512:
6
- metadata.gz: af0f93e54d3a414c63dfb369746f00e8fa9cac609c646c0a48ad5f87275e7b6f5c88c47d4c30218075d3774fd41ba7978f49a0ffbfa070ee42921ba0e500c06e
7
- data.tar.gz: 5b0a45b7ae2cfb0e23c9d3b4a863e381f4d9ba5d6298f864c261e408cb5c366031d6137d623d0d46e3729b7bbe086fc5da5c5e636163bce230ae0f297441e016
6
+ metadata.gz: 0525a60f8fe7512bf23575935d15c7173c825ce6b15a062505d73e9a34836d8b751182280c4b67288af7b949b0417a57a4f384281123ef7b6e90c3072b65f20c
7
+ data.tar.gz: 299034a835b97c80a119614394a650c60104d571ec95ffbff8356531dc1de96cd78b8aa3fa8830520a40d43e4b7feb1958285af29633877a772be7ed995d7d33
data/lib/reline/config.rb CHANGED
@@ -29,6 +29,17 @@ class Reline::Config
29
29
  attr_accessor :autocompletion
30
30
 
31
31
  def initialize
32
+ reset_variables
33
+ end
34
+
35
+ def reset
36
+ if editing_mode_is?(:vi_command)
37
+ @editing_mode_label = :vi_insert
38
+ end
39
+ @oneshot_key_bindings.clear
40
+ end
41
+
42
+ def reset_variables
32
43
  @additional_key_bindings = { # from inputrc
33
44
  emacs: Reline::KeyActor::Base.new,
34
45
  vi_insert: Reline::KeyActor::Base.new,
@@ -51,16 +62,11 @@ class Reline::Config
51
62
  @keyseq_timeout = 500
52
63
  @test_mode = false
53
64
  @autocompletion = false
54
- @convert_meta = true if seven_bit_encoding?(Reline::IOGate.encoding)
65
+ @convert_meta = seven_bit_encoding?(Reline::IOGate.encoding)
55
66
  @loaded = false
56
67
  @enable_bracketed_paste = true
57
- end
58
-
59
- def reset
60
- if editing_mode_is?(:vi_command)
61
- @editing_mode_label = :vi_insert
62
- end
63
- @oneshot_key_bindings.clear
68
+ @show_mode_in_prompt = false
69
+ @default_inputrc_path = nil
64
70
  end
65
71
 
66
72
  def editing_mode
@@ -245,22 +251,6 @@ class Reline::Config
245
251
  rescue ArgumentError
246
252
  @history_size = 500
247
253
  end
248
- when 'bell-style'
249
- @bell_style =
250
- case value
251
- when 'none', 'off'
252
- :none
253
- when 'audible', 'on'
254
- :audible
255
- when 'visible'
256
- :visible
257
- else
258
- :audible
259
- end
260
- when 'comment-begin'
261
- @comment_begin = value.dup
262
- when 'completion-query-items'
263
- @completion_query_items = value.to_i
264
254
  when 'isearch-terminators'
265
255
  @isearch_terminators = retrieve_string(raw_value)
266
256
  when 'editing-mode'
@@ -376,6 +366,11 @@ class Reline::Config
376
366
  ret
377
367
  end
378
368
 
369
+ def reload
370
+ reset_variables
371
+ read
372
+ end
373
+
379
374
  private def seven_bit_encoding?(encoding)
380
375
  encoding == Encoding::US_ASCII
381
376
  end
data/lib/reline/face.rb CHANGED
@@ -107,7 +107,7 @@ class Reline::Face
107
107
 
108
108
  def sgr_rgb_256color(key, value)
109
109
  # 256 colors are
110
- # 0..15: standard colors, hight intensity colors
110
+ # 0..15: standard colors, high intensity colors
111
111
  # 16..232: 216 colors (R, G, B each 6 steps)
112
112
  # 233..255: grayscale colors (24 steps)
113
113
  # This methods converts rgb_expression to 216 colors
@@ -347,6 +347,13 @@ class Reline::ANSI < Reline::IO
347
347
 
348
348
  def set_winch_handler(&handler)
349
349
  @old_winch_handler = Signal.trap('WINCH', &handler)
350
+ @old_cont_handler = Signal.trap('CONT') do
351
+ @input.raw!(intr: true) if @input.tty?
352
+ # Rerender the screen. Note that screen size might be changed while suspended.
353
+ handler.call
354
+ end
355
+ rescue ArgumentError
356
+ # Signal.trap may raise an ArgumentError if the platform doesn't support the signal.
350
357
  end
351
358
 
352
359
  def prep
@@ -360,5 +367,6 @@ class Reline::ANSI < Reline::IO
360
367
  # Disable bracketed paste
361
368
  @output.write "\e[?2004l" if Reline.core.config.enable_bracketed_paste && both_tty?
362
369
  Signal.trap('WINCH', @old_winch_handler) if @old_winch_handler
370
+ Signal.trap('CONT', @old_cont_handler) if @old_cont_handler
363
371
  end
364
372
  end
@@ -159,14 +159,24 @@ class Reline::Windows < Reline::IO
159
159
  FILE_NAME_INFO = 2
160
160
  ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
161
161
 
162
+ # Calling Win32API with console handle is reported to fail after executing some external command.
163
+ # We need to refresh console handle and retry the call again.
164
+ private def call_with_console_handle(win32func, *args)
165
+ val = win32func.call(@hConsoleHandle, *args)
166
+ return val if val != 0
167
+
168
+ @hConsoleHandle = @GetStdHandle.call(STD_OUTPUT_HANDLE)
169
+ win32func.call(@hConsoleHandle, *args)
170
+ end
171
+
162
172
  private def getconsolemode
163
173
  mode = "\000\000\000\000"
164
- @GetConsoleMode.call(@hConsoleHandle, mode)
174
+ call_with_console_handle(@GetConsoleMode, mode)
165
175
  mode.unpack1('L')
166
176
  end
167
177
 
168
178
  private def setconsolemode(mode)
169
- @SetConsoleMode.call(@hConsoleHandle, mode)
179
+ call_with_console_handle(@SetConsoleMode, mode)
170
180
  end
171
181
 
172
182
  #if @legacy_console
@@ -334,7 +344,7 @@ class Reline::Windows < Reline::IO
334
344
  # [18,2] dwMaximumWindowSize.X
335
345
  # [20,2] dwMaximumWindowSize.Y
336
346
  csbi = 0.chr * 22
337
- return if @GetConsoleScreenBufferInfo.call(@hConsoleHandle, csbi) == 0
347
+ return if call_with_console_handle(@GetConsoleScreenBufferInfo, csbi) == 0
338
348
  csbi
339
349
  end
340
350
 
@@ -355,14 +365,14 @@ class Reline::Windows < Reline::IO
355
365
  end
356
366
 
357
367
  def move_cursor_column(val)
358
- @SetConsoleCursorPosition.call(@hConsoleHandle, cursor_pos.y * 65536 + val)
368
+ call_with_console_handle(@SetConsoleCursorPosition, cursor_pos.y * 65536 + val)
359
369
  end
360
370
 
361
371
  def move_cursor_up(val)
362
372
  if val > 0
363
373
  y = cursor_pos.y - val
364
374
  y = 0 if y < 0
365
- @SetConsoleCursorPosition.call(@hConsoleHandle, y * 65536 + cursor_pos.x)
375
+ call_with_console_handle(@SetConsoleCursorPosition, y * 65536 + cursor_pos.x)
366
376
  elsif val < 0
367
377
  move_cursor_down(-val)
368
378
  end
@@ -374,7 +384,7 @@ class Reline::Windows < Reline::IO
374
384
  screen_height = get_screen_size.first
375
385
  y = cursor_pos.y + val
376
386
  y = screen_height - 1 if y > (screen_height - 1)
377
- @SetConsoleCursorPosition.call(@hConsoleHandle, (cursor_pos.y + val) * 65536 + cursor_pos.x)
387
+ call_with_console_handle(@SetConsoleCursorPosition, (cursor_pos.y + val) * 65536 + cursor_pos.x)
378
388
  elsif val < 0
379
389
  move_cursor_up(-val)
380
390
  end
@@ -385,8 +395,8 @@ class Reline::Windows < Reline::IO
385
395
  attributes = csbi[8, 2].unpack1('S')
386
396
  cursor = csbi[4, 4].unpack1('L')
387
397
  written = 0.chr * 4
388
- @FillConsoleOutputCharacter.call(@hConsoleHandle, 0x20, get_screen_size.last - cursor_pos.x, cursor, written)
389
- @FillConsoleOutputAttribute.call(@hConsoleHandle, attributes, get_screen_size.last - cursor_pos.x, cursor, written)
398
+ call_with_console_handle(@FillConsoleOutputCharacter, 0x20, get_screen_size.last - cursor_pos.x, cursor, written)
399
+ call_with_console_handle(@FillConsoleOutputAttribute, attributes, get_screen_size.last - cursor_pos.x, cursor, written)
390
400
  end
391
401
 
392
402
  def scroll_down(val)
@@ -404,7 +414,7 @@ class Reline::Windows < Reline::IO
404
414
  scroll_rectangle = [0, val, buffer_width, buffer_lines - val].pack('s4')
405
415
  destination_origin = 0 # y * 65536 + x
406
416
  fill = [' '.ord, attributes].pack('SS')
407
- @ScrollConsoleScreenBuffer.call(@hConsoleHandle, scroll_rectangle, nil, destination_origin, fill)
417
+ call_with_console_handle(@ScrollConsoleScreenBuffer, scroll_rectangle, nil, destination_origin, fill)
408
418
  else
409
419
  origin_x = x + 1
410
420
  origin_y = y - window_top + 1
@@ -423,9 +433,9 @@ class Reline::Windows < Reline::IO
423
433
  fill_length = buffer_width * (window_bottom - window_top + 1)
424
434
  screen_topleft = window_top * 65536
425
435
  written = 0.chr * 4
426
- @FillConsoleOutputCharacter.call(@hConsoleHandle, 0x20, fill_length, screen_topleft, written)
427
- @FillConsoleOutputAttribute.call(@hConsoleHandle, attributes, fill_length, screen_topleft, written)
428
- @SetConsoleCursorPosition.call(@hConsoleHandle, screen_topleft)
436
+ call_with_console_handle(@FillConsoleOutputCharacter, 0x20, fill_length, screen_topleft, written)
437
+ call_with_console_handle(@FillConsoleOutputAttribute, attributes, fill_length, screen_topleft, written)
438
+ call_with_console_handle(@SetConsoleCursorPosition, screen_topleft)
429
439
  else
430
440
  @output.write "\e[2J" "\e[H"
431
441
  end
@@ -439,14 +449,14 @@ class Reline::Windows < Reline::IO
439
449
  size = 100
440
450
  visible = 0 # 0 means false
441
451
  cursor_info = [size, visible].pack('Li')
442
- @SetConsoleCursorInfo.call(@hConsoleHandle, cursor_info)
452
+ call_with_console_handle(@SetConsoleCursorInfo, cursor_info)
443
453
  end
444
454
 
445
455
  def show_cursor
446
456
  size = 100
447
457
  visible = 1 # 1 means true
448
458
  cursor_info = [size, visible].pack('Li')
449
- @SetConsoleCursorInfo.call(@hConsoleHandle, cursor_info)
459
+ call_with_console_handle(@SetConsoleCursorInfo, cursor_info)
450
460
  end
451
461
 
452
462
  def set_winch_handler(&handler)
@@ -176,9 +176,8 @@ class Reline::LineEditor
176
176
  scroll_into_view
177
177
  Reline::IOGate.move_cursor_up @rendered_screen.cursor_y
178
178
  @rendered_screen.base_y = Reline::IOGate.cursor_pos.y
179
- @rendered_screen.lines = []
180
- @rendered_screen.cursor_y = 0
181
- render_differential
179
+ clear_rendered_screen_cache
180
+ render
182
181
  end
183
182
 
184
183
  private def handle_interrupted
@@ -186,11 +185,11 @@ class Reline::LineEditor
186
185
 
187
186
  @interrupted = false
188
187
  clear_dialogs
189
- scrolldown = render_differential
190
- Reline::IOGate.scroll_down scrolldown
188
+ render
189
+ cursor_to_bottom_offset = @rendered_screen.lines.size - @rendered_screen.cursor_y
190
+ Reline::IOGate.scroll_down cursor_to_bottom_offset
191
191
  Reline::IOGate.move_cursor_column 0
192
- @rendered_screen.lines = []
193
- @rendered_screen.cursor_y = 0
192
+ clear_rendered_screen_cache
194
193
  case @old_trap
195
194
  when 'DEFAULT', 'SYSTEM_DEFAULT'
196
195
  raise Interrupt
@@ -460,28 +459,7 @@ class Reline::LineEditor
460
459
  end
461
460
 
462
461
  def render_finished
463
- clear_rendered_lines
464
- render_full_content
465
- end
466
-
467
- def clear_rendered_lines
468
- Reline::IOGate.move_cursor_up @rendered_screen.cursor_y
469
- Reline::IOGate.move_cursor_column 0
470
-
471
- num_lines = @rendered_screen.lines.size
472
- return unless num_lines && num_lines >= 1
473
-
474
- Reline::IOGate.move_cursor_down num_lines - 1
475
- (num_lines - 1).times do
476
- Reline::IOGate.erase_after_cursor
477
- Reline::IOGate.move_cursor_up 1
478
- end
479
- Reline::IOGate.erase_after_cursor
480
- @rendered_screen.lines = []
481
- @rendered_screen.cursor_y = 0
482
- end
483
-
484
- def render_full_content
462
+ render_differential([], 0, 0)
485
463
  lines = @buffer_of_lines.size.times.map do |i|
486
464
  line = prompt_list[i] + modified_lines[i]
487
465
  wrapped_lines, = split_by_width(line, screen_width)
@@ -490,19 +468,13 @@ class Reline::LineEditor
490
468
  @output.puts lines.map { |l| "#{l}\r\n" }.join
491
469
  end
492
470
 
493
- def print_nomultiline_prompt(prompt)
494
- return unless prompt && !@is_multiline
495
-
471
+ def print_nomultiline_prompt
496
472
  # Readline's test `TestRelineAsReadline#test_readline` requires first output to be prompt, not cursor reset escape sequence.
497
- @rendered_screen.lines = [[[0, Reline::Unicode.calculate_width(prompt, true), prompt]]]
498
- @rendered_screen.cursor_y = 0
499
- @output.write prompt
473
+ @output.write @prompt if @prompt && !@is_multiline
500
474
  end
501
475
 
502
- def render_differential
476
+ def render
503
477
  wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
504
-
505
- rendered_lines = @rendered_screen.lines
506
478
  new_lines = wrapped_prompt_and_input_lines.flatten(1)[screen_scroll_top, screen_height].map do |prompt, line|
507
479
  prompt_width = Reline::Unicode.calculate_width(prompt, true)
508
480
  [[0, prompt_width, prompt], [prompt_width, Reline::Unicode.calculate_width(line, true), line]]
@@ -520,12 +492,21 @@ class Reline::LineEditor
520
492
  x_range, y_range = dialog_range dialog, wrapped_cursor_y - screen_scroll_top
521
493
  y_range.each do |row|
522
494
  next if row < 0 || row >= screen_height
495
+
523
496
  dialog_rows = new_lines[row] ||= []
524
497
  # index 0 is for prompt, index 1 is for line, index 2.. is for dialog
525
498
  dialog_rows[index + 2] = [x_range.begin, dialog.width, dialog.contents[row - y_range.begin]]
526
499
  end
527
500
  end
528
501
 
502
+ render_differential new_lines, wrapped_cursor_x, wrapped_cursor_y - screen_scroll_top
503
+ end
504
+
505
+ # Reflects lines to be rendered and new cursor position to the screen
506
+ # by calculating the difference from the previous render.
507
+
508
+ private def render_differential(new_lines, new_cursor_x, new_cursor_y)
509
+ rendered_lines = @rendered_screen.lines
529
510
  cursor_y = @rendered_screen.cursor_y
530
511
  if new_lines != rendered_lines
531
512
  # Hide cursor while rendering to avoid cursor flickering.
@@ -552,11 +533,14 @@ class Reline::LineEditor
552
533
  @rendered_screen.lines = new_lines
553
534
  Reline::IOGate.show_cursor
554
535
  end
555
- y = wrapped_cursor_y - screen_scroll_top
556
- Reline::IOGate.move_cursor_column wrapped_cursor_x
557
- Reline::IOGate.move_cursor_down y - cursor_y
558
- @rendered_screen.cursor_y = y
559
- new_lines.size - y
536
+ Reline::IOGate.move_cursor_column new_cursor_x
537
+ Reline::IOGate.move_cursor_down new_cursor_y - cursor_y
538
+ @rendered_screen.cursor_y = new_cursor_y
539
+ end
540
+
541
+ private def clear_rendered_screen_cache
542
+ @rendered_screen.lines = []
543
+ @rendered_screen.cursor_y = 0
560
544
  end
561
545
 
562
546
  def upper_space_height(wrapped_cursor_y)
@@ -568,7 +552,7 @@ class Reline::LineEditor
568
552
  end
569
553
 
570
554
  def rerender
571
- render_differential unless @in_pasting
555
+ render unless @in_pasting
572
556
  end
573
557
 
574
558
  class DialogProcScope
@@ -1337,7 +1321,7 @@ class Reline::LineEditor
1337
1321
  @confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n")
1338
1322
  end
1339
1323
 
1340
- def insert_pasted_text(text)
1324
+ def insert_multiline_text(text)
1341
1325
  save_old_buffer
1342
1326
  pre = @buffer_of_lines[@line_index].byteslice(0, @byte_pointer)
1343
1327
  post = @buffer_of_lines[@line_index].byteslice(@byte_pointer..)
@@ -1982,9 +1966,8 @@ class Reline::LineEditor
1982
1966
  private def ed_clear_screen(key)
1983
1967
  Reline::IOGate.clear_screen
1984
1968
  @screen_size = Reline::IOGate.get_screen_size
1985
- @rendered_screen.lines = []
1986
1969
  @rendered_screen.base_y = 0
1987
- @rendered_screen.cursor_y = 0
1970
+ clear_rendered_screen_cache
1988
1971
  end
1989
1972
  alias_method :clear_screen, :ed_clear_screen
1990
1973
 
@@ -2259,9 +2242,11 @@ class Reline::LineEditor
2259
2242
  line, cut = byteslice!(current_line, @byte_pointer, byte_pointer_diff)
2260
2243
  elsif byte_pointer_diff < 0
2261
2244
  line, cut = byteslice!(current_line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
2245
+ else
2246
+ return
2262
2247
  end
2263
2248
  copy_for_vi(cut)
2264
- set_current_line(line || '', @byte_pointer + (byte_pointer_diff < 0 ? byte_pointer_diff : 0))
2249
+ set_current_line(line, @byte_pointer + (byte_pointer_diff < 0 ? byte_pointer_diff : 0))
2265
2250
  end
2266
2251
 
2267
2252
  private def vi_yank(key, arg: nil)
@@ -2280,6 +2265,8 @@ class Reline::LineEditor
2280
2265
  cut = current_line.byteslice(@byte_pointer, byte_pointer_diff)
2281
2266
  elsif byte_pointer_diff < 0
2282
2267
  cut = current_line.byteslice(@byte_pointer + byte_pointer_diff, -byte_pointer_diff)
2268
+ else
2269
+ return
2283
2270
  end
2284
2271
  copy_for_vi(cut)
2285
2272
  end
@@ -2554,4 +2541,8 @@ class Reline::LineEditor
2554
2541
  private def set_next_action_state(type, value)
2555
2542
  @next_action_state = [type, value]
2556
2543
  end
2544
+
2545
+ private def re_read_init_file(_key)
2546
+ @config.reload
2547
+ end
2557
2548
  end
@@ -83,7 +83,7 @@ module Reline::Terminfo
83
83
  end
84
84
 
85
85
  def self.setupterm(term, fildes)
86
- errret_int = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT)
86
+ errret_int = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT, Fiddle::RUBY_FREE)
87
87
  ret = @setupterm.(term, fildes, errret_int)
88
88
  case ret
89
89
  when 0 # OK