reline 0.5.2 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68e79c30bbef8d97090f7126f96c5ee0c32fa95e6dc120a91240a6e9ff3864c6
4
- data.tar.gz: 857716d3f9ab324efef98d3cb42acf2bba17848012a832c5631ca3e6d2f15733
3
+ metadata.gz: bcccc644594f9c2e4b9ae0eb743c2ae293ef084e96a8d9bd032b76825111c01b
4
+ data.tar.gz: b5ab239a3d20925d4fbd8fb827908fa3e4fa70298a172e32e9b2b4de59dc767e
5
5
  SHA512:
6
- metadata.gz: b25e6a151ded60963f660ccafceef8c221577b9f2328b9daa10dc381f5ea63c293a9759a786ab02610eb2fb07c52f3a200303fd9ac672210658884cb9a57c88c
7
- data.tar.gz: 8433437480cf5acf7d87aefc632cc641e9325f163ab1d00d1df9cea5d5f3977f05250b20b366d7fd21ae275edd8f152ddc5879fa88340fbf35990e9b2a7e9725
6
+ metadata.gz: 9bce894711da0253bf9b3f0eb192ff64947d591edd00f9094430431eb470fade4d02f3f8b529d364cdd7124d7f5a5203ea755be41dbfda890e37654aca430706
7
+ data.tar.gz: eed500ad148a1f83e3de03e6d7daaf5d250ba3ea25d47d24070e749dfd44a7d900b83474dd0b427faee74bad883dab97b7af1984a7fb7209e1819fd416d4381b
data/README.md CHANGED
@@ -15,7 +15,7 @@ Reline is compatible with the API of Ruby's stdlib 'readline', GNU Readline and
15
15
 
16
16
  It's compatible with the readline standard library.
17
17
 
18
- See [the document of readline stdlib](https://ruby-doc.org/stdlib/libdoc/readline/rdoc/Readline.html) or [bin/example](https://github.com/ruby/reline/blob/master/bin/example).
18
+ See [the document of readline stdlib](https://ruby-doc.org/stdlib/exts/readline/Readline.html) or [bin/example](https://github.com/ruby/reline/blob/master/bin/example).
19
19
 
20
20
  ### Multi-line editing mode
21
21
 
data/lib/reline/ansi.rb CHANGED
@@ -45,6 +45,7 @@ class Reline::ANSI
45
45
  end
46
46
 
47
47
  def self.set_default_key_bindings(config, allow_terminfo: true)
48
+ set_bracketed_paste_key_bindings(config)
48
49
  set_default_key_bindings_ansi_cursor(config)
49
50
  if allow_terminfo && Reline::Terminfo.enabled?
50
51
  set_default_key_bindings_terminfo(config)
@@ -66,6 +67,12 @@ class Reline::ANSI
66
67
  end
67
68
  end
68
69
 
70
+ def self.set_bracketed_paste_key_bindings(config)
71
+ [:emacs, :vi_insert, :vi_command].each do |keymap|
72
+ config.add_default_key_binding_by_keymap(keymap, START_BRACKETED_PASTE.bytes, :bracketed_paste_start)
73
+ end
74
+ end
75
+
69
76
  def self.set_default_key_bindings_ansi_cursor(config)
70
77
  ANSI_CURSOR_KEY_BINDINGS.each do |char, (default_func, modifiers)|
71
78
  bindings = [["\e[#{char}", default_func]] # CSI + char
@@ -178,46 +185,26 @@ class Reline::ANSI
178
185
  nil
179
186
  end
180
187
 
181
- @@in_bracketed_paste_mode = false
182
- START_BRACKETED_PASTE = String.new("\e[200~,", encoding: Encoding::ASCII_8BIT)
183
- END_BRACKETED_PASTE = String.new("\e[200~.", encoding: Encoding::ASCII_8BIT)
184
- def self.getc_with_bracketed_paste(timeout_second)
188
+ START_BRACKETED_PASTE = String.new("\e[200~", encoding: Encoding::ASCII_8BIT)
189
+ END_BRACKETED_PASTE = String.new("\e[201~", encoding: Encoding::ASCII_8BIT)
190
+ def self.read_bracketed_paste
185
191
  buffer = String.new(encoding: Encoding::ASCII_8BIT)
186
- buffer << inner_getc(timeout_second)
187
- while START_BRACKETED_PASTE.start_with?(buffer) or END_BRACKETED_PASTE.start_with?(buffer) do
188
- if START_BRACKETED_PASTE == buffer
189
- @@in_bracketed_paste_mode = true
190
- return inner_getc(timeout_second)
191
- elsif END_BRACKETED_PASTE == buffer
192
- @@in_bracketed_paste_mode = false
193
- ungetc(-1)
194
- return inner_getc(timeout_second)
195
- end
196
- succ_c = inner_getc(Reline.core.config.keyseq_timeout)
197
-
198
- if succ_c
199
- buffer << succ_c
200
- else
201
- break
202
- end
192
+ until buffer.end_with?(END_BRACKETED_PASTE)
193
+ c = inner_getc(Float::INFINITY)
194
+ break unless c
195
+ buffer << c
203
196
  end
204
- buffer.bytes.reverse_each do |ch|
205
- ungetc ch
206
- end
207
- inner_getc(timeout_second)
197
+ string = buffer.delete_suffix(END_BRACKETED_PASTE).force_encoding(encoding)
198
+ string.valid_encoding? ? string : ''
208
199
  end
209
200
 
210
201
  # if the usage expects to wait indefinitely, use Float::INFINITY for timeout_second
211
202
  def self.getc(timeout_second)
212
- if Reline.core.config.enable_bracketed_paste
213
- getc_with_bracketed_paste(timeout_second)
214
- else
215
- inner_getc(timeout_second)
216
- end
203
+ inner_getc(timeout_second)
217
204
  end
218
205
 
219
206
  def self.in_pasting?
220
- @@in_bracketed_paste_mode or (not empty_buffer?)
207
+ not empty_buffer?
221
208
  end
222
209
 
223
210
  def self.empty_buffer?
@@ -248,7 +235,7 @@ class Reline::ANSI
248
235
  s = [ENV["LINES"].to_i, ENV["COLUMNS"].to_i]
249
236
  return s if s[0] > 0 && s[1] > 0
250
237
  [24, 80]
251
- rescue Errno::ENOTTY
238
+ rescue Errno::ENOTTY, Errno::ENODEV
252
239
  [24, 80]
253
240
  end
254
241
 
@@ -284,7 +271,7 @@ class Reline::ANSI
284
271
  buf = @@output.pread(@@output.pos, 0)
285
272
  row = buf.count("\n")
286
273
  column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0
287
- rescue Errno::ESPIPE
274
+ rescue Errno::ESPIPE, IOError
288
275
  # Just returns column 1 for ambiguous width because this I/O is not
289
276
  # tty and can't seek.
290
277
  row = 0
@@ -361,11 +348,15 @@ class Reline::ANSI
361
348
  end
362
349
 
363
350
  def self.prep
351
+ # Enable bracketed paste
352
+ @@output.write "\e[?2004h" if Reline.core.config.enable_bracketed_paste
364
353
  retrieve_keybuffer
365
354
  nil
366
355
  end
367
356
 
368
357
  def self.deprep(otio)
358
+ # Disable bracketed paste
359
+ @@output.write "\e[?2004l" if Reline.core.config.enable_bracketed_paste
369
360
  Signal.trap('WINCH', @@old_winch_handler) if @@old_winch_handler
370
361
  end
371
362
  end
data/lib/reline/config.rb CHANGED
@@ -8,31 +8,12 @@ class Reline::Config
8
8
  end
9
9
 
10
10
  VARIABLE_NAMES = %w{
11
- bind-tty-special-chars
12
- blink-matching-paren
13
- byte-oriented
14
11
  completion-ignore-case
15
12
  convert-meta
16
13
  disable-completion
17
- enable-keypad
18
- expand-tilde
19
- history-preserve-point
20
14
  history-size
21
- horizontal-scroll-mode
22
- input-meta
23
15
  keyseq-timeout
24
- mark-directories
25
- mark-modified-lines
26
- mark-symlinked-directories
27
- match-hidden-files
28
- meta-flag
29
- output-meta
30
- page-completions
31
- prefer-visible-bell
32
- print-completions-horizontally
33
16
  show-all-if-ambiguous
34
- show-all-if-unmodified
35
- visible-stats
36
17
  show-mode-in-prompt
37
18
  vi-cmd-mode-string
38
19
  vi-ins-mode-string
@@ -53,8 +34,6 @@ class Reline::Config
53
34
  @additional_key_bindings[:vi_insert] = {}
54
35
  @additional_key_bindings[:vi_command] = {}
55
36
  @oneshot_key_bindings = {}
56
- @skip_section = nil
57
- @if_stack = nil
58
37
  @editing_mode_label = :emacs
59
38
  @keymap_label = :emacs
60
39
  @keymap_prefix = []
@@ -71,17 +50,15 @@ class Reline::Config
71
50
  @test_mode = false
72
51
  @autocompletion = false
73
52
  @convert_meta = true if seven_bit_encoding?(Reline::IOGate.encoding)
53
+ @loaded = false
54
+ @enable_bracketed_paste = true
74
55
  end
75
56
 
76
57
  def reset
77
58
  if editing_mode_is?(:vi_command)
78
59
  @editing_mode_label = :vi_insert
79
60
  end
80
- @additional_key_bindings.keys.each do |key|
81
- @additional_key_bindings[key].clear
82
- end
83
61
  @oneshot_key_bindings.clear
84
- reset_default_key_bindings
85
62
  end
86
63
 
87
64
  def editing_mode
@@ -100,6 +77,10 @@ class Reline::Config
100
77
  @key_actors[@keymap_label]
101
78
  end
102
79
 
80
+ def loaded?
81
+ @loaded
82
+ end
83
+
103
84
  def inputrc_path
104
85
  case ENV['INPUTRC']
105
86
  when nil, ''
@@ -131,6 +112,7 @@ class Reline::Config
131
112
  end
132
113
 
133
114
  def read(file = nil)
115
+ @loaded = true
134
116
  file ||= default_inputrc_path
135
117
  begin
136
118
  if file.respond_to?(:readlines)
@@ -173,12 +155,6 @@ class Reline::Config
173
155
  @key_actors[@keymap_label].default_key_bindings[keystroke] = target
174
156
  end
175
157
 
176
- def reset_default_key_bindings
177
- @key_actors.values.each do |ka|
178
- ka.reset_default_key_bindings
179
- end
180
- end
181
-
182
158
  def read_lines(lines, file = nil)
183
159
  if not lines.empty? and lines.first.encoding != Reline.encoding_system_needs
184
160
  begin
@@ -190,9 +166,7 @@ class Reline::Config
190
166
  end
191
167
  end
192
168
  end
193
- conditions = [@skip_section, @if_stack]
194
- @skip_section = nil
195
- @if_stack = []
169
+ if_stack = []
196
170
 
197
171
  lines.each_with_index do |line, no|
198
172
  next if line.match(/\A\s*#/)
@@ -201,62 +175,67 @@ class Reline::Config
201
175
 
202
176
  line = line.chomp.lstrip
203
177
  if line.start_with?('$')
204
- handle_directive(line[1..-1], file, no)
178
+ handle_directive(line[1..-1], file, no, if_stack)
205
179
  next
206
180
  end
207
181
 
208
- next if @skip_section
182
+ next if if_stack.any? { |_no, skip| skip }
209
183
 
210
184
  case line
211
- when /^set +([^ ]+) +([^ ]+)/i
212
- var, value = $1.downcase, $2
213
- bind_variable(var, value)
185
+ when /^set +([^ ]+) +(.+)/i
186
+ # value ignores everything after a space, raw_value does not.
187
+ var, value, raw_value = $1.downcase, $2.partition(' ').first, $2
188
+ bind_variable(var, value, raw_value)
214
189
  next
215
190
  when /\s*("#{KEYSEQ_PATTERN}+")\s*:\s*(.*)\s*$/o
216
191
  key, func_name = $1, $2
192
+ func_name = func_name.split.first
217
193
  keystroke, func = bind_key(key, func_name)
218
194
  next unless keystroke
219
195
  @additional_key_bindings[@keymap_label][@keymap_prefix + keystroke] = func
220
196
  end
221
197
  end
222
- unless @if_stack.empty?
223
- raise InvalidInputrc, "#{file}:#{@if_stack.last[1]}: unclosed if"
198
+ unless if_stack.empty?
199
+ raise InvalidInputrc, "#{file}:#{if_stack.last[0]}: unclosed if"
224
200
  end
225
- ensure
226
- @skip_section, @if_stack = conditions
227
201
  end
228
202
 
229
- def handle_directive(directive, file, no)
203
+ def handle_directive(directive, file, no, if_stack)
230
204
  directive, args = directive.split(' ')
231
205
  case directive
232
206
  when 'if'
233
207
  condition = false
234
208
  case args
235
- when 'mode'
209
+ when /^mode=(vi|emacs)$/i
210
+ mode = $1.downcase
211
+ # NOTE: mode=vi means vi-insert mode
212
+ mode = 'vi_insert' if mode == 'vi'
213
+ if @editing_mode_label == mode.to_sym
214
+ condition = true
215
+ end
236
216
  when 'term'
237
217
  when 'version'
238
218
  else # application name
239
219
  condition = true if args == 'Ruby'
240
220
  condition = true if args == 'Reline'
241
221
  end
242
- @if_stack << [file, no, @skip_section]
243
- @skip_section = !condition
222
+ if_stack << [no, !condition]
244
223
  when 'else'
245
- if @if_stack.empty?
224
+ if if_stack.empty?
246
225
  raise InvalidInputrc, "#{file}:#{no}: unmatched else"
247
226
  end
248
- @skip_section = !@skip_section
227
+ if_stack.last[1] = !if_stack.last[1]
249
228
  when 'endif'
250
- if @if_stack.empty?
229
+ if if_stack.empty?
251
230
  raise InvalidInputrc, "#{file}:#{no}: unmatched endif"
252
231
  end
253
- @skip_section = @if_stack.pop
232
+ if_stack.pop
254
233
  when 'include'
255
234
  read(File.expand_path(args))
256
235
  end
257
236
  end
258
237
 
259
- def bind_variable(name, value)
238
+ def bind_variable(name, value, raw_value)
260
239
  case name
261
240
  when 'history-size'
262
241
  begin
@@ -281,7 +260,7 @@ class Reline::Config
281
260
  when 'completion-query-items'
282
261
  @completion_query_items = value.to_i
283
262
  when 'isearch-terminators'
284
- @isearch_terminators = retrieve_string(value)
263
+ @isearch_terminators = retrieve_string(raw_value)
285
264
  when 'editing-mode'
286
265
  case value
287
266
  when 'emacs'
@@ -323,11 +302,11 @@ class Reline::Config
323
302
  @show_mode_in_prompt = false
324
303
  end
325
304
  when 'vi-cmd-mode-string'
326
- @vi_cmd_mode_string = retrieve_string(value)
305
+ @vi_cmd_mode_string = retrieve_string(raw_value)
327
306
  when 'vi-ins-mode-string'
328
- @vi_ins_mode_string = retrieve_string(value)
307
+ @vi_ins_mode_string = retrieve_string(raw_value)
329
308
  when 'emacs-mode-string'
330
- @emacs_mode_string = retrieve_string(value)
309
+ @emacs_mode_string = retrieve_string(raw_value)
331
310
  when *VARIABLE_NAMES then
332
311
  variable_name = :"@#{name.tr(?-, ?_)}"
333
312
  instance_variable_set(variable_name, value.nil? || value == '1' || value == 'on')
@@ -12,8 +12,4 @@ class Reline::KeyActor::Base
12
12
  def default_key_bindings
13
13
  @default_key_bindings
14
14
  end
15
-
16
- def reset_default_key_bindings
17
- @default_key_bindings.clear
18
- end
19
15
  end
@@ -19,7 +19,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
19
19
  # 8 ^H
20
20
  :em_delete_prev_char,
21
21
  # 9 ^I
22
- :ed_unassigned,
22
+ :complete,
23
23
  # 10 ^J
24
24
  :ed_newline,
25
25
  # 11 ^K
@@ -63,7 +63,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
63
63
  # 30 ^^
64
64
  :ed_unassigned,
65
65
  # 31 ^_
66
- :ed_unassigned,
66
+ :undo,
67
67
  # 32 SPACE
68
68
  :ed_insert,
69
69
  # 33 !
@@ -319,7 +319,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
319
319
  # 158 M-^^
320
320
  :ed_unassigned,
321
321
  # 159 M-^_
322
- :ed_unassigned,
322
+ :redo,
323
323
  # 160 M-SPACE
324
324
  :em_set_mark,
325
325
  # 161 M-!
@@ -19,7 +19,7 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
19
19
  # 8 ^H
20
20
  :vi_delete_prev_char,
21
21
  # 9 ^I
22
- :ed_insert,
22
+ :complete,
23
23
  # 10 ^J
24
24
  :ed_newline,
25
25
  # 11 ^K
@@ -29,11 +29,11 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
29
29
  # 13 ^M
30
30
  :ed_newline,
31
31
  # 14 ^N
32
- :ed_insert,
32
+ :menu_complete,
33
33
  # 15 ^O
34
34
  :ed_insert,
35
35
  # 16 ^P
36
- :ed_insert,
36
+ :menu_complete_backward,
37
37
  # 17 ^Q
38
38
  :ed_ignore,
39
39
  # 18 ^R