reline 0.0.2 → 0.0.3

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