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 +4 -4
- data/README.md +4 -0
- data/lib/reline.rb +11 -5
- data/lib/reline/config.rb +28 -4
- data/lib/reline/history.rb +31 -11
- data/lib/reline/key_actor/emacs.rb +6 -6
- data/lib/reline/key_actor/vi_command.rb +2 -2
- data/lib/reline/key_actor/vi_insert.rb +2 -2
- data/lib/reline/line_editor.rb +107 -8
- data/lib/reline/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41e0f73e51def110f060454c69c3a3a29d3b0cedce2c432cc594df4f6cccf012
|
4
|
+
data.tar.gz: c47d69d20e28f8940c86eedba5349892ecf5e5745e83a8c701eab327e326c6ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
data/lib/reline.rb
CHANGED
@@ -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
|
-
|
340
|
-
|
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
|
data/lib/reline/config.rb
CHANGED
@@ -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 =
|
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 ||=
|
111
|
+
file ||= inputrc_path
|
88
112
|
begin
|
89
113
|
if file.respond_to?(:readlines)
|
90
114
|
lines = file.readlines
|
data/lib/reline/history.rb
CHANGED
@@ -29,27 +29,47 @@ class Reline::History < Array
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def push(*val)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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|
|
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
|
-
|
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
|
-
|
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
|
-
:
|
40
|
+
:vi_search_prev,
|
41
41
|
# 19 ^S
|
42
|
-
:
|
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
|
-
:
|
416
|
+
:vi_search_next,
|
417
417
|
# 207 M-O
|
418
418
|
:ed_sequence_lead_in,
|
419
419
|
# 208 M-P
|
420
|
-
:
|
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
|
-
:
|
480
|
+
:vi_search_next,
|
481
481
|
# 239 M-o
|
482
482
|
:ed_unassigned,
|
483
483
|
# 240 M-p
|
484
|
-
:
|
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
|
-
:
|
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
|
-
:
|
154
|
+
:vi_search_prev,
|
155
155
|
# 76 L
|
156
156
|
:ed_unassigned,
|
157
157
|
# 77 M
|
data/lib/reline/line_editor.rb
CHANGED
@@ -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
|
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
|
1415
|
-
|
1414
|
+
private def vi_search_prev(key)
|
1415
|
+
incremental_search_history(key)
|
1416
1416
|
end
|
1417
|
-
alias_method :reverse_search_history, :
|
1417
|
+
alias_method :reverse_search_history, :vi_search_prev
|
1418
1418
|
|
1419
|
-
private def
|
1420
|
-
|
1419
|
+
private def vi_search_next(key)
|
1420
|
+
incremental_search_history(key)
|
1421
1421
|
end
|
1422
|
-
alias_method :forward_search_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
|
data/lib/reline/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2020-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|