Class: Ratch::Console
Overview
Ratch Shell Console
NOTE: Console class is still a work in progress.
Instance Attribute Summary collapse
-
#suppress_output ⇒ Object
Returns the value of attribute suppress_output.
Instance Method Summary collapse
- #complete_method(receiver, dot, partial_name, pre) ⇒ Object
-
#complete_path(possible_var, accessor, quote, partial_path, pre) ⇒ Object
:nodoc:.
- #complete_variable(partial_name, pre) ⇒ Object
-
#completion_proc ⇒ Object
Try to do tab completion on dir square brackets and slash accessors.
-
#execute(cmd) ⇒ Object
Run a single command.
-
#finish ⇒ Object
Save history to ~/.config/ratch/history when the shell exists.
-
#initialize ⇒ Console
constructor
Set up the user’s environment, including a pure binding into which env.rb and commands.rb are mixed.
-
#path_parts(input) ⇒ Object
:nodoc:.
-
#print_result(res) ⇒ Object
Nice printing of different return types, particularly Rush::SearchResults.
-
#run ⇒ Object
Run the interactive shell using readline.
Constructor Details
#initialize ⇒ Console
Set up the user’s environment, including a pure binding into which env.rb and commands.rb are mixed.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/ratch/console.rb', line 12 def initialize require 'readline' #root = Rush::Dir.new('/') #home = Rush::Dir.new(ENV['HOME']) if ENV['HOME'] #pwd = Rush::Dir.new(ENV['PWD']) if ENV['PWD'] #@config = Rush::Config.new @config.load_history.each do |item| Readline::HISTORY.push(item) end Readline.basic_word_break_characters = "" Readline.completion_append_character = nil Readline.completion_proc = completion_proc @shell = Ratch::Shell.new @pure_binding = @shell.instance_eval("binding") $last_res = nil #eval @config.load_env, @pure_binding #commands = @config.load_commands #Rush::Dir.class_eval commands #Array.class_eval commands end |
Instance Attribute Details
#suppress_output ⇒ Object
Returns the value of attribute suppress_output.
8 9 10 |
# File 'lib/ratch/console.rb', line 8 def suppress_output @suppress_output end |
Instance Method Details
#complete_method(receiver, dot, partial_name, pre) ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/ratch/console.rb', line 132 def complete_method(receiver, dot, partial_name, pre) path = eval("#{receiver}.full_path", @pure_binding) rescue nil box = eval("#{receiver}.box", @pure_binding) rescue nil if path and box (box[path].methods - Object.methods).select do |e| e.match(/^#{Regexp.escape(partial_name)}/) end.map do |e| (pre || '') + receiver + dot + e end end end |
#complete_path(possible_var, accessor, quote, partial_path, pre) ⇒ Object
:nodoc:
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/ratch/console.rb', line 144 def complete_path(possible_var, accessor, quote, partial_path, pre) # :nodoc: original_var, fixed_path = possible_var, '' if /^(.+\/)([^\/]*)$/ === partial_path fixed_path, partial_path = $~.captures possible_var += "['#{fixed_path}']" end full_path = eval("#{possible_var}.full_path", @pure_binding) rescue nil box = eval("#{possible_var}.box", @pure_binding) rescue nil if full_path and box Rush::Dir.new(full_path, box).entries.select do |e| e.name.match(/^#{Regexp.escape(partial_path)}/) end.map do |e| (pre || '') + original_var + accessor + quote + fixed_path + e.name + (e.dir? ? "/" : "") end end end |
#complete_variable(partial_name, pre) ⇒ Object
161 162 163 164 165 166 167 168 169 170 |
# File 'lib/ratch/console.rb', line 161 def complete_variable(partial_name, pre) lvars = eval('local_variables', @pure_binding) gvars = eval('global_variables', @pure_binding) ivars = eval('instance_variables', @pure_binding) (lvars + gvars + ivars).select do |e| e.match(/^#{Regexp.escape(partial_name)}/) end.map do |e| (pre || '') + e end end |
#completion_proc ⇒ Object
Try to do tab completion on dir square brackets and slash accessors.
Example:
dir[‘subd # presing tab here will produce dir[’subdir/ if subdir exists dir/‘subd # presing tab here will produce dir/’subdir/ if subdir exists
This isn’t that cool yet, because it can’t do multiple levels of subdirs. It does work remotely, though, which is pretty sweet.
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/ratch/console.rb', line 181 def completion_proc proc do |input| receiver, accessor, *rest = path_parts(input) if receiver case accessor when /^[\[\/]$/ complete_path(receiver, accessor, *rest) when /^\.$/ complete_method(receiver, accessor, *rest) when nil complete_variable(receiver, *rest) end end end end |
#execute(cmd) ⇒ Object
Run a single command.
57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/ratch/console.rb', line 57 def execute(cmd) res = eval(cmd, @pure_binding) $last_res = res eval("_ = $last_res", @pure_binding) print_result(res) #rescue Rush::Exception => e # puts "Exception #{e.class} -> #{e.message}" rescue ::Exception => e puts "Exception #{e.class} -> #{e.}" e.backtrace.each do |t| puts " #{::File.(t)}" end end |
#finish ⇒ Object
Save history to ~/.config/ratch/history when the shell exists.
72 73 74 75 76 |
# File 'lib/ratch/console.rb', line 72 def finish @config.save_history(Readline::HISTORY.to_a) puts exit end |
#path_parts(input) ⇒ Object
:nodoc:
119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/ratch/console.rb', line 119 def path_parts(input) # :nodoc: case input when /((?:@{1,2}|\$|)\w+(?:\[[^\]]+\])*)([\[\/])(['"])([^\3]*)$/ $~.to_a.slice(1, 4).push($~.pre_match) when /((?:@{1,2}|\$|)\w+(?:\[[^\]]+\])*)(\.)(\w*)$/ $~.to_a.slice(1, 3).push($~.pre_match) when /((?:@{1,2}|\$|)\w+)$/ $~.to_a.slice(1, 1).push(nil).push($~.pre_match) else [ nil, nil, nil ] end end |
#print_result(res) ⇒ Object
Nice printing of different return types, particularly Rush::SearchResults.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/ratch/console.rb', line 81 def print_result(res) return if self.suppress_output if res.kind_of? String puts res elsif res.kind_of? Rush::SearchResults widest = res.entries.map { |k| k.full_path.length }.max res.entries_with_lines.each do |entry, lines| print entry.full_path print ' ' * (widest - entry.full_path.length + 2) print "=> " print res.colorize(lines.first.strip.head(30)) print "..." if lines.first.strip.length > 30 if lines.size > 1 print " (plus #{lines.size - 1} more matches)" end print "\n" end puts "#{res.entries.size} matching files with #{res.lines.size} matching lines" elsif res.respond_to? :each counts = {} res.each do |item| puts item counts[item.class] ||= 0 counts[item.class] += 1 end if counts == {} puts "=> (empty set)" else count_s = counts.map do |klass, count| "#{count} x #{klass}" end.join(', ') puts "=> #{count_s}" end else puts "=> #{res.inspect}" end end |
#run ⇒ Object
Run the interactive shell using readline.
42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/ratch/console.rb', line 42 def run loop do cmd = Readline.readline('ratch> ') finish if cmd.nil? or cmd == 'exit' next if cmd == "" Readline::HISTORY.push(cmd) execute(cmd) end end |