reline 0.1.1 → 0.1.6
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 +4 -4
- data/README.md +4 -0
- data/lib/reline.rb +47 -25
- data/lib/reline/ansi.rb +95 -18
- data/lib/reline/config.rb +69 -10
- data/lib/reline/general_io.rb +12 -0
- data/lib/reline/history.rb +33 -13
- 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/key_stroke.rb +2 -0
- data/lib/reline/line_editor.rb +296 -104
- data/lib/reline/sibori.rb +156 -0
- data/lib/reline/unicode.rb +68 -0
- data/lib/reline/unicode/east_asian_width.rb +1149 -1130
- data/lib/reline/version.rb +1 -1
- data/lib/reline/windows.rb +65 -5
- metadata +22 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0259fdcb2bf55d2b5532e0da9259247dbee06eefc4564e664006218a094d140f'
|
4
|
+
data.tar.gz: ea484914d377faed8c7b346fce10a94e996661950714bac68bf8c604a4bd492b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f108f900ffb86ad334c82f6a64777e78b32e010985f9add33f4ad6ae55f7f1890ed2b16d250d02388ba9b8bc8aed3e985241e3f95b4e43b0d6fe2b9c0ee28057
|
7
|
+
data.tar.gz: eb45c06febe94e7f953f24db1be2375e619c0fb3d270de7dddc3056c0a473438de2c528e78f6d6682b0a35dcd84d901845aba72c0a16346109b3f84de7276702
|
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
[](https://travis-ci.com/ruby/reline)
|
2
2
|
|
3
|
+
This is a screen capture of *IRB improved by Reline*.
|
4
|
+
|
5
|
+

|
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
@@ -7,6 +7,7 @@ require 'reline/key_actor'
|
|
7
7
|
require 'reline/key_stroke'
|
8
8
|
require 'reline/line_editor'
|
9
9
|
require 'reline/history'
|
10
|
+
require 'rbconfig'
|
10
11
|
|
11
12
|
module Reline
|
12
13
|
FILENAME_COMPLETION_PROC = nil
|
@@ -45,40 +46,44 @@ module Reline
|
|
45
46
|
@completion_quote_character = nil
|
46
47
|
end
|
47
48
|
|
49
|
+
def encoding
|
50
|
+
Reline::IOGate.encoding
|
51
|
+
end
|
52
|
+
|
48
53
|
def completion_append_character=(val)
|
49
54
|
if val.nil?
|
50
55
|
@completion_append_character = nil
|
51
56
|
elsif val.size == 1
|
52
|
-
@completion_append_character = val.encode(
|
57
|
+
@completion_append_character = val.encode(Reline::IOGate.encoding)
|
53
58
|
elsif val.size > 1
|
54
|
-
@completion_append_character = val[0].encode(
|
59
|
+
@completion_append_character = val[0].encode(Reline::IOGate.encoding)
|
55
60
|
else
|
56
61
|
@completion_append_character = nil
|
57
62
|
end
|
58
63
|
end
|
59
64
|
|
60
65
|
def basic_word_break_characters=(v)
|
61
|
-
@basic_word_break_characters = v.encode(
|
66
|
+
@basic_word_break_characters = v.encode(Reline::IOGate.encoding)
|
62
67
|
end
|
63
68
|
|
64
69
|
def completer_word_break_characters=(v)
|
65
|
-
@completer_word_break_characters = v.encode(
|
70
|
+
@completer_word_break_characters = v.encode(Reline::IOGate.encoding)
|
66
71
|
end
|
67
72
|
|
68
73
|
def basic_quote_characters=(v)
|
69
|
-
@basic_quote_characters = v.encode(
|
74
|
+
@basic_quote_characters = v.encode(Reline::IOGate.encoding)
|
70
75
|
end
|
71
76
|
|
72
77
|
def completer_quote_characters=(v)
|
73
|
-
@completer_quote_characters = v.encode(
|
78
|
+
@completer_quote_characters = v.encode(Reline::IOGate.encoding)
|
74
79
|
end
|
75
80
|
|
76
81
|
def filename_quote_characters=(v)
|
77
|
-
@filename_quote_characters = v.encode(
|
82
|
+
@filename_quote_characters = v.encode(Reline::IOGate.encoding)
|
78
83
|
end
|
79
84
|
|
80
85
|
def special_prefixes=(v)
|
81
|
-
@special_prefixes = v.encode(
|
86
|
+
@special_prefixes = v.encode(Reline::IOGate.encoding)
|
82
87
|
end
|
83
88
|
|
84
89
|
def completion_case_fold=(v)
|
@@ -94,22 +99,22 @@ module Reline
|
|
94
99
|
end
|
95
100
|
|
96
101
|
def completion_proc=(p)
|
97
|
-
raise ArgumentError unless p.respond_to?(:call)
|
102
|
+
raise ArgumentError unless p.respond_to?(:call) or p.nil?
|
98
103
|
@completion_proc = p
|
99
104
|
end
|
100
105
|
|
101
106
|
def output_modifier_proc=(p)
|
102
|
-
raise ArgumentError unless p.respond_to?(:call)
|
107
|
+
raise ArgumentError unless p.respond_to?(:call) or p.nil?
|
103
108
|
@output_modifier_proc = p
|
104
109
|
end
|
105
110
|
|
106
111
|
def prompt_proc=(p)
|
107
|
-
raise ArgumentError unless p.respond_to?(:call)
|
112
|
+
raise ArgumentError unless p.respond_to?(:call) or p.nil?
|
108
113
|
@prompt_proc = p
|
109
114
|
end
|
110
115
|
|
111
116
|
def auto_indent_proc=(p)
|
112
|
-
raise ArgumentError unless p.respond_to?(:call)
|
117
|
+
raise ArgumentError unless p.respond_to?(:call) or p.nil?
|
113
118
|
@auto_indent_proc = p
|
114
119
|
end
|
115
120
|
|
@@ -118,7 +123,7 @@ module Reline
|
|
118
123
|
end
|
119
124
|
|
120
125
|
def dig_perfect_match_proc=(p)
|
121
|
-
raise ArgumentError unless p.respond_to?(:call)
|
126
|
+
raise ArgumentError unless p.respond_to?(:call) or p.nil?
|
122
127
|
@dig_perfect_match_proc = p
|
123
128
|
end
|
124
129
|
|
@@ -171,7 +176,7 @@ module Reline
|
|
171
176
|
|
172
177
|
whole_buffer = line_editor.whole_buffer.dup
|
173
178
|
whole_buffer.taint if RUBY_VERSION < '2.7'
|
174
|
-
if add_hist and whole_buffer and whole_buffer.chomp.size > 0
|
179
|
+
if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0
|
175
180
|
Reline::HISTORY << whole_buffer
|
176
181
|
end
|
177
182
|
|
@@ -184,8 +189,8 @@ module Reline
|
|
184
189
|
|
185
190
|
line = line_editor.line.dup
|
186
191
|
line.taint if RUBY_VERSION < '2.7'
|
187
|
-
if add_hist and line and line.chomp.size > 0
|
188
|
-
Reline::HISTORY << line.chomp
|
192
|
+
if add_hist and line and line.chomp("\n").size > 0
|
193
|
+
Reline::HISTORY << line.chomp("\n")
|
189
194
|
end
|
190
195
|
|
191
196
|
line_editor.reset_line if line_editor.line.nil?
|
@@ -201,7 +206,7 @@ module Reline
|
|
201
206
|
otio = Reline::IOGate.prep
|
202
207
|
|
203
208
|
may_req_ambiguous_char_width
|
204
|
-
line_editor.reset(prompt)
|
209
|
+
line_editor.reset(prompt, encoding: Reline::IOGate.encoding)
|
205
210
|
if multiline
|
206
211
|
line_editor.multiline_on
|
207
212
|
if block_given?
|
@@ -218,7 +223,6 @@ module Reline
|
|
218
223
|
line_editor.auto_indent_proc = auto_indent_proc
|
219
224
|
line_editor.dig_perfect_match_proc = dig_perfect_match_proc
|
220
225
|
line_editor.pre_input_hook = pre_input_hook
|
221
|
-
line_editor.rerender
|
222
226
|
|
223
227
|
unless config.test_mode
|
224
228
|
config.read
|
@@ -228,17 +232,27 @@ module Reline
|
|
228
232
|
end
|
229
233
|
end
|
230
234
|
|
235
|
+
line_editor.rerender
|
236
|
+
|
231
237
|
begin
|
238
|
+
prev_pasting_state = false
|
232
239
|
loop do
|
240
|
+
prev_pasting_state = Reline::IOGate.in_pasting?
|
233
241
|
read_io(config.keyseq_timeout) { |inputs|
|
234
242
|
inputs.each { |c|
|
235
243
|
line_editor.input_key(c)
|
236
244
|
line_editor.rerender
|
237
245
|
}
|
238
246
|
}
|
247
|
+
if prev_pasting_state == true and not Reline::IOGate.in_pasting? and not line_editor.finished?
|
248
|
+
prev_pasting_state = false
|
249
|
+
line_editor.rerender_all
|
250
|
+
end
|
239
251
|
break if line_editor.finished?
|
240
252
|
end
|
241
253
|
Reline::IOGate.move_cursor_column(0)
|
254
|
+
rescue Errno::EIO
|
255
|
+
# Maybe the I/O has been closed.
|
242
256
|
rescue StandardError => e
|
243
257
|
line_editor.finalize
|
244
258
|
Reline::IOGate.deprep(otio)
|
@@ -332,8 +346,14 @@ module Reline
|
|
332
346
|
@ambiguous_width = 2 if Reline::IOGate == Reline::GeneralIO or STDOUT.is_a?(File)
|
333
347
|
return if ambiguous_width
|
334
348
|
Reline::IOGate.move_cursor_column(0)
|
335
|
-
|
336
|
-
|
349
|
+
begin
|
350
|
+
output.write "\u{25bd}"
|
351
|
+
rescue Encoding::UndefinedConversionError
|
352
|
+
# LANG=C
|
353
|
+
@ambiguous_width = 1
|
354
|
+
else
|
355
|
+
@ambiguous_width = Reline::IOGate.cursor_pos.x
|
356
|
+
end
|
337
357
|
Reline::IOGate.move_cursor_column(0)
|
338
358
|
Reline::IOGate.erase_after_cursor
|
339
359
|
end
|
@@ -387,11 +407,15 @@ module Reline
|
|
387
407
|
def_instance_delegators self, :readmultiline
|
388
408
|
private :readmultiline
|
389
409
|
|
410
|
+
def self.encoding_system_needs
|
411
|
+
self.core.encoding
|
412
|
+
end
|
413
|
+
|
390
414
|
def self.core
|
391
415
|
@core ||= Core.new { |core|
|
392
416
|
core.config = Reline::Config.new
|
393
417
|
core.key_stroke = Reline::KeyStroke.new(core.config)
|
394
|
-
core.line_editor = Reline::LineEditor.new(core.config)
|
418
|
+
core.line_editor = Reline::LineEditor.new(core.config, Reline::IOGate.encoding)
|
395
419
|
|
396
420
|
core.basic_word_break_characters = " \t\n`><=;|&{("
|
397
421
|
core.completer_word_break_characters = " \t\n`><=;|&{("
|
@@ -405,14 +429,11 @@ module Reline
|
|
405
429
|
def self.line_editor
|
406
430
|
core.line_editor
|
407
431
|
end
|
408
|
-
|
409
|
-
HISTORY = History.new(core.config)
|
410
432
|
end
|
411
433
|
|
412
434
|
if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
413
435
|
require 'reline/windows'
|
414
|
-
if Reline::Windows.
|
415
|
-
# Maybe Mintty on Cygwin
|
436
|
+
if Reline::Windows.msys_tty?
|
416
437
|
require 'reline/ansi'
|
417
438
|
Reline::IOGate = Reline::ANSI
|
418
439
|
else
|
@@ -422,4 +443,5 @@ else
|
|
422
443
|
require 'reline/ansi'
|
423
444
|
Reline::IOGate = Reline::ANSI
|
424
445
|
end
|
446
|
+
Reline::HISTORY = Reline::History.new(Reline.core.config)
|
425
447
|
require 'reline/general_io'
|
data/lib/reline/ansi.rb
CHANGED
@@ -1,20 +1,59 @@
|
|
1
1
|
require 'io/console'
|
2
2
|
|
3
3
|
class Reline::ANSI
|
4
|
+
def self.encoding
|
5
|
+
Encoding.default_external
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.win?
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
4
12
|
RAW_KEYSTROKE_CONFIG = {
|
13
|
+
# Console (80x25)
|
14
|
+
[27, 91, 49, 126] => :ed_move_to_beg, # Home
|
15
|
+
[27, 91, 52, 126] => :ed_move_to_end, # End
|
16
|
+
[27, 91, 51, 126] => :key_delete, # Del
|
5
17
|
[27, 91, 65] => :ed_prev_history, # ↑
|
6
18
|
[27, 91, 66] => :ed_next_history, # ↓
|
7
19
|
[27, 91, 67] => :ed_next_char, # →
|
8
20
|
[27, 91, 68] => :ed_prev_char, # ←
|
9
|
-
|
10
|
-
|
11
|
-
[27, 91, 52, 126] => :ed_move_to_end, # End
|
21
|
+
|
22
|
+
# KDE
|
12
23
|
[27, 91, 72] => :ed_move_to_beg, # Home
|
13
24
|
[27, 91, 70] => :ed_move_to_end, # End
|
25
|
+
# Del is 0x08
|
26
|
+
[27, 71, 65] => :ed_prev_history, # ↑
|
27
|
+
[27, 71, 66] => :ed_next_history, # ↓
|
28
|
+
[27, 71, 67] => :ed_next_char, # →
|
29
|
+
[27, 71, 68] => :ed_prev_char, # ←
|
30
|
+
|
31
|
+
# urxvt / exoterm
|
32
|
+
[27, 91, 55, 126] => :ed_move_to_beg, # Home
|
33
|
+
[27, 91, 56, 126] => :ed_move_to_end, # End
|
34
|
+
|
35
|
+
# GNOME
|
36
|
+
[27, 79, 72] => :ed_move_to_beg, # Home
|
37
|
+
[27, 79, 70] => :ed_move_to_end, # End
|
38
|
+
# Del is 0x08
|
39
|
+
# Arrow keys are the same of KDE
|
40
|
+
|
41
|
+
# iTerm2
|
42
|
+
[27, 27, 91, 67] => :em_next_word, # Option+→
|
43
|
+
[27, 27, 91, 68] => :ed_prev_word, # Option+←
|
44
|
+
[195, 166] => :em_next_word, # Option+f
|
45
|
+
[195, 162] => :ed_prev_word, # Option+b
|
46
|
+
|
47
|
+
# others
|
14
48
|
[27, 32] => :em_set_mark, # M-<space>
|
15
49
|
[24, 24] => :em_exchange_mark, # C-x C-x TODO also add Windows
|
16
50
|
[27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→
|
17
51
|
[27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←
|
52
|
+
|
53
|
+
[27, 79, 65] => :ed_prev_history, # ↑
|
54
|
+
[27, 79, 66] => :ed_next_history, # ↓
|
55
|
+
[27, 79, 67] => :ed_next_char, # →
|
56
|
+
[27, 79, 68] => :ed_prev_char, # ←
|
18
57
|
}
|
19
58
|
|
20
59
|
@@input = STDIN
|
@@ -32,8 +71,29 @@ class Reline::ANSI
|
|
32
71
|
unless @@buf.empty?
|
33
72
|
return @@buf.shift
|
34
73
|
end
|
35
|
-
c = @@input.raw(intr: true, &:getbyte)
|
74
|
+
until c = @@input.raw(intr: true, &:getbyte)
|
75
|
+
sleep 0.1
|
76
|
+
end
|
36
77
|
(c == 0x16 && @@input.raw(min: 0, tim: 0, &:getbyte)) || c
|
78
|
+
rescue Errno::EIO
|
79
|
+
# Maybe the I/O has been closed.
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.in_pasting?
|
84
|
+
not Reline::IOGate.empty_buffer?
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.empty_buffer?
|
88
|
+
unless @@buf.empty?
|
89
|
+
return false
|
90
|
+
end
|
91
|
+
rs, = IO.select([@@input], [], [], 0.00001)
|
92
|
+
if rs and rs[0]
|
93
|
+
false
|
94
|
+
else
|
95
|
+
true
|
96
|
+
end
|
37
97
|
end
|
38
98
|
|
39
99
|
def self.ungetc(c)
|
@@ -41,16 +101,23 @@ class Reline::ANSI
|
|
41
101
|
end
|
42
102
|
|
43
103
|
def self.retrieve_keybuffer
|
104
|
+
begin
|
44
105
|
result = select([@@input], [], [], 0.001)
|
45
106
|
return if result.nil?
|
46
107
|
str = @@input.read_nonblock(1024)
|
47
108
|
str.bytes.each do |c|
|
48
109
|
@@buf.push(c)
|
49
110
|
end
|
111
|
+
rescue EOFError
|
112
|
+
end
|
50
113
|
end
|
51
114
|
|
52
115
|
def self.get_screen_size
|
53
|
-
@@input.winsize
|
116
|
+
s = @@input.winsize
|
117
|
+
return s if s[0] > 0 && s[1] > 0
|
118
|
+
s = [ENV["LINES"].to_i, ENV["COLUMNS"].to_i]
|
119
|
+
return s if s[0] > 0 && s[1] > 0
|
120
|
+
[24, 80]
|
54
121
|
rescue Errno::ENOTTY
|
55
122
|
[24, 80]
|
56
123
|
end
|
@@ -69,10 +136,13 @@ class Reline::ANSI
|
|
69
136
|
@@input.raw do |stdin|
|
70
137
|
@@output << "\e[6n"
|
71
138
|
@@output.flush
|
72
|
-
|
73
|
-
|
139
|
+
loop do
|
140
|
+
c = stdin.getc
|
141
|
+
next if c.nil?
|
142
|
+
res << c
|
143
|
+
m = res.match(/\e\[(?<row>\d+);(?<column>\d+)R/)
|
144
|
+
break if m
|
74
145
|
end
|
75
|
-
m = res.match(/\e\[(?<row>\d+);(?<column>\d+)/)
|
76
146
|
(m.pre_match + m.post_match).chars.reverse_each do |ch|
|
77
147
|
stdin.ungetc ch
|
78
148
|
end
|
@@ -80,20 +150,27 @@ class Reline::ANSI
|
|
80
150
|
column = m[:column].to_i - 1
|
81
151
|
row = m[:row].to_i - 1
|
82
152
|
rescue Errno::ENOTTY
|
83
|
-
|
84
|
-
|
85
|
-
|
153
|
+
begin
|
154
|
+
buf = @@output.pread(@@output.pos, 0)
|
155
|
+
row = buf.count("\n")
|
156
|
+
column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0
|
157
|
+
rescue Errno::ESPIPE
|
158
|
+
# Just returns column 1 for ambiguous width because this I/O is not
|
159
|
+
# tty and can't seek.
|
160
|
+
row = 0
|
161
|
+
column = 1
|
162
|
+
end
|
86
163
|
end
|
87
164
|
Reline::CursorPos.new(column, row)
|
88
165
|
end
|
89
166
|
|
90
167
|
def self.move_cursor_column(x)
|
91
|
-
|
168
|
+
@@output.write "\e[#{x + 1}G"
|
92
169
|
end
|
93
170
|
|
94
171
|
def self.move_cursor_up(x)
|
95
172
|
if x > 0
|
96
|
-
|
173
|
+
@@output.write "\e[#{x}A" if x > 0
|
97
174
|
elsif x < 0
|
98
175
|
move_cursor_down(-x)
|
99
176
|
end
|
@@ -101,24 +178,24 @@ class Reline::ANSI
|
|
101
178
|
|
102
179
|
def self.move_cursor_down(x)
|
103
180
|
if x > 0
|
104
|
-
|
181
|
+
@@output.write "\e[#{x}B" if x > 0
|
105
182
|
elsif x < 0
|
106
183
|
move_cursor_up(-x)
|
107
184
|
end
|
108
185
|
end
|
109
186
|
|
110
187
|
def self.erase_after_cursor
|
111
|
-
|
188
|
+
@@output.write "\e[K"
|
112
189
|
end
|
113
190
|
|
114
191
|
def self.scroll_down(x)
|
115
192
|
return if x.zero?
|
116
|
-
|
193
|
+
@@output.write "\e[#{x}S"
|
117
194
|
end
|
118
195
|
|
119
196
|
def self.clear_screen
|
120
|
-
|
121
|
-
|
197
|
+
@@output.write "\e[2J"
|
198
|
+
@@output.write "\e[1;1H"
|
122
199
|
end
|
123
200
|
|
124
201
|
@@old_winch_handler = nil
|
data/lib/reline/config.rb
CHANGED
@@ -1,10 +1,6 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
|
3
1
|
class Reline::Config
|
4
2
|
attr_reader :test_mode
|
5
3
|
|
6
|
-
DEFAULT_PATH = '~/.inputrc'
|
7
|
-
|
8
4
|
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
5
|
|
10
6
|
class InvalidInputrc < RuntimeError
|
@@ -37,6 +33,10 @@ class Reline::Config
|
|
37
33
|
show-all-if-ambiguous
|
38
34
|
show-all-if-unmodified
|
39
35
|
visible-stats
|
36
|
+
show-mode-in-prompt
|
37
|
+
vi-cmd-mode-icon
|
38
|
+
vi-ins-mode-icon
|
39
|
+
emacs-mode-string
|
40
40
|
}
|
41
41
|
VARIABLE_NAME_SYMBOLS = VARIABLE_NAMES.map { |v| :"#{v.tr(?-, ?_)}" }
|
42
42
|
VARIABLE_NAME_SYMBOLS.each do |v|
|
@@ -54,7 +54,11 @@ class Reline::Config
|
|
54
54
|
@key_actors[:emacs] = Reline::KeyActor::Emacs.new
|
55
55
|
@key_actors[:vi_insert] = Reline::KeyActor::ViInsert.new
|
56
56
|
@key_actors[:vi_command] = Reline::KeyActor::ViCommand.new
|
57
|
-
@
|
57
|
+
@vi_cmd_mode_icon = '(cmd)'
|
58
|
+
@vi_ins_mode_icon = '(ins)'
|
59
|
+
@emacs_mode_string = '@'
|
60
|
+
# https://tiswww.case.edu/php/chet/readline/readline.html#IDX25
|
61
|
+
@history_size = -1 # unlimited
|
58
62
|
@keyseq_timeout = 500
|
59
63
|
@test_mode = false
|
60
64
|
end
|
@@ -83,8 +87,34 @@ class Reline::Config
|
|
83
87
|
@key_actors[@keymap_label]
|
84
88
|
end
|
85
89
|
|
90
|
+
def inputrc_path
|
91
|
+
case ENV['INPUTRC']
|
92
|
+
when nil, ''
|
93
|
+
else
|
94
|
+
return File.expand_path(ENV['INPUTRC'])
|
95
|
+
end
|
96
|
+
|
97
|
+
# In the XDG Specification, if ~/.config/readline/inputrc exists, then
|
98
|
+
# ~/.inputrc should not be read, but for compatibility with GNU Readline,
|
99
|
+
# if ~/.inputrc exists, then it is given priority.
|
100
|
+
home_rc_path = File.expand_path('~/.inputrc')
|
101
|
+
return home_rc_path if File.exist?(home_rc_path)
|
102
|
+
|
103
|
+
case path = ENV['XDG_CONFIG_HOME']
|
104
|
+
when nil, ''
|
105
|
+
else
|
106
|
+
path = File.join(path, 'readline/inputrc')
|
107
|
+
return path if File.exist?(path) and path == File.expand_path(path)
|
108
|
+
end
|
109
|
+
|
110
|
+
path = File.expand_path('~/.config/readline/inputrc')
|
111
|
+
return path if File.exist?(path)
|
112
|
+
|
113
|
+
return home_rc_path
|
114
|
+
end
|
115
|
+
|
86
116
|
def read(file = nil)
|
87
|
-
file ||=
|
117
|
+
file ||= inputrc_path
|
88
118
|
begin
|
89
119
|
if file.respond_to?(:readlines)
|
90
120
|
lines = file.readlines
|
@@ -135,7 +165,7 @@ class Reline::Config
|
|
135
165
|
|
136
166
|
case line
|
137
167
|
when /^set +([^ ]+) +([^ ]+)/i
|
138
|
-
var, value = $1.downcase, $2
|
168
|
+
var, value = $1.downcase, $2
|
139
169
|
bind_variable(var, value)
|
140
170
|
next
|
141
171
|
when /\s*("#{KEYSEQ_PATTERN}+")\s*:\s*(.*)\s*$/o
|
@@ -184,9 +214,12 @@ class Reline::Config
|
|
184
214
|
|
185
215
|
def bind_variable(name, value)
|
186
216
|
case name
|
187
|
-
when
|
188
|
-
|
189
|
-
|
217
|
+
when 'history-size'
|
218
|
+
begin
|
219
|
+
@history_size = Integer(value)
|
220
|
+
rescue ArgumentError
|
221
|
+
@history_size = 500
|
222
|
+
end
|
190
223
|
when 'bell-style'
|
191
224
|
@bell_style =
|
192
225
|
case value
|
@@ -225,6 +258,32 @@ class Reline::Config
|
|
225
258
|
end
|
226
259
|
when 'keyseq-timeout'
|
227
260
|
@keyseq_timeout = value.to_i
|
261
|
+
when 'show-mode-in-prompt'
|
262
|
+
case value
|
263
|
+
when 'off'
|
264
|
+
@show_mode_in_prompt = false
|
265
|
+
when 'on'
|
266
|
+
@show_mode_in_prompt = true
|
267
|
+
else
|
268
|
+
@show_mode_in_prompt = false
|
269
|
+
end
|
270
|
+
when 'vi-cmd-mode-string'
|
271
|
+
@vi_cmd_mode_icon = retrieve_string(value)
|
272
|
+
when 'vi-ins-mode-string'
|
273
|
+
@vi_ins_mode_icon = retrieve_string(value)
|
274
|
+
when 'emacs-mode-string'
|
275
|
+
@emacs_mode_string = retrieve_string(value)
|
276
|
+
when *VARIABLE_NAMES then
|
277
|
+
variable_name = :"@#{name.tr(?-, ?_)}"
|
278
|
+
instance_variable_set(variable_name, value.nil? || value == '1' || value == 'on')
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def retrieve_string(str)
|
283
|
+
if str =~ /\A"(.*)"\z/
|
284
|
+
parse_keyseq($1).map(&:chr).join
|
285
|
+
else
|
286
|
+
parse_keyseq(str).map(&:chr).join
|
228
287
|
end
|
229
288
|
end
|
230
289
|
|