reline 0.1.2 → 0.1.7
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 +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 +350 -126
- data/lib/reline/line_editor.rb.orig +2384 -0
- data/lib/reline/line_editor.rb.rej +81 -0
- data/lib/reline/sibori.rb +170 -0
- data/lib/reline/unicode.rb +93 -15
- 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 +24 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bba0b20f31c4777e7cdce2647964cc5837a1646a000019e0b376da8327b0babe
|
4
|
+
data.tar.gz: 887ac3397cb9f1fcfaf60c61fc90ec31c397fc01516f343fff34bf813b2d8f7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5361850fc7402585b7bf9590299e5e218480a4ecac129b677bd69ae7bbcdde98d48b15d6f098f54fa7b50c5135b8d483085b77d0323c4032f29756b9b77626ea
|
7
|
+
data.tar.gz: b9d33fe3736de66b49338b70dbde2efd49bae38146c4bd3330a5cce97cf230715cc0db27b1efce4e6cb6e005d14df6030cc74427b00e7ef9bcccf46f7b171b01
|
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
@@ -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
|
|