reline 0.0.2 → 0.0.3

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: f47cc0525de297744dff41dc87b9a4ac5c9ff1cad21da7f60a41aa4b17bd1b0e
4
- data.tar.gz: '04681f2a2dc431f65fa9f2df68c8b7aa1955a7a4032b8d6d5483984e236d4c9b'
3
+ metadata.gz: 5978554d657a91d17e199389ec2bf7dd1a505436bf0ea9c73478973c202d08c7
4
+ data.tar.gz: cd5b28a0094e1af15c09617b8093550a81ed841ea1e9c9f3db9131eaca694217
5
5
  SHA512:
6
- metadata.gz: ad38bf76659bc7553ebf084fd4aeedf6aba7cba1a2860fc78af0683222109216d59bdb3b4bf66962ce9a640b9033d21f707442151834e9ccc21c6fc8d115347b
7
- data.tar.gz: 95d9d943870e64897076cdc97750f6110817bc4ad14e958755164aa862785d7e48399465f7997f900547f797e6304cf48d6761f78612651ebe7aa6dca505fab3
6
+ metadata.gz: 2d21a0ee4c7a28ef7b7d32db350646b369719b2778d04cb4158cac1583a1f8c41010f55c1e8a81aa1954dce207e2048526cbfcbbebcb8624a3037ff18b0851e9
7
+ data.tar.gz: f1d58c640a8cf6190c65a9bcf0898ecec70d9825f76fc68a28bcfe4300387eb6223f13d226689ecbd7d0fb248365e81a8df8fc8247452519abb163121684f4b3
@@ -287,7 +287,7 @@ module Reline
287
287
  end
288
288
  when :unmatched
289
289
  if buffer.size == 1 and c == "\e".ord
290
- read_escaped_key(keyseq_timeout, buffer, block)
290
+ read_escaped_key(keyseq_timeout, c, block)
291
291
  else
292
292
  block.(buffer.map{ |c| Reline::Key.new(c, c, false) })
293
293
  end
@@ -296,7 +296,7 @@ module Reline
296
296
  end
297
297
  end
298
298
 
299
- private def read_escaped_key(keyseq_timeout, buffer, block)
299
+ private def read_escaped_key(keyseq_timeout, c, block)
300
300
  begin
301
301
  escaped_c = nil
302
302
  Timeout.timeout(keyseq_timeout / 1000.0) {
@@ -24,20 +24,22 @@ class Reline::ANSI
24
24
  unless @@buf.empty?
25
25
  return @@buf.shift
26
26
  end
27
- c = nil
28
- loop do
29
- result = select([@@input], [], [], 0.1)
30
- next if result.nil?
31
- c = @@input.read(1)
32
- break
33
- end
34
- c&.ord
27
+ @@input.getbyte
35
28
  end
36
29
 
37
30
  def self.ungetc(c)
38
31
  @@buf.unshift(c)
39
32
  end
40
33
 
34
+ def self.retrieve_keybuffer
35
+ result = select([@@input], [], [], 0.001)
36
+ return if result.nil?
37
+ str = @@input.read_nonblock(1024)
38
+ str.bytes.each do |c|
39
+ @@buf.push(c)
40
+ end
41
+ end
42
+
41
43
  def self.get_screen_size
42
44
  @@input.winsize
43
45
  rescue Errno::ENOTTY
@@ -112,12 +114,17 @@ class Reline::ANSI
112
114
  end
113
115
 
114
116
  def self.prep
117
+ retrieve_keybuffer
115
118
  int_handle = Signal.trap('INT', 'IGNORE')
116
119
  otio = `stty -g`.chomp
117
120
  setting = ' -echo -icrnl cbreak'
118
- if /-parenb\b/ =~ `stty -a`
121
+ stty = `stty -a`
122
+ if /-parenb\b/ =~ stty
119
123
  setting << ' pass8'
120
124
  end
125
+ if /\bdsusp *=/ =~ stty
126
+ setting << ' dsusp undef'
127
+ end
121
128
  setting << ' -ixoff'
122
129
  `stty #{setting}`
123
130
  Signal.trap('INT', int_handle)
@@ -55,7 +55,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
55
55
  # 26 ^Z
56
56
  :ed_unassigned,
57
57
  # 27 ^[
58
- :em_meta_next,
58
+ :ed_unassigned,
59
59
  # 28 ^\
60
60
  :ed_ignore,
61
61
  # 29 ^]
@@ -65,9 +65,8 @@ class Reline::LineEditor
65
65
  @screen_size = Reline::IOGate.get_screen_size
66
66
  reset_variables(prompt, encoding)
67
67
  @old_trap = Signal.trap('SIGINT') {
68
- scroll_down(@highest_in_all - @first_line_started_from)
69
- Reline::IOGate.move_cursor_column(0)
70
68
  @old_trap.call if @old_trap.respond_to?(:call) # can also be string, ex: "DEFAULT"
69
+ raise Interrupt
71
70
  }
72
71
  Reline::IOGate.set_winch_handler do
73
72
  @rest_height = (Reline::IOGate.get_screen_size.first - 1) - Reline::IOGate.cursor_pos.y
@@ -306,6 +305,7 @@ class Reline::LineEditor
306
305
  @menu_info.list.each do |item|
307
306
  Reline::IOGate.move_cursor_column(0)
308
307
  @output.print item
308
+ @output.flush
309
309
  scroll_down(1)
310
310
  end
311
311
  scroll_down(@highest_in_all - 1)
@@ -541,6 +541,7 @@ class Reline::LineEditor
541
541
  next
542
542
  end
543
543
  @output.print line
544
+ @output.flush
544
545
  if @first_prompt
545
546
  @first_prompt = false
546
547
  @pre_input_hook&.call
@@ -1049,6 +1050,8 @@ class Reline::LineEditor
1049
1050
  end
1050
1051
  end
1051
1052
 
1053
+ private def ed_unassigned(key) end # do nothing
1054
+
1052
1055
  private def ed_insert(key)
1053
1056
  if key.instance_of?(String)
1054
1057
  width = Reline::Unicode.get_mbchar_width(key)
@@ -1279,7 +1282,7 @@ class Reline::LineEditor
1279
1282
  @line = Reline::HISTORY[@history_pointer]
1280
1283
  end
1281
1284
  end
1282
- if @config.editing_mode_is?(:emacs)
1285
+ if @config.editing_mode_is?(:emacs, :vi_insert)
1283
1286
  @cursor_max = @cursor = calculate_width(@line)
1284
1287
  @byte_pointer = @line.bytesize
1285
1288
  elsif @config.editing_mode_is?(:vi_command)
@@ -1326,7 +1329,7 @@ class Reline::LineEditor
1326
1329
  end
1327
1330
  end
1328
1331
  @line = '' unless @line
1329
- if @config.editing_mode_is?(:emacs)
1332
+ if @config.editing_mode_is?(:emacs, :vi_insert)
1330
1333
  @cursor_max = @cursor = calculate_width(@line)
1331
1334
  @byte_pointer = @line.bytesize
1332
1335
  elsif @config.editing_mode_is?(:vi_command)
@@ -1,3 +1,3 @@
1
1
  module Reline
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -11,41 +11,45 @@ class Reline::Windows
11
11
  [224, 79] => :ed_move_to_end, # End
12
12
  }.each_key(&:freeze).freeze
13
13
 
14
- class Win32API
15
- DLL = {}
16
- TYPEMAP = {"0" => Fiddle::TYPE_VOID, "S" => Fiddle::TYPE_VOIDP, "I" => Fiddle::TYPE_LONG}
17
- POINTER_TYPE = Fiddle::SIZEOF_VOIDP == Fiddle::SIZEOF_LONG_LONG ? 'q*' : 'l!*'
18
-
19
- WIN32_TYPES = "VPpNnLlIi"
20
- DL_TYPES = "0SSI"
21
-
22
- def initialize(dllname, func, import, export = "0", calltype = :stdcall)
23
- @proto = [import].join.tr(WIN32_TYPES, DL_TYPES).sub(/^(.)0*$/, '\1')
24
- import = @proto.chars.map {|win_type| TYPEMAP[win_type.tr(WIN32_TYPES, DL_TYPES)]}
25
- export = TYPEMAP[export.tr(WIN32_TYPES, DL_TYPES)]
26
- calltype = Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[calltype]
27
-
28
- handle = DLL[dllname] ||=
29
- begin
30
- Fiddle.dlopen(dllname)
31
- rescue Fiddle::DLError
32
- raise unless File.extname(dllname).empty?
33
- Fiddle.dlopen(dllname + ".dll")
34
- end
35
-
36
- @func = Fiddle::Function.new(handle[func], import, export, calltype)
37
- rescue Fiddle::DLError => e
38
- raise LoadError, e.message, e.backtrace
39
- end
14
+ if defined? JRUBY_VERSION
15
+ require 'win32api'
16
+ else
17
+ class Win32API
18
+ DLL = {}
19
+ TYPEMAP = {"0" => Fiddle::TYPE_VOID, "S" => Fiddle::TYPE_VOIDP, "I" => Fiddle::TYPE_LONG}
20
+ POINTER_TYPE = Fiddle::SIZEOF_VOIDP == Fiddle::SIZEOF_LONG_LONG ? 'q*' : 'l!*'
21
+
22
+ WIN32_TYPES = "VPpNnLlIi"
23
+ DL_TYPES = "0SSI"
24
+
25
+ def initialize(dllname, func, import, export = "0", calltype = :stdcall)
26
+ @proto = [import].join.tr(WIN32_TYPES, DL_TYPES).sub(/^(.)0*$/, '\1')
27
+ import = @proto.chars.map {|win_type| TYPEMAP[win_type.tr(WIN32_TYPES, DL_TYPES)]}
28
+ export = TYPEMAP[export.tr(WIN32_TYPES, DL_TYPES)]
29
+ calltype = Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[calltype]
30
+
31
+ handle = DLL[dllname] ||=
32
+ begin
33
+ Fiddle.dlopen(dllname)
34
+ rescue Fiddle::DLError
35
+ raise unless File.extname(dllname).empty?
36
+ Fiddle.dlopen(dllname + ".dll")
37
+ end
38
+
39
+ @func = Fiddle::Function.new(handle[func], import, export, calltype)
40
+ rescue Fiddle::DLError => e
41
+ raise LoadError, e.message, e.backtrace
42
+ end
40
43
 
41
- def call(*args)
42
- import = @proto.split("")
43
- args.each_with_index do |x, i|
44
- args[i], = [x == 0 ? nil : x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
45
- args[i], = [x].pack("I").unpack("i") if import[i] == "I"
44
+ def call(*args)
45
+ import = @proto.split("")
46
+ args.each_with_index do |x, i|
47
+ args[i], = [x == 0 ? nil : x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
48
+ args[i], = [x].pack("I").unpack("i") if import[i] == "I"
49
+ end
50
+ ret, = @func.call(*args)
51
+ return ret || 0
46
52
  end
47
- ret, = @func.call(*args)
48
- return ret || 0
49
53
  end
50
54
  end
51
55
 
@@ -66,23 +70,27 @@ class Reline::Windows
66
70
  @@hConsoleInputHandle = @@GetStdHandle.call(STD_INPUT_HANDLE)
67
71
  @@GetNumberOfConsoleInputEvents = Win32API.new('kernel32', 'GetNumberOfConsoleInputEvents', ['L', 'P'], 'L')
68
72
  @@ReadConsoleInput = Win32API.new('kernel32', 'ReadConsoleInput', ['L', 'P', 'L', 'P'], 'L')
69
- @@buf = []
73
+ @@input_buf = []
74
+ @@output_buf = []
70
75
 
71
76
  def self.getwch
77
+ unless @@input_buf.empty?
78
+ return @@input_buf.shift
79
+ end
72
80
  while @@kbhit.call == 0
73
81
  sleep(0.001)
74
82
  end
75
- result = []
76
83
  until @@kbhit.call == 0
77
84
  ret = @@getwch.call
78
85
  begin
79
- result.concat(ret.chr(Encoding::UTF_8).encode(Encoding.default_external).bytes)
86
+ bytes = ret.chr(Encoding::UTF_8).encode(Encoding.default_external).bytes
87
+ @@input_buf.push(*bytes)
80
88
  rescue Encoding::UndefinedConversionError
81
- result << ret
82
- result << @@getwch.call if ret == 224
89
+ @@input_buf << ret
90
+ @@input_buf << @@getwch.call if ret == 224
83
91
  end
84
92
  end
85
- result
93
+ @@input_buf.shift
86
94
  end
87
95
 
88
96
  def self.getc
@@ -97,44 +105,42 @@ class Reline::Windows
97
105
  end
98
106
  end
99
107
  end
100
- unless @@buf.empty?
101
- return @@buf.shift
108
+ unless @@output_buf.empty?
109
+ return @@output_buf.shift
102
110
  end
103
111
  input = getwch
104
112
  alt = (@@GetKeyState.call(VK_MENU) & 0x80) != 0
105
- shift_enter = (@@GetKeyState.call(VK_SHIFT) & 0x80) != 0 && input.first == 0x0D
113
+ shift_enter = !input.instance_of?(Array) && (@@GetKeyState.call(VK_SHIFT) & 0x80) != 0 && input == 0x0D
106
114
  if shift_enter
107
115
  # It's treated as Meta+Enter on Windows
108
- @@buf.concat(["\e".ord])
109
- @@buf.concat(input)
110
- elsif input.size > 1
111
- @@buf.concat(input)
112
- else # single byte
113
- case input[0]
116
+ @@output_buf.push("\e".ord)
117
+ @@output_buf.push(input)
118
+ else
119
+ case input
114
120
  when 0x00
115
121
  getwch
116
122
  alt = false
117
123
  input = getwch
118
- @@buf.concat(input)
124
+ @@output_buf.push(*input)
119
125
  when 0xE0
120
- @@buf.concat(input)
126
+ @@output_buf.push(input)
121
127
  input = getwch
122
- @@buf.concat(input)
128
+ @@output_buf.push(*input)
123
129
  when 0x03
124
- @@buf.concat(input)
130
+ @@output_buf.push(input)
125
131
  else
126
- @@buf.concat(input)
132
+ @@output_buf.push(input)
127
133
  end
128
134
  end
129
135
  if alt
130
136
  "\e".ord
131
137
  else
132
- @@buf.shift
138
+ @@output_buf.shift
133
139
  end
134
140
  end
135
141
 
136
142
  def self.ungetc(c)
137
- @@buf.unshift(c)
143
+ @@output_buf.unshift(c)
138
144
  end
139
145
 
140
146
  def self.get_screen_size
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.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-01 00:00:00.000000000 Z
11
+ date: 2019-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler