From 98ef298afd467efffda668cfd2d7430e395a1a71 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/chws.rb | 3 ++- lib/irb/cmd/ls.rb | 20 ++++++++++++++++++++ lib/irb/cmd/measure.rb | 3 +++ lib/irb/cmd/nop.rb | 35 +++++++++++++++++++++++++++++++++++ lib/irb/cmd/pushws.rb | 3 ++- lib/irb/cmd/show_source.rb | 9 --------- lib/irb/context.rb | 10 ++++++---- 7 files changed, 68 insertions(+), 15 deletions(-) diff --git a/lib/irb/cmd/chws.rb b/lib/irb/cmd/chws.rb index 44712fa44..dd6b3a0da 100644 --- a/lib/irb/cmd/chws.rb +++ b/lib/irb/cmd/chws.rb @@ -26,7 +26,8 @@ class ChangeWorkspace < Nop description "Change the current workspace to an object." def execute(*obj) - irb_context.change_workspace(*obj) + objs = obj.map { |o| irb_context.workspace.binding.eval(o)} + irb_context.change_workspace(*objs) irb_context.main end end diff --git a/lib/irb/cmd/ls.rb b/lib/irb/cmd/ls.rb index 063a88d33..0aa737140 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/measure.rb b/lib/irb/cmd/measure.rb index 9122e2dac..4432488db 100644 --- a/lib/irb/cmd/measure.rb +++ b/lib/irb/cmd/measure.rb @@ -13,6 +13,9 @@ def initialize(*args) end def execute(type = nil, arg = nil, &block) + if type + type = type.sub(/\A:/, '').to_sym + end # Please check IRB.init_config in lib/irb/init.rb that sets # IRB.conf[:MEASURE_PROC] to register default "measure" methods, # "measure :time" (abbreviated as "measure") and "measure :stackprof". diff --git a/lib/irb/cmd/nop.rb b/lib/irb/cmd/nop.rb index 7fb197c51..be52229df 100644 --- a/lib/irb/cmd/nop.rb +++ b/lib/irb/cmd/nop.rb @@ -46,6 +46,41 @@ def initialize(irb_context) 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/pushws.rb b/lib/irb/cmd/pushws.rb index d64d82218..242192ce3 100644 --- a/lib/irb/cmd/pushws.rb +++ b/lib/irb/cmd/pushws.rb @@ -25,7 +25,8 @@ class PushWorkspace < Workspaces description "Push an object to the workspace stack." def execute(*obj) - irb_context.push_workspace(*obj) + objs = obj.map { |o| irb_context.workspace.binding.eval(o)} + irb_context.push_workspace(*objs) super end end diff --git a/lib/irb/cmd/show_source.rb b/lib/irb/cmd/show_source.rb index a74895b2d..332bf9745 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..20d961542 100644 --- a/lib/irb/context.rb +++ b/lib/irb/context.rb @@ -490,11 +490,13 @@ 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) + set_last_value(nil) + else + set_last_value(@workspace.evaluate(line, irb_path, line_no)) + end end def inspect_last_value # :nodoc: