irbtools 3.0.5 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -11,27 +11,19 @@ def gemspec2
11
11
  @gemspec2 ||= eval(File.read('irbtools.gemspec'), binding, 'irbtools.gemspec')
12
12
  end
13
13
 
14
- def gemspec3
15
- @gemspec3 ||= eval(File.read('irbtools-more.gemspec'), binding, 'irbtools-more.gemspec')
16
- end
17
-
18
14
  desc "Build the gems"
19
15
  task :gem => :gemspec do
20
16
  sh "gem build #{gemspec2.name}.gemspec"
21
- sh "gem build #{gemspec3.name}.gemspec"
22
17
  FileUtils.mkdir_p 'pkg'
23
18
  FileUtils.mv "#{gemspec2.name}-#{gemspec2.version}.gem", 'pkg'
24
- FileUtils.mv "#{gemspec3.name}-#{gemspec3.version}.gem", 'pkg'
25
19
  end
26
20
 
27
21
  desc "Install the gem locally (without docs)"
28
22
  task :install => :gem do
29
23
  sh %{gem install pkg/#{gemspec2.name}-#{gemspec2.version}.gem --no-document}
30
- sh %{gem install pkg/#{gemspec3.name}-#{gemspec3.version}.gem --no-document}
31
24
  end
32
25
 
33
26
  desc "Validate the gemspec"
34
27
  task :gemspec do
35
28
  gemspec2.validate
36
- gemspec3.validate
37
29
  end
data/irbtools.gemspec CHANGED
@@ -5,59 +5,41 @@ Gem::Specification.new do |s|
5
5
  s.name = 'irbtools'
6
6
  s.version = Irbtools::VERSION
7
7
 
8
- s.homepage = 'https://irb.tools'
8
+ s.homepage = 'https://github.com/janlelis/irbtools'
9
9
  s.authors = ["Jan Lelis"]
10
10
  s.email = ["hi@ruby.consulting"]
11
11
  s.summary = 'Irbtools happy IRB.'
12
12
  s.description = "The Irbtools make working with Ruby's IRB console more fun & productive."
13
- s.files = %w[
14
- lib/irbtools.rb
15
- lib/irbtools/version.rb
16
- lib/irbtools/configure.rb
17
- lib/irbtools/implementation.rb
18
- lib/irbtools/libraries.rb
19
- lib/irbtools/non_fancy.rb
20
- lib/irbtools/hirb.rb
21
- lib/irbtools/minimal.rb
22
- lib/irbtools/binding.rb
23
- Rakefile
24
- irbtools.gemspec
25
- ]
26
- s.extra_rdoc_files = %w[
27
- README.md
28
- CONFIGURE.md
29
- CHANGELOG.md
30
- MIT-LICENSE.txt
31
- ]
13
+ s.files = Dir["{**/}{.*,*}"].select{ |path| File.file?(path) && path !~ /^pkg/ }
14
+ s.metadata = { "rubygems_mfa_required" => "true" }
32
15
  s.license = 'MIT'
33
16
 
34
- s.required_ruby_version = '>= 2.0', '< 4.0'
17
+ s.required_ruby_version = '>= 3.0', '< 4.0'
35
18
 
36
19
  # # #
37
20
  # Dependencies
38
21
 
39
22
  # Core Functionality
40
- s.add_dependency %q<irb>, ">= 0.9.6"
41
- s.add_dependency %q<every_day_irb>, "~> 2.0"
23
+ s.add_dependency %q<irb>, "~> 1.6.2"
24
+ s.add_dependency %q<every_day_irb>, "~> 2.2"
42
25
  s.add_dependency %q<fancy_irb>, "~> 1.2", ">= 1.2.1"
43
26
  s.add_dependency %q<wirb>, "~> 2.0", ">= 2.2.1"
44
27
  s.add_dependency %q<hirb>, "~> 0.7", ">= 0.7.3"
45
- s.add_dependency %q<binding.repl>, "~> 3.0"
46
28
 
47
29
  # Utils
48
30
  s.add_dependency %q<paint>, ">= 0.9", "< 3.0"
49
31
  s.add_dependency %q<clipboard>, "~> 1.3"
50
32
  s.add_dependency %q<interactive_editor>, "~> 0.0", ">= 0.0.10"
51
33
  s.add_dependency %q<coderay>, "~> 1.1"
52
- s.add_dependency %q<debugging>, "~> 1.1"
34
+ s.add_dependency %q<debugging>, "~> 2.1"
53
35
 
54
36
  # Introspection / Docs
37
+ s.add_dependency %q<looksee>, "~> 5.0"
55
38
  s.add_dependency %q<object_shadow>, "~> 1.1"
56
- s.add_dependency %q<code>, ">= 0.9.2", "< 2.0"
57
- s.add_dependency %q<ori>, "~> 0.1.0"
58
- s.add_dependency %q<methodfinder>, "~> 2.2", ">= 2.2.2"
39
+ s.add_dependency %q<code>, ">= 0.9.4", "< 2.0"
40
+ s.add_dependency %q<core_docs>, "~> 0.9.9"
41
+ s.add_dependency %q<methodfinder>, "~> 2.2", ">= 2.2.5"
59
42
  s.add_dependency %q<ruby_version>, "~> 1.0"
60
- s.add_dependency %q<ruby_engine>, "~> 1.0"
61
- s.add_dependency %q<ruby_info>, "~> 1.0"
62
- s.add_dependency %q<os>
43
+ s.add_dependency %q<ruby_engine>, "~> 2.0"
44
+ s.add_dependency %q<os>, "~> 1.1", ">= 1.1.4"
63
45
  end
@@ -3,27 +3,10 @@ begin
3
3
  rescue LoadError
4
4
  end
5
5
 
6
- if RUBY_VERSION >= "2.5.0"
7
- if defined? BindingOfCaller
8
- module Kernel
9
- private def irb
10
- binding.of_caller(1).irb
11
- end
12
- end
13
- end
14
- else
15
- require 'binding.repl'
16
- BindingRepl.auto = %w[irb ripl ir rib pry]
17
-
18
- class Binding
19
- alias irb repl!
20
- end
21
-
22
- if defined? BindingOfCaller
23
- require 'debugging/repl'
24
-
25
- module Debugging
26
- alias irb repl
6
+ if defined? BindingOfCaller
7
+ module Kernel
8
+ private def irb
9
+ binding.of_caller(1).irb
27
10
  end
28
11
  end
29
12
  end
@@ -0,0 +1,35 @@
1
+ require "irb/cmd/nop"
2
+
3
+ module IRB
4
+ module ExtendCommand
5
+ class Code < Nop
6
+ category "Introspection"
7
+ description "Shows the syntax-highlighted source code of a method"
8
+
9
+ class << self
10
+ def transform_args(args)
11
+ if args.strip =~ /\A(?:([\w:]+)([#.]))?(\w+)\z/
12
+ if $1
13
+ if $2 == "#"
14
+ "#{$1}, #{$1}.instance_method(:#{$3})"
15
+ else
16
+ "#{$1}, :#{$3}"
17
+ end
18
+ else
19
+ ":" + $3
20
+ end
21
+ else
22
+ args
23
+ end
24
+ end
25
+ end
26
+
27
+ def execute(*args)
28
+ @irb_context.workspace.binding.send(:code, *args)
29
+ rescue NameError
30
+ warn "code: Class or method not found."
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,35 @@
1
+ require "irb/cmd/nop"
2
+
3
+ module IRB
4
+ module ExtendCommand
5
+ class Howtocall < Nop
6
+ category "Introspection"
7
+ description "Displays method signatures based on Method#parameters"
8
+
9
+ class << self
10
+ def transform_args(args)
11
+ if args.strip =~ /\A(?:([\w:]+)([#.]))?(\w+)\z/
12
+ if $1
13
+ if $2 == "#"
14
+ "#{$1}, #{$1}.instance_method(:#{$3})"
15
+ else
16
+ "#{$1}, :#{$3}"
17
+ end
18
+ else
19
+ ":" + $3
20
+ end
21
+ else
22
+ args
23
+ end
24
+ end
25
+ end
26
+
27
+ def execute(*args)
28
+ @irb_context.workspace.binding.send(:howtocall, *args)
29
+ rescue NameError
30
+ warn "howtocall: Class or method not found"
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,20 @@
1
+ require "irb/cmd/nop"
2
+
3
+ module IRB
4
+ module ExtendCommand
5
+ class Look < Nop
6
+ category "Introspection"
7
+ description 'Method list and lookup path inspection based on looksee gem'
8
+
9
+ def execute(*args)
10
+ if args.empty?
11
+ @irb_context.workspace.binding.look
12
+ else
13
+ obj, *params = *args
14
+ obj.look(*params)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,20 @@
1
+ require "irb/cmd/nop"
2
+
3
+ module IRB
4
+ module ExtendCommand
5
+ class Shadow < Nop
6
+ category "Introspection"
7
+ description 'Method list and lookup path inspection based on object shadow gem'
8
+
9
+ def execute(*args)
10
+ if args.empty?
11
+ @irb_context.workspace.binding.shadow
12
+ else
13
+ obj, *params = *args
14
+ obj.shadow(*params)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,25 @@
1
+ require "irb/cmd/nop"
2
+
3
+ module IRB
4
+ module ExtendCommand
5
+ class Sys < Nop
6
+ category "Misc"
7
+ description 'Run a system command'
8
+
9
+ class << self
10
+ def transform_args(args)
11
+ if args.empty? || string_literal?(args)
12
+ args
13
+ else
14
+ args.strip.dump
15
+ end
16
+ end
17
+ end
18
+
19
+ def execute(*args)
20
+ system(*args)
21
+ end
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,5 @@
1
+ require_relative "commands/code"
2
+ require_relative "commands/howtocall"
3
+ require_relative "commands/look"
4
+ require_relative "commands/shadow"
5
+ require_relative "commands/sys"
@@ -1,4 +1,5 @@
1
1
  require_relative 'version'
2
2
 
3
3
  require_relative 'implementation'
4
+ require_relative "commands"
4
5
  require_relative 'libraries' unless Irbtools.minimal
@@ -1,7 +1,6 @@
1
1
  module Irbtools
2
2
  @libraries = { :start => [], :sub_session => [], :autoload => [], :thread => {}, :late => [], :late_thread => {} }
3
3
  @lib_hooks = Hash.new{|h,k| h[k] = [] }
4
- @packages = []
5
4
  @shell_name = File.split($0)[-1].upcase
6
5
  @welcome_message = "Welcome to #{ @shell_name }. You are using #{ RUBY_DESCRIPTION }. Have fun ;)"
7
6
  @minimal ||= false
@@ -20,9 +19,6 @@ module Irbtools
20
19
  # keys determine if lib is required, required on sub-session or autoloaded
21
20
  attr_accessor :libraries
22
21
 
23
- # an array of extension packages that get loaded (e.g. irbtools-more)
24
- attr_accessor :packages
25
-
26
22
  # add a library. the block gets executed, when the library was loaded.
27
23
  # if the second param is true, it's hooked in into IRB.conf[:IRB_RC] instead of the start.
28
24
  def add_library(lib, options = {}, &block)
@@ -83,23 +79,6 @@ module Irbtools
83
79
  @lib_hooks.delete lib
84
80
  end
85
81
 
86
- # add extensions packages
87
- def add_package(pkg)
88
- @packages << pkg.to_s
89
- end
90
-
91
- # remove extension package
92
- def remove_package(pkg)
93
- @packages.delete pkg.to_s
94
- end
95
-
96
- # actually require registered packages
97
- def load_packages
98
- @packages.each{ |pkg|
99
- require "irbtools/#{pkg}"
100
- }
101
- end
102
-
103
82
  # te be triggered when a library has loaded
104
83
  def library_loaded(lib)
105
84
  @lib_hooks[lib.to_s].each{ |hook| hook.call }
@@ -122,30 +101,62 @@ module Irbtools
122
101
  $VERBOSE, $DEBUG = remember_verbose_and_debug
123
102
  end
124
103
 
125
- # configure irb
126
104
  def configure_irb!
127
105
  if defined?(IRB)
128
106
  IRB.conf[:AUTO_INDENT] = true # simple auto indent
129
107
  IRB.conf[:EVAL_HISTORY] = 42424242424242424242 # creates the special __ variable
130
108
  IRB.conf[:SAVE_HISTORY] = 2000 # how many lines will go to ~/.irb_history
131
-
132
- # prompt
133
- (IRB.conf[:PROMPT] ||= {} ).merge!( {:IRBTOOLS => {
134
- :PROMPT_I => ">> ", # normal
135
- :PROMPT_N => "| ", # indenting
136
- :PROMPT_C => " > ", # continuing a statement
137
- :PROMPT_S => "%l> ", # continuing a string
138
- :RETURN => "=> %s \n",
139
- :AUTO_INDENT => true,
140
- }})
141
-
142
- IRB.conf[:PROMPT_MODE] = :IRBTOOLS
109
+ set_propmt
110
+ load_commands
111
+ add_command_aliases
112
+ rename_ls_to_ils
143
113
  end
144
114
  end
145
115
 
146
- # check if we are in a RIPL session
147
- def ripl?
148
- defined?(Ripl) && Ripl.started?
116
+ def set_propmt
117
+ (IRB.conf[:PROMPT] ||= {} ).merge!( {:IRBTOOLS => {
118
+ :PROMPT_I => ">> ", # normal
119
+ :PROMPT_N => "| ", # indenting
120
+ :PROMPT_C => " > ", # continuing a statement
121
+ :PROMPT_S => "%l> ", # continuing a string
122
+ :RETURN => "=> %s \n",
123
+ :AUTO_INDENT => true,
124
+ }})
125
+
126
+ IRB.conf[:PROMPT_MODE] = :IRBTOOLS
127
+ end
128
+
129
+ def load_commands
130
+ ec = IRB::ExtendCommandBundle.instance_variable_get(:@EXTEND_COMMANDS)
131
+
132
+ [
133
+ [:code, :Code, nil, [:code, IRB::ExtendCommandBundle::OVERRIDE_ALL]],
134
+ [:howtocall, :Howtocall, nil, [:howtocall, IRB::ExtendCommandBundle::OVERRIDE_ALL]],
135
+ [:look, :Look, nil, [:look, IRB::ExtendCommandBundle::OVERRIDE_ALL]],
136
+ [:shadow, :Shadow, nil, [:shadow, IRB::ExtendCommandBundle::OVERRIDE_ALL]],
137
+ [:sys, :Sys, nil, [:sys, IRB::ExtendCommandBundle::OVERRIDE_ALL]],
138
+ ].each{ |ecconfig|
139
+ ec.push(ecconfig)
140
+ IRB::ExtendCommandBundle.def_extend_command(*ecconfig)
141
+ }
142
+ end
143
+
144
+ def add_command_aliases
145
+ IRB.conf[:COMMAND_ALIASES] = (IRB.conf[:COMMAND_ALIASES] || {}).merge({
146
+ :ri => :show_doc,
147
+ :co => :chws,
148
+ :'$' => :sys,
149
+ :'+' => :shadow,
150
+ })
151
+ end
152
+
153
+ # prevent clash between IRB's ls and FileUtil's ls
154
+ def rename_ls_to_ils
155
+ if aliases = IRB::ExtendCommandBundle.instance_variable_get(:@ALIASES)
156
+ if irb_ls = aliases.find{|a,*| a == :ls}
157
+ irb_ls[0] = :ils
158
+ end
159
+ end
149
160
  end
150
161
 
151
162
  # loads all the stuff
@@ -21,14 +21,11 @@ Irbtools.add_library 'wirb/wp', thread: :paint do
21
21
  Wirb.start
22
22
  end
23
23
 
24
- unless Irbtools.ripl?
25
- Irbtools.add_library :fancy_irb, thread: :paint do
26
- FancyIrb.start
27
- end
24
+ Irbtools.add_library :fancy_irb, thread: :paint do
25
+ FancyIrb.start
28
26
  end
29
27
 
30
28
  Irbtools.add_library 'debugging/q', thread: :paint
31
- Irbtools.add_library 'debugging/mof', thread: :paint
32
29
  Irbtools.add_library 'debugging/re', thread: :paint
33
30
  Irbtools.add_library 'debugging/beep', thread: :paint
34
31
  Irbtools.add_library 'debugging/howtocall', thread: :paint
@@ -39,41 +36,23 @@ Irbtools.add_library 'object_shadow', thread: :paint do
39
36
  ObjectShadow.include(ObjectShadow::DeepInspect)
40
37
  end
41
38
 
42
- Irbtools.add_library 'readline', thread: :ori
43
- Irbtools.add_library 'ori', thread: :ori do
44
- # TODO Readline history can be empty (issue)
45
- module ORI::Internals
46
- def self.get_ri_arg_prefix(cmd)
47
- if cmd && (mat = cmd.match /\A(\s*.+?\.ri)\s+\S/)
48
- mat[1]
49
- end
50
- end
51
- end
39
+ Irbtools.add_library 'readline', thread: :readline
40
+ Irbtools.add_library 'os', thread: :os
41
+ Irbtools.add_library 'ruby_engine', thread: :re
42
+ Irbtools.add_library 'ruby_version', thread: :rv
52
43
 
53
- class Object
54
- # patch ori to also allow shell-like "Array#slice" syntax
55
- def ri(*args)
56
- if args[0] &&
57
- self == TOPLEVEL_BINDING.eval('self') &&
58
- args[0] =~ /\A(.*)(?:#|\.)(.*)\Z/
59
- begin
60
- klass = Object.const_get $1
61
- klass.ri $2
62
- rescue
63
- super
64
- end
65
- else
66
- super
67
- end
44
+ begin
45
+ # Object#l method for inspecting its lookup path
46
+ Irbtools.add_library 'looksee', thread: :ls do
47
+ Looksee.rename :lp
48
+ class Object
49
+ alias look lp
68
50
  end
69
51
  end
52
+ rescue LoadError
53
+ # do not load if not supported
70
54
  end
71
55
 
72
- Irbtools.add_library 'ruby_info', thread: :ri
73
- Irbtools.add_library 'os', thread: :os
74
- Irbtools.add_library 'ruby_engine', thread: :re
75
- Irbtools.add_library 'ruby_version', thread: :rv
76
-
77
56
  # # # load via autoload
78
57
 
79
58
  Irbtools.add_library 'code', :autoload => :Code do
@@ -105,12 +84,6 @@ Irbtools.add_library :clipboard, :autoload => :Clipboard do
105
84
  Clipboard.paste
106
85
  end
107
86
 
108
- # copies everything you have entered in this irb session
109
- def copy_input
110
- copy session_history
111
- "The session input history has been copied to the clipboard."
112
- end
113
-
114
87
  # copies the output of all irb commands in this irb session
115
88
  def copy_output
116
89
  copy context.instance_variable_get(:@eval_history_values).inspect.gsub(/^\d+ (.*)/, '\1')
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Irbtools
4
- VERSION = "3.0.5"
4
+ VERSION = "4.0.1"
5
5
  end
data/lib/irbtools.rb CHANGED
@@ -1,13 +1,5 @@
1
1
  require_relative 'irbtools/configure'
2
-
3
- # # # # #
4
- # Make sure we load IRB if we are not in RIPL
5
-
6
- require 'irb' unless Irbtools.ripl?
7
-
8
- # # # # #
9
- # Load irbtools extension packages
10
- Irbtools.load_packages
2
+ require 'irb'
11
3
 
12
4
  # # # # #
13
5
  # Load: start
@@ -27,19 +19,11 @@ Irbtools.configure_irb!
27
19
 
28
20
  # # # # #
29
21
  # Load: sub-session / after_rc
30
- if Irbtools.ripl?
31
- if defined? Ripl::AfterRc
32
- Irbtools.libraries[:sub_session].each{ |r| Ripl.after_rcs << r }
33
- elsif !Irbtools.libraries[:sub_session].empty?
34
- warn "Couldn't load libraries in Irbtools.libraries[:sub_session]. Please install ripl-after_rc to use this feature in Ripl!"
35
- end
36
- else
37
- original_irbrc_proc = IRB.conf[:IRB_RC]
38
- IRB.conf[:IRB_RC] = proc{
39
- Irbtools.load_libraries(Irbtools.libraries[:sub_session])
40
- original_irbrc_proc.call if original_irbrc_proc
41
- }
42
- end
22
+ original_irbrc_proc = IRB.conf[:IRB_RC]
23
+ IRB.conf[:IRB_RC] = proc{
24
+ Irbtools.load_libraries(Irbtools.libraries[:sub_session])
25
+ original_irbrc_proc.call if original_irbrc_proc
26
+ }
43
27
 
44
28
  # # # # #
45
29
  # Load: threads
@@ -0,0 +1,17 @@
1
+ require "irbtools/commands"
2
+
3
+ describe "irbtools commands" do
4
+ describe "[introspection]" do
5
+ describe "howtocall / code" do
6
+ it "support ri Syntax like String.name or String#gsub" do
7
+ expect(
8
+ IRB::ExtendCommand::Howtocall.transform_args("String.name")
9
+ ).to eq "String, :name"
10
+
11
+ expect(
12
+ IRB::ExtendCommand::Code.transform_args("String#gsub")
13
+ ).to eq "String, String.instance_method(:gsub)"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,81 @@
1
+ require "irbtools"
2
+
3
+ describe "irbtools extra methods" do
4
+ describe "[introspection]" do
5
+ describe "code()" do
6
+ it "delegates to Code.for() to show the method's source code" do
7
+ allow(Code).to receive(:for)
8
+ code "require"
9
+ expect(Code).to have_received(:for)
10
+ end
11
+ end
12
+
13
+ describe "mf()" do
14
+ it "returns the MethodFinder class object when no arguments given" do
15
+ expect(mf).to equal(MethodFinder)
16
+ end
17
+
18
+ it "delegates to MethodFinder.find() when arguments given" do
19
+ allow(MethodFinder).to receive(:find)
20
+ mf("bla")
21
+ expect(MethodFinder).to have_received(:find)
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "[utils]" do
27
+ describe "page()" do
28
+ it "will page long content" do
29
+ allow(Hirb::Pager).to receive(:command_pager)
30
+ page "idiosyncratic"
31
+ expect(Hirb::Pager).to have_received(:command_pager)
32
+ end
33
+ end
34
+
35
+ describe "colorize()" do
36
+ it "delegate to CodeRay.scan to syntax highlight given string" do
37
+ allow(CodeRay).to receive(:scan).and_return(CodeRay::TokensProxy.new("", :ruby))
38
+ colorize "def hello() end"
39
+ expect(CodeRay).to have_received(:scan)
40
+ end
41
+ end
42
+
43
+ describe "ray()" do
44
+ it "delegate to CodeRay.scan to syntax highlight given file" do
45
+ allow(CodeRay).to receive(:scan).and_return(CodeRay::TokensProxy.new("", :ruby))
46
+ allow(File).to receive(:read).and_return("stuff")
47
+ ray "/tmp/something"
48
+ expect(File).to have_received(:read)
49
+ expect(CodeRay).to have_received(:scan)
50
+ end
51
+ end
52
+
53
+ describe "copy()" do
54
+ it "delegate to Clipboard.copy to copy string to clipboard" do
55
+ allow(Clipboard).to receive(:copy)
56
+ copy "idiosyncratic"
57
+ expect(Clipboard).to have_received(:copy)
58
+ end
59
+ end
60
+
61
+ describe "paste()" do
62
+ it "delegate to Clipboard.paste to paste clipboard contents" do
63
+ allow(Clipboard).to receive(:paste)
64
+ paste
65
+ expect(Clipboard).to have_received(:paste)
66
+ end
67
+ end
68
+
69
+ describe "copy_input()" do
70
+ it "Copies everything you have entered in this IRB session to the clipboard" do
71
+ # pending
72
+ end
73
+ end
74
+
75
+ describe "copy_output()" do
76
+ it "Copies the output of all IRB commands from the current IRB session to the clipboard" do
77
+ # pending
78
+ end
79
+ end
80
+ end
81
+ end