зеркало из https://github.com/github/ruby.git
[ruby/irb] Introduce cd command
(https://github.com/ruby/irb/pull/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 ``` https://github.com/ruby/irb/commit/4a0e0e89b7
This commit is contained in:
Родитель
f4b313f733
Коммит
7fe5f0a1d0
|
@ -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
|
|
@ -5,6 +5,7 @@ require_relative "command/internal_helpers"
|
|||
require_relative "command/backtrace"
|
||||
require_relative "command/break"
|
||||
require_relative "command/catch"
|
||||
require_relative "command/cd"
|
||||
require_relative "command/chws"
|
||||
require_relative "command/context"
|
||||
require_relative "command/continue"
|
||||
|
@ -240,6 +241,8 @@ module IRB
|
|||
_register_with_aliases(:irb_disable_irb, Command::DisableIrb,
|
||||
[:disable_irb, NO_OVERRIDE]
|
||||
)
|
||||
|
||||
register(:cd, Command::CD)
|
||||
end
|
||||
|
||||
ExtendCommand = Command
|
||||
|
|
|
@ -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
|
Загрузка…
Ссылка в новой задаче