From 7ab79ba83692b01d0eac803d4998333a6b4e91a3 Mon Sep 17 00:00:00 2001 From: Jan Lelis Date: Mon, 30 Sep 2024 23:18:31 +0200 Subject: [PATCH] Fix IRB command loading, minor changes to command argument parsing --- CHANGELOG.md | 6 ++++ irbtools.gemspec | 2 +- lib/irbtools.rb | 1 - lib/irbtools/commands/code.rb | 45 +++++++++++++++++++----------- lib/irbtools/commands/howtocall.rb | 45 +++++++++++++++++++----------- lib/irbtools/commands/look.rb | 23 ++++++++------- lib/irbtools/commands/shadow.rb | 22 +++++++++------ lib/irbtools/commands/sys.rb | 23 ++++++--------- lib/irbtools/configure.rb | 1 + lib/irbtools/implementation.rb | 17 ++++------- spec/irbtools_commands_spec.rb | 12 ++++---- 11 files changed, 112 insertions(+), 85 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b089fe..e0b0bd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/irbtools.gemspec b/irbtools.gemspec index d022324..490097e 100644 --- a/irbtools.gemspec +++ b/irbtools.gemspec @@ -20,7 +20,7 @@ Gem::Specification.new do |s| # Dependencies # Core Functionality - s.add_dependency %q, ">= 1.12.0", "< 1.15" + s.add_dependency %q, ">= 1.13.0", "< 1.15" s.add_dependency %q, "~> 2.2" s.add_dependency %q, "~> 2.1" s.add_dependency %q, "~> 2.0", ">= 2.2.1" diff --git a/lib/irbtools.rb b/lib/irbtools.rb index 9db5909..750de0a 100644 --- a/lib/irbtools.rb +++ b/lib/irbtools.rb @@ -1,5 +1,4 @@ require_relative "irbtools/configure" -require_relative "irbtools/commands" require "irb" diff --git a/lib/irbtools/commands/code.rb b/lib/irbtools/commands/code.rb index 29dc5ff..47fa6d1 100644 --- a/lib/irbtools/commands/code.rb +++ b/lib/irbtools/commands/code.rb @@ -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 diff --git a/lib/irbtools/commands/howtocall.rb b/lib/irbtools/commands/howtocall.rb index 24f4fd2..99a8fd7 100644 --- a/lib/irbtools/commands/howtocall.rb +++ b/lib/irbtools/commands/howtocall.rb @@ -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 diff --git a/lib/irbtools/commands/look.rb b/lib/irbtools/commands/look.rb index e16ae34..d3540d1 100644 --- a/lib/irbtools/commands/look.rb +++ b/lib/irbtools/commands/look.rb @@ -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 - diff --git a/lib/irbtools/commands/shadow.rb b/lib/irbtools/commands/shadow.rb index 3a28b97..178d088 100644 --- a/lib/irbtools/commands/shadow.rb +++ b/lib/irbtools/commands/shadow.rb @@ -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 diff --git a/lib/irbtools/commands/sys.rb b/lib/irbtools/commands/sys.rb index d06fcaa..bc1879d 100644 --- a/lib/irbtools/commands/sys.rb +++ b/lib/irbtools/commands/sys.rb @@ -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 diff --git a/lib/irbtools/configure.rb b/lib/irbtools/configure.rb index 2092e50..4d7b938 100644 --- a/lib/irbtools/configure.rb +++ b/lib/irbtools/configure.rb @@ -1,4 +1,5 @@ require_relative 'version' require_relative 'implementation' +require_relative "commands" require_relative 'libraries' unless Irbtools.minimal diff --git a/lib/irbtools/implementation.rb b/lib/irbtools/implementation.rb index 564eb2b..5e86c90 100644 --- a/lib/irbtools/implementation.rb +++ b/lib/irbtools/implementation.rb @@ -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 diff --git a/spec/irbtools_commands_spec.rb b/spec/irbtools_commands_spec.rb index fdaaf33..ce0dc3f 100644 --- a/spec/irbtools_commands_spec.rb +++ b/spec/irbtools_commands_spec.rb @@ -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