2011-05-01 06:25:37 -04:00
require " pry/default_commands/ls "
class Pry
module DefaultCommands
2011-05-07 01:32:05 -04:00
Context = Pry :: CommandSet . new do
2011-05-01 06:25:37 -04:00
import Ls
2011-09-05 12:12:53 -04:00
command " cd " , " Move into a new context (use `cd ..` to go back and `cd /` to return to Pry top-level). Complex syntax (e.g cd ../@x/y) also supported. " do | obj |
path = arg_string . split ( / \/ / )
stack = _pry_ . binding_stack . dup
# special case when we only get a single "/", return to root
stack = [ stack . first ] if path . empty?
resolve_failure = false
path . each do | context |
begin
case context . chomp
when " "
stack = [ stack . first ]
when " :: "
stack . push ( TOPLEVEL_BINDING )
when " . "
next
when " .. "
2012-01-03 23:45:24 -05:00
unless stack . size == 1
2011-09-05 12:12:53 -04:00
stack . pop
end
else
stack . push ( Pry . binding_for ( stack . last . eval ( context ) ) )
end
2011-10-31 19:34:40 -04:00
rescue RescuableException = > e
2011-11-04 08:27:59 -04:00
output . puts " Bad object path: #{ arg_string . chomp } . Failed trying to resolve: #{ context } "
2011-10-31 19:34:40 -04:00
output . puts e . inspect
2011-09-05 12:12:53 -04:00
resolve_failure = true
2011-09-26 19:30:17 -04:00
break
2011-08-21 22:48:50 -04:00
end
2011-05-01 06:25:37 -04:00
end
2011-09-05 12:12:53 -04:00
next if resolve_failure
_pry_ . binding_stack = stack
2011-05-01 06:25:37 -04:00
end
2011-08-21 22:48:50 -04:00
command " switch-to " , " Start a new sub-session on a binding in the current stack (numbered by nesting). " do | selection |
selection = selection . to_i
2011-08-22 04:56:18 -04:00
if selection < 0 || selection > _pry_ . binding_stack . size - 1
2011-10-01 19:57:39 -04:00
raise CommandError , " Invalid binding index #{ selection } - use `nesting` command to view valid indices. "
2011-08-22 04:56:18 -04:00
else
Pry . start ( _pry_ . binding_stack [ selection ] )
end
2011-08-21 22:48:50 -04:00
end
2011-05-01 06:25:37 -04:00
command " nesting " , " Show nesting information. " do
output . puts " Nesting status: "
output . puts " -- "
2011-08-21 02:22:45 -04:00
_pry_ . binding_stack . each_with_index do | obj , level |
2011-05-01 06:25:37 -04:00
if level == 0
2011-08-21 02:22:45 -04:00
output . puts " #{ level } . #{ Pry . view_clip ( obj . eval ( 'self' ) ) } (Pry top level) "
2011-05-01 06:25:37 -04:00
else
2011-08-21 02:22:45 -04:00
output . puts " #{ level } . #{ Pry . view_clip ( obj . eval ( 'self' ) ) } "
2011-05-01 06:25:37 -04:00
end
end
end
2011-08-25 05:41:43 -04:00
command " jump-to " , " Jump to a binding further up the stack, popping all bindings below. " do | break_level |
2011-05-01 06:25:37 -04:00
break_level = break_level . to_i
2011-08-21 22:48:50 -04:00
nesting_level = _pry_ . binding_stack . size - 1
2011-05-01 06:25:37 -04:00
case break_level
2011-08-21 22:48:50 -04:00
when nesting_level
output . puts " Already at nesting level #{ nesting_level } "
when ( 0 ... nesting_level )
_pry_ . binding_stack . slice! ( break_level + 1 , _pry_ . binding_stack . size )
2011-05-01 06:25:37 -04:00
else
2011-08-21 22:48:50 -04:00
max_nest_level = nesting_level - 1
2011-05-01 06:25:37 -04:00
output . puts " Invalid nest level. Must be between 0 and #{ max_nest_level } . Got #{ break_level } . "
end
end
2011-08-25 05:41:43 -04:00
command " exit-all " , " End the current Pry session (popping all bindings) and returning to caller. Accepts optional return value. Aliases: !!@ " do
2011-08-21 22:48:50 -04:00
# clear the binding stack
2011-08-22 04:56:18 -04:00
_pry_ . binding_stack . clear
2011-08-21 22:48:50 -04:00
# break out of the repl loop
2011-08-21 02:22:45 -04:00
throw ( :breakout , target . eval ( arg_string ) )
2011-05-01 06:25:37 -04:00
end
2011-09-18 02:36:39 -04:00
alias_command " !!@ " , " exit-all "
2011-05-01 06:25:37 -04:00
2011-08-25 05:41:43 -04:00
command " exit " , " Pop the current binding and return to the one immediately prior. Note this does NOT exit the program. Aliases: quit " , :keep_retval = > true do
if _pry_ . binding_stack . one?
# when breaking out of top-level then behave like `exit-all`
_pry_ . binding_stack . clear
throw ( :breakout , target . eval ( arg_string ) )
else
# otherwise just pop a binding
popped_object = _pry_ . binding_stack . pop . eval ( 'self' )
# return a user-specified value if given
if ! arg_string . empty?
target . eval ( arg_string )
else
popped_object
end
end
end
2011-09-18 02:36:39 -04:00
alias_command " quit " , " exit "
2011-08-25 05:41:43 -04:00
command " exit-program " , " End the current program. Aliases: quit-program, !!! " do
2011-08-07 05:30:08 -04:00
Pry . save_history if Pry . config . history . should_save
2011-08-29 11:22:10 -04:00
Kernel . exit target . eval ( arg_string ) . to_i
2011-05-01 06:25:37 -04:00
end
2011-09-18 02:36:39 -04:00
alias_command " quit-program " , " exit-program "
alias_command " !!! " , " exit-program "
2011-05-01 06:25:37 -04:00
2011-08-30 13:35:41 -04:00
command " !pry " , " Start a Pry session on current self; this even works mid multi-line expression. " do
2011-05-29 11:41:40 -04:00
target . pry
2011-05-01 06:25:37 -04:00
end
2011-12-06 12:34:03 -05:00
command " pry-backtrace " , " Show the backtrace for the Pry session " do
2011-11-29 07:35:45 -05:00
output . puts " \n #{ text . bold ( 'Backtrace:' ) } \n -- \n "
output . puts _pry_ . backtrace
end
2011-05-01 06:25:37 -04:00
command " whereami " , " Show the code context for the session. (whereami <n> shows <n> extra lines of code around the invocation line. Default: 5) " do | num |
file = target . eval ( '__FILE__' )
line_num = target . eval ( '__LINE__' )
if num
i_num = num . to_i
else
i_num = 5
end
2011-10-16 02:26:53 -04:00
if file != Pry . eval_path && ( file =~ / ( \ (.* \ ))|<.*> / || file == " " || file == " -e " )
2011-10-01 19:57:39 -04:00
raise CommandError , " Cannot find local context. Did you use `binding.pry`? "
2011-05-01 06:25:37 -04:00
end
set_file_and_dir_locals ( file )
2011-12-02 03:02:14 -05:00
method = Pry :: Method . from_binding ( target )
method_description = method ? " in #{ method . name_with_owner } " : " "
output . puts " \n #{ text . bold ( 'From:' ) } #{ file } @ line #{ line_num } #{ method_description } : \n \n "
2011-05-01 06:25:37 -04:00
2011-10-16 02:26:53 -04:00
if file == Pry . eval_path
f = Pry . line_buffer [ 1 .. - 1 ]
else
unless File . readable? ( file )
raise CommandError , " Cannot open #{ file . inspect } for reading. "
end
f = File . open ( file )
2011-09-10 15:52:05 -04:00
end
2011-09-06 00:32:16 -04:00
2011-05-01 06:25:37 -04:00
# This method inspired by http://rubygems.org/gems/ir_b
2011-10-16 02:26:53 -04:00
begin
f . each_with_index do | line , index |
line_n = index + 1
next unless line_n > ( line_num - i_num - 1 )
break if line_n > ( line_num + i_num )
if line_n == line_num
code = " => #{ line_n . to_s . rjust ( 3 ) } : #{ line . chomp } "
if Pry . color
code = CodeRay . scan ( code , :ruby ) . term
end
output . puts code
code
else
code = " #{ line_n . to_s . rjust ( 6 ) } : #{ line . chomp } "
if Pry . color
code = CodeRay . scan ( code , :ruby ) . term
end
output . puts code
code
2011-05-01 06:25:37 -04:00
end
end
2011-10-16 02:26:53 -04:00
ensure
f . close if f . respond_to? ( :close )
2011-05-01 06:25:37 -04:00
end
end
end
end
end