diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/irb.rb | 84 | ||||
| -rw-r--r-- | lib/irb/ruby-lex.rb | 26 |
2 files changed, 44 insertions, 66 deletions
diff --git a/lib/irb.rb b/lib/irb.rb index ba7feabf06..9d0588d016 100644 --- a/lib/irb.rb +++ b/lib/irb.rb @@ -437,6 +437,7 @@ module IRB @context.workspace.load_commands_to_main @signal_status = :IN_IRB @scanner = RubyLex.new + @line_no = 1 end # A hook point for `debug` command's breakpoint after :IRB_EXIT as well as its clean-up @@ -454,7 +455,7 @@ module IRB workspace = IRB::WorkSpace.new(binding) context.workspace = workspace context.workspace.load_commands_to_main - scanner.increase_line_no(1) + @line_no += 1 # When users run: # 1. Debugging commands, like `step 2` @@ -476,7 +477,7 @@ module IRB end if input&.include?("\n") - scanner.increase_line_no(input.count("\n") - 1) + @line_no += input.count("\n") - 1 end input @@ -513,34 +514,38 @@ module IRB # The lexer used by this irb session attr_accessor :scanner - # Evaluates input for this session. - def eval_input - @scanner.set_prompt do - |ltype, indent, continue, line_no| - if ltype - f = @context.prompt_s - elsif continue - f = @context.prompt_c - else - f = @context.prompt_i - end - f = "" unless f - if @context.prompting? - @context.io.prompt = p = prompt(f, ltype, indent, line_no) - else - @context.io.prompt = p = "" - end - if @context.auto_indent_mode and !@context.io.respond_to?(:auto_indent) - unless ltype - prompt_i = @context.prompt_i.nil? ? "" : @context.prompt_i - ind = prompt(prompt_i, ltype, indent, line_no)[/.*\z/].size + - indent * 2 - p.size - @context.io.prompt = p + " " * ind if ind > 0 - end + private def generate_prompt(opens, continue, line_offset) + ltype = @scanner.ltype_from_open_tokens(opens) + indent = @scanner.calc_indent_level(opens) + continue = opens.any? || continue + line_no = @line_no + line_offset + + if ltype + f = @context.prompt_s + elsif continue + f = @context.prompt_c + else + f = @context.prompt_i + end + f = "" unless f + if @context.prompting? + p = format_prompt(f, ltype, indent, line_no) + else + p = "" + end + if @context.auto_indent_mode and !@context.io.respond_to?(:auto_indent) + unless ltype + prompt_i = @context.prompt_i.nil? ? "" : @context.prompt_i + ind = format_prompt(prompt_i, ltype, indent, line_no)[/.*\z/].size + + indent * 2 - p.size + p += " " * ind if ind > 0 end - @context.io.prompt end + p + end + # Evaluates input for this session. + def eval_input configure_io each_top_level_statement do |statement, line_no| @@ -572,8 +577,9 @@ module IRB end end - def read_input + def read_input(prompt) signal_status(:IN_INPUT) do + @context.io.prompt = prompt if l = @context.io.gets print l if @context.verbose? else @@ -591,16 +597,16 @@ module IRB end def readmultiline - @scanner.save_prompt_to_context_io([], false, 0) + prompt = generate_prompt([], false, 0) # multiline - return read_input if @context.io.respond_to?(:check_termination) + return read_input(prompt) if @context.io.respond_to?(:check_termination) # nomultiline code = '' line_offset = 0 loop do - line = read_input + line = read_input(prompt) unless line return code.empty? ? nil : code end @@ -615,7 +621,7 @@ module IRB line_offset += 1 continue = @scanner.should_continue?(tokens) - @scanner.save_prompt_to_context_io(opens, continue, line_offset) + prompt = generate_prompt(opens, continue, line_offset) end end @@ -625,9 +631,9 @@ module IRB break unless code if code != "\n" - yield build_statement(code), @scanner.line_no + yield build_statement(code), @line_no end - @scanner.increase_line_no(code.count("\n")) + @line_no += code.count("\n") rescue RubyLex::TerminateLineInput end end @@ -688,7 +694,7 @@ module IRB tokens_until_line << token if token != tokens_until_line.last end continue = @scanner.should_continue?(tokens_until_line) - @scanner.prompt(next_opens, continue, line_num_offset) + generate_prompt(next_opens, continue, line_num_offset) end end end @@ -874,7 +880,7 @@ module IRB end end - def truncate_prompt_main(str) # :nodoc: + private def truncate_prompt_main(str) # :nodoc: str = str.tr(CONTROL_CHARACTERS_PATTERN, ' ') if str.size <= PROMPT_MAIN_TRUNCATE_LENGTH str @@ -883,9 +889,8 @@ module IRB end end - def prompt(prompt, ltype, indent, line_no) # :nodoc: - p = prompt.dup - p.gsub!(/%([0-9]+)?([a-zA-Z])/) do + private def format_prompt(format, ltype, indent, line_no) # :nodoc: + format.gsub(/%([0-9]+)?([a-zA-Z])/) do case $2 when "N" @context.irb_name @@ -919,7 +924,6 @@ module IRB "%" end end - p end def output_value(omit = false) # :nodoc: diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb index 63756d8f80..4bce2aa6b2 100644 --- a/lib/irb/ruby-lex.rb +++ b/lib/irb/ruby-lex.rb @@ -42,13 +42,6 @@ module IRB end end - attr_reader :line_no - - def initialize - @line_no = 1 - @prompt = nil - end - def self.compile_with_errors_suppressed(code, line_no: 1) begin result = yield code, line_no @@ -66,10 +59,6 @@ module IRB result end - def set_prompt(&block) - @prompt = block - end - ERROR_TOKENS = [ :on_parse_error, :compile_error, @@ -145,12 +134,6 @@ module IRB $VERBOSE = verbose end - def prompt(opens, continue, line_num_offset) - ltype = ltype_from_open_tokens(opens) - indent_level = calc_indent_level(opens) - @prompt&.call(ltype, indent_level, opens.any? || continue, @line_no + line_num_offset) - end - def check_code_state(code, local_variables:) tokens = self.class.ripper_lex_without_warning(code, local_variables: local_variables) opens = NestingParser.open_tokens(tokens) @@ -170,15 +153,6 @@ module IRB end end - def save_prompt_to_context_io(opens, continue, line_num_offset) - # Implicitly saves prompt string to `@context.io.prompt`. This will be used in the next `@input.call`. - prompt(opens, continue, line_num_offset) - end - - def increase_line_no(addition) - @line_no += addition - end - def assignment_expression?(code, local_variables:) # Try to parse the code and check if the last of possibly multiple # expressions is an assignment type. |
