Created
June 14, 2012 12:14
-
-
Save kyrylo/2929943 to your computer and use it in GitHub Desktop.
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
class Pry | |
module DefaultCommands | |
Cd = Pry::CommandSet.new do | |
create_command "cd" do | |
group "Context" | |
description "Move into a new context (object or scope)." | |
banner <<-BANNER | |
Usage: cd [OPTIONS] [--help] | |
Move into new context (object or scope). As in unix shells use | |
`cd ..` to go back, `cd /` to return to Pry top-level and `cd -` | |
to toggle between last two scopes). | |
Complex syntax (e.g cd ../@x/y) also supported. | |
e.g: `cd @x` | |
e.g: `cd .. | |
e.g: `cd /` | |
e.g: `cd -` | |
https://github.com/pry/pry/wiki/State-navigation#wiki-Changing_scope | |
BANNER | |
command_options :old_binding => nil, :append_binding => true | |
def process | |
# Extract command arguments. Delete blank arguments like " ", but | |
# don't delete empty string like "". | |
path = arg_string.split(/\//).delete_if { |a| a =~ /\A\s+\z/ } | |
stack = _pry_.binding_stack.dup | |
# Save previous command option values for the sake of restoring them | |
# them later (for example, when an exception raised). | |
old_binding = command_options[:old_binding] | |
append_binding = command_options[:append_binding] | |
# Special case when we only get a single "/", return to root. | |
if path.empty? | |
set_toggle_options(stack.last, true) if old_binding | |
stack = [stack.first] | |
end | |
path.each do |context| | |
begin | |
case context.chomp | |
when "" | |
set_toggle_options(stack.last, true) | |
stack = [stack.first] | |
when "::" | |
set_toggle_options(stack.last, false) | |
stack.push(TOPLEVEL_BINDING) | |
when "." | |
next | |
when ".." | |
unless stack.size == 1 | |
set_toggle_options(stack.pop, true) | |
end | |
when "-" | |
if old_binding | |
toggle_old_binding(stack, old_binding, append_binding) | |
end | |
else | |
set_toggle_options(stack.last, false) | |
stack.push(Pry.binding_for(stack.last.eval(context))) | |
end | |
rescue RescuableException => e | |
# Restore previous values. | |
command_options[:old_binding] = old_binding | |
command_options[:append_binding] = append_binding | |
output.puts "Bad object path: #{arg_string.chomp}. Failed trying to resolve: #{context}" | |
output.puts e.inspect | |
return | |
end | |
end | |
_pry_.binding_stack = stack | |
end | |
private | |
# Toggle old binding value by either appending it to the current stack | |
# (when `append_binding` is `true`) or setting the new one (when | |
# `append_binding` is `false`). | |
# | |
# @param [Array<Binding>] The current stack of bindings. | |
# @param [Binding] The old binding. | |
# @param [Boolean] The append_binding flag. | |
# | |
# @return [Binding] The new old binding. | |
def toggle_old_binding(stack, old_binding, append_binding) | |
if append_binding | |
stack.push(old_binding) | |
old_binding = stack[-2] | |
else | |
old_binding = stack.pop | |
end | |
append_binding = !append_binding | |
set_toggle_options(old_binding, append_binding) | |
old_binding | |
end | |
# Set new values for command_options (`:old_binding` and | |
# `:append_binding`). | |
# | |
# @param [Binding] The old binding. | |
# @param [Boolean] The append_binding flag. | |
# | |
# @return [void] | |
def set_toggle_options(old_binding, append_binding) | |
command_options[:old_binding] = old_binding | |
command_options[:append_binding] = append_binding | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment