katakata_irb 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,10 +11,18 @@ module KatakataIrb::Types
11
11
 
12
12
  Splat = Struct.new :item
13
13
 
14
+ MODULE_NAME_METHOD = Module.instance_method(:name)
15
+
16
+ def self.class_name_of(klass)
17
+ klass = klass.superclass if klass.singleton_class?
18
+ MODULE_NAME_METHOD.bind_call klass
19
+ end
20
+
14
21
  def self.rbs_search_method(klass, method_name, singleton)
15
22
  klass.ancestors.each do |ancestor|
16
- next unless ancestor.name
17
- type_name = RBS::TypeName(ancestor.name).absolute!
23
+ name = class_name_of ancestor
24
+ next unless name
25
+ type_name = RBS::TypeName(name).absolute!
18
26
  definition = (singleton ? rbs_builder.build_singleton(type_name) : rbs_builder.build_instance(type_name)) rescue nil
19
27
  method = definition&.methods&.[](method_name)
20
28
  return method if method
@@ -22,9 +30,29 @@ module KatakataIrb::Types
22
30
  nil
23
31
  end
24
32
 
33
+ def self.method_return_type(type, method_name)
34
+ receivers = type.types.map do |t|
35
+ case t
36
+ in ProcType
37
+ [t, Proc, false]
38
+ in SingletonType
39
+ [t, t.module_or_class, true]
40
+ in InstanceType
41
+ [t, t.klass, false]
42
+ end
43
+ end
44
+ types = receivers.flat_map do |receiver_type, klass, singleton|
45
+ method = rbs_search_method klass, method_name, singleton
46
+ next [] unless method
47
+ method.method_types.map do |method|
48
+ from_rbs_type(method.type.return_type, receiver_type, {})
49
+ end
50
+ end
51
+ UnionType[*types]
52
+ end
53
+
25
54
  def self.rbs_methods(type, method_name, args_types, kwargs_type, has_block)
26
- types = (type in UnionType) ? type.types : [type]
27
- receivers = types.map do |t|
55
+ receivers = type.types.map do |t|
28
56
  case t
29
57
  in ProcType
30
58
  [t, Proc, false]
@@ -60,8 +88,15 @@ module KatakataIrb::Types
60
88
  given << UnionType[*centers.drop(opts.size)]
61
89
  expected << rest.type
62
90
  end
63
- score += given.zip(expected).count do |t, e|
64
- intersect? t, from_rbs_type(e, receiver_type)
91
+ score += given.zip(expected).sum do |t, e|
92
+ e = from_rbs_type e, receiver_type
93
+ if intersect? t, e
94
+ 1
95
+ elsif (intersect?(STRING, e) && t.methods.include?(:to_str)) || (intersect?(INTEGER, e) && t.methods.include?(:to_int)) || (intersect?(ARRAY, e) && t.methods.include?(:to_ary))
96
+ 0.5
97
+ else
98
+ 0
99
+ end
65
100
  end
66
101
  end
67
102
  [[method_type, given || [], expected || []], score]
@@ -83,14 +118,24 @@ module KatakataIrb::Types
83
118
  intersect.call(InstanceType, &:klass)
84
119
  end
85
120
 
86
- def self.type_from_object(object, max_level: 4)
121
+ def self.type_from_object(object)
122
+ case object
123
+ when Array, Hash, Module
124
+ type_from_object_recursive(object, max_level: 4)
125
+ else
126
+ klass = object.singleton_class rescue object.class
127
+ InstanceType.new klass
128
+ end
129
+ end
130
+
131
+ def self.type_from_object_recursive(object, max_level:)
87
132
  max_level -= 1
88
133
  sample_size = 1000
89
134
  case object
90
135
  when Array
91
136
  values = object.size > sample_size ? object.sample(sample_size) : object
92
137
  if max_level > 0
93
- InstanceType.new Array, { Elem: UnionType[*values.map { type_from_object(_1, max_level:) }] }
138
+ InstanceType.new Array, { Elem: UnionType[*values.map { type_from_object_recursive(_1, max_level: max_level) }] }
94
139
  else
95
140
  InstanceType.new Array, { Elem: UnionType[*values.map(&:class).uniq.map { InstanceType.new _1 }] }
96
141
  end
@@ -98,8 +143,8 @@ module KatakataIrb::Types
98
143
  keys = object.size > sample_size ? object.keys.sample(sample_size) : object.keys
99
144
  values = object.size > sample_size ? object.values.sample(sample_size) : object.values
100
145
  if max_level > 0
101
- key_types = keys.map { type_from_object(_1, max_level:) }
102
- value_types = values.map { type_from_object(_1, max_level:) }
146
+ key_types = keys.map { type_from_object_recursive(_1, max_level: max_level) }
147
+ value_types = values.map { type_from_object_recursive(_1, max_level: max_level) }
103
148
  InstanceType.new Hash, { K: UnionType[*key_types], V: UnionType[*value_types] }
104
149
  else
105
150
  key_types = keys.map(&:class).uniq.map { InstanceType.new _1 }
@@ -120,9 +165,11 @@ module KatakataIrb::Types
120
165
  end
121
166
  def transform() = yield(self)
122
167
  def methods() = @module_or_class.methods
123
- def all_methods() = methods
168
+ def all_methods() = methods | Kernel.methods
124
169
  def constants() = @module_or_class.constants
125
170
  def types() = [self]
171
+ def nillable?() = false
172
+ def nonnillable() = self
126
173
  end
127
174
 
128
175
  class InstanceType
@@ -136,6 +183,8 @@ module KatakataIrb::Types
136
183
  def all_methods() = @klass.instance_methods | @klass.private_instance_methods
137
184
  def constants() = []
138
185
  def types() = [self]
186
+ def nillable?() = (@klass == NilClass)
187
+ def nonnillable() = self
139
188
  end
140
189
 
141
190
  class ProcType
@@ -150,11 +199,13 @@ module KatakataIrb::Types
150
199
  def all_methods() = Proc.instance_methods | Proc.private_instance_methods
151
200
  def constants() = []
152
201
  def types() = [self]
202
+ def nillable?() = (@klass == NilClass)
203
+ def nonnillable() = self
153
204
  end
154
205
 
155
206
  NIL = InstanceType.new NilClass
156
207
  OBJECT = InstanceType.new Object
157
- TRUE = InstanceType.new FalseClass
208
+ TRUE = InstanceType.new TrueClass
158
209
  FALSE = InstanceType.new FalseClass
159
210
  SYMBOL = InstanceType.new Symbol
160
211
  STRING = InstanceType.new String
@@ -203,6 +254,14 @@ module KatakataIrb::Types
203
254
  UnionType[*types.map(&block)]
204
255
  end
205
256
 
257
+ def nillable?
258
+ types.any?(&:nillable?)
259
+ end
260
+
261
+ def nonnillable
262
+ UnionType[*types.reject { _1.is_a?(InstanceType) && _1.klass == NilClass }]
263
+ end
264
+
206
265
  def self.[](*types)
207
266
  type = new(*types)
208
267
  if type.types.empty?
@@ -219,6 +278,8 @@ module KatakataIrb::Types
219
278
  def constants() = @types.flat_map(&:constants).uniq
220
279
  end
221
280
 
281
+ BOOLEAN = UnionType[TRUE, FALSE]
282
+
222
283
  def self.from_rbs_type(return_type, self_type, extra_vars = {})
223
284
  case return_type
224
285
  when RBS::Types::Bases::Self
@@ -238,7 +299,7 @@ module KatakataIrb::Types
238
299
  end
239
300
  UnionType[*types]
240
301
  when RBS::Types::Bases::Bool
241
- UnionType[TRUE, FALSE]
302
+ BOOLEAN
242
303
  when RBS::Types::Bases::Instance
243
304
  self_type.transform do |type|
244
305
  case type
@@ -286,7 +347,7 @@ module KatakataIrb::Types
286
347
  when :int
287
348
  INTEGER
288
349
  when :boolish
289
- UnionType[TRUE, FALSE]
350
+ BOOLEAN
290
351
  when :string
291
352
  STRING
292
353
  else
@@ -297,19 +358,13 @@ module KatakataIrb::Types
297
358
  # unimplemented
298
359
  OBJECT
299
360
  when RBS::Types::ClassInstance
300
- classes = self_type.types.filter_map do |type|
301
- type.module_or_class if (type in SingletonType) && type.module_or_class.is_a?(Class)
302
- end
303
- if classes.empty?
304
- klass = return_type.name.to_namespace.path.reduce(Object) { _1.const_get _2 }
305
- classes << klass if klass in Class
306
- end
361
+ klass = return_type.name.to_namespace.path.reduce(Object) { _1.const_get _2 }
307
362
  if return_type.args
308
363
  args = return_type.args.map { from_rbs_type _1, self_type, extra_vars }
309
364
  names = rbs_builder.build_singleton(return_type.name).type_params
310
365
  params = names.map.with_index { [_1, args[_2] || OBJECT] }.to_h
311
366
  end
312
- UnionType[*classes.map { InstanceType.new _1, params || {} }]
367
+ InstanceType.new klass, params || {}
313
368
  end
314
369
  end
315
370
 
@@ -338,6 +393,25 @@ module KatakataIrb::Types
338
393
  end
339
394
  in [RBS::Types::Record, InstanceType] if value.klass == Hash
340
395
  # TODO
396
+ in [RBS::Types::Interface,]
397
+ definition = rbs_builder.build_interface rbs_type.name
398
+ convert = {}
399
+ definition.type_params.zip(rbs_type.args).each do |from, arg|
400
+ convert[from] = arg.name if arg.is_a? RBS::Types::Variable
401
+ end
402
+ return if convert.empty?
403
+ ac = {}
404
+ definition.methods.each do |method_name, method|
405
+ return_type = method_return_type value, method_name
406
+ method.defs.each do |method_def|
407
+ interface_return_type = method_def.type.type.return_type
408
+ _match_free_variable convert, interface_return_type, return_type, ac
409
+ end
410
+ end
411
+ convert.each do |from, to|
412
+ values = ac[from]
413
+ (accumulator[to] ||= []).concat values if values
414
+ end
341
415
  else
342
416
  end
343
417
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KatakataIrb
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.5"
5
5
  end
data/lib/katakata_irb.rb CHANGED
@@ -1,11 +1,7 @@
1
- require 'io/console'
2
- module KatakataIrb
3
- def self.repl
4
- require 'katakata_irb/completor'
5
- KatakataIrb::Completor.setup
6
- IRB.start(__FILE__)
7
- end
1
+ require 'katakata_irb/version'
2
+ require 'katakata_irb/completor'
8
3
 
4
+ module KatakataIrb
9
5
  def self.log_output=(output)
10
6
  @log_output = output
11
7
  end
@@ -14,3 +10,5 @@ module KatakataIrb
14
10
  STDOUT.cooked { @log_output&.puts(...) }
15
11
  end
16
12
  end
13
+
14
+ KatakataIrb::Completor.setup
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katakata_irb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - tompng
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-08 00:00:00.000000000 Z
11
+ date: 2023-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: irb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.4.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.4.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rbs
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -27,8 +41,7 @@ dependencies:
27
41
  description: IRB with Typed Completion
28
42
  email:
29
43
  - tomoyapenguin@gmail.com
30
- executables:
31
- - kirb
44
+ executables: []
32
45
  extensions: []
33
46
  extra_rdoc_files: []
34
47
  files:
@@ -39,18 +52,11 @@ files:
39
52
  - Rakefile
40
53
  - bin/console
41
54
  - bin/setup
42
- - exe/kirb
43
55
  - katakata_irb.gemspec
44
56
  - lib/katakata_irb.rb
45
57
  - lib/katakata_irb/completor.rb
46
- - lib/katakata_irb/reline_patch.rb
47
- - lib/katakata_irb/reline_patches/escapeseq.patch
48
- - lib/katakata_irb/reline_patches/indent.patch
49
- - lib/katakata_irb/reline_patches/raw.patch
50
- - lib/katakata_irb/reline_patches/scrollbar.patch
51
- - lib/katakata_irb/reline_patches/wholelines.patch
52
- - lib/katakata_irb/ruby_lex_patch.rb
53
- - lib/katakata_irb/trex.rb
58
+ - lib/katakata_irb/nesting_parser.rb
59
+ - lib/katakata_irb/scope.rb
54
60
  - lib/katakata_irb/type_simulator.rb
55
61
  - lib/katakata_irb/types.rb
56
62
  - lib/katakata_irb/version.rb
@@ -69,14 +75,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
69
75
  requirements:
70
76
  - - ">="
71
77
  - !ruby/object:Gem::Version
72
- version: 3.1.0
78
+ version: 3.0.0
73
79
  required_rubygems_version: !ruby/object:Gem::Requirement
74
80
  requirements:
75
81
  - - ">="
76
82
  - !ruby/object:Gem::Version
77
83
  version: '0'
78
84
  requirements: []
79
- rubygems_version: 3.4.3
85
+ rubygems_version: 3.4.6
80
86
  signing_key:
81
87
  specification_version: 4
82
88
  summary: IRB with Typed Completion
data/exe/kirb DELETED
@@ -1,11 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require_relative '../lib/katakata_irb'
3
- KatakataIrb.log_output = STDERR if ARGV.delete '--debug-output'
4
- unless ARGV.delete '--without-patch'
5
- require_relative '../lib/katakata_irb/reline_patch'
6
- KatakataIrb::RelinePatch.require_patched_reline
7
- require 'katakata_irb/ruby_lex_patch'
8
- KatakataIrb::RubyLexPatch.patch_to_ruby_lex
9
- end
10
- require 'katakata_irb'
11
- KatakataIrb.repl
@@ -1,43 +0,0 @@
1
- module KatakataIrb; end
2
- module KatakataIrb::RelinePatch
3
- module RelinePatchIseqLoader; end
4
- def self.require_patched_reline
5
- # Apply patches of unmerged pull-request to reline
6
- patches = %w[wholelines escapeseq indent raw scrollbar]
7
- patched = {}
8
- require 'reline/version.rb' # result of $LOAD_PATH.resolve_feature_path will change after this require
9
- patches.each do |patch_name|
10
- patch = File.read File.expand_path("reline_patches/#{patch_name}.patch", File.dirname(__FILE__))
11
- current_patched = {}
12
- patch.gsub(/^diff.+\nindex.+$/, '').split(/^--- a(.+)\n\+\+\+ b(.+)\n/).drop(1).each_slice(3) do |file, newfile, diff|
13
- raise if file != newfile
14
- _, path = $LOAD_PATH.resolve_feature_path file.sub(%r{^/lib/}, '')
15
- code = current_patched[path] || patched[path] || File.read(path)
16
- diff.split(/^@@.+\n/).drop(1).map(&:lines).each do |lines|
17
- target = lines.reject { _1[0] == '+' }.map { _1[1..] }.join
18
- replace = lines.reject { _1[0] == '-' }.map { _1[1..] }.join
19
- if code.include? target
20
- code = code.sub target, replace
21
- elsif !code.include?(replace)
22
- raise
23
- end
24
- end
25
- current_patched[path] = code
26
- end
27
- patched.update current_patched
28
- rescue
29
- KatakataIrb.log_puts "Failed to apply katakata_irb/reline_patches/#{patch_name}.patch to reline"
30
- end
31
-
32
- RelinePatchIseqLoader.define_method :load_iseq do |fname|
33
- if patched.key? fname
34
- RubyVM::InstructionSequence.compile patched[fname], fname
35
- else
36
- RubyVM::InstructionSequence.compile_file fname
37
- end
38
- end
39
- RubyVM::InstructionSequence.singleton_class.prepend RelinePatchIseqLoader
40
- require 'reline'
41
- RelinePatchIseqLoader.undef_method :load_iseq
42
- end
43
- end
@@ -1,45 +0,0 @@
1
- diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
2
- index 1c33a4b..bbf5e6c 100644
3
- --- a/lib/reline/line_editor.rb
4
- +++ b/lib/reline/line_editor.rb
5
- @@ -663,8 +663,10 @@ class Reline::LineEditor
6
- dialog.set_cursor_pos(cursor_column, @first_line_started_from + @started_from)
7
- dialog_render_info = dialog.call(@last_key)
8
- if dialog_render_info.nil? or dialog_render_info.contents.nil? or dialog_render_info.contents.empty?
9
- + lines = whole_lines
10
- dialog.lines_backup = {
11
- - lines: modify_lines(whole_lines),
12
- + unmodified_lines: lines,
13
- + lines: modify_lines(lines),
14
- line_index: @line_index,
15
- first_line_started_from: @first_line_started_from,
16
- started_from: @started_from,
17
- @@ -766,8 +768,10 @@ class Reline::LineEditor
18
- Reline::IOGate.move_cursor_column(cursor_column)
19
- move_cursor_up(dialog.vertical_offset + dialog.contents.size - 1)
20
- Reline::IOGate.show_cursor
21
- + lines = whole_lines
22
- dialog.lines_backup = {
23
- - lines: modify_lines(whole_lines),
24
- + unmodified_lines: lines,
25
- + lines: modify_lines(lines),
26
- line_index: @line_index,
27
- first_line_started_from: @first_line_started_from,
28
- started_from: @started_from,
29
- @@ -777,7 +781,7 @@ class Reline::LineEditor
30
- private def reset_dialog(dialog, old_dialog)
31
- return if dialog.lines_backup.nil? or old_dialog.contents.nil?
32
- - prompt, prompt_width, prompt_list = check_multiline_prompt(dialog.lines_backup[:lines])
33
- + prompt, prompt_width, prompt_list = check_multiline_prompt(dialog.lines_backup[:unmodified_lines])
34
- visual_lines = []
35
- visual_start = nil
36
- dialog.lines_backup[:lines].each_with_index { |l, i|
37
- @@ -888,7 +892,7 @@ class Reline::LineEditor
38
- private def clear_each_dialog(dialog)
39
- dialog.trap_key = nil
40
- return unless dialog.contents
41
- - prompt, prompt_width, prompt_list = check_multiline_prompt(dialog.lines_backup[:lines])
42
- + prompt, prompt_width, prompt_list = check_multiline_prompt(dialog.lines_backup[:unmodified_lines])
43
- visual_lines = []
44
- visual_lines_under_dialog = []
45
- visual_start = nil
@@ -1,25 +0,0 @@
1
- diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
2
- index bbf5e6c..c9e613e 100644
3
- --- a/lib/reline/line_editor.rb
4
- +++ b/lib/reline/line_editor.rb
5
- @@ -1707,17 +1707,18 @@ class Reline::LineEditor
6
- end
7
- new_lines = whole_lines
8
- new_indent = @auto_indent_proc.(new_lines, @line_index, @byte_pointer, @check_new_auto_indent)
9
- - new_indent = @cursor_max if new_indent&.> @cursor_max
10
- if new_indent&.>= 0
11
- md = new_lines[@line_index].match(/\A */)
12
- prev_indent = md[0].count(' ')
13
- if @check_new_auto_indent
14
- - @buffer_of_lines[@line_index] = ' ' * new_indent + @buffer_of_lines[@line_index].lstrip
15
- + line = @buffer_of_lines[@line_index] = ' ' * new_indent + @buffer_of_lines[@line_index].lstrip
16
- @cursor = new_indent
17
- + @cursor_max = calculate_width(line)
18
- @byte_pointer = new_indent
19
- else
20
- @line = ' ' * new_indent + @line.lstrip
21
- @cursor += new_indent - prev_indent
22
- + @cursor_max = calculate_width(@line)
23
- @byte_pointer += new_indent - prev_indent
24
- end
25
- end
@@ -1,95 +0,0 @@
1
- diff --git a/lib/reline.rb b/lib/reline.rb
2
- index f22b573..8716a0c 100644
3
- --- a/lib/reline.rb
4
- +++ b/lib/reline.rb
5
- @@ -281,19 +281,21 @@ module Reline
6
- Reline::DEFAULT_DIALOG_CONTEXT = Array.new
7
-
8
- def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
9
- - unless confirm_multiline_termination
10
- - raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
11
- - end
12
- - inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
13
- + Reline::IOGate.with_raw_input do
14
- + unless confirm_multiline_termination
15
- + raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
16
- + end
17
- + inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
18
-
19
- - whole_buffer = line_editor.whole_buffer.dup
20
- - whole_buffer.taint if RUBY_VERSION < '2.7'
21
- - if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0
22
- - Reline::HISTORY << whole_buffer
23
- - end
24
- + whole_buffer = line_editor.whole_buffer.dup
25
- + whole_buffer.taint if RUBY_VERSION < '2.7'
26
- + if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0
27
- + Reline::HISTORY << whole_buffer
28
- + end
29
-
30
- - line_editor.reset_line if line_editor.whole_buffer.nil?
31
- - whole_buffer
32
- + line_editor.reset_line if line_editor.whole_buffer.nil?
33
- + whole_buffer
34
- + end
35
- end
36
-
37
- def readline(prompt = '', add_hist = false)
38
- diff --git a/lib/reline/ansi.rb b/lib/reline/ansi.rb
39
- index ab147a6..ccebe15 100644
40
- --- a/lib/reline/ansi.rb
41
- +++ b/lib/reline/ansi.rb
42
- @@ -142,6 +142,10 @@ class Reline::ANSI
43
- @@output = val
44
- end
45
-
46
- + def self.with_raw_input
47
- + @@input.raw { yield }
48
- + end
49
- +
50
- @@buf = []
51
- def self.inner_getc
52
- unless @@buf.empty?
53
- diff --git a/lib/reline/general_io.rb b/lib/reline/general_io.rb
54
- index 92c76cb..9929846 100644
55
- --- a/lib/reline/general_io.rb
56
- +++ b/lib/reline/general_io.rb
57
- @@ -31,6 +31,10 @@ class Reline::GeneralIO
58
- @@input = val
59
- end
60
-
61
- + def self.with_raw_input
62
- + yield
63
- + end
64
- +
65
- def self.getc
66
- unless @@buf.empty?
67
- return @@buf.shift
68
- diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
69
- index 6acf969..e3985a3 100644
70
- --- a/lib/reline/line_editor.rb
71
- +++ b/lib/reline/line_editor.rb
72
- @@ -452,7 +452,7 @@ class Reline::LineEditor
73
- new_lines = whole_lines
74
- prompt, prompt_width, prompt_list = check_multiline_prompt(new_lines)
75
- modify_lines(new_lines).each_with_index do |line, index|
76
- - @output.write "#{prompt_list ? prompt_list[index] : prompt}#{line}\n"
77
- + @output.write "#{prompt_list ? prompt_list[index] : prompt}#{line}\r\n"
78
- Reline::IOGate.erase_after_cursor
79
- end
80
- @output.flush
81
- diff --git a/lib/reline/windows.rb b/lib/reline/windows.rb
82
- index b952329..7ea2a00 100644
83
- --- a/lib/reline/windows.rb
84
- +++ b/lib/reline/windows.rb
85
- @@ -291,6 +291,10 @@ class Reline::Windows
86
- end
87
- end
88
-
89
- + def self.with_raw_input
90
- + yield
91
- + end
92
- +
93
- def self.getc
94
- check_input_event
95
- @@output_buf.shift
@@ -1,34 +0,0 @@
1
- diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
2
- index 8153aab..50a063a 100644
3
- --- a/lib/reline/line_editor.rb
4
- +++ b/lib/reline/line_editor.rb
5
- @@ -703,17 +703,17 @@ class Reline::LineEditor
6
- dialog.scroll_top = dialog.pointer
7
- end
8
- pointer = dialog.pointer - dialog.scroll_top
9
- + else
10
- + dialog.scroll_top = 0
11
- end
12
- dialog.contents = dialog.contents[dialog.scroll_top, height]
13
- end
14
- - if dialog.contents and dialog.scroll_top >= dialog.contents.size
15
- - dialog.scroll_top = dialog.contents.size - height
16
- - end
17
- if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
18
- bar_max_height = height * 2
19
- moving_distance = (dialog_render_info.contents.size - height) * 2
20
- position_ratio = dialog.scroll_top.zero? ? 0.0 : ((dialog.scroll_top * 2).to_f / moving_distance)
21
- bar_height = (bar_max_height * ((dialog.contents.size * 2).to_f / (dialog_render_info.contents.size * 2))).floor.to_i
22
- + bar_height = 1 if bar_height.zero?
23
- dialog.scrollbar_pos = ((bar_max_height - bar_height) * position_ratio).floor.to_i
24
- else
25
- dialog.scrollbar_pos = nil
26
- @@ -755,7 +755,7 @@ class Reline::LineEditor
27
- str_width = dialog.width - (dialog.scrollbar_pos.nil? ? 0 : @block_elem_width)
28
- str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, str_width), str_width)
29
- @output.write "\e[#{bg_color}m\e[#{fg_color}m#{str}"
30
- - if dialog.scrollbar_pos and (dialog.scrollbar_pos != old_dialog.scrollbar_pos or dialog.column != old_dialog.column)
31
- + if dialog.scrollbar_pos
32
- @output.write "\e[37m"
33
- if dialog.scrollbar_pos <= (i * 2) and (i * 2 + 1) < (dialog.scrollbar_pos + bar_height)
34
- @output.write @full_block