reline 0.1.5 → 0.3.1

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: cb0a1da0d5f51d50b82a78a3084a69ca37821b541e3c362bcb2b9a10a04664a3
4
- data.tar.gz: bc1860cf76efa34984aef1dbafb60d1f7781b86ba44a9392dc5fbd8025631121
3
+ metadata.gz: 1009c9156a8c15c1f3c64a3cb89a0d6a1acef037185bfb76c24ed9df7e49cb2c
4
+ data.tar.gz: 983ad1d570617a47d732402485a79eba8bd1acc6f3555f117ca6822cee52030d
5
5
  SHA512:
6
- metadata.gz: 4691bf1855429c5f1c25b16f66bc1e4793290579ae9a7345d1dd97c2694863bec59bab30edb232665b38a1f302a4e601c99111c84e5c277651ab2e53d4353982
7
- data.tar.gz: 9ba7b27a82ce1d823f394c78ba1d995b6c4f71ddecb13c17c27fb39a13b7503c3b84402feb0239eb33d19d87f00d06c0608e35439413f6c72d2bdea50e84d10e
6
+ metadata.gz: 424c026623c896ccd59fed73b5f61e7bb067dfdc8fe34a13bdb317895fb512eb666b25c76439e940915307e658e85dbbfcb8339ecfae5c5b72fa9239d1599778
7
+ data.tar.gz: 93077ced9c8009d5c2f7f59eb013f8134394347c57660e7958244a2adfe60b2a09463ac2062d9ce31e5d75974b19665f7e800f2078bf9b461dfbada76c3e572e
data/README.md CHANGED
@@ -8,6 +8,56 @@ This is a screen capture of *IRB improved by Reline*.
8
8
 
9
9
  Reline is compatible with the API of Ruby's stdlib 'readline', GNU Readline and Editline by pure Ruby implementation.
10
10
 
11
+ ## Usage
12
+
13
+ ### Single line editing mode
14
+
15
+ It's compatible with the readline standard library.
16
+
17
+ 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
+
19
+ ### Multi-line editing mode
20
+
21
+ ```ruby
22
+ require "reline"
23
+
24
+ prompt = 'prompt> '
25
+ use_history = true
26
+
27
+ begin
28
+ while true
29
+ text = Reline.readmultiline(prompt, use_history) do |multiline_input|
30
+ # Accept the input until `end` is entered
31
+ multiline_input.split.last == "end"
32
+ end
33
+
34
+ puts 'You entered:'
35
+ puts text
36
+ end
37
+ # If you want to exit, type Ctrl-C
38
+ rescue Interrupt
39
+ puts '^C'
40
+ exit 0
41
+ end
42
+ ```
43
+
44
+ ```bash
45
+ $ ruby example.rb
46
+ prompt> aaa
47
+ prompt> bbb
48
+ prompt> end
49
+ You entered:
50
+ aaa
51
+ bbb
52
+ end
53
+ ```
54
+
55
+ See also: [test/reline/yamatanooroti/multiline_repl](https://github.com/ruby/reline/blob/master/test/reline/yamatanooroti/multiline_repl)
56
+
11
57
  ## License
12
58
 
13
59
  The gem is available as open source under the terms of the [Ruby License](https://www.ruby-lang.org/en/about/license.txt).
60
+
61
+ ## Acknowledgments for [rb-readline](https://github.com/ConnorAtherton/rb-readline)
62
+
63
+ In developing Reline, we have used some of the rb-readline implementation, so this library includes [copyright notice, list of conditions and the disclaimer](license_of_rb-readline) under the 3-Clause BSD License. Reline would never have been developed without rb-readline. Thank you for the tremendous accomplishments.
data/lib/reline/ansi.rb CHANGED
@@ -1,6 +1,26 @@
1
1
  require 'io/console'
2
+ require 'io/wait'
3
+ require 'timeout'
4
+ require_relative 'terminfo'
2
5
 
3
6
  class Reline::ANSI
7
+ CAPNAME_KEY_BINDINGS = {
8
+ 'khome' => :ed_move_to_beg,
9
+ 'kend' => :ed_move_to_end,
10
+ 'kcuu1' => :ed_prev_history,
11
+ 'kcud1' => :ed_next_history,
12
+ 'kcuf1' => :ed_next_char,
13
+ 'kcub1' => :ed_prev_char,
14
+ 'cuu' => :ed_prev_history,
15
+ 'cud' => :ed_next_history,
16
+ 'cuf' => :ed_next_char,
17
+ 'cub' => :ed_prev_char,
18
+ }
19
+
20
+ if Reline::Terminfo.enabled?
21
+ Reline::Terminfo.setupterm(0, 2)
22
+ end
23
+
4
24
  def self.encoding
5
25
  Encoding.default_external
6
26
  end
@@ -9,52 +29,108 @@ class Reline::ANSI
9
29
  false
10
30
  end
11
31
 
12
- RAW_KEYSTROKE_CONFIG = {
13
- # Console (80x25)
14
- [27, 91, 49, 126] => :ed_move_to_beg, # Home
15
- [27, 91, 52, 126] => :ed_move_to_end, # End
16
- [27, 91, 51, 126] => :key_delete, # Del
17
- [27, 91, 65] => :ed_prev_history, # ↑
18
- [27, 91, 66] => :ed_next_history, # ↓
19
- [27, 91, 67] => :ed_next_char, # →
20
- [27, 91, 68] => :ed_prev_char, #
21
-
22
- # KDE
23
- [27, 91, 72] => :ed_move_to_beg, # Home
24
- [27, 91, 70] => :ed_move_to_end, # End
25
- # Del is 0x08
26
- [27, 71, 65] => :ed_prev_history, # ↑
27
- [27, 71, 66] => :ed_next_history, # ↓
28
- [27, 71, 67] => :ed_next_char, # →
29
- [27, 71, 68] => :ed_prev_char, # ←
30
-
31
- # urxvt / exoterm
32
- [27, 91, 55, 126] => :ed_move_to_beg, # Home
33
- [27, 91, 56, 126] => :ed_move_to_end, # End
34
-
35
- # GNOME
36
- [27, 79, 72] => :ed_move_to_beg, # Home
37
- [27, 79, 70] => :ed_move_to_end, # End
38
- # Del is 0x08
39
- # Arrow keys are the same of KDE
40
-
41
- # iTerm2
42
- [27, 27, 91, 67] => :em_next_word, # Option+→
43
- [27, 27, 91, 68] => :ed_prev_word, # Option+←
44
- [195, 166] => :em_next_word, # Option+f
45
- [195, 162] => :ed_prev_word, # Option+b
46
-
47
- # others
48
- [27, 32] => :em_set_mark, # M-<space>
49
- [24, 24] => :em_exchange_mark, # C-x C-x TODO also add Windows
50
- [27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→
51
- [27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←
52
-
53
- [27, 79, 65] => :ed_prev_history, # ↑
54
- [27, 79, 66] => :ed_next_history, # ↓
55
- [27, 79, 67] => :ed_next_char, # →
56
- [27, 79, 68] => :ed_prev_char, # ←
57
- }
32
+ def self.set_default_key_bindings(config)
33
+ if Reline::Terminfo.enabled?
34
+ set_default_key_bindings_terminfo(config)
35
+ else
36
+ set_default_key_bindings_comprehensive_list(config)
37
+ end
38
+ {
39
+ # extended entries of terminfo
40
+ [27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→, extended entry
41
+ [27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←, extended entry
42
+ [27, 91, 49, 59, 51, 67] => :em_next_word, # Meta+→, extended entry
43
+ [27, 91, 49, 59, 51, 68] => :ed_prev_word, # Meta+←, extended entry
44
+ }.each_pair do |key, func|
45
+ config.add_default_key_binding_by_keymap(:emacs, key, func)
46
+ config.add_default_key_binding_by_keymap(:vi_insert, key, func)
47
+ config.add_default_key_binding_by_keymap(:vi_command, key, func)
48
+ end
49
+ {
50
+ [27, 91, 90] => :completion_journey_up, # S-Tab
51
+ }.each_pair do |key, func|
52
+ config.add_default_key_binding_by_keymap(:emacs, key, func)
53
+ config.add_default_key_binding_by_keymap(:vi_insert, key, func)
54
+ end
55
+ {
56
+ # default bindings
57
+ [27, 32] => :em_set_mark, # M-<space>
58
+ [24, 24] => :em_exchange_mark, # C-x C-x
59
+ }.each_pair do |key, func|
60
+ config.add_default_key_binding_by_keymap(:emacs, key, func)
61
+ end
62
+ end
63
+
64
+ def self.set_default_key_bindings_terminfo(config)
65
+ key_bindings = CAPNAME_KEY_BINDINGS.map do |capname, key_binding|
66
+ begin
67
+ key_code = Reline::Terminfo.tigetstr(capname)
68
+ case capname
69
+ # Escape sequences that omit the move distance and are set to defaults
70
+ # value 1 may be sometimes sent by pressing the arrow-key.
71
+ when 'cuu', 'cud', 'cuf', 'cub'
72
+ [ key_code.sub(/%p1%d/, '').bytes, key_binding ]
73
+ else
74
+ [ key_code.bytes, key_binding ]
75
+ end
76
+ rescue Reline::Terminfo::TerminfoError
77
+ # capname is undefined
78
+ end
79
+ end.compact.to_h
80
+
81
+ key_bindings.each_pair do |key, func|
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
+
88
+ def self.set_default_key_bindings_comprehensive_list(config)
89
+ {
90
+ # Console (80x25)
91
+ [27, 91, 49, 126] => :ed_move_to_beg, # Home
92
+ [27, 91, 52, 126] => :ed_move_to_end, # End
93
+ [27, 91, 51, 126] => :key_delete, # Del
94
+ [27, 91, 65] => :ed_prev_history, # ↑
95
+ [27, 91, 66] => :ed_next_history, # ↓
96
+ [27, 91, 67] => :ed_next_char, # →
97
+ [27, 91, 68] => :ed_prev_char, # ←
98
+
99
+ # KDE
100
+ [27, 91, 72] => :ed_move_to_beg, # Home
101
+ [27, 91, 70] => :ed_move_to_end, # End
102
+ # Del is 0x08
103
+ [27, 71, 65] => :ed_prev_history, # ↑
104
+ [27, 71, 66] => :ed_next_history, # ↓
105
+ [27, 71, 67] => :ed_next_char, # →
106
+ [27, 71, 68] => :ed_prev_char, # ←
107
+
108
+ # urxvt / exoterm
109
+ [27, 91, 55, 126] => :ed_move_to_beg, # Home
110
+ [27, 91, 56, 126] => :ed_move_to_end, # End
111
+
112
+ # GNOME
113
+ [27, 79, 72] => :ed_move_to_beg, # Home
114
+ [27, 79, 70] => :ed_move_to_end, # End
115
+ # Del is 0x08
116
+ # Arrow keys are the same of KDE
117
+
118
+ # iTerm2
119
+ [27, 27, 91, 67] => :em_next_word, # Option+→, extended entry
120
+ [27, 27, 91, 68] => :ed_prev_word, # Option+←, extended entry
121
+ [195, 166] => :em_next_word, # Option+f
122
+ [195, 162] => :ed_prev_word, # Option+b
123
+
124
+ [27, 79, 65] => :ed_prev_history, # ↑
125
+ [27, 79, 66] => :ed_next_history, # ↓
126
+ [27, 79, 67] => :ed_next_char, # →
127
+ [27, 79, 68] => :ed_prev_char, # ←
128
+ }.each_pair do |key, func|
129
+ config.add_default_key_binding_by_keymap(:emacs, key, func)
130
+ config.add_default_key_binding_by_keymap(:vi_insert, key, func)
131
+ config.add_default_key_binding_by_keymap(:vi_command, key, func)
132
+ end
133
+ end
58
134
 
59
135
  @@input = STDIN
60
136
  def self.input=(val)
@@ -67,17 +143,70 @@ class Reline::ANSI
67
143
  end
68
144
 
69
145
  @@buf = []
70
- def self.getc
146
+ def self.inner_getc
71
147
  unless @@buf.empty?
72
148
  return @@buf.shift
73
149
  end
74
- until c = @@input.raw(intr: true, &:getbyte)
75
- sleep 0.1
150
+ until c = @@input.raw(intr: true) { @@input.wait_readable(0.1) && @@input.getbyte }
151
+ Reline.core.line_editor.resize
76
152
  end
77
153
  (c == 0x16 && @@input.raw(min: 0, tim: 0, &:getbyte)) || c
78
154
  rescue Errno::EIO
79
155
  # Maybe the I/O has been closed.
80
156
  nil
157
+ rescue Errno::ENOTTY
158
+ nil
159
+ end
160
+
161
+ @@in_bracketed_paste_mode = false
162
+ START_BRACKETED_PASTE = String.new("\e[200~,", encoding: Encoding::ASCII_8BIT)
163
+ END_BRACKETED_PASTE = String.new("\e[200~.", encoding: Encoding::ASCII_8BIT)
164
+ def self.getc_with_bracketed_paste
165
+ buffer = String.new(encoding: Encoding::ASCII_8BIT)
166
+ buffer << inner_getc
167
+ while START_BRACKETED_PASTE.start_with?(buffer) or END_BRACKETED_PASTE.start_with?(buffer) do
168
+ if START_BRACKETED_PASTE == buffer
169
+ @@in_bracketed_paste_mode = true
170
+ return inner_getc
171
+ elsif END_BRACKETED_PASTE == buffer
172
+ @@in_bracketed_paste_mode = false
173
+ ungetc(-1)
174
+ return inner_getc
175
+ end
176
+ begin
177
+ succ_c = nil
178
+ Timeout.timeout(Reline.core.config.keyseq_timeout * 100) {
179
+ succ_c = inner_getc
180
+ }
181
+ rescue Timeout::Error
182
+ break
183
+ else
184
+ buffer << succ_c
185
+ end
186
+ end
187
+ buffer.bytes.reverse_each do |ch|
188
+ ungetc ch
189
+ end
190
+ inner_getc
191
+ end
192
+
193
+ def self.getc
194
+ if Reline.core.config.enable_bracketed_paste
195
+ getc_with_bracketed_paste
196
+ else
197
+ inner_getc
198
+ end
199
+ end
200
+
201
+ def self.in_pasting?
202
+ @@in_bracketed_paste_mode or (not Reline::IOGate.empty_buffer?)
203
+ end
204
+
205
+ def self.empty_buffer?
206
+ unless @@buf.empty?
207
+ return false
208
+ end
209
+ !@@input.wait_readable(0)
81
210
  end
82
211
 
83
212
  def self.ungetc(c)
@@ -86,8 +215,7 @@ class Reline::ANSI
86
215
 
87
216
  def self.retrieve_keybuffer
88
217
  begin
89
- result = select([@@input], [], [], 0.001)
90
- return if result.nil?
218
+ return unless @@input.wait_readable(0.001)
91
219
  str = @@input.read_nonblock(1024)
92
220
  str.bytes.each do |c|
93
221
  @@buf.push(c)
@@ -115,7 +243,7 @@ class Reline::ANSI
115
243
 
116
244
  def self.cursor_pos
117
245
  begin
118
- res = ''
246
+ res = +''
119
247
  m = nil
120
248
  @@input.raw do |stdin|
121
249
  @@output << "\e[6n"
@@ -154,7 +282,7 @@ class Reline::ANSI
154
282
 
155
283
  def self.move_cursor_up(x)
156
284
  if x > 0
157
- @@output.write "\e[#{x}A" if x > 0
285
+ @@output.write "\e[#{x}A"
158
286
  elsif x < 0
159
287
  move_cursor_down(-x)
160
288
  end
@@ -162,12 +290,36 @@ class Reline::ANSI
162
290
 
163
291
  def self.move_cursor_down(x)
164
292
  if x > 0
165
- @@output.write "\e[#{x}B" if x > 0
293
+ @@output.write "\e[#{x}B"
166
294
  elsif x < 0
167
295
  move_cursor_up(-x)
168
296
  end
169
297
  end
170
298
 
299
+ def self.hide_cursor
300
+ if Reline::Terminfo.enabled?
301
+ begin
302
+ @@output.write Reline::Terminfo.tigetstr('civis')
303
+ rescue Reline::Terminfo::TerminfoError
304
+ # civis is undefined
305
+ end
306
+ else
307
+ # ignored
308
+ end
309
+ end
310
+
311
+ def self.show_cursor
312
+ if Reline::Terminfo.enabled?
313
+ begin
314
+ @@output.write Reline::Terminfo.tigetstr('cnorm')
315
+ rescue Reline::Terminfo::TerminfoError
316
+ # cnorm is undefined
317
+ end
318
+ else
319
+ # ignored
320
+ end
321
+ end
322
+
171
323
  def self.erase_after_cursor
172
324
  @@output.write "\e[K"
173
325
  end
@@ -189,14 +341,10 @@ class Reline::ANSI
189
341
 
190
342
  def self.prep
191
343
  retrieve_keybuffer
192
- int_handle = Signal.trap('INT', 'IGNORE')
193
- Signal.trap('INT', int_handle)
194
344
  nil
195
345
  end
196
346
 
197
347
  def self.deprep(otio)
198
- int_handle = Signal.trap('INT', 'IGNORE')
199
- Signal.trap('INT', int_handle)
200
348
  Signal.trap('WINCH', @@old_winch_handler) if @@old_winch_handler
201
349
  end
202
350
  end
data/lib/reline/config.rb CHANGED
@@ -34,9 +34,11 @@ class Reline::Config
34
34
  show-all-if-unmodified
35
35
  visible-stats
36
36
  show-mode-in-prompt
37
- vi-cmd-mode-icon
38
- vi-ins-mode-icon
37
+ vi-cmd-mode-string
38
+ vi-ins-mode-string
39
39
  emacs-mode-string
40
+ enable-bracketed-paste
41
+ isearch-terminators
40
42
  }
41
43
  VARIABLE_NAME_SYMBOLS = VARIABLE_NAMES.map { |v| :"#{v.tr(?-, ?_)}" }
42
44
  VARIABLE_NAME_SYMBOLS.each do |v|
@@ -45,7 +47,10 @@ class Reline::Config
45
47
 
46
48
  def initialize
47
49
  @additional_key_bindings = {} # from inputrc
48
- @default_key_bindings = {} # environment-dependent
50
+ @additional_key_bindings[:emacs] = {}
51
+ @additional_key_bindings[:vi_insert] = {}
52
+ @additional_key_bindings[:vi_command] = {}
53
+ @oneshot_key_bindings = {}
49
54
  @skip_section = nil
50
55
  @if_stack = nil
51
56
  @editing_mode_label = :emacs
@@ -54,21 +59,26 @@ class Reline::Config
54
59
  @key_actors[:emacs] = Reline::KeyActor::Emacs.new
55
60
  @key_actors[:vi_insert] = Reline::KeyActor::ViInsert.new
56
61
  @key_actors[:vi_command] = Reline::KeyActor::ViCommand.new
57
- @vi_cmd_mode_icon = '(cmd)'
58
- @vi_ins_mode_icon = '(ins)'
62
+ @vi_cmd_mode_string = '(cmd)'
63
+ @vi_ins_mode_string = '(ins)'
59
64
  @emacs_mode_string = '@'
60
65
  # https://tiswww.case.edu/php/chet/readline/readline.html#IDX25
61
66
  @history_size = -1 # unlimited
62
67
  @keyseq_timeout = 500
63
68
  @test_mode = false
69
+ @autocompletion = false
70
+ @convert_meta = true if seven_bit_encoding?(Reline::IOGate.encoding)
64
71
  end
65
72
 
66
73
  def reset
67
74
  if editing_mode_is?(:vi_command)
68
75
  @editing_mode_label = :vi_insert
69
76
  end
70
- @additional_key_bindings = {}
71
- @default_key_bindings = {}
77
+ @additional_key_bindings.keys.each do |key|
78
+ @additional_key_bindings[key].clear
79
+ end
80
+ @oneshot_key_bindings.clear
81
+ reset_default_key_bindings
72
82
  end
73
83
 
74
84
  def editing_mode
@@ -83,6 +93,14 @@ class Reline::Config
83
93
  (val.respond_to?(:any?) ? val : [val]).any?(@editing_mode_label)
84
94
  end
85
95
 
96
+ def autocompletion=(val)
97
+ @autocompletion = val
98
+ end
99
+
100
+ def autocompletion
101
+ @autocompletion
102
+ end
103
+
86
104
  def keymap
87
105
  @key_actors[@keymap_label]
88
106
  end
@@ -113,8 +131,12 @@ class Reline::Config
113
131
  return home_rc_path
114
132
  end
115
133
 
134
+ private def default_inputrc_path
135
+ @default_inputrc_path ||= inputrc_path
136
+ end
137
+
116
138
  def read(file = nil)
117
- file ||= inputrc_path
139
+ file ||= default_inputrc_path
118
140
  begin
119
141
  if file.respond_to?(:readlines)
120
142
  lines = file.readlines
@@ -133,19 +155,46 @@ class Reline::Config
133
155
  end
134
156
 
135
157
  def key_bindings
136
- # override @default_key_bindings with @additional_key_bindings
137
- @default_key_bindings.merge(@additional_key_bindings)
158
+ # The key bindings for each editing mode will be overwritten by the user-defined ones.
159
+ kb = @key_actors[@editing_mode_label].default_key_bindings.dup
160
+ kb.merge!(@additional_key_bindings[@editing_mode_label])
161
+ kb.merge!(@oneshot_key_bindings)
162
+ kb
163
+ end
164
+
165
+ def add_oneshot_key_binding(keystroke, target)
166
+ @oneshot_key_bindings[keystroke] = target
167
+ end
168
+
169
+ def reset_oneshot_key_bindings
170
+ @oneshot_key_bindings.clear
171
+ end
172
+
173
+ def add_default_key_binding_by_keymap(keymap, keystroke, target)
174
+ @key_actors[keymap].default_key_bindings[keystroke] = target
138
175
  end
139
176
 
140
177
  def add_default_key_binding(keystroke, target)
141
- @default_key_bindings[keystroke] = target
178
+ @key_actors[@keymap_label].default_key_bindings[keystroke] = target
142
179
  end
143
180
 
144
181
  def reset_default_key_bindings
145
- @default_key_bindings = {}
182
+ @key_actors.values.each do |ka|
183
+ ka.reset_default_key_bindings
184
+ end
146
185
  end
147
186
 
148
187
  def read_lines(lines, file = nil)
188
+ if not lines.empty? and lines.first.encoding != Reline.encoding_system_needs
189
+ begin
190
+ lines = lines.map do |l|
191
+ l.encode(Reline.encoding_system_needs)
192
+ rescue Encoding::UndefinedConversionError
193
+ mes = "The inputrc encoded in #{lines.first.encoding.name} can't be converted to the locale #{Reline.encoding_system_needs.name}."
194
+ raise Reline::ConfigEncodingConversionError.new(mes)
195
+ end
196
+ end
197
+ end
149
198
  conditions = [@skip_section, @if_stack]
150
199
  @skip_section = nil
151
200
  @if_stack = []
@@ -172,7 +221,7 @@ class Reline::Config
172
221
  key, func_name = $1, $2
173
222
  keystroke, func = bind_key(key, func_name)
174
223
  next unless keystroke
175
- @additional_key_bindings[keystroke] = func
224
+ @additional_key_bindings[@keymap_label][keystroke] = func
176
225
  end
177
226
  end
178
227
  unless @if_stack.empty?
@@ -237,7 +286,7 @@ class Reline::Config
237
286
  when 'completion-query-items'
238
287
  @completion_query_items = value.to_i
239
288
  when 'isearch-terminators'
240
- @isearch_terminators = instance_eval(value)
289
+ @isearch_terminators = retrieve_string(value)
241
290
  when 'editing-mode'
242
291
  case value
243
292
  when 'emacs'
@@ -268,9 +317,9 @@ class Reline::Config
268
317
  @show_mode_in_prompt = false
269
318
  end
270
319
  when 'vi-cmd-mode-string'
271
- @vi_cmd_mode_icon = retrieve_string(value)
320
+ @vi_cmd_mode_string = retrieve_string(value)
272
321
  when 'vi-ins-mode-string'
273
- @vi_ins_mode_icon = retrieve_string(value)
322
+ @vi_ins_mode_string = retrieve_string(value)
274
323
  when 'emacs-mode-string'
275
324
  @emacs_mode_string = retrieve_string(value)
276
325
  when *VARIABLE_NAMES then
@@ -280,11 +329,8 @@ class Reline::Config
280
329
  end
281
330
 
282
331
  def retrieve_string(str)
283
- if str =~ /\A"(.*)"\z/
284
- parse_keyseq($1).map(&:chr).join
285
- else
286
- parse_keyseq(str).map(&:chr).join
287
- end
332
+ str = $1 if str =~ /\A"(.*)"\z/
333
+ parse_keyseq(str).map { |c| c.chr(Reline.encoding_system_needs) }.join
288
334
  end
289
335
 
290
336
  def bind_key(key, func_name)
@@ -342,4 +388,8 @@ class Reline::Config
342
388
  end
343
389
  ret
344
390
  end
391
+
392
+ private def seven_bit_encoding?(encoding)
393
+ encoding == Encoding::US_ASCII
394
+ end
345
395
  end
@@ -1,17 +1,31 @@
1
1
  require 'timeout'
2
+ require 'io/wait'
2
3
 
3
4
  class Reline::GeneralIO
5
+ def self.reset(encoding: nil)
6
+ @@pasting = false
7
+ @@encoding = encoding
8
+ end
9
+
4
10
  def self.encoding
5
- RUBY_PLATFORM =~ /mswin|mingw/ ? Encoding::UTF_8 : Encoding::default_external
11
+ if defined?(@@encoding)
12
+ @@encoding
13
+ elsif RUBY_PLATFORM =~ /mswin|mingw/
14
+ Encoding::UTF_8
15
+ else
16
+ Encoding::default_external
17
+ end
6
18
  end
7
19
 
8
20
  def self.win?
9
21
  false
10
22
  end
11
23
 
12
- RAW_KEYSTROKE_CONFIG = {}
24
+ def self.set_default_key_bindings(_)
25
+ end
13
26
 
14
27
  @@buf = []
28
+ @@input = STDIN
15
29
 
16
30
  def self.input=(val)
17
31
  @@input = val
@@ -23,7 +37,7 @@ class Reline::GeneralIO
23
37
  end
24
38
  c = nil
25
39
  loop do
26
- result = select([@@input], [], [], 0.1)
40
+ result = @@input.wait_readable(0.1)
27
41
  next if result.nil?
28
42
  c = @@input.read(1)
29
43
  break
@@ -67,6 +81,20 @@ class Reline::GeneralIO
67
81
  def self.set_winch_handler(&handler)
68
82
  end
69
83
 
84
+ @@pasting = false
85
+
86
+ def self.in_pasting?
87
+ @@pasting
88
+ end
89
+
90
+ def self.start_pasting
91
+ @@pasting = true
92
+ end
93
+
94
+ def self.finish_pasting
95
+ @@pasting = false
96
+ end
97
+
70
98
  def self.prep
71
99
  end
72
100
 
@@ -4,4 +4,16 @@ class Reline::KeyActor::Base
4
4
  def get_method(key)
5
5
  self.class::MAPPING[key]
6
6
  end
7
+
8
+ def initialize
9
+ @default_key_bindings = {}
10
+ end
11
+
12
+ def default_key_bindings
13
+ @default_key_bindings
14
+ end
15
+
16
+ def reset_default_key_bindings
17
+ @default_key_bindings.clear
18
+ end
7
19
  end
@@ -43,7 +43,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
43
43
  # 20 ^T
44
44
  :ed_transpose_chars,
45
45
  # 21 ^U
46
- :em_kill_line,
46
+ :unix_line_discard,
47
47
  # 22 ^V
48
48
  :ed_quoted_insert,
49
49
  # 23 ^W
@@ -307,7 +307,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
307
307
  # 152 M-^X
308
308
  :ed_unassigned,
309
309
  # 153 M-^Y
310
- :ed_unassigned,
310
+ :em_yank_pop,
311
311
  # 154 M-^Z
312
312
  :ed_unassigned,
313
313
  # 155 M-^[