summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/irb.rb84
-rw-r--r--lib/irb/ruby-lex.rb26
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.