2011-01-12 01:16:04 +00:00
|
|
|
direc = File.dirname(__FILE__)
|
|
|
|
require "#{direc}/command_base"
|
2011-02-16 16:27:55 +00:00
|
|
|
require "optparse"
|
2011-01-11 00:01:48 +00:00
|
|
|
|
2011-01-12 01:16:04 +00:00
|
|
|
class Pry
|
2011-01-18 03:40:28 +00:00
|
|
|
|
2010-12-30 15:01:11 +00:00
|
|
|
# Default commands used by Pry.
|
2011-01-12 01:16:04 +00:00
|
|
|
class Commands < CommandBase
|
2011-02-14 09:48:19 +00:00
|
|
|
|
|
|
|
# We make this a lambda to avoid documenting it
|
|
|
|
meth_name_from_binding = lambda do |b|
|
|
|
|
meth_name = b.eval('__method__')
|
|
|
|
if [nil, :__binding__, :__binding_impl__].include?(meth_name)
|
|
|
|
nil
|
|
|
|
else
|
|
|
|
meth_name
|
|
|
|
end
|
|
|
|
end
|
2010-12-26 13:39:46 +00:00
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do
|
2011-02-13 15:49:53 +00:00
|
|
|
output.puts "Input buffer cleared!"
|
2011-01-17 14:38:09 +00:00
|
|
|
opts[:eval_string].clear
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-01-17 14:38:09 +00:00
|
|
|
command "!pry", "Start a Pry session on current self; this even works mid-expression." do
|
2011-01-20 14:41:41 +00:00
|
|
|
Pry.start(target)
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
2011-01-10 13:54:17 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "exit-program", "End the current program. Aliases: quit-program" do
|
2011-01-17 14:38:09 +00:00
|
|
|
exit
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
alias_command "quit-program", "exit-program", ""
|
|
|
|
|
2011-01-17 14:38:09 +00:00
|
|
|
command "nesting", "Show nesting information." do
|
|
|
|
nesting = opts[:nesting]
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "Nesting status:"
|
|
|
|
output.puts "--"
|
2011-01-17 14:38:09 +00:00
|
|
|
nesting.each do |level, obj|
|
|
|
|
if level == 0
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "#{level}. #{Pry.view_clip(obj)} (Pry top level)"
|
2011-01-17 14:38:09 +00:00
|
|
|
else
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "#{level}. #{Pry.view_clip(obj)}"
|
2010-12-26 13:39:46 +00:00
|
|
|
end
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
2010-12-26 13:39:46 +00:00
|
|
|
end
|
|
|
|
|
2011-01-17 14:38:09 +00:00
|
|
|
command "status", "Show status information." do
|
|
|
|
nesting = opts[:nesting]
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "Status:"
|
|
|
|
output.puts "--"
|
|
|
|
output.puts "Receiver: #{Pry.view_clip(target.eval('self'))}"
|
|
|
|
output.puts "Nesting level: #{nesting.level}"
|
|
|
|
output.puts "Pry version: #{Pry::VERSION}"
|
|
|
|
output.puts "Ruby version: #{RUBY_VERSION}"
|
2011-02-14 09:48:19 +00:00
|
|
|
|
|
|
|
mn = meth_name_from_binding.call(target)
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "Current method: #{mn ? mn : "N/A"}"
|
|
|
|
output.puts "Pry instance: #{Pry.active_instance}"
|
|
|
|
output.puts "Last result: #{Pry.view(Pry.last_result)}"
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-02-14 09:48:19 +00:00
|
|
|
command "version", "Show Pry version." do
|
|
|
|
output.puts "Pry version: #{Pry::VERSION}"
|
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "exit-all", "End all nested Pry sessions." do
|
2011-01-17 14:38:09 +00:00
|
|
|
throw(:breakout, 0)
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "ls", "Show the list of vars in the current scope. Type `ls --help` for more info." do |*args|
|
|
|
|
options = {}
|
2011-02-16 21:22:59 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
# Set target local to the default -- note that we can set a different target for
|
|
|
|
# ls if we like: e.g ls my_var
|
|
|
|
target = target()
|
|
|
|
|
|
|
|
OptionParser.new do |opts|
|
|
|
|
opts.banner = %{Usage: ls [OPTIONS] [VAR]\n\
|
|
|
|
List information about VAR (the current context by default).
|
2011-02-16 21:22:59 +00:00
|
|
|
Shows local and instance variables by default.
|
2011-02-16 16:27:55 +00:00
|
|
|
--
|
|
|
|
}
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-g", "--globals", "Display global variables.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:g] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-c", "--constants", "Display constants.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:c] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-l", "--locals", "Display locals.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:l] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-i", "--ivars", "Display instance variables.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:i] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-k", "--class-vars", "Display class variables.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:k] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-m", "--methods", "Display methods.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:m] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-M", "--instance-methods", "Display instance methods (only relevant to classes and modules).") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:M] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:s] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-a", "--all", "Display all types of entries.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:a] = true
|
2011-02-13 15:49:53 +00:00
|
|
|
end
|
2011-02-16 16:27:55 +00:00
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-v", "--verbose", "Verbose ouput.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:v] = true
|
|
|
|
end
|
|
|
|
|
|
|
|
opts.on_tail("-h", "--help", "Show this message.") do
|
|
|
|
output.puts opts
|
|
|
|
options[:h] = true
|
|
|
|
end
|
|
|
|
end.order(args) do |new_target|
|
|
|
|
target = Pry.binding_for(target.eval("#{new_target}")) if !options[:h]
|
2011-02-13 15:49:53 +00:00
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
# exit if we've displayed help
|
|
|
|
next if options[:h]
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
# default is locals/ivars/class vars.
|
|
|
|
# Only occurs when no options or when only option is verbose
|
|
|
|
options.merge!({
|
|
|
|
:l => true,
|
|
|
|
:i => true,
|
|
|
|
:k => true
|
|
|
|
}) if options.empty? || (options.size == 1 && options[:v])
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
info = {}
|
2011-02-02 10:43:21 +00:00
|
|
|
target_self = target.eval('self')
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
# ensure we have a real boolean and not a `nil` (important when
|
|
|
|
# interpolating in the string)
|
|
|
|
options[:s] = !!options[:s]
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
# Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby 1.8
|
2011-02-16 16:27:55 +00:00
|
|
|
i = -1
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
# Start collecting the entries selected by the user
|
|
|
|
info["local variables"] = [Array(target.eval("local_variables")).sort, i += 1] if options[:l] || options[:a]
|
|
|
|
info["instance variables"] = [Array(target.eval("instance_variables")).sort, i += 1] if options[:i] || options[:a]
|
|
|
|
|
|
|
|
info["class variables"] = [if target_self.is_a?(Module)
|
|
|
|
Array(target.eval("class_variables")).sort
|
|
|
|
else
|
|
|
|
Array(target.eval("self.class.class_variables")).sort
|
|
|
|
end, i += 1] if options[:k] || options[:a]
|
|
|
|
|
|
|
|
info["global variables"] = [Array(target.eval("global_variables")).sort, i += 1] if options[:g] || options[:a]
|
2011-02-16 16:27:55 +00:00
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
info["methods"] = [Array(target.eval("methods(#{options[:s]}) + public_methods(#{options[:s]}) +\
|
2011-02-16 16:27:55 +00:00
|
|
|
protected_methods(#{options[:s]}) +\
|
2011-02-16 21:22:59 +00:00
|
|
|
private_methods(#{options[:s]})")).uniq.sort, i += 1] if options[:m] || options[:a]
|
2011-02-13 15:49:53 +00:00
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
info["instance methods"] = [Array(target.eval("instance_methods(#{options[:s]}) +\
|
2011-02-16 16:27:55 +00:00
|
|
|
public_instance_methods(#{options[:s]}) +\
|
|
|
|
protected_instance_methods(#{options[:s]}) +\
|
2011-02-16 21:22:59 +00:00
|
|
|
private_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && (options[:M] || options[:a])
|
2011-02-16 16:27:55 +00:00
|
|
|
|
|
|
|
# dealing with 1.8/1.9 compatibility issues :/
|
|
|
|
csuper = options[:s]
|
|
|
|
if Module.method(:constants).arity == 0
|
|
|
|
csuper = nil
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
info["constants"] = [Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") :
|
|
|
|
target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1] if options[:c] || options[:a]
|
2011-02-16 16:27:55 +00:00
|
|
|
|
|
|
|
# verbose output?
|
|
|
|
if options[:v]
|
|
|
|
|
|
|
|
# verbose
|
|
|
|
info.each.sort_by { |k, v| v.last }.each do |k, v|
|
|
|
|
if !v.first.empty?
|
|
|
|
output.puts "#{k}:\n--"
|
|
|
|
output.puts Pry.view(v.first)
|
|
|
|
output.puts
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# plain
|
2011-02-02 10:43:21 +00:00
|
|
|
else
|
2011-02-16 16:27:55 +00:00
|
|
|
output.puts Pry.view(info.values.sort_by { |v| v.last }.map { |v| v.first }.inject(&:+))
|
2011-02-02 10:43:21 +00:00
|
|
|
end
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
command "cat-file", "Show output of file FILE" do |file_name|
|
|
|
|
if !file_name
|
|
|
|
output.puts "Must provide a file name."
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
output.puts File.read(file_name)
|
|
|
|
end
|
|
|
|
|
|
|
|
command "eval-file", "Eval a Ruby script. Type `eval-file --help` for more info." do |*args|
|
|
|
|
options = {}
|
|
|
|
file_name = nil
|
|
|
|
|
|
|
|
OptionParser.new do |opts|
|
|
|
|
opts.banner = %{Usage: eval-file [OPTIONS] FILE
|
|
|
|
Eval a Ruby script at top-level or in the current context.
|
|
|
|
e.g: eval-script -c "hello.rb"
|
|
|
|
--
|
|
|
|
}
|
|
|
|
opts.on("-c", "--context", "Eval the script in the current context.") do
|
|
|
|
options[:c] = true
|
|
|
|
end
|
|
|
|
|
|
|
|
opts.on_tail("-h", "--help", "This message.") do
|
|
|
|
output.puts opts
|
|
|
|
options[:h] = true
|
|
|
|
end
|
|
|
|
end.order(args) do |v|
|
|
|
|
file_name = v
|
|
|
|
end
|
|
|
|
|
|
|
|
next if options[:h]
|
|
|
|
|
|
|
|
if !file_name
|
|
|
|
output.puts "You need to specify a file name. Type `eval-script --help` for help"
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
old_constants = Object.constants
|
|
|
|
if options[:c]
|
|
|
|
target.eval(File.read(file_name))
|
|
|
|
output.puts "--\nEval'd '#{file_name}' in the current context."
|
|
|
|
else
|
|
|
|
TOPLEVEL_BINDING.eval(File.read(file_name))
|
|
|
|
output.puts "--\nEval'd '#{file_name}' at top-level."
|
|
|
|
end
|
|
|
|
new_constants = Object.constants - old_constants
|
|
|
|
output.puts "Brought in the following top-level constants: #{new_constants.inspect}" if !new_constants.empty?
|
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "cat", "Show output of VAR.inspect. Aliases: inspect" do |obj|
|
|
|
|
if !obj
|
|
|
|
output.puts "Must provide an object to inspect."
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts Pry.view(target.eval("#{obj}"))
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
2011-02-14 09:48:19 +00:00
|
|
|
|
|
|
|
alias_command "inspect", "cat", ""
|
2011-01-12 01:16:04 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "cd", "Start a Pry session on VAR (use `cd ..` to go back)" do |obj|
|
|
|
|
if !obj
|
|
|
|
output.puts "Must provide an object."
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
2011-01-17 14:38:09 +00:00
|
|
|
throw(:breakout, opts[:nesting].level) if obj == ".."
|
2011-01-20 14:41:41 +00:00
|
|
|
target.eval("#{obj}.pry")
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info." do |*args|
|
|
|
|
options = {}
|
|
|
|
meth_name = nil
|
|
|
|
|
|
|
|
OptionParser.new do |opts|
|
|
|
|
opts.banner = %{Usage: show-doc [OPTIONS] [METH]
|
|
|
|
Show the comments above method METH. Shows _method_ comments (rather than instance methods) by default.
|
|
|
|
e.g show-doc hello_method
|
|
|
|
--
|
|
|
|
}
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:M] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on_tail("-h", "--help", "This message.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
output.puts opts
|
|
|
|
options[:h] = true
|
|
|
|
end
|
|
|
|
end.order(args) do |v|
|
|
|
|
meth_name = v
|
|
|
|
end
|
|
|
|
|
|
|
|
next if options[:h]
|
2011-01-12 01:16:04 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
if !meth_name
|
|
|
|
output.puts "You need to specify a method. Type `show-doc --help` for help"
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
begin
|
|
|
|
if options[:M]
|
|
|
|
meth = target.eval("instance_method(:#{meth_name})")
|
|
|
|
else
|
|
|
|
meth = target.eval("method(:#{meth_name})")
|
|
|
|
end
|
|
|
|
rescue
|
|
|
|
output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
doc = meth.comment
|
|
|
|
file, line = meth.source_location
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "From #{file} @ line ~#{line}:\n--"
|
2011-01-20 14:41:41 +00:00
|
|
|
output.puts doc
|
2010-12-26 13:39:46 +00:00
|
|
|
end
|
2010-12-24 08:30:51 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "show-method", "Show the source for METH. Type `show-method --help` for more info." do |*args|
|
|
|
|
options = {}
|
|
|
|
meth_name = nil
|
|
|
|
|
|
|
|
OptionParser.new do |opts|
|
|
|
|
opts.banner = %{Usage: show-method [OPTIONS] [METH]
|
|
|
|
Show the source for method METH. Shows _method_ source (rather than instance methods) by default.
|
|
|
|
e.g: show-method hello_method
|
|
|
|
--
|
|
|
|
}
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:M] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on_tail("-h", "--help", "This message.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
output.puts opts
|
|
|
|
options[:h] = true
|
|
|
|
end
|
|
|
|
end.order(args) do |v|
|
|
|
|
meth_name = v
|
|
|
|
end
|
|
|
|
|
|
|
|
next if options[:h]
|
|
|
|
|
|
|
|
# If no method name is given then use current method, if it exists
|
2011-02-14 09:48:19 +00:00
|
|
|
meth_name = meth_name_from_binding.call(target) if !meth_name
|
2011-02-16 16:27:55 +00:00
|
|
|
|
|
|
|
if !meth_name
|
|
|
|
output.puts "You need to specify a method. Type `show-method --help` for help"
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
begin
|
|
|
|
if options[:M]
|
|
|
|
meth = target.eval("instance_method(:#{meth_name})")
|
|
|
|
else
|
|
|
|
meth = target.eval("method(:#{meth_name})")
|
|
|
|
end
|
|
|
|
rescue
|
|
|
|
output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help"
|
|
|
|
next
|
2011-01-26 18:05:40 +00:00
|
|
|
end
|
2011-01-12 01:16:04 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
code = meth.source
|
|
|
|
file, line = meth.source_location
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "From #{file} @ line #{line}:\n--"
|
2011-01-27 09:37:43 +00:00
|
|
|
output.puts code
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
2011-02-16 16:27:55 +00:00
|
|
|
|
|
|
|
command "show-command", "Show sourcecode for a Pry command, e.g: show-command ls" do |command_name|
|
2011-02-13 15:49:53 +00:00
|
|
|
cmds = Pry.active_instance.commands.commands
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
if !command_name
|
|
|
|
output.puts "You must provide a command name."
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
2011-02-13 15:49:53 +00:00
|
|
|
if cmds[command_name]
|
2011-02-16 16:27:55 +00:00
|
|
|
meth = cmds[command_name][:action]
|
|
|
|
code = meth.source
|
|
|
|
file, line = meth.source_location
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "From #{file} @ line #{line}:\n--"
|
2011-02-13 15:49:53 +00:00
|
|
|
output.puts code
|
|
|
|
else
|
|
|
|
output.puts "No such command: #{command_name}."
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
|
2011-01-17 14:38:09 +00:00
|
|
|
break_level = break_level.to_i
|
|
|
|
nesting = opts[:nesting]
|
2011-01-12 01:16:04 +00:00
|
|
|
|
2011-01-17 14:38:09 +00:00
|
|
|
case break_level
|
|
|
|
when nesting.level
|
2011-01-20 14:41:41 +00:00
|
|
|
output.puts "Already at nesting level #{nesting.level}"
|
2011-01-17 14:38:09 +00:00
|
|
|
when (0...nesting.level)
|
|
|
|
throw(:breakout, break_level + 1)
|
|
|
|
else
|
|
|
|
max_nest_level = nesting.level - 1
|
2011-01-20 14:41:41 +00:00
|
|
|
output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
|
2010-12-25 13:51:34 +00:00
|
|
|
end
|
2010-12-24 08:30:51 +00:00
|
|
|
end
|
2010-12-25 13:51:34 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "exit", "End the current Pry session. Aliases: quit, back" do
|
2011-01-17 14:38:09 +00:00
|
|
|
throw(:breakout, opts[:nesting].level)
|
2010-12-26 13:39:46 +00:00
|
|
|
end
|
2011-02-16 16:27:55 +00:00
|
|
|
|
|
|
|
alias_command "quit", "exit", ""
|
|
|
|
alias_command "back", "exit", ""
|
2010-12-26 13:39:46 +00:00
|
|
|
end
|
|
|
|
end
|