irb 1.14.3 → 1.15.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.
data/lib/irb/pager.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'reline'
4
+
3
5
  module IRB
4
6
  # The implementation of this class is borrowed from RDoc's lib/rdoc/ri/driver.rb.
5
7
  # Please do NOT use this class directly outside of IRB.
@@ -47,12 +49,42 @@ module IRB
47
49
  rescue Errno::EPIPE
48
50
  end
49
51
 
50
- private
51
-
52
52
  def should_page?
53
53
  IRB.conf[:USE_PAGER] && STDIN.tty? && (ENV.key?("TERM") && ENV["TERM"] != "dumb")
54
54
  end
55
55
 
56
+ def page_with_preview(width, height, formatter_proc)
57
+ overflow_callback = ->(lines) do
58
+ modified_output = formatter_proc.call(lines.join, true)
59
+ content, = take_first_page(width, [height - 2, 0].max) {|o| o.write modified_output }
60
+ content = content.chomp
61
+ content = "#{content}\e[0m" if Color.colorable?
62
+ $stdout.puts content
63
+ $stdout.puts 'Preparing full inspection value...'
64
+ end
65
+ out = PageOverflowIO.new(width, height, overflow_callback, delay: 0.1)
66
+ yield out
67
+ content = formatter_proc.call(out.string, out.multipage?)
68
+ if out.multipage?
69
+ page(retain_content: true) do |io|
70
+ io.puts content
71
+ end
72
+ else
73
+ $stdout.puts content
74
+ end
75
+ end
76
+
77
+ def take_first_page(width, height)
78
+ overflow_callback = proc do |lines|
79
+ return lines.join, true
80
+ end
81
+ out = Pager::PageOverflowIO.new(width, height, overflow_callback)
82
+ yield out
83
+ [out.string, false]
84
+ end
85
+
86
+ private
87
+
56
88
  def content_exceeds_screen_height?(content)
57
89
  screen_height, screen_width = begin
58
90
  Reline.get_screen_size
@@ -62,10 +94,10 @@ module IRB
62
94
 
63
95
  pageable_height = screen_height - 3 # leave some space for previous and the current prompt
64
96
 
65
- # If the content has more lines than the pageable height
66
- content.lines.count > pageable_height ||
67
- # Or if the content is a few long lines
68
- pageable_height * screen_width < Reline::Unicode.calculate_width(content, true)
97
+ return true if content.lines.size > pageable_height
98
+
99
+ _, overflow = take_first_page(screen_width, pageable_height) {|out| out.write content }
100
+ overflow
69
101
  end
70
102
 
71
103
  def setup_pager(retain_content:)
@@ -96,5 +128,86 @@ module IRB
96
128
  nil
97
129
  end
98
130
  end
131
+
132
+ # Writable IO that has page overflow callback
133
+ class PageOverflowIO
134
+ attr_reader :string, :first_page_lines
135
+
136
+ # Maximum size of a single cell in terminal
137
+ # Assumed worst case: "\e[1;3;4;9;38;2;255;128;128;48;2;128;128;255mA\e[0m"
138
+ # bold, italic, underline, crossed_out, RGB forgound, RGB background
139
+ MAX_CHAR_PER_CELL = 50
140
+
141
+ def initialize(width, height, overflow_callback, delay: nil)
142
+ @lines = []
143
+ @first_page_lines = nil
144
+ @width = width
145
+ @height = height
146
+ @buffer = +''
147
+ @overflow_callback = overflow_callback
148
+ @col = 0
149
+ @string = +''
150
+ @multipage = false
151
+ @delay_until = (Time.now + delay if delay)
152
+ end
153
+
154
+ def puts(text = '')
155
+ text = text.to_s unless text.is_a?(String)
156
+ write(text)
157
+ write("\n") unless text.end_with?("\n")
158
+ end
159
+
160
+ def write(text)
161
+ text = text.to_s unless text.is_a?(String)
162
+ @string << text
163
+ if @multipage
164
+ if @delay_until && Time.now > @delay_until
165
+ @overflow_callback.call(@first_page_lines)
166
+ @delay_until = nil
167
+ end
168
+ return
169
+ end
170
+
171
+ overflow_size = (@width * (@height - @lines.size) + @width - @col) * MAX_CHAR_PER_CELL
172
+ if text.size >= overflow_size
173
+ text = text[0, overflow_size]
174
+ overflow = true
175
+ end
176
+ @buffer << text
177
+ @col += Reline::Unicode.calculate_width(text, true)
178
+ if text.include?("\n") || @col >= @width
179
+ @buffer.lines.each do |line|
180
+ wrapped_lines = Reline::Unicode.split_by_width(line.chomp, @width).first.compact
181
+ wrapped_lines.pop if wrapped_lines.last == ''
182
+ @lines.concat(wrapped_lines)
183
+ if line.end_with?("\n")
184
+ if @lines.empty? || @lines.last.end_with?("\n")
185
+ @lines << "\n"
186
+ else
187
+ @lines[-1] += "\n"
188
+ end
189
+ end
190
+ end
191
+ @buffer.clear
192
+ @buffer << @lines.pop if !@lines.empty? && !@lines.last.end_with?("\n")
193
+ @col = Reline::Unicode.calculate_width(@buffer, true)
194
+ end
195
+ if overflow || @lines.size > @height || (@lines.size == @height && @col > 0)
196
+ @first_page_lines = @lines.take(@height)
197
+ if !@delay_until || Time.now > @delay_until
198
+ @overflow_callback.call(@first_page_lines)
199
+ @delay_until = nil
200
+ end
201
+ @multipage = true
202
+ end
203
+ end
204
+
205
+ def multipage?
206
+ @multipage
207
+ end
208
+
209
+ alias print write
210
+ alias << write
211
+ end
99
212
  end
100
213
  end
data/lib/irb/ruby-lex.rb CHANGED
@@ -52,6 +52,27 @@ module IRB
52
52
  on_words_beg on_qwords_beg
53
53
  ]
54
54
 
55
+ RESERVED_WORDS = %i[
56
+ __ENCODING__ __LINE__ __FILE__
57
+ BEGIN END
58
+ alias and
59
+ begin break
60
+ case class
61
+ def defined? do
62
+ else elsif end ensure
63
+ false for
64
+ if in
65
+ module
66
+ next nil not
67
+ or
68
+ redo rescue retry return
69
+ self super
70
+ then true
71
+ undef unless until
72
+ when while
73
+ yield
74
+ ]
75
+
55
76
  class TerminateLineInput < StandardError
56
77
  def initialize
57
78
  super("Terminate Line Input")
@@ -77,6 +98,10 @@ module IRB
77
98
  end
78
99
 
79
100
  def generate_local_variables_assign_code(local_variables)
101
+ # Some reserved words could be a local variable
102
+ # Example: def f(if: 1); binding.irb; end
103
+ # These reserved words should be removed from assignment code
104
+ local_variables -= RESERVED_WORDS
80
105
  "#{local_variables.join('=')}=nil;" unless local_variables.empty?
81
106
  end
82
107
 
@@ -114,7 +114,7 @@ module IRB
114
114
  when "owner"
115
115
  target_method = owner_receiver.instance_method(method)
116
116
  when "receiver"
117
- target_method = owner_receiver.method(method)
117
+ target_method = Kernel.instance_method(:method).bind_call(owner_receiver, method)
118
118
  end
119
119
  super_level.times do |s|
120
120
  target_method = target_method.super_method if target_method
data/lib/irb/statement.rb CHANGED
@@ -54,6 +54,27 @@ module IRB
54
54
  end
55
55
  end
56
56
 
57
+ class IncorrectAlias < Statement
58
+ attr_reader :message
59
+
60
+ def initialize(message)
61
+ @code = ""
62
+ @message = message
63
+ end
64
+
65
+ def should_be_handled_by_debugger?
66
+ false
67
+ end
68
+
69
+ def is_assignment?
70
+ false
71
+ end
72
+
73
+ def suppresses_echo?
74
+ true
75
+ end
76
+ end
77
+
57
78
  class Command < Statement
58
79
  attr_reader :command_class, :arg
59
80
 
data/lib/irb/version.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  #
6
6
 
7
7
  module IRB # :nodoc:
8
- VERSION = "1.14.3"
8
+ VERSION = "1.15.3"
9
9
  @RELEASE_VERSION = VERSION
10
- @LAST_UPDATE_DATE = "2024-12-18"
10
+ @LAST_UPDATE_DATE = "2025-11-01"
11
11
  end