Skip to content

Commit 19b6c20

Browse files
committed
Implement ls command
1 parent 209f53c commit 19b6c20

File tree

4 files changed

+84
-7
lines changed

4 files changed

+84
-7
lines changed

lib/irb/cmd/ls.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# frozen_string_literal: true
2+
3+
require_relative "nop"
4+
require_relative "../color"
5+
6+
# :stopdoc:
7+
module IRB
8+
module ExtendCommand
9+
class Ls < Nop
10+
def execute(*arg, grep: nil)
11+
o = Output.new(grep: grep)
12+
13+
obj = arg.empty? ? irb_context.workspace.main : arg.first
14+
locals = arg.empty? ? irb_context.workspace.binding.local_variables : []
15+
klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
16+
17+
o.dump("constants", obj.constants) if obj.respond_to?(:constants)
18+
o.dump("#{klass}.methods", obj.singleton_methods(false))
19+
o.dump("#{klass}#methods", klass.public_instance_methods(false))
20+
o.dump("instance variables", obj.instance_variables)
21+
o.dump("class variables", klass.class_variables)
22+
o.dump("locals", locals)
23+
end
24+
25+
class Output
26+
def initialize(grep: nil)
27+
@grep = grep
28+
end
29+
30+
def dump(name, strs)
31+
strs = strs.grep(@grep) if @grep
32+
strs = strs.sort
33+
return if strs.empty?
34+
35+
print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
36+
if strs.size > 7
37+
len = [strs.map(&:length).max, 16].min
38+
puts; strs.each_slice(7) { |ss| puts " #{ss.map { |s| "%-#{len}s" % s }.join(" ")}" }
39+
else
40+
puts strs.join(" ")
41+
end
42+
end
43+
end
44+
private_constant :Output
45+
end
46+
end
47+
end
48+
# :startdoc:

lib/irb/cmd/nop.rb

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@ module IRB
1414
module ExtendCommand
1515
class Nop
1616

17-
18-
def self.execute(conf, *opts, &block)
19-
command = new(conf)
20-
command.execute(*opts, &block)
17+
if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
18+
def self.execute(conf, *opts, **kwargs, &block)
19+
command = new(conf)
20+
command.execute(*opts, **kwargs, &block)
21+
end
22+
else
23+
def self.execute(conf, *opts, &block)
24+
command = new(conf)
25+
command.execute(*opts, &block)
26+
end
2127
end
2228

2329
def initialize(conf)

lib/irb/extend-command.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ def irb_context
125125
:irb_info, :Info, "irb/cmd/info"
126126
],
127127

128+
[
129+
:irb_ls, :Ls, "irb/cmd/ls",
130+
[:ls, NO_OVERRIDE],
131+
],
132+
128133
[
129134
:irb_measure, :Measure, "irb/cmd/measure",
130135
[:measure, NO_OVERRIDE],
@@ -169,12 +174,13 @@ def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases)
169174
end
170175

171176
if load_file
177+
kwargs = ", **kwargs" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
172178
line = __LINE__; eval %[
173-
def #{cmd_name}(*opts, &b)
179+
def #{cmd_name}(*opts#{kwargs}, &b)
174180
require "#{load_file}"
175181
arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
176182
args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
177-
args << "*opts" if arity < 0
183+
args << "*opts#{kwargs}" if arity < 0
178184
args << "&block"
179185
args = args.join(", ")
180186
line = __LINE__; eval %[
@@ -185,7 +191,7 @@ def self.#{cmd_name}_(\#{args})
185191
end
186192
end
187193
], nil, __FILE__, line
188-
__send__ :#{cmd_name}_, *opts, &b
194+
__send__ :#{cmd_name}_, *opts#{kwargs}, &b
189195
end
190196
], nil, __FILE__, line
191197
else

test/irb/test_cmd.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,5 +372,22 @@ def test_irb_load
372372
/=> "bug17564"\n/,
373373
], out)
374374
end
375+
376+
def test_ls
377+
IRB.init_config(nil)
378+
workspace = IRB::WorkSpace.new(self)
379+
irb = IRB::Irb.new(workspace)
380+
IRB.conf[:MAIN_CONTEXT] = irb.context
381+
input = TestInputMethod.new([
382+
"ls Object.new.tap { |o| o.instance_variable_set(:@a, 1) }\n",
383+
])
384+
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
385+
irb.context.return_format = "=> %s\n"
386+
out, err = capture_output do
387+
irb.eval_input
388+
end
389+
assert_empty err
390+
assert_match(/^instance variables: @a\n/, out)
391+
end
375392
end
376393
end

0 commit comments

Comments
 (0)