reline 0.0.6 → 0.1.3
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/lib/reline.rb +41 -20
- data/lib/reline/ansi.rb +59 -26
- data/lib/reline/config.rb +6 -4
- data/lib/reline/general_io.rb +8 -0
- data/lib/reline/history.rb +4 -4
- data/lib/reline/key_actor/emacs.rb +2 -2
- data/lib/reline/key_actor/vi_command.rb +1 -1
- data/lib/reline/key_actor/vi_insert.rb +1 -1
- data/lib/reline/line_editor.rb +339 -89
- data/lib/reline/version.rb +1 -1
- data/lib/reline/windows.rb +41 -4
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6e100afbceacfa4a270221c7e5158f211dc9972efbbec251108661a380d43b1
|
4
|
+
data.tar.gz: 051ef05dac8d446be2b0268202da3762d702287650dc05a3041aa7910f481624
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0068601561915d76b2ce265c7de49252941dbe1e57464db9b08876dfd49da6fc12c3821d90d8240b4f64728a4a55a469726233689fa077ef7296796495025295'
|
7
|
+
data.tar.gz: 4385616c29cba0596c84d98219d658361cae3dc8c9427e8460d1703972995a9adcb242ab252c30fe2abcf712d2d824a4cb41691b44e241a9d711a89da3e0d62d
|
data/lib/reline.rb
CHANGED
@@ -32,55 +32,69 @@ module Reline
|
|
32
32
|
dig_perfect_match_proc
|
33
33
|
).each(&method(:attr_reader))
|
34
34
|
|
35
|
-
ATTR_ACCESSOR_NAMES = %i(
|
36
|
-
completion_case_fold
|
37
|
-
).each(&method(:attr_accessor))
|
38
|
-
|
39
35
|
attr_accessor :config
|
40
36
|
attr_accessor :key_stroke
|
41
37
|
attr_accessor :line_editor
|
42
38
|
attr_accessor :ambiguous_width
|
39
|
+
attr_accessor :last_incremental_search
|
43
40
|
attr_reader :output
|
44
41
|
|
45
42
|
def initialize
|
46
43
|
self.output = STDOUT
|
47
44
|
yield self
|
45
|
+
@completion_quote_character = nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def encoding
|
49
|
+
Reline::IOGate.encoding
|
48
50
|
end
|
49
51
|
|
50
52
|
def completion_append_character=(val)
|
51
53
|
if val.nil?
|
52
54
|
@completion_append_character = nil
|
53
55
|
elsif val.size == 1
|
54
|
-
@completion_append_character = val.encode(
|
56
|
+
@completion_append_character = val.encode(Reline::IOGate.encoding)
|
55
57
|
elsif val.size > 1
|
56
|
-
@completion_append_character = val[0].encode(
|
58
|
+
@completion_append_character = val[0].encode(Reline::IOGate.encoding)
|
57
59
|
else
|
58
60
|
@completion_append_character = nil
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
62
64
|
def basic_word_break_characters=(v)
|
63
|
-
@basic_word_break_characters = v.encode(
|
65
|
+
@basic_word_break_characters = v.encode(Reline::IOGate.encoding)
|
64
66
|
end
|
65
67
|
|
66
68
|
def completer_word_break_characters=(v)
|
67
|
-
@completer_word_break_characters = v.encode(
|
69
|
+
@completer_word_break_characters = v.encode(Reline::IOGate.encoding)
|
68
70
|
end
|
69
71
|
|
70
72
|
def basic_quote_characters=(v)
|
71
|
-
@basic_quote_characters = v.encode(
|
73
|
+
@basic_quote_characters = v.encode(Reline::IOGate.encoding)
|
72
74
|
end
|
73
75
|
|
74
76
|
def completer_quote_characters=(v)
|
75
|
-
@completer_quote_characters = v.encode(
|
77
|
+
@completer_quote_characters = v.encode(Reline::IOGate.encoding)
|
76
78
|
end
|
77
79
|
|
78
80
|
def filename_quote_characters=(v)
|
79
|
-
@filename_quote_characters = v.encode(
|
81
|
+
@filename_quote_characters = v.encode(Reline::IOGate.encoding)
|
80
82
|
end
|
81
83
|
|
82
84
|
def special_prefixes=(v)
|
83
|
-
@special_prefixes = v.encode(
|
85
|
+
@special_prefixes = v.encode(Reline::IOGate.encoding)
|
86
|
+
end
|
87
|
+
|
88
|
+
def completion_case_fold=(v)
|
89
|
+
@config.completion_ignore_case = v
|
90
|
+
end
|
91
|
+
|
92
|
+
def completion_case_fold
|
93
|
+
@config.completion_ignore_case
|
94
|
+
end
|
95
|
+
|
96
|
+
def completion_quote_character
|
97
|
+
@completion_quote_character
|
84
98
|
end
|
85
99
|
|
86
100
|
def completion_proc=(p)
|
@@ -191,7 +205,7 @@ module Reline
|
|
191
205
|
otio = Reline::IOGate.prep
|
192
206
|
|
193
207
|
may_req_ambiguous_char_width
|
194
|
-
line_editor.reset(prompt)
|
208
|
+
line_editor.reset(prompt, encoding: Reline::IOGate.encoding)
|
195
209
|
if multiline
|
196
210
|
line_editor.multiline_on
|
197
211
|
if block_given?
|
@@ -202,6 +216,7 @@ module Reline
|
|
202
216
|
end
|
203
217
|
line_editor.output = output
|
204
218
|
line_editor.completion_proc = completion_proc
|
219
|
+
line_editor.completion_append_character = completion_append_character
|
205
220
|
line_editor.output_modifier_proc = output_modifier_proc
|
206
221
|
line_editor.prompt_proc = prompt_proc
|
207
222
|
line_editor.auto_indent_proc = auto_indent_proc
|
@@ -321,7 +336,7 @@ module Reline
|
|
321
336
|
@ambiguous_width = 2 if Reline::IOGate == Reline::GeneralIO or STDOUT.is_a?(File)
|
322
337
|
return if ambiguous_width
|
323
338
|
Reline::IOGate.move_cursor_column(0)
|
324
|
-
|
339
|
+
output.write "\u{25bd}"
|
325
340
|
@ambiguous_width = Reline::IOGate.cursor_pos.x
|
326
341
|
Reline::IOGate.move_cursor_column(0)
|
327
342
|
Reline::IOGate.erase_after_cursor
|
@@ -335,12 +350,14 @@ module Reline
|
|
335
350
|
# Documented API
|
336
351
|
#--------------------------------------------------------
|
337
352
|
|
338
|
-
(Core::ATTR_READER_NAMES
|
353
|
+
(Core::ATTR_READER_NAMES).each { |name|
|
339
354
|
def_single_delegators :core, "#{name}", "#{name}="
|
340
355
|
}
|
341
356
|
def_single_delegators :core, :input=, :output=
|
342
357
|
def_single_delegators :core, :vi_editing_mode, :emacs_editing_mode
|
343
358
|
def_single_delegators :core, :readline
|
359
|
+
def_single_delegators :core, :completion_case_fold, :completion_case_fold=
|
360
|
+
def_single_delegators :core, :completion_quote_character
|
344
361
|
def_instance_delegators self, :readline
|
345
362
|
private :readline
|
346
363
|
|
@@ -367,16 +384,22 @@ module Reline
|
|
367
384
|
def_single_delegator :line_editor, :rerender, :redisplay
|
368
385
|
def_single_delegators :core, :vi_editing_mode?, :emacs_editing_mode?
|
369
386
|
def_single_delegators :core, :ambiguous_width
|
387
|
+
def_single_delegators :core, :last_incremental_search
|
388
|
+
def_single_delegators :core, :last_incremental_search=
|
370
389
|
|
371
390
|
def_single_delegators :core, :readmultiline
|
372
391
|
def_instance_delegators self, :readmultiline
|
373
392
|
private :readmultiline
|
374
393
|
|
394
|
+
def self.encoding_system_needs
|
395
|
+
self.core.encoding
|
396
|
+
end
|
397
|
+
|
375
398
|
def self.core
|
376
399
|
@core ||= Core.new { |core|
|
377
400
|
core.config = Reline::Config.new
|
378
401
|
core.key_stroke = Reline::KeyStroke.new(core.config)
|
379
|
-
core.line_editor = Reline::LineEditor.new(core.config)
|
402
|
+
core.line_editor = Reline::LineEditor.new(core.config, Reline::IOGate.encoding)
|
380
403
|
|
381
404
|
core.basic_word_break_characters = " \t\n`><=;|&{("
|
382
405
|
core.completer_word_break_characters = " \t\n`><=;|&{("
|
@@ -390,14 +413,11 @@ module Reline
|
|
390
413
|
def self.line_editor
|
391
414
|
core.line_editor
|
392
415
|
end
|
393
|
-
|
394
|
-
HISTORY = History.new(core.config)
|
395
416
|
end
|
396
417
|
|
397
418
|
if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
398
419
|
require 'reline/windows'
|
399
|
-
if Reline::Windows.
|
400
|
-
# Maybe Mintty on Cygwin
|
420
|
+
if Reline::Windows.msys_tty?
|
401
421
|
require 'reline/ansi'
|
402
422
|
Reline::IOGate = Reline::ANSI
|
403
423
|
else
|
@@ -407,4 +427,5 @@ else
|
|
407
427
|
require 'reline/ansi'
|
408
428
|
Reline::IOGate = Reline::ANSI
|
409
429
|
end
|
430
|
+
Reline::HISTORY = Reline::History.new(Reline.core.config)
|
410
431
|
require 'reline/general_io'
|
data/lib/reline/ansi.rb
CHANGED
@@ -1,16 +1,49 @@
|
|
1
|
+
require 'io/console'
|
2
|
+
|
1
3
|
class Reline::ANSI
|
4
|
+
def self.encoding
|
5
|
+
Encoding.default_external
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.win?
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
2
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
|
3
17
|
[27, 91, 65] => :ed_prev_history, # ↑
|
4
18
|
[27, 91, 66] => :ed_next_history, # ↓
|
5
19
|
[27, 91, 67] => :ed_next_char, # →
|
6
20
|
[27, 91, 68] => :ed_prev_char, # ←
|
7
|
-
|
8
|
-
|
9
|
-
[27, 91, 52, 126] => :ed_move_to_end, # End
|
21
|
+
|
22
|
+
# KDE
|
10
23
|
[27, 91, 72] => :ed_move_to_beg, # Home
|
11
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
|
+
# GNOME
|
32
|
+
[27, 79, 72] => :ed_move_to_beg, # Home
|
33
|
+
[27, 79, 70] => :ed_move_to_end, # End
|
34
|
+
# Del is 0x08
|
35
|
+
# Arrow keys are the same of KDE
|
36
|
+
|
37
|
+
# others
|
12
38
|
[27, 32] => :em_set_mark, # M-<space>
|
13
39
|
[24, 24] => :em_exchange_mark, # C-x C-x TODO also add Windows
|
40
|
+
[27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→
|
41
|
+
[27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←
|
42
|
+
|
43
|
+
[27, 79, 65] => :ed_prev_history, # ↑
|
44
|
+
[27, 79, 66] => :ed_next_history, # ↓
|
45
|
+
[27, 79, 67] => :ed_next_char, # →
|
46
|
+
[27, 79, 68] => :ed_prev_char, # ←
|
14
47
|
}
|
15
48
|
|
16
49
|
@@input = STDIN
|
@@ -28,7 +61,8 @@ class Reline::ANSI
|
|
28
61
|
unless @@buf.empty?
|
29
62
|
return @@buf.shift
|
30
63
|
end
|
31
|
-
@@input.getbyte
|
64
|
+
c = @@input.raw(intr: true, &:getbyte)
|
65
|
+
(c == 0x16 && @@input.raw(min: 0, tim: 0, &:getbyte)) || c
|
32
66
|
end
|
33
67
|
|
34
68
|
def self.ungetc(c)
|
@@ -36,16 +70,23 @@ class Reline::ANSI
|
|
36
70
|
end
|
37
71
|
|
38
72
|
def self.retrieve_keybuffer
|
73
|
+
begin
|
39
74
|
result = select([@@input], [], [], 0.001)
|
40
75
|
return if result.nil?
|
41
76
|
str = @@input.read_nonblock(1024)
|
42
77
|
str.bytes.each do |c|
|
43
78
|
@@buf.push(c)
|
44
79
|
end
|
80
|
+
rescue EOFError
|
81
|
+
end
|
45
82
|
end
|
46
83
|
|
47
84
|
def self.get_screen_size
|
48
|
-
@@input.winsize
|
85
|
+
s = @@input.winsize
|
86
|
+
return s if s[0] > 0 && s[1] > 0
|
87
|
+
s = [ENV["LINES"].to_i, ENV["COLUMNS"].to_i]
|
88
|
+
return s if s[0] > 0 && s[1] > 0
|
89
|
+
[24, 80]
|
49
90
|
rescue Errno::ENOTTY
|
50
91
|
[24, 80]
|
51
92
|
end
|
@@ -60,14 +101,18 @@ class Reline::ANSI
|
|
60
101
|
def self.cursor_pos
|
61
102
|
begin
|
62
103
|
res = ''
|
104
|
+
m = nil
|
63
105
|
@@input.raw do |stdin|
|
64
106
|
@@output << "\e[6n"
|
65
107
|
@@output.flush
|
66
108
|
while (c = stdin.getc) != 'R'
|
67
109
|
res << c if c
|
68
110
|
end
|
111
|
+
m = res.match(/\e\[(?<row>\d+);(?<column>\d+)/)
|
112
|
+
(m.pre_match + m.post_match).chars.reverse_each do |ch|
|
113
|
+
stdin.ungetc ch
|
114
|
+
end
|
69
115
|
end
|
70
|
-
m = res.match(/(?<row>\d+);(?<column>\d+)/)
|
71
116
|
column = m[:column].to_i - 1
|
72
117
|
row = m[:row].to_i - 1
|
73
118
|
rescue Errno::ENOTTY
|
@@ -79,12 +124,12 @@ class Reline::ANSI
|
|
79
124
|
end
|
80
125
|
|
81
126
|
def self.move_cursor_column(x)
|
82
|
-
|
127
|
+
@@output.write "\e[#{x + 1}G"
|
83
128
|
end
|
84
129
|
|
85
130
|
def self.move_cursor_up(x)
|
86
131
|
if x > 0
|
87
|
-
|
132
|
+
@@output.write "\e[#{x}A" if x > 0
|
88
133
|
elsif x < 0
|
89
134
|
move_cursor_down(-x)
|
90
135
|
end
|
@@ -92,24 +137,24 @@ class Reline::ANSI
|
|
92
137
|
|
93
138
|
def self.move_cursor_down(x)
|
94
139
|
if x > 0
|
95
|
-
|
140
|
+
@@output.write "\e[#{x}B" if x > 0
|
96
141
|
elsif x < 0
|
97
142
|
move_cursor_up(-x)
|
98
143
|
end
|
99
144
|
end
|
100
145
|
|
101
146
|
def self.erase_after_cursor
|
102
|
-
|
147
|
+
@@output.write "\e[K"
|
103
148
|
end
|
104
149
|
|
105
150
|
def self.scroll_down(x)
|
106
151
|
return if x.zero?
|
107
|
-
|
152
|
+
@@output.write "\e[#{x}S"
|
108
153
|
end
|
109
154
|
|
110
155
|
def self.clear_screen
|
111
|
-
|
112
|
-
|
156
|
+
@@output.write "\e[2J"
|
157
|
+
@@output.write "\e[1;1H"
|
113
158
|
end
|
114
159
|
|
115
160
|
@@old_winch_handler = nil
|
@@ -120,24 +165,12 @@ class Reline::ANSI
|
|
120
165
|
def self.prep
|
121
166
|
retrieve_keybuffer
|
122
167
|
int_handle = Signal.trap('INT', 'IGNORE')
|
123
|
-
otio = `stty -g`.chomp
|
124
|
-
setting = ' -echo -icrnl cbreak'
|
125
|
-
stty = `stty -a`
|
126
|
-
if /-parenb\b/ =~ stty
|
127
|
-
setting << ' pass8'
|
128
|
-
end
|
129
|
-
if /\bdsusp *=/ =~ stty
|
130
|
-
setting << ' dsusp undef'
|
131
|
-
end
|
132
|
-
setting << ' -ixoff'
|
133
|
-
`stty #{setting}`
|
134
168
|
Signal.trap('INT', int_handle)
|
135
|
-
|
169
|
+
nil
|
136
170
|
end
|
137
171
|
|
138
172
|
def self.deprep(otio)
|
139
173
|
int_handle = Signal.trap('INT', 'IGNORE')
|
140
|
-
system("stty #{otio}", err: File::NULL)
|
141
174
|
Signal.trap('INT', int_handle)
|
142
175
|
Signal.trap('WINCH', @@old_winch_handler) if @@old_winch_handler
|
143
176
|
end
|
data/lib/reline/config.rb
CHANGED
@@ -157,7 +157,7 @@ class Reline::Config
|
|
157
157
|
case directive
|
158
158
|
when 'if'
|
159
159
|
condition = false
|
160
|
-
case args
|
160
|
+
case args
|
161
161
|
when 'mode'
|
162
162
|
when 'term'
|
163
163
|
when 'version'
|
@@ -184,9 +184,8 @@ class Reline::Config
|
|
184
184
|
|
185
185
|
def bind_variable(name, value)
|
186
186
|
case name
|
187
|
-
when
|
188
|
-
|
189
|
-
instance_variable_set(variable_name, value.nil? || value == '1' || value == 'on')
|
187
|
+
when 'history-size'
|
188
|
+
@history_size = value.to_i
|
190
189
|
when 'bell-style'
|
191
190
|
@bell_style =
|
192
191
|
case value
|
@@ -225,6 +224,9 @@ class Reline::Config
|
|
225
224
|
end
|
226
225
|
when 'keyseq-timeout'
|
227
226
|
@keyseq_timeout = value.to_i
|
227
|
+
when *VARIABLE_NAMES then
|
228
|
+
variable_name = :"@#{name.tr(?-, ?_)}"
|
229
|
+
instance_variable_set(variable_name, value.nil? || value == '1' || value == 'on')
|
228
230
|
end
|
229
231
|
end
|
230
232
|
|
data/lib/reline/general_io.rb
CHANGED
data/lib/reline/history.rb
CHANGED
@@ -13,13 +13,13 @@ class Reline::History < Array
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def [](index)
|
16
|
-
index = check_index(index)
|
16
|
+
index = check_index(index) unless index.is_a?(Range)
|
17
17
|
super(index)
|
18
18
|
end
|
19
19
|
|
20
20
|
def []=(index, val)
|
21
21
|
index = check_index(index)
|
22
|
-
super(index, String.new(val, encoding:
|
22
|
+
super(index, String.new(val, encoding: Reline.encoding_system_needs))
|
23
23
|
end
|
24
24
|
|
25
25
|
def concat(*val)
|
@@ -39,12 +39,12 @@ class Reline::History < Array
|
|
39
39
|
val.shift(diff)
|
40
40
|
end
|
41
41
|
end
|
42
|
-
super(*(val.map{ |v| String.new(v, encoding:
|
42
|
+
super(*(val.map{ |v| String.new(v, encoding: Reline.encoding_system_needs) }))
|
43
43
|
end
|
44
44
|
|
45
45
|
def <<(val)
|
46
46
|
shift if size + 1 > @config.history_size
|
47
|
-
super(String.new(val, encoding:
|
47
|
+
super(String.new(val, encoding: Reline.encoding_system_needs))
|
48
48
|
end
|
49
49
|
|
50
50
|
private def check_index(index)
|
@@ -9,7 +9,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
9
9
|
# 3 ^C
|
10
10
|
:ed_ignore,
|
11
11
|
# 4 ^D
|
12
|
-
:
|
12
|
+
:em_delete,
|
13
13
|
# 5 ^E
|
14
14
|
:ed_move_to_end,
|
15
15
|
# 6 ^F
|
@@ -39,7 +39,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
39
39
|
# 18 ^R
|
40
40
|
:ed_search_prev_history,
|
41
41
|
# 19 ^S
|
42
|
-
:
|
42
|
+
:ed_search_next_history,
|
43
43
|
# 20 ^T
|
44
44
|
:ed_transpose_chars,
|
45
45
|
# 21 ^U
|