reline 0.3.6 → 0.3.8
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/ansi.rb +60 -54
- data/lib/reline/general_io.rb +1 -2
- data/lib/reline/line_editor.rb +3 -1
- data/lib/reline/version.rb +1 -1
- data/lib/reline/windows.rb +1 -1
- data/lib/reline.rb +14 -26
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 709b8943f16732f771d45da031e9676dc01c8b75f0410134a8b1fa8ab590d294
|
4
|
+
data.tar.gz: 04aa52c6ea6a8939402a1554b42bce891bd65a13be6b76cbfd3f4859df1455d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab8a124f732cfa4b8522f397a546fc89ea93f188ca9f44f7f560ea2afb00abbe3b95486c17a20b826d360a8bb064ca441bd357acffe1eb4ec371fbf6380cd37d
|
7
|
+
data.tar.gz: e756e58d4ae8929045998b8278fcee48ba1867741cc4d47bd72beb3e3a74902938d4c8a9dcd4c0452f20b25f5b4fe05eb96929bc39c28f326dc88c9bdf7be458
|
data/lib/reline/ansi.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'io/console'
|
2
2
|
require 'io/wait'
|
3
|
-
require 'timeout'
|
4
3
|
require_relative 'terminfo'
|
5
4
|
|
6
5
|
class Reline::ANSI
|
@@ -14,10 +13,21 @@ class Reline::ANSI
|
|
14
13
|
'kcud1' => :ed_next_history,
|
15
14
|
'kcuf1' => :ed_next_char,
|
16
15
|
'kcub1' => :ed_prev_char,
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
}
|
17
|
+
|
18
|
+
ANSI_CURSOR_KEY_BINDINGS = {
|
19
|
+
# Up
|
20
|
+
'A' => [:ed_prev_history, {}],
|
21
|
+
# Down
|
22
|
+
'B' => [:ed_next_history, {}],
|
23
|
+
# Right
|
24
|
+
'C' => [:ed_next_char, { ctrl: :em_next_word, meta: :em_next_word }],
|
25
|
+
# Left
|
26
|
+
'D' => [:ed_prev_char, { ctrl: :ed_prev_word, meta: :ed_prev_word }],
|
27
|
+
# End
|
28
|
+
'F' => [:ed_move_to_end, {}],
|
29
|
+
# Home
|
30
|
+
'H' => [:ed_move_to_beg, {}],
|
21
31
|
}
|
22
32
|
|
23
33
|
if Reline::Terminfo.enabled?
|
@@ -33,22 +43,12 @@ class Reline::ANSI
|
|
33
43
|
end
|
34
44
|
|
35
45
|
def self.set_default_key_bindings(config, allow_terminfo: true)
|
46
|
+
set_default_key_bindings_ansi_cursor(config)
|
36
47
|
if allow_terminfo && Reline::Terminfo.enabled?
|
37
48
|
set_default_key_bindings_terminfo(config)
|
38
49
|
else
|
39
50
|
set_default_key_bindings_comprehensive_list(config)
|
40
51
|
end
|
41
|
-
{
|
42
|
-
# extended entries of terminfo
|
43
|
-
[27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→, extended entry
|
44
|
-
[27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←, extended entry
|
45
|
-
[27, 91, 49, 59, 51, 67] => :em_next_word, # Meta+→, extended entry
|
46
|
-
[27, 91, 49, 59, 51, 68] => :ed_prev_word, # Meta+←, extended entry
|
47
|
-
}.each_pair do |key, func|
|
48
|
-
config.add_default_key_binding_by_keymap(:emacs, key, func)
|
49
|
-
config.add_default_key_binding_by_keymap(:vi_insert, key, func)
|
50
|
-
config.add_default_key_binding_by_keymap(:vi_command, key, func)
|
51
|
-
end
|
52
52
|
{
|
53
53
|
[27, 91, 90] => :completion_journey_up, # S-Tab
|
54
54
|
}.each_pair do |key, func|
|
@@ -64,18 +64,33 @@ class Reline::ANSI
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
+
def self.set_default_key_bindings_ansi_cursor(config)
|
68
|
+
ANSI_CURSOR_KEY_BINDINGS.each do |char, (default_func, modifiers)|
|
69
|
+
bindings = [["\e[#{char}", default_func]] # CSI + char
|
70
|
+
if modifiers[:ctrl]
|
71
|
+
# CSI + ctrl_key_modifier + char
|
72
|
+
bindings << ["\e[1;5#{char}", modifiers[:ctrl]]
|
73
|
+
end
|
74
|
+
if modifiers[:meta]
|
75
|
+
# CSI + meta_key_modifier + char
|
76
|
+
bindings << ["\e[1;3#{char}", modifiers[:meta]]
|
77
|
+
# Meta(ESC) + CSI + char
|
78
|
+
bindings << ["\e\e[#{char}", modifiers[:meta]]
|
79
|
+
end
|
80
|
+
bindings.each do |sequence, func|
|
81
|
+
key = sequence.bytes
|
82
|
+
config.add_default_key_binding_by_keymap(:emacs, key, func)
|
83
|
+
config.add_default_key_binding_by_keymap(:vi_insert, key, func)
|
84
|
+
config.add_default_key_binding_by_keymap(:vi_command, key, func)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
67
89
|
def self.set_default_key_bindings_terminfo(config)
|
68
90
|
key_bindings = CAPNAME_KEY_BINDINGS.map do |capname, key_binding|
|
69
91
|
begin
|
70
92
|
key_code = Reline::Terminfo.tigetstr(capname)
|
71
|
-
|
72
|
-
# Escape sequences that omit the move distance and are set to defaults
|
73
|
-
# value 1 may be sometimes sent by pressing the arrow-key.
|
74
|
-
when 'cuu', 'cud', 'cuf', 'cub'
|
75
|
-
[ key_code.sub(/%p1%d/, '').bytes, key_binding ]
|
76
|
-
else
|
77
|
-
[ key_code.bytes, key_binding ]
|
78
|
-
end
|
93
|
+
[ key_code.bytes, key_binding ]
|
79
94
|
rescue Reline::Terminfo::TerminfoError
|
80
95
|
# capname is undefined
|
81
96
|
end
|
@@ -94,14 +109,8 @@ class Reline::ANSI
|
|
94
109
|
[27, 91, 49, 126] => :ed_move_to_beg, # Home
|
95
110
|
[27, 91, 52, 126] => :ed_move_to_end, # End
|
96
111
|
[27, 91, 51, 126] => :key_delete, # Del
|
97
|
-
[27, 91, 65] => :ed_prev_history, # ↑
|
98
|
-
[27, 91, 66] => :ed_next_history, # ↓
|
99
|
-
[27, 91, 67] => :ed_next_char, # →
|
100
|
-
[27, 91, 68] => :ed_prev_char, # ←
|
101
112
|
|
102
113
|
# KDE
|
103
|
-
[27, 91, 72] => :ed_move_to_beg, # Home
|
104
|
-
[27, 91, 70] => :ed_move_to_end, # End
|
105
114
|
# Del is 0x08
|
106
115
|
[27, 71, 65] => :ed_prev_history, # ↑
|
107
116
|
[27, 71, 66] => :ed_next_history, # ↓
|
@@ -118,12 +127,6 @@ class Reline::ANSI
|
|
118
127
|
# Del is 0x08
|
119
128
|
# Arrow keys are the same of KDE
|
120
129
|
|
121
|
-
# iTerm2
|
122
|
-
[27, 27, 91, 67] => :em_next_word, # Option+→, extended entry
|
123
|
-
[27, 27, 91, 68] => :ed_prev_word, # Option+←, extended entry
|
124
|
-
[195, 166] => :em_next_word, # Option+f
|
125
|
-
[195, 162] => :ed_prev_word, # Option+b
|
126
|
-
|
127
130
|
[27, 79, 65] => :ed_prev_history, # ↑
|
128
131
|
[27, 79, 66] => :ed_next_history, # ↓
|
129
132
|
[27, 79, 67] => :ed_next_char, # →
|
@@ -150,11 +153,13 @@ class Reline::ANSI
|
|
150
153
|
end
|
151
154
|
|
152
155
|
@@buf = []
|
153
|
-
def self.inner_getc
|
156
|
+
def self.inner_getc(timeout_second)
|
154
157
|
unless @@buf.empty?
|
155
158
|
return @@buf.shift
|
156
159
|
end
|
157
160
|
until c = @@input.raw(intr: true) { @@input.wait_readable(0.1) && @@input.getbyte }
|
161
|
+
timeout_second -= 0.1
|
162
|
+
return nil if timeout_second <= 0
|
158
163
|
Reline.core.line_editor.resize
|
159
164
|
end
|
160
165
|
(c == 0x16 && @@input.raw(min: 0, time: 0, &:getbyte)) || c
|
@@ -168,40 +173,38 @@ class Reline::ANSI
|
|
168
173
|
@@in_bracketed_paste_mode = false
|
169
174
|
START_BRACKETED_PASTE = String.new("\e[200~,", encoding: Encoding::ASCII_8BIT)
|
170
175
|
END_BRACKETED_PASTE = String.new("\e[200~.", encoding: Encoding::ASCII_8BIT)
|
171
|
-
def self.getc_with_bracketed_paste
|
176
|
+
def self.getc_with_bracketed_paste(timeout_second)
|
172
177
|
buffer = String.new(encoding: Encoding::ASCII_8BIT)
|
173
|
-
buffer << inner_getc
|
178
|
+
buffer << inner_getc(timeout_second)
|
174
179
|
while START_BRACKETED_PASTE.start_with?(buffer) or END_BRACKETED_PASTE.start_with?(buffer) do
|
175
180
|
if START_BRACKETED_PASTE == buffer
|
176
181
|
@@in_bracketed_paste_mode = true
|
177
|
-
return inner_getc
|
182
|
+
return inner_getc(timeout_second)
|
178
183
|
elsif END_BRACKETED_PASTE == buffer
|
179
184
|
@@in_bracketed_paste_mode = false
|
180
185
|
ungetc(-1)
|
181
|
-
return inner_getc
|
186
|
+
return inner_getc(timeout_second)
|
182
187
|
end
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
succ_c = inner_getc
|
187
|
-
}
|
188
|
-
rescue Timeout::Error
|
189
|
-
break
|
190
|
-
else
|
188
|
+
succ_c = inner_getc(Reline.core.config.keyseq_timeout)
|
189
|
+
|
190
|
+
if succ_c
|
191
191
|
buffer << succ_c
|
192
|
+
else
|
193
|
+
break
|
192
194
|
end
|
193
195
|
end
|
194
196
|
buffer.bytes.reverse_each do |ch|
|
195
197
|
ungetc ch
|
196
198
|
end
|
197
|
-
inner_getc
|
199
|
+
inner_getc(timeout_second)
|
198
200
|
end
|
199
201
|
|
200
|
-
|
202
|
+
# if the usage expects to wait indefinitely, use Float::INFINITY for timeout_second
|
203
|
+
def self.getc(timeout_second)
|
201
204
|
if Reline.core.config.enable_bracketed_paste
|
202
|
-
getc_with_bracketed_paste
|
205
|
+
getc_with_bracketed_paste(timeout_second)
|
203
206
|
else
|
204
|
-
inner_getc
|
207
|
+
inner_getc(timeout_second)
|
205
208
|
end
|
206
209
|
end
|
207
210
|
|
@@ -331,9 +334,12 @@ class Reline::ANSI
|
|
331
334
|
@@output.write "\e[K"
|
332
335
|
end
|
333
336
|
|
337
|
+
# This only works when the cursor is at the bottom of the scroll range
|
338
|
+
# For more details, see https://github.com/ruby/reline/pull/577#issuecomment-1646679623
|
334
339
|
def self.scroll_down(x)
|
335
340
|
return if x.zero?
|
336
|
-
|
341
|
+
# We use `\n` instead of CSI + S because CSI + S would cause https://github.com/ruby/reline/issues/576
|
342
|
+
@@output.write "\n" * x
|
337
343
|
end
|
338
344
|
|
339
345
|
def self.clear_screen
|
data/lib/reline/general_io.rb
CHANGED
data/lib/reline/line_editor.rb
CHANGED
@@ -1605,7 +1605,7 @@ class Reline::LineEditor
|
|
1605
1605
|
else
|
1606
1606
|
@just_cursor_moving = false
|
1607
1607
|
end
|
1608
|
-
if @is_multiline and @auto_indent_proc and not simplified_rendering?
|
1608
|
+
if @is_multiline and @auto_indent_proc and not simplified_rendering? and @line
|
1609
1609
|
process_auto_indent
|
1610
1610
|
end
|
1611
1611
|
end
|
@@ -2696,6 +2696,7 @@ class Reline::LineEditor
|
|
2696
2696
|
@cursor_max -= width
|
2697
2697
|
end
|
2698
2698
|
end
|
2699
|
+
alias_method :kill_word, :em_delete_next_word
|
2699
2700
|
|
2700
2701
|
private def ed_delete_prev_word(key)
|
2701
2702
|
if @byte_pointer > 0
|
@@ -2707,6 +2708,7 @@ class Reline::LineEditor
|
|
2707
2708
|
@cursor_max -= width
|
2708
2709
|
end
|
2709
2710
|
end
|
2711
|
+
alias_method :backward_kill_word, :ed_delete_prev_word
|
2710
2712
|
|
2711
2713
|
private def ed_transpose_chars(key)
|
2712
2714
|
if @byte_pointer > 0
|
data/lib/reline/version.rb
CHANGED
data/lib/reline/windows.rb
CHANGED
data/lib/reline.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'io/console'
|
2
|
-
require 'timeout'
|
3
2
|
require 'forwardable'
|
4
3
|
require 'reline/version'
|
5
4
|
require 'reline/config'
|
@@ -397,7 +396,7 @@ module Reline
|
|
397
396
|
private def read_io(keyseq_timeout, &block)
|
398
397
|
buffer = []
|
399
398
|
loop do
|
400
|
-
c = io_gate.getc
|
399
|
+
c = io_gate.getc(Float::INFINITY)
|
401
400
|
if c == -1
|
402
401
|
result = :unmatched
|
403
402
|
@bracketed_paste_finished = true
|
@@ -434,15 +433,8 @@ module Reline
|
|
434
433
|
end
|
435
434
|
|
436
435
|
private def read_2nd_character_of_key_sequence(keyseq_timeout, buffer, c, block)
|
437
|
-
|
438
|
-
|
439
|
-
Timeout.timeout(keyseq_timeout / 1000.0) {
|
440
|
-
succ_c = io_gate.getc
|
441
|
-
}
|
442
|
-
rescue Timeout::Error # cancel matching only when first byte
|
443
|
-
block.([Reline::Key.new(c, c, false)])
|
444
|
-
return :break
|
445
|
-
else
|
436
|
+
succ_c = io_gate.getc(keyseq_timeout.fdiv(1000))
|
437
|
+
if succ_c
|
446
438
|
case key_stroke.match_status(buffer.dup.push(succ_c))
|
447
439
|
when :unmatched
|
448
440
|
if c == "\e".ord
|
@@ -462,27 +454,23 @@ module Reline
|
|
462
454
|
block.(expanded)
|
463
455
|
return :break
|
464
456
|
end
|
457
|
+
else
|
458
|
+
block.([Reline::Key.new(c, c, false)])
|
459
|
+
return :break
|
465
460
|
end
|
466
461
|
end
|
467
462
|
|
468
463
|
private def read_escaped_key(keyseq_timeout, c, block)
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
escaped_c = io_gate.getc
|
473
|
-
}
|
474
|
-
rescue Timeout::Error # independent ESC
|
464
|
+
escaped_c = io_gate.getc(keyseq_timeout.fdiv(1000))
|
465
|
+
|
466
|
+
if escaped_c.nil?
|
475
467
|
block.([Reline::Key.new(c, c, false)])
|
468
|
+
elsif escaped_c >= 128 # maybe, first byte of multi byte
|
469
|
+
block.([Reline::Key.new(c, c, false), Reline::Key.new(escaped_c, escaped_c, false)])
|
470
|
+
elsif escaped_c == "\e".ord # escape twice
|
471
|
+
block.([Reline::Key.new(c, c, false), Reline::Key.new(c, c, false)])
|
476
472
|
else
|
477
|
-
|
478
|
-
block.([Reline::Key.new(c, c, false)])
|
479
|
-
elsif escaped_c >= 128 # maybe, first byte of multi byte
|
480
|
-
block.([Reline::Key.new(c, c, false), Reline::Key.new(escaped_c, escaped_c, false)])
|
481
|
-
elsif escaped_c == "\e".ord # escape twice
|
482
|
-
block.([Reline::Key.new(c, c, false), Reline::Key.new(c, c, false)])
|
483
|
-
else
|
484
|
-
block.([Reline::Key.new(escaped_c, escaped_c | 0b10000000, true)])
|
485
|
-
end
|
473
|
+
block.([Reline::Key.new(escaped_c, escaped_c | 0b10000000, true)])
|
486
474
|
end
|
487
475
|
end
|
488
476
|
|
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.3.
|
4
|
+
version: 0.3.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|
@@ -72,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
72
|
- !ruby/object:Gem::Version
|
73
73
|
version: '0'
|
74
74
|
requirements: []
|
75
|
-
rubygems_version: 3.4.
|
75
|
+
rubygems_version: 3.4.10
|
76
76
|
signing_key:
|
77
77
|
specification_version: 4
|
78
78
|
summary: Alternative GNU Readline or Editline implementation by pure Ruby.
|