reline 0.2.6 → 0.2.7
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.rb +3 -0
- data/lib/reline/ansi.rb +3 -8
- data/lib/reline/config.rb +10 -2
- data/lib/reline/line_editor.rb +11 -3
- data/lib/reline/terminfo.rb +52 -10
- data/lib/reline/version.rb +1 -1
- data/lib/reline/windows.rb +70 -38
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bb2255429504a1beb1a5a9f863f7cba5c4c65781b7cd8b2aa843b0df639fb26
|
4
|
+
data.tar.gz: c9372db87ad831e06d0e99d20981cb14a08e8b15ca3011f4b6df2a05aaeef7b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63e8b6f4a9de8a69a8f22c979b6fee92026143be658b9e928da43dddb868fb6b641b5f140de436c1dd5ed1f3cdbc3c42c7c41084fcc1d811cd713c684aedda8e
|
7
|
+
data.tar.gz: 7a459412f528f43d5e65f4c7c6a5c74055e2c5334f21a65411bc4f187b55b649c15fd612ed27f2dc0032f7fdc5973c7fa57b674b0a323ac2d9537b23fff19664
|
data/lib/reline.rb
CHANGED
@@ -7,12 +7,15 @@ require 'reline/key_actor'
|
|
7
7
|
require 'reline/key_stroke'
|
8
8
|
require 'reline/line_editor'
|
9
9
|
require 'reline/history'
|
10
|
+
require 'reline/terminfo'
|
10
11
|
require 'rbconfig'
|
11
12
|
|
12
13
|
module Reline
|
13
14
|
FILENAME_COMPLETION_PROC = nil
|
14
15
|
USERNAME_COMPLETION_PROC = nil
|
15
16
|
|
17
|
+
class ConfigEncodingConversionError < StandardError; end
|
18
|
+
|
16
19
|
Key = Struct.new('Key', :char, :combined_char, :with_meta)
|
17
20
|
CursorPos = Struct.new(:x, :y)
|
18
21
|
|
data/lib/reline/ansi.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'io/console'
|
2
|
+
require 'io/wait'
|
2
3
|
require 'timeout'
|
3
4
|
require_relative 'terminfo'
|
4
5
|
|
@@ -183,12 +184,7 @@ class Reline::ANSI
|
|
183
184
|
unless @@buf.empty?
|
184
185
|
return false
|
185
186
|
end
|
186
|
-
|
187
|
-
if rs and rs[0]
|
188
|
-
false
|
189
|
-
else
|
190
|
-
true
|
191
|
-
end
|
187
|
+
!@@input.wait_readable(0)
|
192
188
|
end
|
193
189
|
|
194
190
|
def self.ungetc(c)
|
@@ -197,8 +193,7 @@ class Reline::ANSI
|
|
197
193
|
|
198
194
|
def self.retrieve_keybuffer
|
199
195
|
begin
|
200
|
-
|
201
|
-
return if result.nil?
|
196
|
+
return unless @@input.wait_readable(0.001)
|
202
197
|
str = @@input.read_nonblock(1024)
|
203
198
|
str.bytes.each do |c|
|
204
199
|
@@buf.push(c)
|
data/lib/reline/config.rb
CHANGED
@@ -74,6 +74,7 @@ class Reline::Config
|
|
74
74
|
@additional_key_bindings.keys.each do |key|
|
75
75
|
@additional_key_bindings[key].clear
|
76
76
|
end
|
77
|
+
reset_default_key_bindings
|
77
78
|
end
|
78
79
|
|
79
80
|
def editing_mode
|
@@ -157,8 +158,15 @@ class Reline::Config
|
|
157
158
|
end
|
158
159
|
|
159
160
|
def read_lines(lines, file = nil)
|
160
|
-
if lines.first.encoding != Reline.encoding_system_needs
|
161
|
-
|
161
|
+
if not lines.empty? and lines.first.encoding != Reline.encoding_system_needs
|
162
|
+
begin
|
163
|
+
lines = lines.map do |l|
|
164
|
+
l.encode(Reline.encoding_system_needs)
|
165
|
+
rescue Encoding::UndefinedConversionError
|
166
|
+
mes = "The inputrc encoded in #{lines.first.encoding.name} can't be converted to the locale #{Reline.encoding_system_needs.name}."
|
167
|
+
raise Reline::ConfigEncodingConversionError.new(mes)
|
168
|
+
end
|
169
|
+
end
|
162
170
|
end
|
163
171
|
conditions = [@skip_section, @if_stack]
|
164
172
|
@skip_section = nil
|
data/lib/reline/line_editor.rb
CHANGED
@@ -150,7 +150,7 @@ class Reline::LineEditor
|
|
150
150
|
@screen_size = Reline::IOGate.get_screen_size
|
151
151
|
@screen_height = @screen_size.first
|
152
152
|
reset_variables(prompt, encoding: encoding)
|
153
|
-
@old_trap = Signal.trap(
|
153
|
+
@old_trap = Signal.trap(:INT) {
|
154
154
|
if @scroll_partial_screen
|
155
155
|
move_cursor_down(@screen_height - (@line_index - @scroll_partial_screen) - 1)
|
156
156
|
else
|
@@ -158,8 +158,16 @@ class Reline::LineEditor
|
|
158
158
|
end
|
159
159
|
Reline::IOGate.move_cursor_column(0)
|
160
160
|
scroll_down(1)
|
161
|
-
|
162
|
-
|
161
|
+
case @old_trap
|
162
|
+
when 'DEFAULT', 'SYSTEM_DEFAULT'
|
163
|
+
raise Interrupt
|
164
|
+
when 'IGNORE'
|
165
|
+
# Do nothing
|
166
|
+
when 'EXIT'
|
167
|
+
exit
|
168
|
+
else
|
169
|
+
@old_trap.call
|
170
|
+
end
|
163
171
|
}
|
164
172
|
Reline::IOGate.set_winch_handler do
|
165
173
|
@rest_height = (Reline::IOGate.get_screen_size.first - 1) - Reline::IOGate.cursor_pos.y
|
data/lib/reline/terminfo.rb
CHANGED
@@ -6,12 +6,39 @@ module Reline::Terminfo
|
|
6
6
|
|
7
7
|
class TerminfoError < StandardError; end
|
8
8
|
|
9
|
-
|
9
|
+
def self.curses_dl_files
|
10
|
+
case RUBY_PLATFORM
|
11
|
+
when /mingw/, /mswin/
|
12
|
+
# aren't supported
|
13
|
+
[]
|
14
|
+
when /cygwin/
|
15
|
+
%w[cygncursesw-10.dll cygncurses-10.dll]
|
16
|
+
when /darwin/
|
17
|
+
%w[libncursesw.dylib libcursesw.dylib libncurses.dylib libcurses.dylib]
|
18
|
+
else
|
19
|
+
%w[libncursesw.so libcursesw.so libncurses.so libcurses.so]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
@curses_dl = false
|
10
24
|
def self.curses_dl
|
11
|
-
return @curses_dl
|
12
|
-
if
|
25
|
+
return @curses_dl unless @curses_dl == false
|
26
|
+
if RUBY_VERSION >= '3.0.0'
|
27
|
+
# Gem module isn't defined in test-all of the Ruby repository, and
|
28
|
+
# Fiddle in Ruby 3.0.0 or later supports Fiddle::TYPE_VARIADIC.
|
29
|
+
fiddle_supports_variadic = true
|
30
|
+
elsif Fiddle.const_defined?(:VERSION) and Gem::Version.create(Fiddle::VERSION) >= Gem::Version.create('1.0.1')
|
13
31
|
# Fiddle::TYPE_VARIADIC is supported from Fiddle 1.0.1.
|
14
|
-
|
32
|
+
fiddle_supports_variadic = true
|
33
|
+
else
|
34
|
+
fiddle_supports_variadic = false
|
35
|
+
end
|
36
|
+
if fiddle_supports_variadic and not Fiddle.const_defined?(:TYPE_VARIADIC)
|
37
|
+
# If the libffi version is not 3.0.5 or higher, there isn't TYPE_VARIADIC.
|
38
|
+
fiddle_supports_variadic = false
|
39
|
+
end
|
40
|
+
if fiddle_supports_variadic
|
41
|
+
curses_dl_files.each do |curses_name|
|
15
42
|
result = Fiddle::Handle.new(curses_name)
|
16
43
|
rescue Fiddle::DLError
|
17
44
|
next
|
@@ -20,6 +47,7 @@ module Reline::Terminfo
|
|
20
47
|
break
|
21
48
|
end
|
22
49
|
end
|
50
|
+
@curses_dl = nil if @curses_dl == false
|
23
51
|
@curses_dl
|
24
52
|
end
|
25
53
|
end
|
@@ -30,8 +58,15 @@ module Reline::Terminfo
|
|
30
58
|
@setupterm = Fiddle::Function.new(curses_dl['setupterm'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
|
31
59
|
#extern 'char *tigetstr(char *capname)'
|
32
60
|
@tigetstr = Fiddle::Function.new(curses_dl['tigetstr'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_VOIDP)
|
33
|
-
|
34
|
-
|
61
|
+
begin
|
62
|
+
#extern 'char *tiparm(const char *str, ...)'
|
63
|
+
@tiparm = Fiddle::Function.new(curses_dl['tiparm'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VARIADIC], Fiddle::TYPE_VOIDP)
|
64
|
+
rescue Fiddle::DLError
|
65
|
+
# OpenBSD lacks tiparm
|
66
|
+
#extern 'char *tparm(const char *str, ...)'
|
67
|
+
@tiparm = Fiddle::Function.new(curses_dl['tparm'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VARIADIC], Fiddle::TYPE_VOIDP)
|
68
|
+
end
|
69
|
+
# TODO: add int tigetflag(char *capname) and int tigetnum(char *capname)
|
35
70
|
|
36
71
|
def self.setupterm(term, fildes)
|
37
72
|
errret_int = String.new("\x00" * 8, encoding: 'ASCII-8BIT')
|
@@ -56,12 +91,19 @@ module Reline::Terminfo
|
|
56
91
|
end
|
57
92
|
end
|
58
93
|
|
59
|
-
|
60
|
-
|
61
|
-
def result.tiparm(*args) # for method chain
|
94
|
+
class StringWithTiparm < String
|
95
|
+
def tiparm(*args) # for method chain
|
62
96
|
Reline::Terminfo.tiparm(self, *args)
|
63
97
|
end
|
64
|
-
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.tigetstr(capname)
|
101
|
+
capability = @tigetstr.(capname)
|
102
|
+
case capability.to_i
|
103
|
+
when 0, -1
|
104
|
+
raise TerminfoError, "can't find capability: #{capname}"
|
105
|
+
end
|
106
|
+
StringWithTiparm.new(capability.to_s)
|
65
107
|
end
|
66
108
|
|
67
109
|
def self.tiparm(str, *args)
|
data/lib/reline/version.rb
CHANGED
data/lib/reline/windows.rb
CHANGED
@@ -91,6 +91,7 @@ class Reline::Windows
|
|
91
91
|
VK_LMENU = 0xA4
|
92
92
|
VK_CONTROL = 0x11
|
93
93
|
VK_SHIFT = 0x10
|
94
|
+
VK_DIVIDE = 0x6F
|
94
95
|
|
95
96
|
KEY_EVENT = 0x01
|
96
97
|
WINDOW_BUFFER_SIZE_EVENT = 0x04
|
@@ -180,46 +181,38 @@ class Reline::Windows
|
|
180
181
|
name =~ /(msys-|cygwin-).*-pty/ ? true : false
|
181
182
|
end
|
182
183
|
|
184
|
+
KEY_MAP = [
|
185
|
+
# It's treated as Meta+Enter on Windows.
|
186
|
+
[ { control_keys: :CTRL, virtual_key_code: 0x0D }, "\e\r".bytes ],
|
187
|
+
[ { control_keys: :SHIFT, virtual_key_code: 0x0D }, "\e\r".bytes ],
|
188
|
+
|
189
|
+
# It's treated as Meta+Space on Windows.
|
190
|
+
[ { control_keys: :CTRL, char_code: 0x20 }, "\e ".bytes ],
|
191
|
+
|
192
|
+
# Emulate getwch() key sequences.
|
193
|
+
[ { control_keys: [], virtual_key_code: VK_UP }, [0, 72] ],
|
194
|
+
[ { control_keys: [], virtual_key_code: VK_DOWN }, [0, 80] ],
|
195
|
+
[ { control_keys: [], virtual_key_code: VK_RIGHT }, [0, 77] ],
|
196
|
+
[ { control_keys: [], virtual_key_code: VK_LEFT }, [0, 75] ],
|
197
|
+
[ { control_keys: [], virtual_key_code: VK_DELETE }, [0, 83] ],
|
198
|
+
[ { control_keys: [], virtual_key_code: VK_HOME }, [0, 71] ],
|
199
|
+
[ { control_keys: [], virtual_key_code: VK_END }, [0, 79] ],
|
200
|
+
]
|
201
|
+
|
183
202
|
def self.process_key_event(repeat_count, virtual_key_code, virtual_scan_code, char_code, control_key_state)
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
@@output_buf.push("\e".ord)
|
192
|
-
@@output_buf.push(char_code)
|
193
|
-
elsif control_key_state.anybits?(LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)
|
194
|
-
@@output_buf.push("\e".ord)
|
195
|
-
@@output_buf.concat(char.bytes)
|
196
|
-
elsif control_key_state.anybits?(ENHANCED_KEY)
|
197
|
-
case virtual_key_code # Emulate getwch() key sequences.
|
198
|
-
when VK_END
|
199
|
-
@@output_buf.push(0, 79)
|
200
|
-
when VK_HOME
|
201
|
-
@@output_buf.push(0, 71)
|
202
|
-
when VK_LEFT
|
203
|
-
@@output_buf.push(0, 75)
|
204
|
-
when VK_UP
|
205
|
-
@@output_buf.push(0, 72)
|
206
|
-
when VK_RIGHT
|
207
|
-
@@output_buf.push(0, 77)
|
208
|
-
when VK_DOWN
|
209
|
-
@@output_buf.push(0, 80)
|
210
|
-
when VK_DELETE
|
211
|
-
@@output_buf.push(0, 83)
|
212
|
-
end
|
213
|
-
elsif char_code == 0 and control_key_state != 0
|
214
|
-
# unknown
|
215
|
-
else
|
216
|
-
case virtual_key_code
|
217
|
-
when VK_RETURN
|
218
|
-
@@output_buf.push("\n".ord)
|
219
|
-
else
|
220
|
-
@@output_buf.concat(char.bytes)
|
221
|
-
end
|
203
|
+
|
204
|
+
key = KeyEventRecord.new(virtual_key_code, char_code, control_key_state)
|
205
|
+
|
206
|
+
match = KEY_MAP.find { |args,| key.matches?(**args) }
|
207
|
+
unless match.nil?
|
208
|
+
@@output_buf.concat(match.last)
|
209
|
+
return
|
222
210
|
end
|
211
|
+
|
212
|
+
# no char, only control keys
|
213
|
+
return if key.char_code == 0 and key.control_keys.any?
|
214
|
+
|
215
|
+
@@output_buf.concat(key.char.bytes)
|
223
216
|
end
|
224
217
|
|
225
218
|
def self.check_input_event
|
@@ -360,4 +353,43 @@ class Reline::Windows
|
|
360
353
|
def self.deprep(otio)
|
361
354
|
# do nothing
|
362
355
|
end
|
356
|
+
|
357
|
+
class KeyEventRecord
|
358
|
+
|
359
|
+
attr_reader :virtual_key_code, :char_code, :control_key_state, :control_keys
|
360
|
+
|
361
|
+
def initialize(virtual_key_code, char_code, control_key_state)
|
362
|
+
@virtual_key_code = virtual_key_code
|
363
|
+
@char_code = char_code
|
364
|
+
@control_key_state = control_key_state
|
365
|
+
@enhanced = control_key_state & ENHANCED_KEY != 0
|
366
|
+
|
367
|
+
(@control_keys = []).tap do |control_keys|
|
368
|
+
# symbols must be sorted to make comparison is easier later on
|
369
|
+
control_keys << :ALT if control_key_state & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) != 0
|
370
|
+
control_keys << :CTRL if control_key_state & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) != 0
|
371
|
+
control_keys << :SHIFT if control_key_state & SHIFT_PRESSED != 0
|
372
|
+
end.freeze
|
373
|
+
end
|
374
|
+
|
375
|
+
def char
|
376
|
+
@char_code.chr(Encoding::UTF_8)
|
377
|
+
end
|
378
|
+
|
379
|
+
def enhanced?
|
380
|
+
@enhanced
|
381
|
+
end
|
382
|
+
|
383
|
+
# Verifies if the arguments match with this key event.
|
384
|
+
# Nil arguments are ignored, but at least one must be passed as non-nil.
|
385
|
+
# To verify that no control keys were pressed, pass an empty array: `control_keys: []`.
|
386
|
+
def matches?(control_keys: nil, virtual_key_code: nil, char_code: nil)
|
387
|
+
raise ArgumentError, 'No argument was passed to match key event' if control_keys.nil? && virtual_key_code.nil? && char_code.nil?
|
388
|
+
|
389
|
+
(control_keys.nil? || [*control_keys].sort == @control_keys) &&
|
390
|
+
(virtual_key_code.nil? || @virtual_key_code == virtual_key_code) &&
|
391
|
+
(char_code.nil? || char_code == @char_code)
|
392
|
+
end
|
393
|
+
|
394
|
+
end
|
363
395
|
end
|
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.2.
|
4
|
+
version: 0.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|
@@ -73,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '0'
|
75
75
|
requirements: []
|
76
|
-
rubygems_version: 3.2.
|
76
|
+
rubygems_version: 3.2.22
|
77
77
|
signing_key:
|
78
78
|
specification_version: 4
|
79
79
|
summary: Alternative GNU Readline or Editline implementation by pure Ruby.
|