reline 0.0.6 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|