reline 0.5.2 → 0.5.8

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: 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