reline 0.1.3 → 0.1.4

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: 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