Class: Rush::Shell

Inherits:
Object
  • Object
show all
Includes:
Completion
Defined in:
lib/rush/shell.rb

Overview

Rush::Shell is used to create an interactive shell. It is invoked by the rush binary.

Constant Summary

Constants included from Completion

Completion::TEMPLATES

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Completion

#complete, #complete_constant, #complete_for, #complete_global_method, #complete_method, #complete_object_constant, #complete_path, #executables

Constructor Details

#initializeShell

Set up the user’s environment, including a pure binding into which env.rb and commands.rb are mixed.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/rush/shell.rb', line 16

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
  @history = Coolline::History.new config.history_file.full_path
  Coolline::Settings[:word_boundaries] = [' ', "\t"]
  Coolline::Settings[:completion_word_boundaries] = [' ', "\t"]
  @readline = Coolline.new do |c|
    c.transform_proc  = proc { syntax_highlight c.line }
    c.completion_proc = proc { complete c.completed_word }
  end

  @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
  Rush::File.class_eval commands
  Array.class_eval     commands

  # Multiline commands should be stored somewhere
  @multiline_cmd = ''
end

Class Attribute Details

.promptObject

Returns the value of attribute prompt.



81
82
83
# File 'lib/rush/shell.rb', line 81

def prompt
  @prompt
end

Instance Attribute Details

#configObject

Returns the value of attribute config.



13
14
15
# File 'lib/rush/shell.rb', line 13

def config
  @config
end

#historyObject

Returns the value of attribute history.



13
14
15
# File 'lib/rush/shell.rb', line 13

def history
  @history
end

#pure_bindingObject

Returns the value of attribute pure_binding.



13
14
15
# File 'lib/rush/shell.rb', line 13

def pure_binding
  @pure_binding
end

#suppress_outputObject

Returns the value of attribute suppress_output.



13
14
15
# File 'lib/rush/shell.rb', line 13

def suppress_output
  @suppress_output
end

Instance Method Details

#execute(cmd) ⇒ Object

Run a single command.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rush/shell.rb', line 45

def execute(cmd)
  res = eval(@multiline_cmd << "\n" << cmd, @pure_binding)
  $last_res = res
  eval('_ = $last_res', @pure_binding)
  @multiline_cmd = ''
  print_result res
rescue SyntaxError => e
  unless e.message.include? 'unexpected end-of-input'
    @multiline_cmd = ''
    puts "Exception #{e.class} -> #{e.message}"
  end
  # Else it should be multiline command.
rescue Rush::Exception => e
  puts "Exception #{e.class} -> #{e.message}"
  @multiline_cmd = ''
rescue ::Exception => e
  puts "Exception #{e.class} -> #{e.message}"
  e.backtrace.each { |t| puts "\t#{::File.expand_path(t)}" }
  @multiline_cmd = ''
end

#finishObject

Save history to ~/.rush/history when the shell exists.



85
86
87
88
# File 'lib/rush/shell.rb', line 85

def finish
  puts
  exit
end

Nice printing of different return types, particularly Rush::SearchResults.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rush/shell.rb', line 92

def print_result(res)
  return if suppress_output
  if res.is_a? String
    output = res
  elsif res.is_a? Rush::SearchResults
    output = res.to_s <<
      "#{res.entries.size} matching files with #{res.lines.size} lines"
  elsif res.respond_to? :each
    output = res.pretty_inspect
  else
    output = "   = #{res.inspect}"
  end
  output.lines.count > 5 ? output.less : puts(output)
end

#runObject

Run the interactive shell using coolline.



67
68
69
70
71
72
73
74
75
76
# File 'lib/rush/shell.rb', line 67

def run
  loop do
    prompt = self.class.prompt || "#{`whoami`.chomp} $ "
    cmd = @readline.readline prompt
    finish if cmd.nil? || cmd == 'exit'
    next   if cmd.empty?
    @history << cmd
    execute cmd
  end
end

#syntax_highlight(input) ⇒ Object

Syntax highlighting with coderay.



109
110
111
# File 'lib/rush/shell.rb', line 109

def syntax_highlight(input)
  CodeRay.encode input, :ruby, :term
end