Class: Rush::Shell
- Inherits:
-
Object
- Object
- Rush::Shell
- Defined in:
- lib/rush/shell.rb
Instance Attribute Summary collapse
-
#suppress_output ⇒ Object
Returns the value of attribute suppress_output.
Instance Method Summary collapse
-
#completion_proc ⇒ Object
Try to do tab completion on dir square brackets accessors.
-
#execute(cmd) ⇒ Object
Run a single command.
-
#finish ⇒ Object
Save history to ~/.rush/history when the shell exists.
-
#initialize ⇒ Shell
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 ⇒ Shell
Set up the user’s environment, including a pure binding into which env.rb and commands.rb are mixed.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/rush/shell.rb', line 9 def initialize 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 @box = Rush::Box.new @pure_binding = @box.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.
6 7 8 |
# File 'lib/rush/shell.rb', line 6 def suppress_output @suppress_output end |
Instance Method Details
#completion_proc ⇒ Object
Try to do tab completion on dir square brackets accessors.
Example:
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.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/rush/shell.rb', line 124 def completion_proc proc do |input| possible_var, quote, partial_path, pre = path_parts(input) if possible_var 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 dir = Rush::Dir.new(full_path, box) return dir.entries.select do |e| e.name.match(/^#{Regexp.escape(partial_path)}/) end.map do |e| (pre || '') + original_var + '[' + quote + fixed_path + e.name + (e.dir? ? "/" : "") end end end nil end end |
#execute(cmd) ⇒ Object
Run a single command.
36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/rush/shell.rb', line 36 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.}" rescue ::Exception => e puts "Exception #{e.class} -> #{e.}" e.backtrace.each do |t| puts " #{::File.(t)}" end end |
#finish ⇒ Object
Save history to ~/.rush/history when the shell exists.
64 65 66 67 68 |
# File 'lib/rush/shell.rb', line 64 def finish @config.save_history(Readline::HISTORY.to_a) puts exit end |
#path_parts(input) ⇒ Object
:nodoc:
109 110 111 112 113 114 |
# File 'lib/rush/shell.rb', line 109 def path_parts(input) # :nodoc: input.match(/(\w+(?:\[[^\]]+\])*)\[(['"])([^\]]+)$/) $~.to_a.slice(1, 3).push($~.pre_match) rescue [ nil, nil, nil, nil ] end |
#print_result(res) ⇒ Object
Nice printing of different return types, particularly Rush::SearchResults.
71 72 73 74 75 76 77 78 79 80 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 |
# File 'lib/rush/shell.rb', line 71 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.
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rush/shell.rb', line 51 def run loop do cmd = Readline.readline('rush> ') finish if cmd.nil? or cmd == 'exit' next if cmd == "" Readline::HISTORY.push(cmd) execute(cmd) end end |