diff options
Diffstat (limited to 'lib/irb')
-rw-r--r-- | lib/irb/color.rb | 13 | ||||
-rw-r--r-- | lib/irb/context.rb | 4 | ||||
-rw-r--r-- | lib/irb/input-method.rb | 3 | ||||
-rw-r--r-- | lib/irb/ruby-lex.rb | 33 |
4 files changed, 33 insertions, 20 deletions
diff --git a/lib/irb/color.rb b/lib/irb/color.rb index 7071696cb2..34912420e4 100644 --- a/lib/irb/color.rb +++ b/lib/irb/color.rb @@ -123,13 +123,15 @@ module IRB # :nodoc: # If `complete` is false (code is incomplete), this does not warn compile_error. # This option is needed to avoid warning a user when the compile_error is happening # because the input is not wrong but just incomplete. - def colorize_code(code, complete: true, ignore_error: false, colorable: colorable?) + def colorize_code(code, complete: true, ignore_error: false, colorable: colorable?, local_variables: []) return code unless colorable symbol_state = SymbolState.new colored = +'' + lvars_code = RubyLex.generate_local_variables_assign_code(local_variables) + code_with_lvars = lvars_code ? "#{lvars_code}\n#{code}" : code - scan(code, allow_last_error: !complete) do |token, str, expr| + scan(code_with_lvars, allow_last_error: !complete) do |token, str, expr| # handle uncolorable code if token.nil? colored << Reline::Unicode.escape_for_print(str) @@ -152,7 +154,12 @@ module IRB # :nodoc: end end end - colored + + if lvars_code + colored.sub(/\A.+\n/, '') + else + colored + end end private diff --git a/lib/irb/context.rb b/lib/irb/context.rb index 5e07f5dfb0..d238da9350 100644 --- a/lib/irb/context.rb +++ b/lib/irb/context.rb @@ -518,5 +518,9 @@ module IRB end alias __to_s__ to_s alias to_s inspect + + def local_variables # :nodoc: + workspace.binding.local_variables + end end end diff --git a/lib/irb/input-method.rb b/lib/irb/input-method.rb index aa5cb5adb9..b0110dd09b 100644 --- a/lib/irb/input-method.rb +++ b/lib/irb/input-method.rb @@ -286,7 +286,8 @@ module IRB if IRB.conf[:USE_COLORIZE] proc do |output, complete: | next unless IRB::Color.colorable? - IRB::Color.colorize_code(output, complete: complete) + lvars = IRB.CurrentContext&.local_variables || [] + IRB::Color.colorize_code(output, complete: complete, local_variables: lvars) end else proc do |output| diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb index cb6d669a72..54ea2a9e7b 100644 --- a/lib/irb/ruby-lex.rb +++ b/lib/irb/ruby-lex.rb @@ -136,16 +136,18 @@ class RubyLex :on_param_error ] + def self.generate_local_variables_assign_code(local_variables) + "#{local_variables.join('=')}=nil;" unless local_variables.empty? + end + def self.ripper_lex_without_warning(code, context: nil) verbose, $VERBOSE = $VERBOSE, nil - if context - lvars = context.workspace&.binding&.local_variables - if lvars && !lvars.empty? - code = "#{lvars.join('=')}=nil\n#{code}" - line_no = 0 - else - line_no = 1 - end + lvars_code = generate_local_variables_assign_code(context&.local_variables || []) + if lvars_code + code = "#{lvars_code}\n#{code}" + line_no = 0 + else + line_no = 1 end compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no| @@ -214,6 +216,8 @@ class RubyLex ltype = process_literal_type(tokens) indent = process_nesting_level(tokens) continue = process_continue(tokens) + lvars_code = self.class.generate_local_variables_assign_code(context&.local_variables || []) + code = "#{lvars_code}\n#{code}" if lvars_code code_block_open = check_code_block(code, tokens) [ltype, indent, continue, code_block_open] end @@ -233,13 +237,13 @@ class RubyLex @code_block_open = false end - def each_top_level_statement + def each_top_level_statement(context) initialize_input catch(:TERM_INPUT) do loop do begin prompt - unless l = lex + unless l = lex(context) throw :TERM_INPUT if @line == '' else @line_no += l.count("\n") @@ -269,18 +273,15 @@ class RubyLex end end - def lex + def lex(context) line = @input.call if @io.respond_to?(:check_termination) return line # multiline end code = @line + (line.nil? ? '' : line) code.gsub!(/\s*\z/, '').concat("\n") - @tokens = self.class.ripper_lex_without_warning(code) - @continue = process_continue - @code_block_open = check_code_block(code) - @indent = process_nesting_level - @ltype = process_literal_type + @tokens = self.class.ripper_lex_without_warning(code, context: context) + @ltype, @indent, @continue, @code_block_open = check_state(code, @tokens, context: context) line end |