From d4795245b195a25e89cea93f29cfd1669b7a3a94 Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Mon, 13 Mar 2023 00:06:09 +0800 Subject: [PATCH] WIP --- lib/irb/cmd/help.rb | 11 ----------- lib/irb/cmd/irb_info.rb | 4 +++- lib/irb/cmd/ls.rb | 20 ++++++++++++++++++++ lib/irb/cmd/nop.rb | 35 +++++++++++++++++++++++++++++++++++ lib/irb/cmd/show_source.rb | 9 --------- lib/irb/context.rb | 9 +++++---- 6 files changed, 63 insertions(+), 25 deletions(-) diff --git a/lib/irb/cmd/help.rb b/lib/irb/cmd/help.rb index 9896fa9db..dfb50c86f 100644 --- a/lib/irb/cmd/help.rb +++ b/lib/irb/cmd/help.rb @@ -10,17 +10,6 @@ module IRB module ExtendCommand class Help < Nop - class << self - def transform_args(args) - # Return a string literal as is for backward compatibility - if args.empty? || string_literal?(args) - args - else # Otherwise, consider the input as a String for convenience - args.strip.dump - end - end - end - category "Context" description "Enter the mode to look up RI documents." diff --git a/lib/irb/cmd/irb_info.rb b/lib/irb/cmd/irb_info.rb index da11e8d40..b81a670b6 100644 --- a/lib/irb/cmd/irb_info.rb +++ b/lib/irb/cmd/irb_info.rb @@ -11,7 +11,7 @@ class IrbInfo < Nop description "Show information about IRB." def execute - Class.new { + c = Class.new { def inspect str = "Ruby version: #{RUBY_VERSION}\n" str += "IRB version: #{IRB.version}\n" @@ -29,6 +29,8 @@ def inspect end alias_method :to_s, :inspect }.new + puts c + c end end end diff --git a/lib/irb/cmd/ls.rb b/lib/irb/cmd/ls.rb index d5a371a4d..7574bdfe5 100644 --- a/lib/irb/cmd/ls.rb +++ b/lib/irb/cmd/ls.rb @@ -21,6 +21,26 @@ def self.transform_args(args) end end + def execute_with_raw_args(raw_args) + raw_args = raw_args.strip + + if raw_args.empty? + execute + else + if match = raw_args.match(/\A(?.+\s|)(-g|-G)\s+(?[^\s]+)\s*\z/) + args = match[:args] + + if !args.empty? + execute(evaluate(args), grep: /#{match[:grep]}/) + else + execute(grep: /#{match[:grep]}/) + end + else + execute(evaluate(raw_args)) + end + end + end + def execute(*arg, grep: nil) o = Output.new(grep: grep) diff --git a/lib/irb/cmd/nop.rb b/lib/irb/cmd/nop.rb index 34facc757..b82b89b69 100644 --- a/lib/irb/cmd/nop.rb +++ b/lib/irb/cmd/nop.rb @@ -59,6 +59,41 @@ def irb def execute(*opts) #nop end + + def transform_args(raw_args) + if string_literal?(raw_args) + evaluate(raw_args) + else + raw_args + end + end + + def execute_with_raw_args(raw_args) + if raw_args.nil? || raw_args.empty? + execute + else + raw_args = raw_args.strip + + args = + if respond_to?(:transform_args) + transform_args(raw_args) + else + evaluate(raw_args) + end + execute(args) + end + end + + private + + def string_literal?(args) + sexp = Ripper.sexp(args) + sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal + end + + def evaluate(str) + eval(str, @irb_context.workspace.binding) + end end end diff --git a/lib/irb/cmd/show_source.rb b/lib/irb/cmd/show_source.rb index eb21533b5..356794804 100644 --- a/lib/irb/cmd/show_source.rb +++ b/lib/irb/cmd/show_source.rb @@ -13,15 +13,6 @@ class ShowSource < Nop description "Show the source code of a given method or constant." class << self - def transform_args(args) - # Return a string literal as is for backward compatibility - if args.empty? || string_literal?(args) - args - else # Otherwise, consider the input as a String for convenience - args.strip.dump - end - end - def find_source(str, irb_context) case str when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name diff --git a/lib/irb/context.rb b/lib/irb/context.rb index f398c6f75..0f63ab3ea 100644 --- a/lib/irb/context.rb +++ b/lib/irb/context.rb @@ -490,11 +490,12 @@ def evaluate(line, line_no, exception: nil) # :nodoc: # Hook command-specific transformation command_class = ExtendCommandBundle.load_command(command) - if command_class&.respond_to?(:transform_args) - line = "#{command} #{command_class.transform_args(args)}" - end - set_last_value(@workspace.evaluate(line, irb_path, line_no)) + if command_class + command_class.new(self).execute_with_raw_args(args) + else + set_last_value(@workspace.evaluate(line, irb_path, line_no)) + end end def inspect_last_value # :nodoc: