Skip to content

Commit

Permalink
Fix IRB command loading, minor changes to command argument parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
janlelis committed Sep 30, 2024
1 parent 75c9e78 commit 7ab79ba
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 85 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Irbtools Changelog

## 4.1.0 (unreleased)

- Fix command loading (was broken in previous version)
- Minor changes to command argument parsing
- Set required IRB to 1.13.0

## 4.0.11

- Loosen IRB dependency to allow IRB 1.14
Expand Down
2 changes: 1 addition & 1 deletion irbtools.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Gem::Specification.new do |s|
# Dependencies

# Core Functionality
s.add_dependency %q<irb>, ">= 1.12.0", "< 1.15"
s.add_dependency %q<irb>, ">= 1.13.0", "< 1.15"
s.add_dependency %q<every_day_irb>, "~> 2.2"
s.add_dependency %q<fancy_irb>, "~> 2.1"
s.add_dependency %q<wirb>, "~> 2.0", ">= 2.2.1"
Expand Down
1 change: 0 additions & 1 deletion lib/irbtools.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require_relative "irbtools/configure"
require_relative "irbtools/commands"

require "irb"

Expand Down
45 changes: 29 additions & 16 deletions lib/irbtools/commands/code.rb
Original file line number Diff line number Diff line change
@@ -1,31 +1,44 @@
require "irb/command/base"
require "irb/command"

module IRB
module Irbtools
module Command
class Code < Base
class Code < IRB::Command::Base
category "Introspection"
description "Shows the syntax-highlighted source code of a method"
help_message <<~HELP
Shows the syntax-highlighted source code of a method. Works with Ruby's
native methods.
class << self
def transform_args(args)
if args.strip =~ /\A(?:([\w:]+)([#.]))?(\w+[?!]?)\z/
if $1
if $2 == "#"
"#{$1}, #{$1}.instance_method(:#{$3})"
else
"#{$1}, :#{$3}"
end
Example usages:
>> code SecureRandom.uuid
>> code Array#reverse
HELP

def transform_arg(arg)
if arg.empty?
"[]"
elsif arg.strip =~ /\A(?:([\w:]+)([#.]))?(\w+[?!]?)\z/
if $1
if $2 == "#"
"[#{$1}, #{$1}.instance_method(:#{$3})]"
else
":" + $3
"[#{$1}, :#{$3}]"
end
else
args
"[:#{$3}]"
end
else
nil
end
end

def execute(*args)
@irb_context.workspace.binding.send(:code, *args)
def execute(arg)
if code_parameters_code = transform_arg(arg)
code_parameters = @irb_context.workspace.binding.eval(code_parameters_code)
@irb_context.workspace.binding.send(:code, *code_parameters)
else
warn "code: Please use rdoc syntax, e.g. Array#sum"
end
rescue NameError
warn "code: Class or method not found."
end
Expand Down
45 changes: 29 additions & 16 deletions lib/irbtools/commands/howtocall.rb
Original file line number Diff line number Diff line change
@@ -1,31 +1,44 @@
require "irb/command/base"
require "irb/command"

module IRB
module Irbtools
module Command
class Howtocall < Base
class Howtocall < IRB::Command::Base
category "Introspection"
description "Displays method signatures based on Method#parameters"
help_message <<~HELP
Displays method signatures based on Method#parameters, with the same limitations,
so it's more useful with methods implemented in Ruby itself
class << self
def transform_args(args)
if args.strip =~ /\A(?:([\w:]+)([#.]))?(\w+[?!]?)\z/
if $1
if $2 == "#"
"#{$1}, #{$1}.instance_method(:#{$3})"
else
"#{$1}, :#{$3}"
end
Example usages:
>> howtocall Gem.add_to_load_path
>> howtocall Array#sum
HELP

def transform_arg(arg)
if arg.empty?
"[]"
elsif arg.strip =~ /\A(?:([\w:]+)([#.]))?(\w+[?!]?)\z/
if $1
if $2 == "#"
"[#{$1}, #{$1}.instance_method(:#{$3})]"
else
":" + $3
"[#{$1}, :#{$3}]"
end
else
args
"[:#{$3}]"
end
else
nil
end
end

def execute(*args)
@irb_context.workspace.binding.send(:howtocall, *args)
def execute(arg)
if howtocall_parameters_code = transform_arg(arg)
howtocall_parameters = @irb_context.workspace.binding.eval(howtocall_parameters_code)
@irb_context.workspace.binding.send(:howtocall, *howtocall_parameters)
else
warn "howtocall: Please use rdoc syntax, e.g. Array#sum"
end
rescue NameError
warn "howtocall: Class or method not found"
end
Expand Down
23 changes: 13 additions & 10 deletions lib/irbtools/commands/look.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
require "irb/command/base"
require "irb/command"

module IRB
module Irbtools
module Command
class Look < Base
class Look < IRB::Command::Base
category "Introspection"
description 'Method list and lookup path inspection based on looksee gem'
description 'Method list and lookup path inspection based on the looksee gem'
help_message <<~HELP
Method list and lookup path inspection based on the looksee gem.
def execute(*args)
if args.empty?
@irb_context.workspace.binding.look
Example usage: look [1,2,3]
HELP

def execute(arg)
if arg.strip.empty?
p @irb_context.workspace.binding.look
else
obj, *params = *args
obj.look(*params)
p @irb_context.workspace.binding.eval(arg).look
end
end
end
end
end

22 changes: 13 additions & 9 deletions lib/irbtools/commands/shadow.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
require "irb/command/base"
require "irb/command"

module IRB
module Irbtools
module Command
class Shadow < Base
class Shadow < IRB::Command::Base
category "Introspection"
description 'Method list and lookup path inspection based on object shadow gem'
description 'Method list and lookup path inspection based on the object shadow gem'
help_message <<~HELP
Method list and lookup path inspection based on the object shadow gem.
def execute(*args)
if args.empty?
@irb_context.workspace.binding.shadow
Example usage: + [1,2,3]
HELP

def execute(arg)
if arg.strip.empty?
p @irb_context.workspace.binding.shadow
else
obj, *params = *args
obj.shadow(*params)
p @irb_context.workspace.binding.eval(arg).shadow
end
end
end
Expand Down
23 changes: 9 additions & 14 deletions lib/irbtools/commands/sys.rb
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
require "irb/command/base"
require "irb/command"

module IRB
module Irbtools
module Command
class Sys < Base
class Sys < IRB::Command::Base
category "Misc"
description 'Run a system command'
help_message <<~HELP
Run a command via Ruby's Kernel#system method
class << self
def transform_args(args)
if args.empty? || string_literal?(args)
args
else
args.strip.dump
end
end
end
Example usage: $ cowsay "Hello from IRB"
HELP

def execute(*args)
system(*args)
def execute(arg)
system(arg)
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/irbtools/configure.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require_relative 'version'

require_relative 'implementation'
require_relative "commands"
require_relative 'libraries' unless Irbtools.minimal
17 changes: 5 additions & 12 deletions lib/irbtools/implementation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,18 +127,11 @@ def set_propmt
end

def load_commands
ec = IRB::ExtendCommandBundle.instance_variable_get(:@EXTEND_COMMANDS)

[
[:code, :Code, nil, [:code, IRB::ExtendCommandBundle::OVERRIDE_ALL]],
[:howtocall, :Howtocall, nil, [:howtocall, IRB::ExtendCommandBundle::OVERRIDE_ALL]],
[:look, :Look, nil, [:look, IRB::ExtendCommandBundle::OVERRIDE_ALL]],
[:shadow, :Shadow, nil, [:shadow, IRB::ExtendCommandBundle::OVERRIDE_ALL]],
[:sys, :Sys, nil, [:sys, IRB::ExtendCommandBundle::OVERRIDE_ALL]],
].each{ |ecconfig|
ec.push(ecconfig)
IRB::ExtendCommandBundle.def_extend_command(*ecconfig)
}
IRB::Command.register(:code, Irbtools::Command::Code)
IRB::Command.register(:howtocall, Irbtools::Command::Howtocall)
IRB::Command.register(:look, Irbtools::Command::Look)
IRB::Command.register(:shadow, Irbtools::Command::Shadow)
IRB::Command.register(:sys, Irbtools::Command::Sys)
end

def add_command_aliases
Expand Down
12 changes: 6 additions & 6 deletions spec/irbtools_commands_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
describe "howtocall / code" do
it "support ri Syntax like String.name or String#gsub" do
expect(
IRB::Command::Howtocall.transform_args("String.name")
).to eq "String, :name"
Irbtools::Command::Howtocall.new(nil).transform_arg("String.name")
).to eq "[String, :name]"

expect(
IRB::Command::Code.transform_args("String#gsub")
).to eq "String, String.instance_method(:gsub)"
Irbtools::Command::Code.new(nil).transform_arg("String#gsub")
).to eq "[String, String.instance_method(:gsub)]"
end

it "supports question-mark methods" do
expect(
IRB::Command::Howtocall.transform_args("String#ascii_only?")
).to eq "String, String.instance_method(:ascii_only?)"
Irbtools::Command::Howtocall.new(nil).transform_arg("String#ascii_only?")
).to eq "[String, String.instance_method(:ascii_only?)]"
end
end
end
Expand Down

0 comments on commit 7ab79ba

Please sign in to comment.