reline 0.5.8 → 0.5.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bcccc644594f9c2e4b9ae0eb743c2ae293ef084e96a8d9bd032b76825111c01b
4
- data.tar.gz: b5ab239a3d20925d4fbd8fb827908fa3e4fa70298a172e32e9b2b4de59dc767e
3
+ metadata.gz: 402ac8415b342c58b741ab1ae942818c44f092d43665d9546fde986572ce2bcf
4
+ data.tar.gz: 0a54115c2e2b02720e67a7870edc77430493b3d2fa89c033046d817b5b984b13
5
5
  SHA512:
6
- metadata.gz: 9bce894711da0253bf9b3f0eb192ff64947d591edd00f9094430431eb470fade4d02f3f8b529d364cdd7124d7f5a5203ea755be41dbfda890e37654aca430706
7
- data.tar.gz: eed500ad148a1f83e3de03e6d7daaf5d250ba3ea25d47d24070e749dfd44a7d900b83474dd0b427faee74bad883dab97b7af1984a7fb7209e1819fd416d4381b
6
+ metadata.gz: 0525a60f8fe7512bf23575935d15c7173c825ce6b15a062505d73e9a34836d8b751182280c4b67288af7b949b0417a57a4f384281123ef7b6e90c3072b65f20c
7
+ data.tar.gz: 299034a835b97c80a119614394a650c60104d571ec95ffbff8356531dc1de96cd78b8aa3fa8830520a40d43e4b7feb1958285af29633877a772be7ed995d7d33
data/lib/reline/config.rb CHANGED
@@ -29,18 +29,31 @@ class Reline::Config
29
29
  attr_accessor :autocompletion
30
30
 
31
31
  def initialize
32
- @additional_key_bindings = {} # from inputrc
33
- @additional_key_bindings[:emacs] = {}
34
- @additional_key_bindings[:vi_insert] = {}
35
- @additional_key_bindings[:vi_command] = {}
36
- @oneshot_key_bindings = {}
32
+ reset_variables
33
+ end
34
+
35
+ def reset
36
+ if editing_mode_is?(:vi_command)
37
+ @editing_mode_label = :vi_insert
38
+ end
39
+ @oneshot_key_bindings.clear
40
+ end
41
+
42
+ def reset_variables
43
+ @additional_key_bindings = { # from inputrc
44
+ emacs: Reline::KeyActor::Base.new,
45
+ vi_insert: Reline::KeyActor::Base.new,
46
+ vi_command: Reline::KeyActor::Base.new
47
+ }
48
+ @oneshot_key_bindings = Reline::KeyActor::Base.new
37
49
  @editing_mode_label = :emacs
38
50
  @keymap_label = :emacs
39
51
  @keymap_prefix = []
40
- @key_actors = {}
41
- @key_actors[:emacs] = Reline::KeyActor::Emacs.new
42
- @key_actors[:vi_insert] = Reline::KeyActor::ViInsert.new
43
- @key_actors[:vi_command] = Reline::KeyActor::ViCommand.new
52
+ @default_key_bindings = {
53
+ emacs: Reline::KeyActor::Base.new(Reline::KeyActor::EMACS_MAPPING),
54
+ vi_insert: Reline::KeyActor::Base.new(Reline::KeyActor::VI_INSERT_MAPPING),
55
+ vi_command: Reline::KeyActor::Base.new(Reline::KeyActor::VI_COMMAND_MAPPING)
56
+ }
44
57
  @vi_cmd_mode_string = '(cmd)'
45
58
  @vi_ins_mode_string = '(ins)'
46
59
  @emacs_mode_string = '@'
@@ -49,20 +62,15 @@ class Reline::Config
49
62
  @keyseq_timeout = 500
50
63
  @test_mode = false
51
64
  @autocompletion = false
52
- @convert_meta = true if seven_bit_encoding?(Reline::IOGate.encoding)
65
+ @convert_meta = seven_bit_encoding?(Reline::IOGate.encoding)
53
66
  @loaded = false
54
67
  @enable_bracketed_paste = true
55
- end
56
-
57
- def reset
58
- if editing_mode_is?(:vi_command)
59
- @editing_mode_label = :vi_insert
60
- end
61
- @oneshot_key_bindings.clear
68
+ @show_mode_in_prompt = false
69
+ @default_inputrc_path = nil
62
70
  end
63
71
 
64
72
  def editing_mode
65
- @key_actors[@editing_mode_label]
73
+ @default_key_bindings[@editing_mode_label]
66
74
  end
67
75
 
68
76
  def editing_mode=(val)
@@ -74,7 +82,7 @@ class Reline::Config
74
82
  end
75
83
 
76
84
  def keymap
77
- @key_actors[@keymap_label]
85
+ @default_key_bindings[@keymap_label]
78
86
  end
79
87
 
80
88
  def loaded?
@@ -133,14 +141,14 @@ class Reline::Config
133
141
 
134
142
  def key_bindings
135
143
  # The key bindings for each editing mode will be overwritten by the user-defined ones.
136
- kb = @key_actors[@editing_mode_label].default_key_bindings.dup
137
- kb.merge!(@additional_key_bindings[@editing_mode_label])
138
- kb.merge!(@oneshot_key_bindings)
139
- kb
144
+ Reline::KeyActor::Composite.new([@oneshot_key_bindings, @additional_key_bindings[@editing_mode_label], @default_key_bindings[@editing_mode_label]])
140
145
  end
141
146
 
142
147
  def add_oneshot_key_binding(keystroke, target)
143
- @oneshot_key_bindings[keystroke] = target
148
+ # IRB sets invalid keystroke [Reline::Key]. We should ignore it.
149
+ return unless keystroke.all? { |c| c.is_a?(Integer) }
150
+
151
+ @oneshot_key_bindings.add(keystroke, target)
144
152
  end
145
153
 
146
154
  def reset_oneshot_key_bindings
@@ -148,11 +156,11 @@ class Reline::Config
148
156
  end
149
157
 
150
158
  def add_default_key_binding_by_keymap(keymap, keystroke, target)
151
- @key_actors[keymap].default_key_bindings[keystroke] = target
159
+ @default_key_bindings[keymap].add(keystroke, target)
152
160
  end
153
161
 
154
162
  def add_default_key_binding(keystroke, target)
155
- @key_actors[@keymap_label].default_key_bindings[keystroke] = target
163
+ add_default_key_binding_by_keymap(@keymap_label, keystroke, target)
156
164
  end
157
165
 
158
166
  def read_lines(lines, file = nil)
@@ -192,7 +200,7 @@ class Reline::Config
192
200
  func_name = func_name.split.first
193
201
  keystroke, func = bind_key(key, func_name)
194
202
  next unless keystroke
195
- @additional_key_bindings[@keymap_label][@keymap_prefix + keystroke] = func
203
+ @additional_key_bindings[@keymap_label].add(@keymap_prefix + keystroke, func)
196
204
  end
197
205
  end
198
206
  unless if_stack.empty?
@@ -243,22 +251,6 @@ class Reline::Config
243
251
  rescue ArgumentError
244
252
  @history_size = 500
245
253
  end
246
- when 'bell-style'
247
- @bell_style =
248
- case value
249
- when 'none', 'off'
250
- :none
251
- when 'audible', 'on'
252
- :audible
253
- when 'visible'
254
- :visible
255
- else
256
- :audible
257
- end
258
- when 'comment-begin'
259
- @comment_begin = value.dup
260
- when 'completion-query-items'
261
- @completion_query_items = value.to_i
262
254
  when 'isearch-terminators'
263
255
  @isearch_terminators = retrieve_string(raw_value)
264
256
  when 'editing-mode'
@@ -374,6 +366,11 @@ class Reline::Config
374
366
  ret
375
367
  end
376
368
 
369
+ def reload
370
+ reset_variables
371
+ read
372
+ end
373
+
377
374
  private def seven_bit_encoding?(encoding)
378
375
  encoding == Encoding::US_ASCII
379
376
  end
data/lib/reline/face.rb CHANGED
@@ -107,7 +107,7 @@ class Reline::Face
107
107
 
108
108
  def sgr_rgb_256color(key, value)
109
109
  # 256 colors are
110
- # 0..15: standard colors, hight intensity colors
110
+ # 0..15: standard colors, high intensity colors
111
111
  # 16..232: 216 colors (R, G, B each 6 steps)
112
112
  # 233..255: grayscale colors (24 steps)
113
113
  # This methods converts rgb_expression to 216 colors
@@ -1,10 +1,7 @@
1
1
  require 'io/console'
2
2
  require 'io/wait'
3
- require_relative 'terminfo'
4
-
5
- class Reline::ANSI
6
- RESET_COLOR = "\e[0m"
7
3
 
4
+ class Reline::ANSI < Reline::IO
8
5
  CAPNAME_KEY_BINDINGS = {
9
6
  'khome' => :ed_move_to_beg,
10
7
  'kend' => :ed_move_to_end,
@@ -36,15 +33,18 @@ class Reline::ANSI
36
33
  Reline::Terminfo.setupterm(0, 2)
37
34
  end
38
35
 
39
- def self.encoding
40
- Encoding.default_external
36
+ def initialize
37
+ @input = STDIN
38
+ @output = STDOUT
39
+ @buf = []
40
+ @old_winch_handler = nil
41
41
  end
42
42
 
43
- def self.win?
44
- false
43
+ def encoding
44
+ Encoding.default_external
45
45
  end
46
46
 
47
- def self.set_default_key_bindings(config, allow_terminfo: true)
47
+ def set_default_key_bindings(config, allow_terminfo: true)
48
48
  set_bracketed_paste_key_bindings(config)
49
49
  set_default_key_bindings_ansi_cursor(config)
50
50
  if allow_terminfo && Reline::Terminfo.enabled?
@@ -67,13 +67,13 @@ class Reline::ANSI
67
67
  end
68
68
  end
69
69
 
70
- def self.set_bracketed_paste_key_bindings(config)
70
+ def set_bracketed_paste_key_bindings(config)
71
71
  [:emacs, :vi_insert, :vi_command].each do |keymap|
72
72
  config.add_default_key_binding_by_keymap(keymap, START_BRACKETED_PASTE.bytes, :bracketed_paste_start)
73
73
  end
74
74
  end
75
75
 
76
- def self.set_default_key_bindings_ansi_cursor(config)
76
+ def set_default_key_bindings_ansi_cursor(config)
77
77
  ANSI_CURSOR_KEY_BINDINGS.each do |char, (default_func, modifiers)|
78
78
  bindings = [["\e[#{char}", default_func]] # CSI + char
79
79
  if modifiers[:ctrl]
@@ -95,7 +95,7 @@ class Reline::ANSI
95
95
  end
96
96
  end
97
97
 
98
- def self.set_default_key_bindings_terminfo(config)
98
+ def set_default_key_bindings_terminfo(config)
99
99
  key_bindings = CAPNAME_KEY_BINDINGS.map do |capname, key_binding|
100
100
  begin
101
101
  key_code = Reline::Terminfo.tigetstr(capname)
@@ -112,12 +112,16 @@ class Reline::ANSI
112
112
  end
113
113
  end
114
114
 
115
- def self.set_default_key_bindings_comprehensive_list(config)
115
+ def set_default_key_bindings_comprehensive_list(config)
116
116
  {
117
+ # xterm
118
+ [27, 91, 51, 126] => :key_delete, # kdch1
119
+ [27, 91, 53, 126] => :ed_search_prev_history, # kpp
120
+ [27, 91, 54, 126] => :ed_search_next_history, # knp
121
+
117
122
  # Console (80x25)
118
123
  [27, 91, 49, 126] => :ed_move_to_beg, # Home
119
124
  [27, 91, 52, 126] => :ed_move_to_end, # End
120
- [27, 91, 51, 126] => :key_delete, # Del
121
125
 
122
126
  # KDE
123
127
  # Del is 0x08
@@ -147,47 +151,42 @@ class Reline::ANSI
147
151
  end
148
152
  end
149
153
 
150
- @@input = STDIN
151
- def self.input=(val)
152
- @@input = val
154
+ def input=(val)
155
+ @input = val
153
156
  end
154
157
 
155
- @@output = STDOUT
156
- def self.output=(val)
157
- @@output = val
158
+ def output=(val)
159
+ @output = val
158
160
  end
159
161
 
160
- def self.with_raw_input
161
- if @@input.tty?
162
- @@input.raw(intr: true) { yield }
162
+ def with_raw_input
163
+ if @input.tty?
164
+ @input.raw(intr: true) { yield }
163
165
  else
164
166
  yield
165
167
  end
166
168
  end
167
169
 
168
- @@buf = []
169
- def self.inner_getc(timeout_second)
170
- unless @@buf.empty?
171
- return @@buf.shift
170
+ def inner_getc(timeout_second)
171
+ unless @buf.empty?
172
+ return @buf.shift
172
173
  end
173
- until @@input.wait_readable(0.01)
174
+ until @input.wait_readable(0.01)
174
175
  timeout_second -= 0.01
175
176
  return nil if timeout_second <= 0
176
177
 
177
178
  Reline.core.line_editor.handle_signal
178
179
  end
179
- c = @@input.getbyte
180
- (c == 0x16 && @@input.raw(min: 0, time: 0, &:getbyte)) || c
180
+ c = @input.getbyte
181
+ (c == 0x16 && @input.tty? && @input.raw(min: 0, time: 0, &:getbyte)) || c
181
182
  rescue Errno::EIO
182
183
  # Maybe the I/O has been closed.
183
184
  nil
184
- rescue Errno::ENOTTY
185
- nil
186
185
  end
187
186
 
188
187
  START_BRACKETED_PASTE = String.new("\e[200~", encoding: Encoding::ASCII_8BIT)
189
188
  END_BRACKETED_PASTE = String.new("\e[201~", encoding: Encoding::ASCII_8BIT)
190
- def self.read_bracketed_paste
189
+ def read_bracketed_paste
191
190
  buffer = String.new(encoding: Encoding::ASCII_8BIT)
192
191
  until buffer.end_with?(END_BRACKETED_PASTE)
193
192
  c = inner_getc(Float::INFINITY)
@@ -199,38 +198,38 @@ class Reline::ANSI
199
198
  end
200
199
 
201
200
  # if the usage expects to wait indefinitely, use Float::INFINITY for timeout_second
202
- def self.getc(timeout_second)
201
+ def getc(timeout_second)
203
202
  inner_getc(timeout_second)
204
203
  end
205
204
 
206
- def self.in_pasting?
205
+ def in_pasting?
207
206
  not empty_buffer?
208
207
  end
209
208
 
210
- def self.empty_buffer?
211
- unless @@buf.empty?
209
+ def empty_buffer?
210
+ unless @buf.empty?
212
211
  return false
213
212
  end
214
- !@@input.wait_readable(0)
213
+ !@input.wait_readable(0)
215
214
  end
216
215
 
217
- def self.ungetc(c)
218
- @@buf.unshift(c)
216
+ def ungetc(c)
217
+ @buf.unshift(c)
219
218
  end
220
219
 
221
- def self.retrieve_keybuffer
220
+ def retrieve_keybuffer
222
221
  begin
223
- return unless @@input.wait_readable(0.001)
224
- str = @@input.read_nonblock(1024)
222
+ return unless @input.wait_readable(0.001)
223
+ str = @input.read_nonblock(1024)
225
224
  str.bytes.each do |c|
226
- @@buf.push(c)
225
+ @buf.push(c)
227
226
  end
228
227
  rescue EOFError
229
228
  end
230
229
  end
231
230
 
232
- def self.get_screen_size
233
- s = @@input.winsize
231
+ def get_screen_size
232
+ s = @input.winsize
234
233
  return s if s[0] > 0 && s[1] > 0
235
234
  s = [ENV["LINES"].to_i, ENV["COLUMNS"].to_i]
236
235
  return s if s[0] > 0 && s[1] > 0
@@ -239,20 +238,20 @@ class Reline::ANSI
239
238
  [24, 80]
240
239
  end
241
240
 
242
- def self.set_screen_size(rows, columns)
243
- @@input.winsize = [rows, columns]
241
+ def set_screen_size(rows, columns)
242
+ @input.winsize = [rows, columns]
244
243
  self
245
- rescue Errno::ENOTTY
244
+ rescue Errno::ENOTTY, Errno::ENODEV
246
245
  self
247
246
  end
248
247
 
249
- def self.cursor_pos
250
- begin
248
+ def cursor_pos
249
+ if both_tty?
251
250
  res = +''
252
251
  m = nil
253
- @@input.raw do |stdin|
254
- @@output << "\e[6n"
255
- @@output.flush
252
+ @input.raw do |stdin|
253
+ @output << "\e[6n"
254
+ @output.flush
256
255
  loop do
257
256
  c = stdin.getc
258
257
  next if c.nil?
@@ -266,9 +265,9 @@ class Reline::ANSI
266
265
  end
267
266
  column = m[:column].to_i - 1
268
267
  row = m[:row].to_i - 1
269
- rescue Errno::ENOTTY
268
+ else
270
269
  begin
271
- buf = @@output.pread(@@output.pos, 0)
270
+ buf = @output.pread(@output.pos, 0)
272
271
  row = buf.count("\n")
273
272
  column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0
274
273
  rescue Errno::ESPIPE, IOError
@@ -281,82 +280,93 @@ class Reline::ANSI
281
280
  Reline::CursorPos.new(column, row)
282
281
  end
283
282
 
284
- def self.move_cursor_column(x)
285
- @@output.write "\e[#{x + 1}G"
283
+ def both_tty?
284
+ @input.tty? && @output.tty?
285
+ end
286
+
287
+ def move_cursor_column(x)
288
+ @output.write "\e[#{x + 1}G"
286
289
  end
287
290
 
288
- def self.move_cursor_up(x)
291
+ def move_cursor_up(x)
289
292
  if x > 0
290
- @@output.write "\e[#{x}A"
293
+ @output.write "\e[#{x}A"
291
294
  elsif x < 0
292
295
  move_cursor_down(-x)
293
296
  end
294
297
  end
295
298
 
296
- def self.move_cursor_down(x)
299
+ def move_cursor_down(x)
297
300
  if x > 0
298
- @@output.write "\e[#{x}B"
301
+ @output.write "\e[#{x}B"
299
302
  elsif x < 0
300
303
  move_cursor_up(-x)
301
304
  end
302
305
  end
303
306
 
304
- def self.hide_cursor
307
+ def hide_cursor
308
+ seq = "\e[?25l"
305
309
  if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported?
306
310
  begin
307
- @@output.write Reline::Terminfo.tigetstr('civis')
311
+ seq = Reline::Terminfo.tigetstr('civis')
308
312
  rescue Reline::Terminfo::TerminfoError
309
313
  # civis is undefined
310
314
  end
311
- else
312
- # ignored
313
315
  end
316
+ @output.write seq
314
317
  end
315
318
 
316
- def self.show_cursor
319
+ def show_cursor
320
+ seq = "\e[?25h"
317
321
  if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported?
318
322
  begin
319
- @@output.write Reline::Terminfo.tigetstr('cnorm')
323
+ seq = Reline::Terminfo.tigetstr('cnorm')
320
324
  rescue Reline::Terminfo::TerminfoError
321
325
  # cnorm is undefined
322
326
  end
323
- else
324
- # ignored
325
327
  end
328
+ @output.write seq
326
329
  end
327
330
 
328
- def self.erase_after_cursor
329
- @@output.write "\e[K"
331
+ def erase_after_cursor
332
+ @output.write "\e[K"
330
333
  end
331
334
 
332
335
  # This only works when the cursor is at the bottom of the scroll range
333
336
  # For more details, see https://github.com/ruby/reline/pull/577#issuecomment-1646679623
334
- def self.scroll_down(x)
337
+ def scroll_down(x)
335
338
  return if x.zero?
336
339
  # We use `\n` instead of CSI + S because CSI + S would cause https://github.com/ruby/reline/issues/576
337
- @@output.write "\n" * x
340
+ @output.write "\n" * x
338
341
  end
339
342
 
340
- def self.clear_screen
341
- @@output.write "\e[2J"
342
- @@output.write "\e[1;1H"
343
+ def clear_screen
344
+ @output.write "\e[2J"
345
+ @output.write "\e[1;1H"
343
346
  end
344
347
 
345
- @@old_winch_handler = nil
346
- def self.set_winch_handler(&handler)
347
- @@old_winch_handler = Signal.trap('WINCH', &handler)
348
+ def set_winch_handler(&handler)
349
+ @old_winch_handler = Signal.trap('WINCH', &handler)
350
+ @old_cont_handler = Signal.trap('CONT') do
351
+ @input.raw!(intr: true) if @input.tty?
352
+ # Rerender the screen. Note that screen size might be changed while suspended.
353
+ handler.call
354
+ end
355
+ rescue ArgumentError
356
+ # Signal.trap may raise an ArgumentError if the platform doesn't support the signal.
348
357
  end
349
358
 
350
- def self.prep
359
+ def prep
351
360
  # Enable bracketed paste
352
- @@output.write "\e[?2004h" if Reline.core.config.enable_bracketed_paste
361
+ @output.write "\e[?2004h" if Reline.core.config.enable_bracketed_paste && both_tty?
353
362
  retrieve_keybuffer
354
363
  nil
355
364
  end
356
365
 
357
- def self.deprep(otio)
366
+ def deprep(otio)
358
367
  # Disable bracketed paste
359
- @@output.write "\e[?2004l" if Reline.core.config.enable_bracketed_paste
360
- Signal.trap('WINCH', @@old_winch_handler) if @@old_winch_handler
368
+ @output.write "\e[?2004l" if Reline.core.config.enable_bracketed_paste && both_tty?
369
+ Signal.trap('WINCH', @old_winch_handler) if @old_winch_handler
370
+ Signal.trap('CONT', @old_cont_handler) if @old_cont_handler
361
371
  end
362
372
  end
@@ -0,0 +1,106 @@
1
+ require 'io/wait'
2
+
3
+ class Reline::Dumb < Reline::IO
4
+ RESET_COLOR = '' # Do not send color reset sequence
5
+
6
+ def initialize(encoding: nil)
7
+ @input = STDIN
8
+ @buf = []
9
+ @pasting = false
10
+ @encoding = encoding
11
+ @screen_size = [24, 80]
12
+ end
13
+
14
+ def dumb?
15
+ true
16
+ end
17
+
18
+ def encoding
19
+ if @encoding
20
+ @encoding
21
+ elsif RUBY_PLATFORM =~ /mswin|mingw/
22
+ Encoding::UTF_8
23
+ else
24
+ Encoding::default_external
25
+ end
26
+ end
27
+
28
+ def set_default_key_bindings(_)
29
+ end
30
+
31
+ def input=(val)
32
+ @input = val
33
+ end
34
+
35
+ def with_raw_input
36
+ yield
37
+ end
38
+
39
+ def getc(_timeout_second)
40
+ unless @buf.empty?
41
+ return @buf.shift
42
+ end
43
+ c = nil
44
+ loop do
45
+ Reline.core.line_editor.handle_signal
46
+ result = @input.wait_readable(0.1)
47
+ next if result.nil?
48
+ c = @input.read(1)
49
+ break
50
+ end
51
+ c&.ord
52
+ end
53
+
54
+ def ungetc(c)
55
+ @buf.unshift(c)
56
+ end
57
+
58
+ def get_screen_size
59
+ @screen_size
60
+ end
61
+
62
+ def cursor_pos
63
+ Reline::CursorPos.new(1, 1)
64
+ end
65
+
66
+ def hide_cursor
67
+ end
68
+
69
+ def show_cursor
70
+ end
71
+
72
+ def move_cursor_column(val)
73
+ end
74
+
75
+ def move_cursor_up(val)
76
+ end
77
+
78
+ def move_cursor_down(val)
79
+ end
80
+
81
+ def erase_after_cursor
82
+ end
83
+
84
+ def scroll_down(val)
85
+ end
86
+
87
+ def clear_screen
88
+ end
89
+
90
+ def set_screen_size(rows, columns)
91
+ @screen_size = [rows, columns]
92
+ end
93
+
94
+ def set_winch_handler(&handler)
95
+ end
96
+
97
+ def in_pasting?
98
+ @pasting
99
+ end
100
+
101
+ def prep
102
+ end
103
+
104
+ def deprep(otio)
105
+ end
106
+ end