-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(ruby/irb#971) It's essentially a combination of pushws and popws commands that are easier to use. Help message: ``` Usage: cd ([target]|..) IRB uses a stack of workspaces to keep track of context(s), with `pushws` and `popws` commands to manipulate the stack. The `cd` command is an attempt to simplify the operation and will be subject to change. When given: - an object, cd will use that object as the new context by pushing it onto the workspace stack. - "..", cd will leave the current context by popping the top workspace off the stack. - no arguments, cd will move to the top workspace on the stack by popping off all workspaces. Examples: cd Foo cd Foo.new cd @ivar cd .. cd ``` ruby/irb@4a0e0e89b7
- Loading branch information
Showing
3 changed files
with
119 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# frozen_string_literal: true | ||
|
||
module IRB | ||
module Command | ||
class CD < Base | ||
category "Workspace" | ||
description "Move into the given object or leave the current context." | ||
|
||
help_message(<<~HELP) | ||
Usage: cd ([target]|..) | ||
IRB uses a stack of workspaces to keep track of context(s), with `pushws` and `popws` commands to manipulate the stack. | ||
The `cd` command is an attempt to simplify the operation and will be subject to change. | ||
When given: | ||
- an object, cd will use that object as the new context by pushing it onto the workspace stack. | ||
- "..", cd will leave the current context by popping the top workspace off the stack. | ||
- no arguments, cd will move to the top workspace on the stack by popping off all workspaces. | ||
Examples: | ||
cd Foo | ||
cd Foo.new | ||
cd @ivar | ||
cd .. | ||
cd | ||
HELP | ||
|
||
def execute(arg) | ||
case arg | ||
when ".." | ||
irb_context.pop_workspace | ||
when "" | ||
# TODO: decide what workspace commands should be kept, and underlying APIs should look like, | ||
# and perhaps add a new API to clear the workspace stack. | ||
prev_workspace = irb_context.pop_workspace | ||
while prev_workspace | ||
prev_workspace = irb_context.pop_workspace | ||
end | ||
else | ||
begin | ||
obj = eval(arg, irb_context.workspace.binding) | ||
irb_context.push_workspace(obj) | ||
rescue StandardError => e | ||
warn "Error: #{e}" | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
require "tempfile" | ||
require_relative "../helper" | ||
|
||
module TestIRB | ||
class CDTest < IntegrationTestCase | ||
def setup | ||
super | ||
|
||
write_ruby <<~'RUBY' | ||
class Foo | ||
class Bar | ||
def bar | ||
"this is bar" | ||
end | ||
end | ||
def foo | ||
"this is foo" | ||
end | ||
end | ||
binding.irb | ||
RUBY | ||
end | ||
|
||
def test_cd | ||
out = run_ruby_file do | ||
type "cd Foo" | ||
type "ls" | ||
type "cd Bar" | ||
type "ls" | ||
type "cd .." | ||
type "exit" | ||
end | ||
|
||
assert_match(/irb\(Foo\):002>/, out) | ||
assert_match(/Foo#methods: foo/, out) | ||
assert_match(/irb\(Foo::Bar\):004>/, out) | ||
assert_match(/Bar#methods: bar/, out) | ||
assert_match(/irb\(Foo\):006>/, out) | ||
end | ||
|
||
def test_cd_moves_top_level_with_no_args | ||
out = run_ruby_file do | ||
type "cd Foo" | ||
type "cd Bar" | ||
type "cd" | ||
type "exit" | ||
end | ||
|
||
assert_match(/irb\(Foo::Bar\):003>/, out) | ||
assert_match(/irb\(main\):004>/, out) | ||
end | ||
|
||
def test_cd_with_error | ||
out = run_ruby_file do | ||
type "cd Baz" | ||
type "exit" | ||
end | ||
|
||
assert_match(/Error: uninitialized constant Baz/, out) | ||
assert_match(/irb\(main\):002>/, out) # the context should not change | ||
end | ||
end | ||
end |