reline 0.5.0 → 0.5.2
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 +12 -6
- data/lib/reline/general_io.rb +1 -0
- data/lib/reline/key_actor/emacs.rb +11 -11
- data/lib/reline/key_actor/vi_command.rb +23 -23
- data/lib/reline/key_actor/vi_insert.rb +2 -2
- data/lib/reline/line_editor.rb +249 -207
- data/lib/reline/terminfo.rb +7 -14
- data/lib/reline/version.rb +1 -1
- data/lib/reline/windows.rb +1 -1
- data/lib/reline.rb +31 -42
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68e79c30bbef8d97090f7126f96c5ee0c32fa95e6dc120a91240a6e9ff3864c6
|
4
|
+
data.tar.gz: 857716d3f9ab324efef98d3cb42acf2bba17848012a832c5631ca3e6d2f15733
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b25e6a151ded60963f660ccafceef8c221577b9f2328b9daa10dc381f5ea63c293a9759a786ab02610eb2fb07c52f3a200303fd9ac672210658884cb9a57c88c
|
7
|
+
data.tar.gz: 8433437480cf5acf7d87aefc632cc641e9325f163ab1d00d1df9cea5d5f3977f05250b20b366d7fd21ae275edd8f152ddc5879fa88340fbf35990e9b2a7e9725
|
data/lib/reline/ansi.rb
CHANGED
@@ -151,7 +151,11 @@ class Reline::ANSI
|
|
151
151
|
end
|
152
152
|
|
153
153
|
def self.with_raw_input
|
154
|
-
@@input.
|
154
|
+
if @@input.tty?
|
155
|
+
@@input.raw(intr: true) { yield }
|
156
|
+
else
|
157
|
+
yield
|
158
|
+
end
|
155
159
|
end
|
156
160
|
|
157
161
|
@@buf = []
|
@@ -159,11 +163,13 @@ class Reline::ANSI
|
|
159
163
|
unless @@buf.empty?
|
160
164
|
return @@buf.shift
|
161
165
|
end
|
162
|
-
until
|
163
|
-
timeout_second -= 0.
|
166
|
+
until @@input.wait_readable(0.01)
|
167
|
+
timeout_second -= 0.01
|
164
168
|
return nil if timeout_second <= 0
|
165
|
-
|
169
|
+
|
170
|
+
Reline.core.line_editor.handle_signal
|
166
171
|
end
|
172
|
+
c = @@input.getbyte
|
167
173
|
(c == 0x16 && @@input.raw(min: 0, time: 0, &:getbyte)) || c
|
168
174
|
rescue Errno::EIO
|
169
175
|
# Maybe the I/O has been closed.
|
@@ -309,7 +315,7 @@ class Reline::ANSI
|
|
309
315
|
end
|
310
316
|
|
311
317
|
def self.hide_cursor
|
312
|
-
if Reline::Terminfo.enabled?
|
318
|
+
if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported?
|
313
319
|
begin
|
314
320
|
@@output.write Reline::Terminfo.tigetstr('civis')
|
315
321
|
rescue Reline::Terminfo::TerminfoError
|
@@ -321,7 +327,7 @@ class Reline::ANSI
|
|
321
327
|
end
|
322
328
|
|
323
329
|
def self.show_cursor
|
324
|
-
if Reline::Terminfo.enabled?
|
330
|
+
if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported?
|
325
331
|
begin
|
326
332
|
@@output.write Reline::Terminfo.tigetstr('cnorm')
|
327
333
|
rescue Reline::Terminfo::TerminfoError
|
data/lib/reline/general_io.rb
CHANGED
@@ -49,13 +49,13 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
49
49
|
# 23 ^W
|
50
50
|
:em_kill_region,
|
51
51
|
# 24 ^X
|
52
|
-
:
|
52
|
+
:ed_unassigned,
|
53
53
|
# 25 ^Y
|
54
54
|
:em_yank,
|
55
55
|
# 26 ^Z
|
56
56
|
:ed_ignore,
|
57
57
|
# 27 ^[
|
58
|
-
:
|
58
|
+
:ed_unassigned,
|
59
59
|
# 28 ^\
|
60
60
|
:ed_ignore,
|
61
61
|
# 29 ^]
|
@@ -319,9 +319,9 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
319
319
|
# 158 M-^^
|
320
320
|
:ed_unassigned,
|
321
321
|
# 159 M-^_
|
322
|
-
:em_copy_prev_word,
|
323
|
-
# 160 M-SPACE
|
324
322
|
:ed_unassigned,
|
323
|
+
# 160 M-SPACE
|
324
|
+
:em_set_mark,
|
325
325
|
# 161 M-!
|
326
326
|
:ed_unassigned,
|
327
327
|
# 162 M-"
|
@@ -415,7 +415,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
415
415
|
# 206 M-N
|
416
416
|
:vi_search_next,
|
417
417
|
# 207 M-O
|
418
|
-
:
|
418
|
+
:ed_unassigned,
|
419
419
|
# 208 M-P
|
420
420
|
:vi_search_prev,
|
421
421
|
# 209 M-Q
|
@@ -431,15 +431,15 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
431
431
|
# 214 M-V
|
432
432
|
:ed_unassigned,
|
433
433
|
# 215 M-W
|
434
|
-
:
|
434
|
+
:ed_unassigned,
|
435
435
|
# 216 M-X
|
436
|
-
:ed_command,
|
437
|
-
# 217 M-Y
|
438
436
|
:ed_unassigned,
|
437
|
+
# 217 M-Y
|
438
|
+
:em_yank_pop,
|
439
439
|
# 218 M-Z
|
440
440
|
:ed_unassigned,
|
441
441
|
# 219 M-[
|
442
|
-
:
|
442
|
+
:ed_unassigned,
|
443
443
|
# 220 M-\
|
444
444
|
:ed_unassigned,
|
445
445
|
# 221 M-]
|
@@ -495,9 +495,9 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
495
495
|
# 246 M-v
|
496
496
|
:ed_unassigned,
|
497
497
|
# 247 M-w
|
498
|
-
:
|
498
|
+
:ed_unassigned,
|
499
499
|
# 248 M-x
|
500
|
-
:
|
500
|
+
:ed_unassigned,
|
501
501
|
# 249 M-y
|
502
502
|
:ed_unassigned,
|
503
503
|
# 250 M-z
|
@@ -17,7 +17,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
17
17
|
# 7 ^G
|
18
18
|
:ed_unassigned,
|
19
19
|
# 8 ^H
|
20
|
-
:
|
20
|
+
:ed_prev_char,
|
21
21
|
# 9 ^I
|
22
22
|
:ed_unassigned,
|
23
23
|
# 10 ^J
|
@@ -41,7 +41,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
41
41
|
# 19 ^S
|
42
42
|
:ed_ignore,
|
43
43
|
# 20 ^T
|
44
|
-
:
|
44
|
+
:ed_transpose_chars,
|
45
45
|
# 21 ^U
|
46
46
|
:vi_kill_line_prev,
|
47
47
|
# 22 ^V
|
@@ -51,7 +51,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
51
51
|
# 24 ^X
|
52
52
|
:ed_unassigned,
|
53
53
|
# 25 ^Y
|
54
|
-
:
|
54
|
+
:em_yank,
|
55
55
|
# 26 ^Z
|
56
56
|
:ed_unassigned,
|
57
57
|
# 27 ^[
|
@@ -75,7 +75,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
75
75
|
# 36 $
|
76
76
|
:ed_move_to_end,
|
77
77
|
# 37 %
|
78
|
-
:
|
78
|
+
:ed_unassigned,
|
79
79
|
# 38 &
|
80
80
|
:ed_unassigned,
|
81
81
|
# 39 '
|
@@ -89,11 +89,11 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
89
89
|
# 43 +
|
90
90
|
:ed_next_history,
|
91
91
|
# 44 ,
|
92
|
-
:
|
92
|
+
:ed_unassigned,
|
93
93
|
# 45 -
|
94
94
|
:ed_prev_history,
|
95
95
|
# 46 .
|
96
|
-
:
|
96
|
+
:ed_unassigned,
|
97
97
|
# 47 /
|
98
98
|
:vi_search_prev,
|
99
99
|
# 48 0
|
@@ -117,9 +117,9 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
117
117
|
# 57 9
|
118
118
|
:ed_argument_digit,
|
119
119
|
# 58 :
|
120
|
-
:
|
120
|
+
:ed_unassigned,
|
121
121
|
# 59 ;
|
122
|
-
:
|
122
|
+
:ed_unassigned,
|
123
123
|
# 60 <
|
124
124
|
:ed_unassigned,
|
125
125
|
# 61 =
|
@@ -157,21 +157,21 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
157
157
|
# 77 M
|
158
158
|
:ed_unassigned,
|
159
159
|
# 78 N
|
160
|
-
:
|
160
|
+
:ed_unassigned,
|
161
161
|
# 79 O
|
162
|
-
:
|
162
|
+
:ed_unassigned,
|
163
163
|
# 80 P
|
164
164
|
:vi_paste_prev,
|
165
165
|
# 81 Q
|
166
166
|
:ed_unassigned,
|
167
167
|
# 82 R
|
168
|
-
:
|
168
|
+
:ed_unassigned,
|
169
169
|
# 83 S
|
170
|
-
:
|
170
|
+
:ed_unassigned,
|
171
171
|
# 84 T
|
172
172
|
:vi_to_prev_char,
|
173
173
|
# 85 U
|
174
|
-
:
|
174
|
+
:ed_unassigned,
|
175
175
|
# 86 V
|
176
176
|
:ed_unassigned,
|
177
177
|
# 87 W
|
@@ -179,11 +179,11 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
179
179
|
# 88 X
|
180
180
|
:ed_delete_prev_char,
|
181
181
|
# 89 Y
|
182
|
-
:
|
182
|
+
:ed_unassigned,
|
183
183
|
# 90 Z
|
184
184
|
:ed_unassigned,
|
185
185
|
# 91 [
|
186
|
-
:
|
186
|
+
:ed_unassigned,
|
187
187
|
# 92 \
|
188
188
|
:ed_unassigned,
|
189
189
|
# 93 ]
|
@@ -191,7 +191,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
191
191
|
# 94 ^
|
192
192
|
:vi_first_print,
|
193
193
|
# 95 _
|
194
|
-
:
|
194
|
+
:ed_unassigned,
|
195
195
|
# 96 `
|
196
196
|
:ed_unassigned,
|
197
197
|
# 97 a
|
@@ -221,7 +221,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
221
221
|
# 109 m
|
222
222
|
:ed_unassigned,
|
223
223
|
# 110 n
|
224
|
-
:
|
224
|
+
:ed_unassigned,
|
225
225
|
# 111 o
|
226
226
|
:ed_unassigned,
|
227
227
|
# 112 p
|
@@ -231,11 +231,11 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
231
231
|
# 114 r
|
232
232
|
:vi_replace_char,
|
233
233
|
# 115 s
|
234
|
-
:
|
234
|
+
:ed_unassigned,
|
235
235
|
# 116 t
|
236
236
|
:vi_to_next_char,
|
237
237
|
# 117 u
|
238
|
-
:
|
238
|
+
:ed_unassigned,
|
239
239
|
# 118 v
|
240
240
|
:vi_histedit,
|
241
241
|
# 119 w
|
@@ -253,9 +253,9 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
253
253
|
# 125 }
|
254
254
|
:ed_unassigned,
|
255
255
|
# 126 ~
|
256
|
-
:vi_change_case,
|
257
|
-
# 127 ^?
|
258
256
|
:ed_unassigned,
|
257
|
+
# 127 ^?
|
258
|
+
:em_delete_prev_char,
|
259
259
|
# 128 M-^@
|
260
260
|
:ed_unassigned,
|
261
261
|
# 129 M-^A
|
@@ -415,7 +415,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
415
415
|
# 206 M-N
|
416
416
|
:ed_unassigned,
|
417
417
|
# 207 M-O
|
418
|
-
:
|
418
|
+
:ed_unassigned,
|
419
419
|
# 208 M-P
|
420
420
|
:ed_unassigned,
|
421
421
|
# 209 M-Q
|
@@ -439,7 +439,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
|
439
439
|
# 218 M-Z
|
440
440
|
:ed_unassigned,
|
441
441
|
# 219 M-[
|
442
|
-
:
|
442
|
+
:ed_unassigned,
|
443
443
|
# 220 M-\
|
444
444
|
:ed_unassigned,
|
445
445
|
# 221 M-]
|
@@ -41,7 +41,7 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
|
|
41
41
|
# 19 ^S
|
42
42
|
:vi_search_next,
|
43
43
|
# 20 ^T
|
44
|
-
:
|
44
|
+
:ed_transpose_chars,
|
45
45
|
# 21 ^U
|
46
46
|
:vi_kill_line_prev,
|
47
47
|
# 22 ^V
|
@@ -51,7 +51,7 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
|
|
51
51
|
# 24 ^X
|
52
52
|
:ed_insert,
|
53
53
|
# 25 ^Y
|
54
|
-
:
|
54
|
+
:em_yank,
|
55
55
|
# 26 ^Z
|
56
56
|
:ed_insert,
|
57
57
|
# 27 ^[
|
data/lib/reline/line_editor.rb
CHANGED
@@ -33,23 +33,42 @@ class Reline::LineEditor
|
|
33
33
|
vi_next_big_word
|
34
34
|
vi_prev_big_word
|
35
35
|
vi_end_big_word
|
36
|
-
vi_repeat_next_char
|
37
|
-
vi_repeat_prev_char
|
38
36
|
}
|
39
37
|
|
40
38
|
module CompletionState
|
41
39
|
NORMAL = :normal
|
42
40
|
COMPLETION = :completion
|
43
41
|
MENU = :menu
|
44
|
-
JOURNEY = :journey
|
45
42
|
MENU_WITH_PERFECT_MATCH = :menu_with_perfect_match
|
46
43
|
PERFECT_MATCH = :perfect_match
|
47
44
|
end
|
48
45
|
|
49
46
|
RenderedScreen = Struct.new(:base_y, :lines, :cursor_y, keyword_init: true)
|
50
47
|
|
51
|
-
|
52
|
-
|
48
|
+
CompletionJourneyState = Struct.new(:line_index, :pre, :target, :post, :list, :pointer)
|
49
|
+
|
50
|
+
class MenuInfo
|
51
|
+
attr_reader :list
|
52
|
+
|
53
|
+
def initialize(list)
|
54
|
+
@list = list
|
55
|
+
end
|
56
|
+
|
57
|
+
def lines(screen_width)
|
58
|
+
return [] if @list.empty?
|
59
|
+
|
60
|
+
list = @list.sort
|
61
|
+
sizes = list.map { |item| Reline::Unicode.calculate_width(item) }
|
62
|
+
item_width = sizes.max + 2
|
63
|
+
num_cols = [screen_width / item_width, 1].max
|
64
|
+
num_rows = list.size.fdiv(num_cols).ceil
|
65
|
+
list_with_padding = list.zip(sizes).map { |item, size| item + ' ' * (item_width - size) }
|
66
|
+
aligned = (list_with_padding + [nil] * (num_rows * num_cols - list_with_padding.size)).each_slice(num_rows).to_a.transpose
|
67
|
+
aligned.map do |row|
|
68
|
+
row.join.rstrip
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
53
72
|
|
54
73
|
MINIMUM_SCROLLBAR_HEIGHT = 1
|
55
74
|
|
@@ -117,9 +136,6 @@ class Reline::LineEditor
|
|
117
136
|
@screen_size = Reline::IOGate.get_screen_size
|
118
137
|
reset_variables(prompt, encoding: encoding)
|
119
138
|
@rendered_screen.base_y = Reline::IOGate.cursor_pos.y
|
120
|
-
Reline::IOGate.set_winch_handler do
|
121
|
-
@resized = true
|
122
|
-
end
|
123
139
|
if ENV.key?('RELINE_ALT_SCROLLBAR')
|
124
140
|
@full_block = '::'
|
125
141
|
@upper_half_block = "''"
|
@@ -143,7 +159,12 @@ class Reline::LineEditor
|
|
143
159
|
end
|
144
160
|
end
|
145
161
|
|
146
|
-
def
|
162
|
+
def handle_signal
|
163
|
+
handle_interrupted
|
164
|
+
handle_resized
|
165
|
+
end
|
166
|
+
|
167
|
+
private def handle_resized
|
147
168
|
return unless @resized
|
148
169
|
|
149
170
|
@screen_size = Reline::IOGate.get_screen_size
|
@@ -156,25 +177,35 @@ class Reline::LineEditor
|
|
156
177
|
render_differential
|
157
178
|
end
|
158
179
|
|
180
|
+
private def handle_interrupted
|
181
|
+
return unless @interrupted
|
182
|
+
|
183
|
+
@interrupted = false
|
184
|
+
clear_dialogs
|
185
|
+
scrolldown = render_differential
|
186
|
+
Reline::IOGate.scroll_down scrolldown
|
187
|
+
Reline::IOGate.move_cursor_column 0
|
188
|
+
@rendered_screen.lines = []
|
189
|
+
@rendered_screen.cursor_y = 0
|
190
|
+
case @old_trap
|
191
|
+
when 'DEFAULT', 'SYSTEM_DEFAULT'
|
192
|
+
raise Interrupt
|
193
|
+
when 'IGNORE'
|
194
|
+
# Do nothing
|
195
|
+
when 'EXIT'
|
196
|
+
exit
|
197
|
+
else
|
198
|
+
@old_trap.call if @old_trap.respond_to?(:call)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
159
202
|
def set_signal_handlers
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
@rendered_screen.cursor_y = 0
|
167
|
-
case @old_trap
|
168
|
-
when 'DEFAULT', 'SYSTEM_DEFAULT'
|
169
|
-
raise Interrupt
|
170
|
-
when 'IGNORE'
|
171
|
-
# Do nothing
|
172
|
-
when 'EXIT'
|
173
|
-
exit
|
174
|
-
else
|
175
|
-
@old_trap.call if @old_trap.respond_to?(:call)
|
176
|
-
end
|
177
|
-
}
|
203
|
+
Reline::IOGate.set_winch_handler do
|
204
|
+
@resized = true
|
205
|
+
end
|
206
|
+
@old_trap = Signal.trap('INT') do
|
207
|
+
@interrupted = true
|
208
|
+
end
|
178
209
|
end
|
179
210
|
|
180
211
|
def finalize
|
@@ -191,16 +222,16 @@ class Reline::LineEditor
|
|
191
222
|
@encoding = encoding
|
192
223
|
@is_multiline = false
|
193
224
|
@finished = false
|
194
|
-
@cleared = false
|
195
225
|
@history_pointer = nil
|
196
226
|
@kill_ring ||= Reline::KillRing.new
|
197
227
|
@vi_clipboard = ''
|
198
228
|
@vi_arg = nil
|
199
229
|
@waiting_proc = nil
|
200
|
-
@
|
201
|
-
@
|
202
|
-
@
|
230
|
+
@vi_waiting_operator = nil
|
231
|
+
@vi_waiting_operator_arg = nil
|
232
|
+
@completion_journey_state = nil
|
203
233
|
@completion_state = CompletionState::NORMAL
|
234
|
+
@completion_occurs = false
|
204
235
|
@perfect_matched = nil
|
205
236
|
@menu_info = nil
|
206
237
|
@searching_prompt = nil
|
@@ -213,6 +244,7 @@ class Reline::LineEditor
|
|
213
244
|
@in_pasting = false
|
214
245
|
@auto_indent_proc = nil
|
215
246
|
@dialogs = []
|
247
|
+
@interrupted = false
|
216
248
|
@resized = false
|
217
249
|
@cache = {}
|
218
250
|
@rendered_screen = RenderedScreen.new(base_y: 0, lines: [], cursor_y: 0)
|
@@ -458,7 +490,7 @@ class Reline::LineEditor
|
|
458
490
|
[[0, Reline::Unicode.calculate_width(l, true), l]]
|
459
491
|
end
|
460
492
|
if @menu_info
|
461
|
-
@menu_info.
|
493
|
+
@menu_info.lines(screen_width).each do |item|
|
462
494
|
new_lines << [[0, Reline::Unicode.calculate_width(item), item]]
|
463
495
|
end
|
464
496
|
@menu_info = nil # TODO: do not change state here
|
@@ -508,10 +540,6 @@ class Reline::LineEditor
|
|
508
540
|
new_lines.size - y
|
509
541
|
end
|
510
542
|
|
511
|
-
def current_row
|
512
|
-
wrapped_lines.flatten[wrapped_cursor_y]
|
513
|
-
end
|
514
|
-
|
515
543
|
def upper_space_height(wrapped_cursor_y)
|
516
544
|
wrapped_cursor_y - screen_scroll_top
|
517
545
|
end
|
@@ -520,23 +548,13 @@ class Reline::LineEditor
|
|
520
548
|
screen_height - wrapped_cursor_y + screen_scroll_top - @rendered_screen.base_y - 1
|
521
549
|
end
|
522
550
|
|
523
|
-
def handle_cleared
|
524
|
-
return unless @cleared
|
525
|
-
|
526
|
-
@cleared = false
|
527
|
-
Reline::IOGate.clear_screen
|
528
|
-
@screen_size = Reline::IOGate.get_screen_size
|
529
|
-
@rendered_screen.lines = []
|
530
|
-
@rendered_screen.base_y = 0
|
531
|
-
@rendered_screen.cursor_y = 0
|
532
|
-
end
|
533
|
-
|
534
551
|
def rerender
|
535
|
-
handle_cleared
|
536
552
|
render_differential unless @in_pasting
|
537
553
|
end
|
538
554
|
|
539
555
|
class DialogProcScope
|
556
|
+
CompletionJourneyData = Struct.new(:preposing, :postposing, :list, :pointer)
|
557
|
+
|
540
558
|
def initialize(line_editor, config, proc_to_exec, context)
|
541
559
|
@line_editor = line_editor
|
542
560
|
@config = config
|
@@ -600,7 +618,7 @@ class Reline::LineEditor
|
|
600
618
|
end
|
601
619
|
|
602
620
|
def completion_journey_data
|
603
|
-
@line_editor.
|
621
|
+
@line_editor.dialog_proc_scope_completion_journey_data
|
604
622
|
end
|
605
623
|
|
606
624
|
def config
|
@@ -771,7 +789,7 @@ class Reline::LineEditor
|
|
771
789
|
if after = @output_modifier_proc&.call("#{before.join("\n")}\n", complete: complete)
|
772
790
|
after.lines("\n").map { |l| l.chomp('') }
|
773
791
|
else
|
774
|
-
before
|
792
|
+
before.map { |l| Reline::Unicode.escape_for_print(l) }
|
775
793
|
end
|
776
794
|
end
|
777
795
|
|
@@ -779,8 +797,8 @@ class Reline::LineEditor
|
|
779
797
|
@config.editing_mode
|
780
798
|
end
|
781
799
|
|
782
|
-
private def menu(
|
783
|
-
@menu_info = MenuInfo.new(
|
800
|
+
private def menu(_target, list)
|
801
|
+
@menu_info = MenuInfo.new(list)
|
784
802
|
end
|
785
803
|
|
786
804
|
private def complete_internal_proc(list, is_menu)
|
@@ -829,9 +847,9 @@ class Reline::LineEditor
|
|
829
847
|
[target, preposing, completed, postposing]
|
830
848
|
end
|
831
849
|
|
832
|
-
private def complete(list, just_show_list
|
850
|
+
private def complete(list, just_show_list)
|
833
851
|
case @completion_state
|
834
|
-
when CompletionState::NORMAL
|
852
|
+
when CompletionState::NORMAL
|
835
853
|
@completion_state = CompletionState::COMPLETION
|
836
854
|
when CompletionState::PERFECT_MATCH
|
837
855
|
@dig_perfect_match_proc&.(@perfect_matched)
|
@@ -871,80 +889,64 @@ class Reline::LineEditor
|
|
871
889
|
end
|
872
890
|
end
|
873
891
|
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
@
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
end
|
894
|
-
end
|
895
|
-
@completion_state = CompletionState::JOURNEY
|
896
|
-
else
|
897
|
-
case direction
|
898
|
-
when :up
|
899
|
-
@completion_journey_data.pointer -= 1
|
900
|
-
if @completion_journey_data.pointer < 0
|
901
|
-
@completion_journey_data.pointer = @completion_journey_data.list.size - 1
|
902
|
-
end
|
903
|
-
when :down
|
904
|
-
@completion_journey_data.pointer += 1
|
905
|
-
if @completion_journey_data.pointer >= @completion_journey_data.list.size
|
906
|
-
@completion_journey_data.pointer = 0
|
907
|
-
end
|
908
|
-
end
|
892
|
+
def dialog_proc_scope_completion_journey_data
|
893
|
+
return nil unless @completion_journey_state
|
894
|
+
line_index = @completion_journey_state.line_index
|
895
|
+
pre_lines = @buffer_of_lines[0...line_index].map { |line| line + "\n" }
|
896
|
+
post_lines = @buffer_of_lines[(line_index + 1)..-1].map { |line| line + "\n" }
|
897
|
+
DialogProcScope::CompletionJourneyData.new(
|
898
|
+
pre_lines.join + @completion_journey_state.pre,
|
899
|
+
@completion_journey_state.post + post_lines.join,
|
900
|
+
@completion_journey_state.list,
|
901
|
+
@completion_journey_state.pointer
|
902
|
+
)
|
903
|
+
end
|
904
|
+
|
905
|
+
private def move_completed_list(direction)
|
906
|
+
@completion_journey_state ||= retrieve_completion_journey_state
|
907
|
+
return false unless @completion_journey_state
|
908
|
+
|
909
|
+
if (delta = { up: -1, down: +1 }[direction])
|
910
|
+
@completion_journey_state.pointer = (@completion_journey_state.pointer + delta) % @completion_journey_state.list.size
|
909
911
|
end
|
910
|
-
completed = @
|
911
|
-
|
912
|
-
|
913
|
-
|
912
|
+
completed = @completion_journey_state.list[@completion_journey_state.pointer]
|
913
|
+
set_current_line(@completion_journey_state.pre + completed + @completion_journey_state.post, @completion_journey_state.pre.bytesize + completed.bytesize)
|
914
|
+
true
|
915
|
+
end
|
916
|
+
|
917
|
+
private def retrieve_completion_journey_state
|
918
|
+
preposing, target, postposing = retrieve_completion_block
|
919
|
+
list = call_completion_proc
|
920
|
+
return unless list.is_a?(Array)
|
921
|
+
|
922
|
+
candidates = list.select{ |item| item.start_with?(target) }
|
923
|
+
return if candidates.empty?
|
924
|
+
|
925
|
+
pre = preposing.split("\n", -1).last || ''
|
926
|
+
post = postposing.split("\n", -1).first || ''
|
927
|
+
CompletionJourneyState.new(
|
928
|
+
@line_index, pre, target, post, [target] + candidates, 0
|
929
|
+
)
|
914
930
|
end
|
915
931
|
|
916
932
|
private def run_for_operators(key, method_symbol, &block)
|
917
|
-
if @
|
933
|
+
if @vi_waiting_operator
|
918
934
|
if VI_MOTIONS.include?(method_symbol)
|
919
935
|
old_byte_pointer = @byte_pointer
|
920
|
-
@vi_arg = @
|
936
|
+
@vi_arg = (@vi_arg || 1) * @vi_waiting_operator_arg
|
921
937
|
block.(true)
|
922
938
|
unless @waiting_proc
|
923
939
|
byte_pointer_diff = @byte_pointer - old_byte_pointer
|
924
940
|
@byte_pointer = old_byte_pointer
|
925
|
-
@
|
926
|
-
|
927
|
-
old_waiting_proc = @waiting_proc
|
928
|
-
old_waiting_operator_proc = @waiting_operator_proc
|
929
|
-
current_waiting_operator_proc = @waiting_operator_proc
|
930
|
-
@waiting_proc = proc { |k|
|
931
|
-
old_byte_pointer = @byte_pointer
|
932
|
-
old_waiting_proc.(k)
|
933
|
-
byte_pointer_diff = @byte_pointer - old_byte_pointer
|
934
|
-
@byte_pointer = old_byte_pointer
|
935
|
-
current_waiting_operator_proc.(byte_pointer_diff)
|
936
|
-
@waiting_operator_proc = old_waiting_operator_proc
|
937
|
-
}
|
941
|
+
send(@vi_waiting_operator, byte_pointer_diff)
|
942
|
+
cleanup_waiting
|
938
943
|
end
|
939
944
|
else
|
940
945
|
# Ignores operator when not motion is given.
|
941
946
|
block.(false)
|
947
|
+
cleanup_waiting
|
942
948
|
end
|
943
|
-
@
|
944
|
-
@waiting_operator_vi_arg = nil
|
945
|
-
if @vi_arg
|
946
|
-
@vi_arg = nil
|
947
|
-
end
|
949
|
+
@vi_arg = nil
|
948
950
|
else
|
949
951
|
block.(false)
|
950
952
|
end
|
@@ -961,7 +963,7 @@ class Reline::LineEditor
|
|
961
963
|
end
|
962
964
|
|
963
965
|
def wrap_method_call(method_symbol, method_obj, key, with_operator = false)
|
964
|
-
if @config.editing_mode_is?(:emacs, :vi_insert) and @
|
966
|
+
if @config.editing_mode_is?(:emacs, :vi_insert) and @vi_waiting_operator.nil?
|
965
967
|
not_insertion = method_symbol != :ed_insert
|
966
968
|
process_insert(force: not_insertion)
|
967
969
|
end
|
@@ -980,11 +982,32 @@ class Reline::LineEditor
|
|
980
982
|
end
|
981
983
|
end
|
982
984
|
|
985
|
+
private def cleanup_waiting
|
986
|
+
@waiting_proc = nil
|
987
|
+
@vi_waiting_operator = nil
|
988
|
+
@vi_waiting_operator_arg = nil
|
989
|
+
@searching_prompt = nil
|
990
|
+
@drop_terminate_spaces = false
|
991
|
+
end
|
992
|
+
|
983
993
|
private def process_key(key, method_symbol)
|
994
|
+
if key.is_a?(Symbol)
|
995
|
+
cleanup_waiting
|
996
|
+
elsif @waiting_proc
|
997
|
+
old_byte_pointer = @byte_pointer
|
998
|
+
@waiting_proc.call(key)
|
999
|
+
if @vi_waiting_operator
|
1000
|
+
byte_pointer_diff = @byte_pointer - old_byte_pointer
|
1001
|
+
@byte_pointer = old_byte_pointer
|
1002
|
+
send(@vi_waiting_operator, byte_pointer_diff)
|
1003
|
+
cleanup_waiting
|
1004
|
+
end
|
1005
|
+
@kill_ring.process
|
1006
|
+
return
|
1007
|
+
end
|
1008
|
+
|
984
1009
|
if method_symbol and respond_to?(method_symbol, true)
|
985
1010
|
method_obj = method(method_symbol)
|
986
|
-
else
|
987
|
-
method_obj = nil
|
988
1011
|
end
|
989
1012
|
if method_symbol and key.is_a?(Symbol)
|
990
1013
|
if @vi_arg and argumentable?(method_obj)
|
@@ -1006,8 +1029,6 @@ class Reline::LineEditor
|
|
1006
1029
|
run_for_operators(key, method_symbol) do |with_operator|
|
1007
1030
|
wrap_method_call(method_symbol, method_obj, key, with_operator)
|
1008
1031
|
end
|
1009
|
-
elsif @waiting_proc
|
1010
|
-
@waiting_proc.(key)
|
1011
1032
|
elsif method_obj
|
1012
1033
|
wrap_method_call(method_symbol, method_obj, key)
|
1013
1034
|
else
|
@@ -1018,9 +1039,6 @@ class Reline::LineEditor
|
|
1018
1039
|
@vi_arg = nil
|
1019
1040
|
end
|
1020
1041
|
end
|
1021
|
-
elsif @waiting_proc
|
1022
|
-
@waiting_proc.(key)
|
1023
|
-
@kill_ring.process
|
1024
1042
|
elsif method_obj
|
1025
1043
|
if method_symbol == :ed_argument_digit
|
1026
1044
|
wrap_method_call(method_symbol, method_obj, key)
|
@@ -1097,52 +1115,51 @@ class Reline::LineEditor
|
|
1097
1115
|
end
|
1098
1116
|
old_lines = @buffer_of_lines.dup
|
1099
1117
|
@first_char = false
|
1100
|
-
completion_occurs = false
|
1118
|
+
@completion_occurs = false
|
1101
1119
|
if @config.editing_mode_is?(:emacs, :vi_insert) and key.char == "\C-i".ord
|
1102
|
-
|
1103
|
-
|
1104
|
-
if
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1120
|
+
if !@config.disable_completion
|
1121
|
+
process_insert(force: true)
|
1122
|
+
if @config.autocompletion
|
1123
|
+
@completion_state = CompletionState::NORMAL
|
1124
|
+
@completion_occurs = move_completed_list(:down)
|
1125
|
+
else
|
1126
|
+
@completion_journey_state = nil
|
1127
|
+
result = call_completion_proc
|
1128
|
+
if result.is_a?(Array)
|
1129
|
+
@completion_occurs = true
|
1130
|
+
complete(result, false)
|
1111
1131
|
end
|
1112
1132
|
end
|
1113
1133
|
end
|
1114
|
-
elsif @config.editing_mode_is?(:
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
move_completed_list(result, :up)
|
1121
|
-
end
|
1122
|
-
end
|
1123
|
-
elsif not @config.disable_completion and @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key.char)
|
1124
|
-
unless @config.disable_completion
|
1125
|
-
result = call_completion_proc
|
1126
|
-
if result.is_a?(Array)
|
1127
|
-
completion_occurs = true
|
1128
|
-
process_insert
|
1129
|
-
move_completed_list(result, "\C-p".ord == key.char ? :up : :down)
|
1130
|
-
end
|
1134
|
+
elsif @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key.char)
|
1135
|
+
# In vi mode, move completed list even if autocompletion is off
|
1136
|
+
if not @config.disable_completion
|
1137
|
+
process_insert(force: true)
|
1138
|
+
@completion_state = CompletionState::NORMAL
|
1139
|
+
@completion_occurs = move_completed_list("\C-p".ord == key.char ? :up : :down)
|
1131
1140
|
end
|
1132
1141
|
elsif Symbol === key.char and respond_to?(key.char, true)
|
1133
1142
|
process_key(key.char, key.char)
|
1134
1143
|
else
|
1135
1144
|
normal_char(key)
|
1136
1145
|
end
|
1137
|
-
unless completion_occurs
|
1146
|
+
unless @completion_occurs
|
1138
1147
|
@completion_state = CompletionState::NORMAL
|
1139
|
-
@
|
1148
|
+
@completion_journey_state = nil
|
1140
1149
|
end
|
1150
|
+
|
1141
1151
|
if @in_pasting
|
1142
1152
|
clear_dialogs
|
1143
|
-
|
1144
|
-
|
1153
|
+
return
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
modified = old_lines != @buffer_of_lines
|
1157
|
+
if !@completion_occurs && modified && !@config.disable_completion && @config.autocompletion
|
1158
|
+
# Auto complete starts only when edited
|
1159
|
+
process_insert(force: true)
|
1160
|
+
@completion_journey_state = retrieve_completion_journey_state
|
1145
1161
|
end
|
1162
|
+
modified
|
1146
1163
|
end
|
1147
1164
|
|
1148
1165
|
def scroll_into_view
|
@@ -1194,10 +1211,11 @@ class Reline::LineEditor
|
|
1194
1211
|
new_indent = @auto_indent_proc.(@buffer_of_lines.take(line_index + 1).push(''), line_index, byte_pointer, add_newline)
|
1195
1212
|
return unless new_indent
|
1196
1213
|
|
1197
|
-
|
1214
|
+
new_line = ' ' * new_indent + line.lstrip
|
1215
|
+
@buffer_of_lines[line_index] = new_line
|
1198
1216
|
if @line_index == line_index
|
1199
|
-
|
1200
|
-
@byte_pointer = [@byte_pointer +
|
1217
|
+
indent_diff = new_line.bytesize - line.bytesize
|
1218
|
+
@byte_pointer = [@byte_pointer + indent_diff, 0].max
|
1201
1219
|
end
|
1202
1220
|
end
|
1203
1221
|
|
@@ -1405,6 +1423,14 @@ class Reline::LineEditor
|
|
1405
1423
|
end
|
1406
1424
|
end
|
1407
1425
|
|
1426
|
+
private def completion_journey_up(key)
|
1427
|
+
if not @config.disable_completion and @config.autocompletion
|
1428
|
+
@completion_state = CompletionState::NORMAL
|
1429
|
+
@completion_occurs = move_completed_list(:up)
|
1430
|
+
end
|
1431
|
+
end
|
1432
|
+
alias_method :menu_complete_backward, :completion_journey_up
|
1433
|
+
|
1408
1434
|
# Editline:: +ed-unassigned+ This editor command always results in an error.
|
1409
1435
|
# GNU Readline:: There is no corresponding macro.
|
1410
1436
|
private def ed_unassigned(key) end # do nothing
|
@@ -1506,6 +1532,7 @@ class Reline::LineEditor
|
|
1506
1532
|
@byte_pointer = 0
|
1507
1533
|
end
|
1508
1534
|
alias_method :beginning_of_line, :ed_move_to_beg
|
1535
|
+
alias_method :vi_zero, :ed_move_to_beg
|
1509
1536
|
|
1510
1537
|
private def ed_move_to_end(key)
|
1511
1538
|
@byte_pointer = 0
|
@@ -2020,7 +2047,7 @@ class Reline::LineEditor
|
|
2020
2047
|
private def em_delete_or_list(key)
|
2021
2048
|
if current_line.empty? or @byte_pointer < current_line.bytesize
|
2022
2049
|
em_delete(key)
|
2023
|
-
|
2050
|
+
elsif !@config.autocompletion # show completed list
|
2024
2051
|
result = call_completion_proc
|
2025
2052
|
if result.is_a?(Array)
|
2026
2053
|
complete(result, true)
|
@@ -2046,7 +2073,11 @@ class Reline::LineEditor
|
|
2046
2073
|
alias_method :yank_pop, :em_yank_pop
|
2047
2074
|
|
2048
2075
|
private def ed_clear_screen(key)
|
2049
|
-
|
2076
|
+
Reline::IOGate.clear_screen
|
2077
|
+
@screen_size = Reline::IOGate.get_screen_size
|
2078
|
+
@rendered_screen.lines = []
|
2079
|
+
@rendered_screen.base_y = 0
|
2080
|
+
@rendered_screen.cursor_y = 0
|
2050
2081
|
end
|
2051
2082
|
alias_method :clear_screen, :ed_clear_screen
|
2052
2083
|
|
@@ -2287,50 +2318,63 @@ class Reline::LineEditor
|
|
2287
2318
|
copy_for_vi(deleted)
|
2288
2319
|
end
|
2289
2320
|
|
2290
|
-
private def
|
2291
|
-
@
|
2321
|
+
private def vi_change_meta(key, arg: nil)
|
2322
|
+
if @vi_waiting_operator
|
2323
|
+
set_current_line('', 0) if @vi_waiting_operator == :vi_change_meta_confirm && arg.nil?
|
2324
|
+
@vi_waiting_operator = nil
|
2325
|
+
@vi_waiting_operator_arg = nil
|
2326
|
+
else
|
2327
|
+
@drop_terminate_spaces = true
|
2328
|
+
@vi_waiting_operator = :vi_change_meta_confirm
|
2329
|
+
@vi_waiting_operator_arg = arg || 1
|
2330
|
+
end
|
2292
2331
|
end
|
2293
2332
|
|
2294
|
-
private def
|
2295
|
-
|
2296
|
-
@
|
2297
|
-
|
2298
|
-
line, cut = byteslice!(current_line, @byte_pointer, byte_pointer_diff)
|
2299
|
-
elsif byte_pointer_diff < 0
|
2300
|
-
line, cut = byteslice!(current_line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
|
2301
|
-
end
|
2302
|
-
set_current_line(line)
|
2303
|
-
copy_for_vi(cut)
|
2304
|
-
@byte_pointer += byte_pointer_diff if byte_pointer_diff < 0
|
2305
|
-
@config.editing_mode = :vi_insert
|
2306
|
-
@drop_terminate_spaces = false
|
2307
|
-
}
|
2308
|
-
@waiting_operator_vi_arg = arg
|
2333
|
+
private def vi_change_meta_confirm(byte_pointer_diff)
|
2334
|
+
vi_delete_meta_confirm(byte_pointer_diff)
|
2335
|
+
@config.editing_mode = :vi_insert
|
2336
|
+
@drop_terminate_spaces = false
|
2309
2337
|
end
|
2310
2338
|
|
2311
|
-
private def vi_delete_meta(key, arg:
|
2312
|
-
@
|
2313
|
-
if
|
2314
|
-
|
2315
|
-
|
2316
|
-
|
2317
|
-
|
2318
|
-
|
2319
|
-
|
2320
|
-
}
|
2321
|
-
@waiting_operator_vi_arg = arg
|
2339
|
+
private def vi_delete_meta(key, arg: nil)
|
2340
|
+
if @vi_waiting_operator
|
2341
|
+
set_current_line('', 0) if @vi_waiting_operator == :vi_delete_meta_confirm && arg.nil?
|
2342
|
+
@vi_waiting_operator = nil
|
2343
|
+
@vi_waiting_operator_arg = nil
|
2344
|
+
else
|
2345
|
+
@vi_waiting_operator = :vi_delete_meta_confirm
|
2346
|
+
@vi_waiting_operator_arg = arg || 1
|
2347
|
+
end
|
2322
2348
|
end
|
2323
2349
|
|
2324
|
-
private def
|
2325
|
-
|
2326
|
-
|
2327
|
-
|
2328
|
-
|
2329
|
-
|
2330
|
-
|
2331
|
-
|
2332
|
-
|
2333
|
-
|
2350
|
+
private def vi_delete_meta_confirm(byte_pointer_diff)
|
2351
|
+
if byte_pointer_diff > 0
|
2352
|
+
line, cut = byteslice!(current_line, @byte_pointer, byte_pointer_diff)
|
2353
|
+
elsif byte_pointer_diff < 0
|
2354
|
+
line, cut = byteslice!(current_line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
|
2355
|
+
end
|
2356
|
+
copy_for_vi(cut)
|
2357
|
+
set_current_line(line || '', @byte_pointer + (byte_pointer_diff < 0 ? byte_pointer_diff : 0))
|
2358
|
+
end
|
2359
|
+
|
2360
|
+
private def vi_yank(key, arg: nil)
|
2361
|
+
if @vi_waiting_operator
|
2362
|
+
copy_for_vi(current_line) if @vi_waiting_operator == :vi_yank_confirm && arg.nil?
|
2363
|
+
@vi_waiting_operator = nil
|
2364
|
+
@vi_waiting_operator_arg = nil
|
2365
|
+
else
|
2366
|
+
@vi_waiting_operator = :vi_yank_confirm
|
2367
|
+
@vi_waiting_operator_arg = arg || 1
|
2368
|
+
end
|
2369
|
+
end
|
2370
|
+
|
2371
|
+
private def vi_yank_confirm(byte_pointer_diff)
|
2372
|
+
if byte_pointer_diff > 0
|
2373
|
+
cut = current_line.byteslice(@byte_pointer, byte_pointer_diff)
|
2374
|
+
elsif byte_pointer_diff < 0
|
2375
|
+
cut = current_line.byteslice(@byte_pointer + byte_pointer_diff, -byte_pointer_diff)
|
2376
|
+
end
|
2377
|
+
copy_for_vi(cut)
|
2334
2378
|
end
|
2335
2379
|
|
2336
2380
|
private def vi_list_or_eof(key)
|
@@ -2435,18 +2479,11 @@ class Reline::LineEditor
|
|
2435
2479
|
end
|
2436
2480
|
|
2437
2481
|
private def vi_to_column(key, arg: 0)
|
2438
|
-
|
2439
|
-
@byte_pointer, = current_line.grapheme_clusters.inject([0, 0]) { |
|
2440
|
-
# total has [byte_size, cursor]
|
2482
|
+
# Implementing behavior of vi, not Readline's vi-mode.
|
2483
|
+
@byte_pointer, = current_line.grapheme_clusters.inject([0, 0]) { |(total_byte_size, total_width), gc|
|
2441
2484
|
mbchar_width = Reline::Unicode.get_mbchar_width(gc)
|
2442
|
-
if (
|
2443
|
-
|
2444
|
-
elsif (total.last + mbchar_width) >= current_row_width
|
2445
|
-
break total
|
2446
|
-
else
|
2447
|
-
total = [total.first + gc.bytesize, total.last + mbchar_width]
|
2448
|
-
total
|
2449
|
-
end
|
2485
|
+
break [total_byte_size, total_width] if (total_width + mbchar_width) >= arg
|
2486
|
+
[total_byte_size + gc.bytesize, total_width + mbchar_width]
|
2450
2487
|
}
|
2451
2488
|
end
|
2452
2489
|
|
@@ -2594,6 +2631,11 @@ class Reline::LineEditor
|
|
2594
2631
|
end
|
2595
2632
|
alias_method :exchange_point_and_mark, :em_exchange_mark
|
2596
2633
|
|
2597
|
-
private def
|
2634
|
+
private def emacs_editing_mode(key)
|
2635
|
+
@config.editing_mode = :emacs
|
2636
|
+
end
|
2637
|
+
|
2638
|
+
private def vi_editing_mode(key)
|
2639
|
+
@config.editing_mode = :vi_insert
|
2598
2640
|
end
|
2599
2641
|
end
|
data/lib/reline/terminfo.rb
CHANGED
@@ -80,23 +80,11 @@ module Reline::Terminfo
|
|
80
80
|
def self.setupterm(term, fildes)
|
81
81
|
errret_int = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT)
|
82
82
|
ret = @setupterm.(term, fildes, errret_int)
|
83
|
-
errret = errret_int[0, Fiddle::SIZEOF_INT].unpack1('i')
|
84
83
|
case ret
|
85
84
|
when 0 # OK
|
86
|
-
|
85
|
+
@term_supported = true
|
87
86
|
when -1 # ERR
|
88
|
-
|
89
|
-
when 1
|
90
|
-
raise TerminfoError.new('The terminal is hardcopy, cannot be used for curses applications.')
|
91
|
-
when 0
|
92
|
-
raise TerminfoError.new('The terminal could not be found, or that it is a generic type, having too little information for curses applications to run.')
|
93
|
-
when -1
|
94
|
-
raise TerminfoError.new('The terminfo database could not be found.')
|
95
|
-
else # unknown
|
96
|
-
-1
|
97
|
-
end
|
98
|
-
else # unknown
|
99
|
-
-2
|
87
|
+
@term_supported = false
|
100
88
|
end
|
101
89
|
end
|
102
90
|
|
@@ -148,9 +136,14 @@ module Reline::Terminfo
|
|
148
136
|
num
|
149
137
|
end
|
150
138
|
|
139
|
+
# NOTE: This means Fiddle and curses are enabled.
|
151
140
|
def self.enabled?
|
152
141
|
true
|
153
142
|
end
|
143
|
+
|
144
|
+
def self.term_supported?
|
145
|
+
@term_supported
|
146
|
+
end
|
154
147
|
end if Reline::Terminfo.curses_dl
|
155
148
|
|
156
149
|
module Reline::Terminfo
|
data/lib/reline/version.rb
CHANGED
data/lib/reline/windows.rb
CHANGED
@@ -259,7 +259,7 @@ class Reline::Windows
|
|
259
259
|
def self.check_input_event
|
260
260
|
num_of_events = 0.chr * 8
|
261
261
|
while @@output_buf.empty?
|
262
|
-
Reline.core.line_editor.
|
262
|
+
Reline.core.line_editor.handle_signal
|
263
263
|
if @@WaitForSingleObject.(@@hConsoleInputHandle, 100) != 0 # max 0.1 sec
|
264
264
|
# prevent for background consolemode change
|
265
265
|
@@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
|
data/lib/reline.rb
CHANGED
@@ -75,6 +75,7 @@ module Reline
|
|
75
75
|
|
76
76
|
def initialize
|
77
77
|
self.output = STDOUT
|
78
|
+
@mutex = Mutex.new
|
78
79
|
@dialog_proc_list = {}
|
79
80
|
yield self
|
80
81
|
@completion_quote_character = nil
|
@@ -219,26 +220,16 @@ module Reline
|
|
219
220
|
|
220
221
|
Reline::DEFAULT_DIALOG_PROC_AUTOCOMPLETE = ->() {
|
221
222
|
# autocomplete
|
222
|
-
return
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
result = completion_journey_data.list.dup
|
233
|
-
result.shift
|
234
|
-
pointer = completion_journey_data.pointer - 1
|
235
|
-
else
|
236
|
-
result = call_completion_proc_with_checking_args(pre, target, post)
|
237
|
-
pointer = nil
|
238
|
-
end
|
239
|
-
if result and result.size == 1 and result[0] == target and pointer != 0
|
240
|
-
result = nil
|
241
|
-
end
|
223
|
+
return unless config.autocompletion
|
224
|
+
|
225
|
+
journey_data = completion_journey_data
|
226
|
+
return unless journey_data
|
227
|
+
|
228
|
+
target = journey_data.list[journey_data.pointer]
|
229
|
+
result = journey_data.list.drop(1)
|
230
|
+
pointer = journey_data.pointer - 1
|
231
|
+
return if target.empty? || (result == [target] && pointer < 0)
|
232
|
+
|
242
233
|
target_width = Reline::Unicode.calculate_width(target)
|
243
234
|
x = cursor_pos.x - target_width
|
244
235
|
if x < 0
|
@@ -264,12 +255,15 @@ module Reline
|
|
264
255
|
Reline::DEFAULT_DIALOG_CONTEXT = Array.new
|
265
256
|
|
266
257
|
def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
|
267
|
-
|
268
|
-
io_gate.with_raw_input do
|
258
|
+
@mutex.synchronize do
|
269
259
|
unless confirm_multiline_termination
|
270
260
|
raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
|
271
261
|
end
|
272
|
-
|
262
|
+
|
263
|
+
Reline.update_iogate
|
264
|
+
io_gate.with_raw_input do
|
265
|
+
inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
|
266
|
+
end
|
273
267
|
|
274
268
|
whole_buffer = line_editor.whole_buffer.dup
|
275
269
|
whole_buffer.taint if RUBY_VERSION < '2.7'
|
@@ -288,17 +282,21 @@ module Reline
|
|
288
282
|
end
|
289
283
|
|
290
284
|
def readline(prompt = '', add_hist = false)
|
291
|
-
|
292
|
-
|
285
|
+
@mutex.synchronize do
|
286
|
+
Reline.update_iogate
|
287
|
+
io_gate.with_raw_input do
|
288
|
+
inner_readline(prompt, add_hist, false)
|
289
|
+
end
|
293
290
|
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
291
|
+
line = line_editor.line.dup
|
292
|
+
line.taint if RUBY_VERSION < '2.7'
|
293
|
+
if add_hist and line and line.chomp("\n").size > 0
|
294
|
+
Reline::HISTORY << line.chomp("\n")
|
295
|
+
end
|
299
296
|
|
300
|
-
|
301
|
-
|
297
|
+
line_editor.reset_line if line_editor.line.nil?
|
298
|
+
line
|
299
|
+
end
|
302
300
|
end
|
303
301
|
|
304
302
|
private def inner_readline(prompt, add_hist, multiline, &confirm_multiline_termination)
|
@@ -365,19 +363,10 @@ module Reline
|
|
365
363
|
io_gate.move_cursor_column(0)
|
366
364
|
rescue Errno::EIO
|
367
365
|
# Maybe the I/O has been closed.
|
368
|
-
|
369
|
-
line_editor.finalize
|
370
|
-
io_gate.deprep(otio)
|
371
|
-
raise e
|
372
|
-
rescue Exception
|
373
|
-
# Including Interrupt
|
366
|
+
ensure
|
374
367
|
line_editor.finalize
|
375
368
|
io_gate.deprep(otio)
|
376
|
-
raise
|
377
369
|
end
|
378
|
-
|
379
|
-
line_editor.finalize
|
380
|
-
io_gate.deprep(otio)
|
381
370
|
end
|
382
371
|
|
383
372
|
# GNU Readline waits for "keyseq-timeout" milliseconds to see if the ESC
|
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.5.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|