2011-05-01 10:25:37 +00:00
class Pry
module DefaultCommands
2011-05-07 05:32:05 +00:00
Input = Pry :: CommandSet . new do
2011-05-01 10:25:37 +00:00
2011-07-26 09:42:44 +00:00
command " ! " , " Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop. " , :use_prefix = > false do
2011-05-01 10:25:37 +00:00
output . puts " Input buffer cleared! "
2011-05-31 08:45:42 +00:00
eval_string . replace ( " " )
2011-05-01 10:25:37 +00:00
end
2011-06-16 13:49:31 +00:00
command " show-input " , " Show the contents of the input buffer for the current multi-line expression. " do
render_output ( false , 1 , Pry . color ? CodeRay . scan ( eval_string , :ruby ) . term : eval_string )
2011-05-27 16:18:34 +00:00
end
2011-09-08 05:17:01 +00:00
command ( / amend-line(?: (-? \ d+)(?: \ . \ .(-? \ d+))?)? / , " Amend a line of input in multi-line mode. Type `amend-line --help` for more information. Aliases % " ,
2011-06-13 11:17:59 +00:00
:interpolate = > false , :listing = > " amend-line " ) do | * args |
start_line_number , end_line_number , replacement_line = * args
opts = Slop . parse! ( args . compact ) do | opt |
2011-09-10 20:22:47 +00:00
opt . banner unindent <<-USAGE
Amend a line of input in multi - line mode . ` amend-line N ` , where the N in ` amend-line N ` represents line to replace .
Can also specify a range of lines using ` amend-line N..M ` syntax . Passing '!' as replacement content deletes the line ( s ) instead . Aliases : % N
e . g amend - line 1 puts 'hello world! # replace line 1'
e . g amend - line 1 .. 4 ! # delete lines 1..4
e . g amend - line 3 > puts 'goodbye' # insert before line 3
e . g amend - line puts 'hello again' # no line number modifies immediately preceding line
USAGE
2011-06-15 13:37:06 +00:00
2011-06-13 11:17:59 +00:00
opt . on :h , :help , " This message. " do
output . puts opt
end
end
next if opts . h?
next output . puts " No input to amend. " if eval_string . empty?
2011-05-05 10:06:56 +00:00
replacement_line = " " if ! replacement_line
2011-05-27 16:18:34 +00:00
input_array = eval_string . each_line . to_a
2011-06-13 11:17:59 +00:00
2011-06-12 06:14:23 +00:00
end_line_number = start_line_number . to_i if ! end_line_number
2011-06-16 13:49:31 +00:00
line_range = start_line_number ? ( one_index_number ( start_line_number . to_i ) .. one_index_number ( end_line_number . to_i ) ) : input_array . size - 1
2011-06-12 06:14:23 +00:00
# delete selected lines if replacement line is '!'
if arg_string == " ! "
input_array . slice! ( line_range )
2011-06-15 13:37:06 +00:00
elsif arg_string . start_with? ( " > " )
insert_slot = Array ( line_range ) . first
input_array . insert ( insert_slot , arg_string [ 1 .. - 1 ] + " \n " )
2011-06-12 06:14:23 +00:00
else
input_array [ line_range ] = arg_string + " \n "
end
2011-05-27 16:18:34 +00:00
eval_string . replace input_array . join
2011-06-15 13:37:06 +00:00
run " show-input "
2011-05-05 10:06:56 +00:00
end
2011-09-18 06:36:39 +00:00
alias_command ( / %.?(-? \ d+)?(?: \ . \ .(-? \ d+))? / , / amend-line(?: (-? \ d+)(?: \ . \ .(-? \ d+))?)? / )
2011-05-05 10:06:56 +00:00
2011-09-06 11:55:41 +00:00
command " play " , " Play back a string variable or a method or a file as input. Type `play --help` for more information. " do | * args |
2011-06-12 13:07:31 +00:00
opts = Slop . parse! ( args ) do | opt |
2011-09-10 20:22:47 +00:00
opt . banner unindent <<-USAGE
Usage : play [ OPTIONS ] [ - - help ]
Default action ( no options ) is to play the provided string variable
e . g ` play _in_[20] --lines 1..3 `
e . g ` play -m Pry # repl --lines 1..-1 `
e . g ` play -f Rakefile --lines 5 `
USAGE
2011-06-12 13:07:31 +00:00
opt . on :l , :lines , 'The line (or range of lines) to replay.' , true , :as = > Range
opt . on :m , :method , 'Play a method.' , true
2011-07-26 17:09:21 +00:00
opt . on :f , " file " , 'The file to replay in context.' , true
2011-06-14 11:08:09 +00:00
opt . on :o , " open " , 'When used with the -m switch, it plays the entire method except the last line, leaving the method definition "open". `amend-line` can then be used to modify the method.'
2011-06-12 13:07:31 +00:00
opt . on :h , :help , " This message. " do
output . puts opt
end
end
if opts . m?
meth_name = opts [ :m ]
2011-09-25 06:53:08 +00:00
meth = get_method_or_print_error ( meth_name , target , { } , :omit_help )
next unless meth and meth . source
2011-06-12 13:07:31 +00:00
2011-06-16 13:49:31 +00:00
range = opts . l? ? one_index_range_or_number ( opts [ :l ] ) : ( 0 .. - 1 )
2011-06-14 11:08:09 +00:00
range = ( 0 .. - 2 ) if opts . o?
2011-06-12 13:07:31 +00:00
2011-09-25 05:13:01 +00:00
eval_string << Array ( meth . source . each_line . to_a [ range ] ) . join
2011-09-06 11:55:41 +00:00
elsif opts . f?
2011-06-14 11:08:09 +00:00
file_name = File . expand_path ( opts [ :f ] )
next output . puts " No such file: #{ opts [ :f ] } " if ! File . exists? ( file_name )
text_array = File . readlines ( file_name )
2011-06-16 13:49:31 +00:00
range = opts . l? ? one_index_range_or_number ( opts [ :l ] ) : ( 0 .. - 1 )
2011-06-14 11:08:09 +00:00
range = ( 0 .. - 2 ) if opts . o?
2011-06-12 13:07:31 +00:00
2011-09-19 05:44:47 +00:00
_pry_ . input_stack << _pry_ . input
2011-08-16 01:02:32 +00:00
_pry_ . input = StringIO . new ( Array ( text_array [ range ] ) . join )
2011-09-06 11:55:41 +00:00
else
2011-09-07 06:59:34 +00:00
next output . puts " Error: no input to play command " if ! args . first
2011-09-06 11:55:41 +00:00
code = target . eval ( args . first )
range = opts . l? ? one_index_range_or_number ( opts [ :l ] ) : ( 0 .. - 1 )
range = ( 0 .. - 2 ) if opts . o?
eval_string << Array ( code . each_line . to_a [ range ] ) . join
2011-06-12 13:07:31 +00:00
end
2011-09-17 12:43:08 +00:00
run " show-input " if ! _pry_ . valid_expression? ( eval_string )
2011-06-12 13:07:31 +00:00
end
2011-05-05 10:06:56 +00:00
2011-07-26 10:12:23 +00:00
command " hist " , " Show and replay Readline history. Type `hist --help` for more info. Aliases: history " do | * args |
2011-07-24 23:20:32 +00:00
# exclude the current command from history.
2011-09-05 08:46:16 +00:00
history = Pry . history . to_a [ 0 .. - 2 ]
2011-06-14 15:05:56 +00:00
opts = Slop . parse! ( args ) do | opt |
opt . banner " Usage: hist [--replay START..END] [--clear] [--grep PATTERN] [--head N] [--tail N] [--help] [--save [START..END] file.txt] \n "
2011-05-01 10:25:37 +00:00
2011-09-13 04:09:15 +00:00
opt . on :n , 'no-numbers' , 'Omit line numbers.'
2011-05-05 10:06:56 +00:00
2011-09-13 04:09:15 +00:00
opt . on :g , :grep , 'A pattern to match against the history.' , true
2011-05-10 12:21:17 +00:00
2011-09-13 04:09:15 +00:00
opt . on :head , 'Display the first N items of history.' ,
:optional = > true ,
:as = > Integer
2011-05-01 10:25:37 +00:00
2011-09-13 04:09:15 +00:00
opt . on :t , :tail , 'Display the last N items of history.' ,
2011-06-14 11:08:09 +00:00
:optional = > true ,
2011-09-13 04:09:15 +00:00
:as = > Integer
2011-06-14 11:08:09 +00:00
2011-09-13 04:09:15 +00:00
opt . on :s , :show , 'Show the history corresponding to the history line (or range of lines).' ,
:optional = > true ,
:as = > Range
2011-05-15 10:17:45 +00:00
2011-09-13 04:09:15 +00:00
opt . on :e , :exclude , 'Exclude pry commands from the history.'
2011-05-15 10:17:45 +00:00
2011-09-13 04:09:15 +00:00
opt . on :r , :replay , 'The line (or range of lines) to replay.' , true ,
:as = > Range
2011-06-05 23:07:08 +00:00
2011-09-13 04:09:15 +00:00
opt . on " save " , " Save history to a file. --save [start..end] output.txt. Pry commands are excluded from saved history. " , true ,
:as = > Range
2011-05-15 10:17:45 +00:00
2011-09-13 04:09:15 +00:00
opt . on :c , :clear , 'Clear the history.' , :unless = > :grep
2011-06-14 11:08:09 +00:00
2011-09-13 04:09:15 +00:00
opt . on :h , :help , 'Show this message.' , :tail = > true , :unless = > :grep do
output . puts opt . help
2011-05-29 15:42:36 +00:00
end
2011-09-13 04:09:15 +00:00
end
next if opts . help?
if opts . grep?
pattern = Regexp . new ( arg_string . strip . split ( / / , 2 ) . last . strip )
history . pop
2011-05-29 15:42:36 +00:00
2011-09-13 04:09:15 +00:00
history . map! . with_index do | element , index |
if element =~ pattern
if opts . n?
element
else
2011-06-05 23:07:08 +00:00
" #{ text . blue index } : #{ element } "
2011-05-09 06:07:04 +00:00
end
end
end
2011-09-13 04:09:15 +00:00
stagger_output history . compact . join " \n "
next
end
if opts . head?
limit = opts [ 'head' ] || 10
list = history . first limit
lines = list . join ( " \n " )
if opts . n?
stagger_output lines
else
stagger_output text . with_line_numbers ( lines , 0 )
2011-05-04 18:46:49 +00:00
end
2011-09-13 04:09:15 +00:00
next
end
2011-05-04 18:46:49 +00:00
2011-09-13 04:09:15 +00:00
if opts . tail?
limit = opts [ 'tail' ] || 10
offset = history . size - limit
offset = offset < 0 ? 0 : offset
2011-06-14 15:05:56 +00:00
2011-09-13 04:09:15 +00:00
list = history . last limit
lines = list . join ( " \n " )
if opts . n?
stagger_output lines
else
stagger_output text . with_line_numbers ( lines , offset )
2011-05-04 18:46:49 +00:00
end
2011-09-13 04:09:15 +00:00
next
end
2011-05-04 18:46:49 +00:00
2011-09-13 04:09:15 +00:00
if opts . show?
range = opts [ 'show' ]
start_line = range . is_a? ( Range ) ? range . first : range
lines = Array ( history [ range ] ) . join ( " \n " )
if opts . n?
stagger_output lines
else
stagger_output text . with_line_numbers ( lines , start_line )
2011-05-01 10:25:37 +00:00
end
2011-09-13 04:09:15 +00:00
next
end
2011-05-01 10:25:37 +00:00
2011-09-13 04:09:15 +00:00
if opts . exclude?
history . map! . with_index do | element , index |
unless command_processor . valid_command? element
if opts . n?
element
else
" #{ text . blue index } : #{ element } "
end
end
2011-05-04 17:55:34 +00:00
end
2011-09-13 04:09:15 +00:00
stagger_output history . compact . join " \n "
next
end
if opts . replay?
range = opts [ 'replay' ]
actions = Array ( history [ range ] ) . join ( " \n " ) + " \n "
2011-09-19 05:44:47 +00:00
_pry_ . input_stack << _pry_ . input
2011-09-13 04:09:15 +00:00
_pry_ . input = StringIO . new ( actions )
next
end
if opts . clear?
Pry . history . clear
output . puts 'History cleared.'
next
2011-05-01 10:25:37 +00:00
end
2011-06-14 15:05:56 +00:00
# FIXME: hack to save history (this must be refactored)
if opts [ " save " ]
file_name = nil
hist_array = nil
case opts [ " save " ]
when Range
hist_array = Array ( history [ opts [ " save " ] ] )
next output . puts " Must provide a file name. " if ! args . first
file_name = File . expand_path ( args . first )
when String
hist_array = history
file_name = File . expand_path ( opts [ " save " ] )
end
output . puts " Saving history in #{ file_name } ... "
# exclude pry commands
hist_array . reject! do | element |
command_processor . valid_command? ( element )
end
File . open ( file_name , 'w' ) do | f |
f . write hist_array . join ( " \n " )
end
output . puts " ... history saved. "
2011-09-13 04:09:15 +00:00
next
2011-06-14 15:05:56 +00:00
end
2011-09-13 04:09:15 +00:00
lines = history . join ( " \n " )
if opts . n?
stagger_output lines
else
stagger_output text . with_line_numbers ( lines , 0 )
end
2011-05-01 10:25:37 +00:00
end
2011-06-16 13:49:31 +00:00
2011-09-18 06:36:39 +00:00
alias_command " history " , " hist "
2011-06-16 13:49:31 +00:00
helpers do
def one_index_number ( line_number )
if line_number > 0
line_number - 1
elsif line_number < 0
line_number
else
line_number
end
end
def one_index_range ( range )
Range . new ( one_index_number ( range . begin ) , one_index_number ( range . end ) )
end
def one_index_range_or_number ( range_or_number )
case range_or_number
when Range
one_index_range ( range_or_number )
else
one_index_number ( range_or_number )
end
end
end
2011-05-01 10:25:37 +00:00
end
end
end