reline 0.1.3 → 0.1.4

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
  SHA256:
3
- metadata.gz: d6e100afbceacfa4a270221c7e5158f211dc9972efbbec251108661a380d43b1
4
- data.tar.gz: 051ef05dac8d446be2b0268202da3762d702287650dc05a3041aa7910f481624
3
+ metadata.gz: 41e0f73e51def110f060454c69c3a3a29d3b0cedce2c432cc594df4f6cccf012
4
+ data.tar.gz: c47d69d20e28f8940c86eedba5349892ecf5e5745e83a8c701eab327e326c6ba
5
5
  SHA512:
6
- metadata.gz: '0068601561915d76b2ce265c7de49252941dbe1e57464db9b08876dfd49da6fc12c3821d90d8240b4f64728a4a55a469726233689fa077ef7296796495025295'
7
- data.tar.gz: 4385616c29cba0596c84d98219d658361cae3dc8c9427e8460d1703972995a9adcb242ab252c30fe2abcf712d2d824a4cb41691b44e241a9d711a89da3e0d62d
6
+ metadata.gz: b494460955ab34ccf2e4c0443e76598c692d2846162be5081ecc8234181b47771721e5969fa76acd54bcce7f6d2c3dbc7e6469b23897c144c6233db5c08c915b
7
+ data.tar.gz: 7c0f5bd0caf7f79113b479e9785aa2260536356ff7196fa1d034fe669f60fca7078771575d8002edf18a5c256105e22d550d9b4e0382071e2c240ef0a34b0287
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  [![Build Status](https://travis-ci.com/ruby/reline.svg?branch=master)](https://travis-ci.com/ruby/reline)
2
2
 
3
+ This is a screen capture of *IRB improved by Reline*.
4
+
5
+ ![IRB improved by Reline](https://raw.githubusercontent.com/wiki/ruby/reline/images/irb_improved_by_reline.gif)
6
+
3
7
  # Reline
4
8
 
5
9
  Reline is compatible with the API of Ruby's stdlib 'readline', GNU Readline and Editline by pure Ruby implementation.
@@ -175,7 +175,7 @@ module Reline
175
175
 
176
176
  whole_buffer = line_editor.whole_buffer.dup
177
177
  whole_buffer.taint if RUBY_VERSION < '2.7'
178
- if add_hist and whole_buffer and whole_buffer.chomp.size > 0
178
+ if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0
179
179
  Reline::HISTORY << whole_buffer
180
180
  end
181
181
 
@@ -188,8 +188,8 @@ module Reline
188
188
 
189
189
  line = line_editor.line.dup
190
190
  line.taint if RUBY_VERSION < '2.7'
191
- if add_hist and line and line.chomp.size > 0
192
- Reline::HISTORY << line.chomp
191
+ if add_hist and line and line.chomp("\n").size > 0
192
+ Reline::HISTORY << line.chomp("\n")
193
193
  end
194
194
 
195
195
  line_editor.reset_line if line_editor.line.nil?
@@ -336,8 +336,14 @@ module Reline
336
336
  @ambiguous_width = 2 if Reline::IOGate == Reline::GeneralIO or STDOUT.is_a?(File)
337
337
  return if ambiguous_width
338
338
  Reline::IOGate.move_cursor_column(0)
339
- output.write "\u{25bd}"
340
- @ambiguous_width = Reline::IOGate.cursor_pos.x
339
+ begin
340
+ output.write "\u{25bd}"
341
+ rescue Encoding::UndefinedConversionError
342
+ # LANG=C
343
+ @ambiguous_width = 1
344
+ else
345
+ @ambiguous_width = Reline::IOGate.cursor_pos.x
346
+ end
341
347
  Reline::IOGate.move_cursor_column(0)
342
348
  Reline::IOGate.erase_after_cursor
343
349
  end
@@ -3,8 +3,6 @@ require 'pathname'
3
3
  class Reline::Config
4
4
  attr_reader :test_mode
5
5
 
6
- DEFAULT_PATH = '~/.inputrc'
7
-
8
6
  KEYSEQ_PATTERN = /\\(?:C|Control)-[A-Za-z_]|\\(?:M|Meta)-[0-9A-Za-z_]|\\(?:C|Control)-(?:M|Meta)-[A-Za-z_]|\\(?:M|Meta)-(?:C|Control)-[A-Za-z_]|\\e|\\[\\\"\'abdfnrtv]|\\\d{1,3}|\\x\h{1,2}|./
9
7
 
10
8
  class InvalidInputrc < RuntimeError
@@ -54,7 +52,7 @@ class Reline::Config
54
52
  @key_actors[:emacs] = Reline::KeyActor::Emacs.new
55
53
  @key_actors[:vi_insert] = Reline::KeyActor::ViInsert.new
56
54
  @key_actors[:vi_command] = Reline::KeyActor::ViCommand.new
57
- @history_size = 500
55
+ @history_size = -1 # unlimited
58
56
  @keyseq_timeout = 500
59
57
  @test_mode = false
60
58
  end
@@ -83,8 +81,34 @@ class Reline::Config
83
81
  @key_actors[@keymap_label]
84
82
  end
85
83
 
84
+ def inputrc_path
85
+ case ENV['INPUTRC']
86
+ when nil, ''
87
+ else
88
+ return File.expand_path(ENV['INPUTRC'])
89
+ end
90
+
91
+ # In the XDG Specification, if ~/.config/readline/inputrc exists, then
92
+ # ~/.inputrc should not be read, but for compatibility with GNU Readline,
93
+ # if ~/.inputrc exists, then it is given priority.
94
+ home_rc_path = File.expand_path('~/.inputrc')
95
+ return home_rc_path if File.exist?(home_rc_path)
96
+
97
+ case path = ENV['XDG_CONFIG_HOME']
98
+ when nil, ''
99
+ else
100
+ path = File.join(path, 'readline/inputrc')
101
+ return path if File.exist?(path) and path == File.expand_path(path)
102
+ end
103
+
104
+ path = File.expand_path('~/.config/readline/inputrc')
105
+ return path if File.exist?(path)
106
+
107
+ return home_rc_path
108
+ end
109
+
86
110
  def read(file = nil)
87
- file ||= File.expand_path(ENV['INPUTRC'] || DEFAULT_PATH)
111
+ file ||= inputrc_path
88
112
  begin
89
113
  if file.respond_to?(:readlines)
90
114
  lines = file.readlines
@@ -29,27 +29,47 @@ class Reline::History < Array
29
29
  end
30
30
 
31
31
  def push(*val)
32
- diff = size + val.size - @config.history_size
33
- if diff > 0
34
- if diff <= size
35
- shift(diff)
36
- else
37
- diff -= size
38
- clear
39
- val.shift(diff)
32
+ # If history_size is zero, all histories are dropped.
33
+ return self if @config.history_size.zero?
34
+ # If history_size is negative, history size is unlimited.
35
+ if @config.history_size.positive?
36
+ diff = size + val.size - @config.history_size
37
+ if diff > 0
38
+ if diff <= size
39
+ shift(diff)
40
+ else
41
+ diff -= size
42
+ clear
43
+ val.shift(diff)
44
+ end
40
45
  end
41
46
  end
42
- super(*(val.map{ |v| String.new(v, encoding: Reline.encoding_system_needs) }))
47
+ super(*(val.map{ |v|
48
+ String.new(v, encoding: Reline.encoding_system_needs)
49
+ }))
43
50
  end
44
51
 
45
52
  def <<(val)
46
- shift if size + 1 > @config.history_size
53
+ # If history_size is zero, all histories are dropped.
54
+ return self if @config.history_size.zero?
55
+ # If history_size is negative, history size is unlimited.
56
+ if @config.history_size.positive?
57
+ shift if size + 1 > @config.history_size
58
+ end
47
59
  super(String.new(val, encoding: Reline.encoding_system_needs))
48
60
  end
49
61
 
50
62
  private def check_index(index)
51
63
  index += size if index < 0
52
- raise RangeError.new("index=<#{index}>") if index < -@config.history_size or @config.history_size < index
64
+ if index < -2147483648 or 2147483647 < index
65
+ raise RangeError.new("integer #{index} too big to convert to `int'")
66
+ end
67
+ # If history_size is negative, history size is unlimited.
68
+ if @config.history_size.positive?
69
+ if index < -@config.history_size or @config.history_size < index
70
+ raise RangeError.new("index=<#{index}>")
71
+ end
72
+ end
53
73
  raise IndexError.new("index=<#{index}>") if index < 0 or size <= index
54
74
  index
55
75
  end
@@ -37,9 +37,9 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
37
37
  # 17 ^Q
38
38
  :ed_quoted_insert,
39
39
  # 18 ^R
40
- :ed_search_prev_history,
40
+ :vi_search_prev,
41
41
  # 19 ^S
42
- :ed_search_next_history,
42
+ :vi_search_next,
43
43
  # 20 ^T
44
44
  :ed_transpose_chars,
45
45
  # 21 ^U
@@ -413,11 +413,11 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
413
413
  # 205 M-M
414
414
  :ed_unassigned,
415
415
  # 206 M-N
416
- :ed_search_next_history,
416
+ :vi_search_next,
417
417
  # 207 M-O
418
418
  :ed_sequence_lead_in,
419
419
  # 208 M-P
420
- :ed_search_prev_history,
420
+ :vi_search_prev,
421
421
  # 209 M-Q
422
422
  :ed_unassigned,
423
423
  # 210 M-R
@@ -477,11 +477,11 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
477
477
  # 237 M-m
478
478
  :ed_unassigned,
479
479
  # 238 M-n
480
- :ed_search_next_history,
480
+ :vi_search_next,
481
481
  # 239 M-o
482
482
  :ed_unassigned,
483
483
  # 240 M-p
484
- :ed_search_prev_history,
484
+ :vi_search_prev,
485
485
  # 241 M-q
486
486
  :ed_unassigned,
487
487
  # 242 M-r
@@ -37,7 +37,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
37
37
  # 17 ^Q
38
38
  :ed_ignore,
39
39
  # 18 ^R
40
- :ed_search_prev_history,
40
+ :vi_search_prev,
41
41
  # 19 ^S
42
42
  :ed_ignore,
43
43
  # 20 ^T
@@ -151,7 +151,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
151
151
  # 74 J
152
152
  :vi_join_lines,
153
153
  # 75 K
154
- :ed_search_prev_history,
154
+ :vi_search_prev,
155
155
  # 76 L
156
156
  :ed_unassigned,
157
157
  # 77 M
@@ -37,9 +37,9 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
37
37
  # 17 ^Q
38
38
  :ed_ignore,
39
39
  # 18 ^R
40
- :ed_search_prev_history,
40
+ :vi_search_prev,
41
41
  # 19 ^S
42
- :ed_search_next_history,
42
+ :vi_search_next,
43
43
  # 20 ^T
44
44
  :ed_insert,
45
45
  # 21 ^U
@@ -543,7 +543,7 @@ class Reline::LineEditor
543
543
  return before if before.nil? || before.empty?
544
544
 
545
545
  if after = @output_modifier_proc&.call("#{before.join("\n")}\n", complete: finished?)
546
- after.lines(chomp: true)
546
+ after.lines("\n", chomp: true)
547
547
  else
548
548
  before
549
549
  end
@@ -1330,7 +1330,7 @@ class Reline::LineEditor
1330
1330
  end
1331
1331
  end
1332
1332
 
1333
- private def search_history(key)
1333
+ private def incremental_search_history(key)
1334
1334
  unless @history_pointer
1335
1335
  if @is_multiline
1336
1336
  @line_backup_in_history = whole_buffer
@@ -1411,15 +1411,114 @@ class Reline::LineEditor
1411
1411
  }
1412
1412
  end
1413
1413
 
1414
- private def ed_search_prev_history(key)
1415
- search_history(key)
1414
+ private def vi_search_prev(key)
1415
+ incremental_search_history(key)
1416
1416
  end
1417
- alias_method :reverse_search_history, :ed_search_prev_history
1417
+ alias_method :reverse_search_history, :vi_search_prev
1418
1418
 
1419
- private def ed_search_next_history(key)
1420
- search_history(key)
1419
+ private def vi_search_next(key)
1420
+ incremental_search_history(key)
1421
1421
  end
1422
- alias_method :forward_search_history, :ed_search_next_history
1422
+ alias_method :forward_search_history, :vi_search_next
1423
+
1424
+ private def ed_search_prev_history(key, arg: 1)
1425
+ history = nil
1426
+ h_pointer = nil
1427
+ line_no = nil
1428
+ substr = @line.slice(0, @byte_pointer)
1429
+ if @history_pointer.nil?
1430
+ return if not @line.empty? and substr.empty?
1431
+ history = Reline::HISTORY
1432
+ elsif @history_pointer.zero?
1433
+ history = nil
1434
+ h_pointer = nil
1435
+ else
1436
+ history = Reline::HISTORY.slice(0, @history_pointer)
1437
+ end
1438
+ return if history.nil?
1439
+ if @is_multiline
1440
+ h_pointer = history.rindex { |h|
1441
+ h.split("\n").each_with_index { |l, i|
1442
+ if l.start_with?(substr)
1443
+ line_no = i
1444
+ break
1445
+ end
1446
+ }
1447
+ not line_no.nil?
1448
+ }
1449
+ else
1450
+ h_pointer = history.rindex { |l|
1451
+ l.start_with?(substr)
1452
+ }
1453
+ end
1454
+ return if h_pointer.nil?
1455
+ @history_pointer = h_pointer
1456
+ if @is_multiline
1457
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
1458
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
1459
+ @line_index = line_no
1460
+ @line = @buffer_of_lines.last
1461
+ @rerender_all = true
1462
+ else
1463
+ @line = Reline::HISTORY[@history_pointer]
1464
+ end
1465
+ @cursor_max = calculate_width(@line)
1466
+ arg -= 1
1467
+ ed_search_prev_history(key, arg: arg) if arg > 0
1468
+ end
1469
+ alias_method :history_search_backward, :ed_search_prev_history
1470
+
1471
+ private def ed_search_next_history(key, arg: 1)
1472
+ substr = @line.slice(0, @byte_pointer)
1473
+ if @history_pointer.nil?
1474
+ return
1475
+ elsif @history_pointer == (Reline::HISTORY.size - 1) and not substr.empty?
1476
+ return
1477
+ end
1478
+ history = Reline::HISTORY.slice((@history_pointer + 1)..-1)
1479
+ h_pointer = nil
1480
+ line_no = nil
1481
+ if @is_multiline
1482
+ h_pointer = history.index { |h|
1483
+ h.split("\n").each_with_index { |l, i|
1484
+ if l.start_with?(substr)
1485
+ line_no = i
1486
+ break
1487
+ end
1488
+ }
1489
+ not line_no.nil?
1490
+ }
1491
+ else
1492
+ h_pointer = history.index { |l|
1493
+ l.start_with?(substr)
1494
+ }
1495
+ end
1496
+ h_pointer += @history_pointer + 1 if h_pointer and @history_pointer
1497
+ return if h_pointer.nil? and not substr.empty?
1498
+ @history_pointer = h_pointer
1499
+ if @is_multiline
1500
+ if @history_pointer.nil? and substr.empty?
1501
+ @buffer_of_lines = []
1502
+ @line_index = 0
1503
+ else
1504
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
1505
+ @line_index = line_no
1506
+ end
1507
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
1508
+ @line = @buffer_of_lines.last
1509
+ @rerender_all = true
1510
+ else
1511
+ if @history_pointer.nil? and substr.empty?
1512
+ @line = ''
1513
+ else
1514
+ @line = Reline::HISTORY[@history_pointer]
1515
+ end
1516
+ end
1517
+ @cursor_max = calculate_width(@line)
1518
+ arg -= 1
1519
+ ed_search_next_history(key, arg: arg) if arg > 0
1520
+ end
1521
+ alias_method :history_search_forward, :ed_search_next_history
1423
1522
 
1424
1523
  private def ed_prev_history(key, arg: 1)
1425
1524
  if @is_multiline and @line_index > 0
@@ -1,3 +1,3 @@
1
1
  module Reline
2
- VERSION = '0.1.3'
2
+ VERSION = '0.1.4'
3
3
  end
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.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-14 00:00:00.000000000 Z
11
+ date: 2020-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: io-console