Skip to content

Commit

Permalink
Use optparse to parse command flags
Browse files Browse the repository at this point in the history
  • Loading branch information
st0012 committed Dec 10, 2023
1 parent 715526b commit 84988e2
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 18 deletions.
5 changes: 3 additions & 2 deletions lib/irb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -616,15 +616,16 @@ def build_statement(code)

if command_match
command_or_alias = command_match[:cmd_name]
arg = [command_match[:cmd_arg], command_match[:cmd_flag]].compact.join(' ')
# Transform a non-identifier alias (@, $) or keywords (next, break)
command_name = @context.command_aliases[command_or_alias.to_sym]
command = command_name || command_or_alias
command_class = ExtendCommandBundle.load_command(command)
end

if command_class
Statement::Command.new(code, command, arg, command_class)
arg = command_match[:cmd_arg]
flags = command_match[:cmd_flag]
Statement::Command.new(code, command, arg, flags, command_class)
else
is_assignment_expression = @scanner.assignment_expression?(code, local_variables: @context.local_variables)
Statement::Expression.new(code, is_assignment_expression)
Expand Down
9 changes: 4 additions & 5 deletions lib/irb/cmd/history.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ class History < Nop
category "IRB"
description "Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output."

def self.transform_args(args)
match = args&.match(/(-g|-G)\s+(?<grep>.+)\s*\n\z/)
return unless match

"grep: #{Regexp.new(match[:grep]).inspect}"
def self.set_options(options, parser)
parser.on("-g [query]", "-G [query]", "Filter out the output with a query") do |v|
options[:grep] = "\/#{v}\/"
end
end

def execute(grep: nil)
Expand Down
11 changes: 5 additions & 6 deletions lib/irb/cmd/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ class Ls < Nop
category "Context"
description "Show methods, constants, and variables. `-g [query]` or `-G [query]` allows you to filter out the output."

def self.transform_args(args)
if match = args&.match(/\A(?<args>.+\s|)(-g|-G)\s+(?<grep>[^\s]+)\s*\z/)
args = match[:args]
"#{args}#{',' unless args.chomp.empty?} grep: /#{match[:grep]}/"
else
args
class << self
def set_options(options, parser)
parser.on("-g [query]", "-G [query]", "Filter out the output with a query") do |v|
options[:grep] = "\/#{v}\/"
end
end
end

Expand Down
18 changes: 18 additions & 0 deletions lib/irb/cmd/nop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# nop.rb -
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
require "optparse"

module IRB
# :stopdoc:
Expand All @@ -22,12 +23,29 @@ def description(description = nil)
@description
end

def parse_flags(flags)
options = {}

OptionParser.new do |parser|
set_options(options, parser)
end.parse(flags)

options
rescue OptionParser::InvalidOption => e
warn e
options
end

private

def string_literal?(args)
sexp = Ripper.sexp(args)
sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal
end

def set_options(opts, _parser)
opts
end
end

def self.execute(irb_context, *opts, **kwargs, &block)
Expand Down
12 changes: 9 additions & 3 deletions lib/irb/cmd/show_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ class ShowSource < Nop
description "Show the source code of a given method or constant."

class << self
def set_options(options, parser)
parser.on("-s", "show super method") do |v|
options[:super_level] ||= 0
options[:super_level] += 1
end
end

def transform_args(args)
# Return a string literal as is for backward compatibility
if args.empty? || string_literal?(args)
Expand All @@ -22,14 +29,13 @@ def transform_args(args)
end
end

def execute(str = nil)
def execute(str = nil, super_level: nil)
unless str.is_a?(String)
puts "Error: Expected a string but got #{str.inspect}"
return
end

str, esses = str.split(" -")
super_level = esses ? esses.count("s") : 0
super_level ||= 0
source = SourceFinder.new(@irb_context).find_source(str, super_level)

if source
Expand Down
16 changes: 14 additions & 2 deletions lib/irb/statement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ def evaluable_code
end

class Command < Statement
def initialize(code, command, arg, command_class)
def initialize(code, command, arg, flags, command_class)
@code = code
@command = command
@arg = arg
@flags = command_class.parse_flags(flags&.split || [])
@command_class = command_class
end

Expand All @@ -73,7 +74,18 @@ def evaluable_code
arg = @arg
end

[@command, arg].compact.join(' ')
result = [@command, arg].compact.join(' ')

if @flags.any?
converted_flags = @flags.map do |k, v|
"#{k}: #{v}"
end

result += "," if arg
result += " #{converted_flags.join(' ')}"
end

result
end
end
end
Expand Down

0 comments on commit 84988e2

Please sign in to comment.