require 'terminal-table' require 'pry' require 'collins_shell/console/commands' require 'collins_shell/console/filesystem' class Pry # We kill the built in completion so we can tell users what things are available module InputCompleter class << self def build_completion_proc(target, commands=[""], cmplns = nil) if cmplns.is_a?(Array) then # Work around for breakage between pry 0.9.9.6 and 0.9.12 commands = cmplns end proc do |input| commands.map do |cmd| cmd_s = cmd.to_s if cmd_s.include?(":wtf") then "wtf?" else cmd_s end end.select{|s| s.start_with?(input)}.uniq # commands.map end # proc do end # def build_completion_proc end # class << self end # module InputCompleter end # class Pry module CollinsShell; module Console class << self def run_pry_command command_string, options = {} options = { :show_output => true, :output => Pry.output, :commands => get_pry_commands }.merge!(options) output = options[:show_output] ? options[:output] : StringIO.new pry = Pry.new( :output => output, :input => StringIO.new(command_string), :commands => options[:commands], :prompt => proc{""}, :hooks => Pry::Hooks.new ) if options[:binding_stack] then pry.binding_stack = options[:binding_stack] end pry.rep(options[:context]) end def launch(options) self.options = options Pry.config.commands = get_pry_commands Pry.config.pager = true Pry.custom_completions = get_pry_custom_completions Pry.config.exception_handler = get_pry_exception_handler target = CollinsShell::Console::Filesystem.new options setup_pry_hooks Pry.start(target, :prompt => get_pry_prompt) end def options=(options) @options = options end def options @options end private def setup_pry_hooks before_message = [ 'Welcome to the collins console. A few notes:', ' - collins-shell interacts with real servers (BE CAREFUL).', ' - collins-shell operates in contexts, which the prompt tells you about.', ' - collins-shell can be customized to your tastes. Read the docs.', ' - Type help at any time for help' ].join("\n") Pry.config.hooks.add_hook(:before_session, :session_start) do |out, *| out.puts before_message end Pry.config.hooks.add_hook(:after_session, :session_end) do |out, *| out.puts "Goodbye!" end end def get_pry_prompt get_prompt = proc { |o, waiting| sym = waiting ? "*" : ">" if o.is_a?(CollinsShell::Console::Filesystem) then ext = "" if o.asset? then ext = "*" end "collins #{o.path}#{ext} #{sym} " else "collins-#{o.class} #{sym} " end } [ proc { |o, *| get_prompt.call(o, false) }, proc { |o, *| get_prompt.call(o, true) } ] end def get_pry_custom_completions proc do last = binding_stack.last last = last.eval('self') unless last.nil? if last.is_a?(CollinsShell::Console::Filesystem) then (last.available_commands + commands.commands.keys).flatten else commands.commands.keys end end end def get_pry_exception_handler proc do |output, exception, _pry_| if exception.is_a?(Interrupt) then output.puts "" else cli = CollinsShell::Cli.new [], {} cli.print_error exception, "command failed" output.puts "" bold = Pry::Helpers::Text.bold("type 'bt' or 'wtf?!?' for more context") output.puts bold end end end def get_pry_commands Pry::CommandSet.new do import_from Pry::Commands, "help", "history", "hist", "wtf?", "show-doc", "show-source" alias_command "bt", "wtf?" import CollinsShell::Console::Commands::Default end end end end; end