rish 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/rish +79 -0
- data/lib/rish/autoreload.rb +123 -0
- data/lib/rish/commands.rb +28 -0
- data/lib/rish/hook.rb +63 -0
- data/lib/rish/interactive.rb +188 -0
- data/lib/rish/irb.rb +104 -0
- data/lib/rish/shell.rb +28 -0
- metadata +81 -0
data/bin/rish
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
#!/usr/bin/env/ruby
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2010 by Mikio L. Braun
|
5
|
+
# rish is distributed under a BSD-style license. See COPYING
|
6
|
+
|
7
|
+
require 'rish/shell'
|
8
|
+
require 'rish/autoreload'
|
9
|
+
|
10
|
+
def banner
|
11
|
+
puts <<EOS
|
12
|
+
|
13
|
+
rish - Ruby Interactive Shell
|
14
|
+
|
15
|
+
an autoreloading interactive shell with
|
16
|
+
interactive help, shell-outs and profiling.
|
17
|
+
|
18
|
+
written by Mikio L. Braun
|
19
|
+
|
20
|
+
Type 'exit' or hit Ctrl-D on an empty line to exit.
|
21
|
+
Type '@h' to get help on built-in commands
|
22
|
+
|
23
|
+
EOS
|
24
|
+
end
|
25
|
+
|
26
|
+
def usage
|
27
|
+
puts <<EOS
|
28
|
+
Usage: rish [options] files_to_require.rb ...
|
29
|
+
|
30
|
+
Options:
|
31
|
+
-a dir : load all *.rb files in dir/ on startup
|
32
|
+
-w dir : watch all *.rb files in dir/ for changes
|
33
|
+
-I dir : add dir/ to load-path
|
34
|
+
--irb : use IRB as shell (default)
|
35
|
+
--rish : user rish's own shell
|
36
|
+
-h, --help : show help (this)
|
37
|
+
EOS
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Main
|
42
|
+
#
|
43
|
+
|
44
|
+
banner
|
45
|
+
|
46
|
+
type = :irb
|
47
|
+
|
48
|
+
until ARGV.empty?
|
49
|
+
cmd = ARGV.shift
|
50
|
+
case cmd
|
51
|
+
when '-I'
|
52
|
+
dir = ARGV.shift
|
53
|
+
$: << dir
|
54
|
+
when '-a'
|
55
|
+
dir = ARGV.shift
|
56
|
+
puts "Loading all ruby files in #{dir}/"
|
57
|
+
Dir.glob("#{dir}/**/*.rb").each {|fn| require fn}
|
58
|
+
when '-w'
|
59
|
+
dir = ARGV.shift
|
60
|
+
Rish::Autoreload.watch_directory dir
|
61
|
+
when '-h', '--help'
|
62
|
+
usage
|
63
|
+
exit
|
64
|
+
when '-e'
|
65
|
+
cmd = ARGV.shift
|
66
|
+
puts eval(cmd)
|
67
|
+
exit
|
68
|
+
when '--irb'
|
69
|
+
type = :irb
|
70
|
+
when '--rish'
|
71
|
+
type = :rish
|
72
|
+
else
|
73
|
+
require cmd
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
Rish::Autoreload.check_directories
|
78
|
+
|
79
|
+
shell = Rish.shell(type)
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# Copyright (c) 2010 by Mikio L. Braun
|
2
|
+
# rish is distributed under a BSD-style license. See COPYING
|
3
|
+
|
4
|
+
require 'pp'
|
5
|
+
require 'set'
|
6
|
+
|
7
|
+
module Rish
|
8
|
+
# This module tracks loaded files and their timestamps and allows to reload
|
9
|
+
# files which have changed automatically by calling reload.
|
10
|
+
#
|
11
|
+
# There is nothing magically happening here. Basically, you can
|
12
|
+
# reload a file by removing it from $" (the list of all loaded
|
13
|
+
# files) and require'ing it again.
|
14
|
+
module Autoreload
|
15
|
+
|
16
|
+
# stores the normalized filenames and their File.mtime timestamps
|
17
|
+
@timestamps = Hash.new
|
18
|
+
@notfound = Set.new
|
19
|
+
@verbose = false
|
20
|
+
@watched_dirs = []
|
21
|
+
|
22
|
+
# Set verbosity flag. Setting this to true will report each file
|
23
|
+
# that has been reloaded.
|
24
|
+
def self.verbose=(flag)
|
25
|
+
@verbose = flag
|
26
|
+
end
|
27
|
+
|
28
|
+
# Find the full path to a file.
|
29
|
+
def self.locate(file)
|
30
|
+
return nil if @notfound.include? file
|
31
|
+
$:.each do |dir|
|
32
|
+
fullpath = File.join(dir, file)
|
33
|
+
if File.exists? fullpath
|
34
|
+
return fullpath
|
35
|
+
elsif File.exists?(fullpath + '.rb')
|
36
|
+
return fullpath + '.rb'
|
37
|
+
elsif File.exists?(fullpath + '.so')
|
38
|
+
return fullpath + '.so'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
# puts "[JML::AutoReload] File #{file} not found!"
|
42
|
+
@notfound.add file
|
43
|
+
return nil
|
44
|
+
end
|
45
|
+
|
46
|
+
# Store the time stamp of a file.
|
47
|
+
def self.timestamp(file)
|
48
|
+
path = locate(file)
|
49
|
+
if path
|
50
|
+
file = normalize(path, file)
|
51
|
+
@timestamps[file] = File.mtime(path)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Put the extension on a filename.
|
56
|
+
def self.normalize(path, file)
|
57
|
+
if File.extname(file) == ""
|
58
|
+
return file + File.extname(path)
|
59
|
+
else
|
60
|
+
return file
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Show all stored files and their timestamp.
|
65
|
+
def self.dump
|
66
|
+
pp @timestamps
|
67
|
+
end
|
68
|
+
|
69
|
+
# Reload a file. With force=true, file is reloaded in
|
70
|
+
# any case.
|
71
|
+
def self.reload(file, force=false)
|
72
|
+
path = locate(file)
|
73
|
+
file = normalize(path, file)
|
74
|
+
|
75
|
+
if force or (path and File.mtime(path) > @timestamps[file])
|
76
|
+
puts "[JML::AutoReload] reloading #{file}" if @verbose
|
77
|
+
|
78
|
+
# delete file from list of loaded modules, and reload
|
79
|
+
$".delete file
|
80
|
+
require file
|
81
|
+
return true
|
82
|
+
else
|
83
|
+
return false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Reload all files which were required.
|
88
|
+
def self.reload_all(force=false)
|
89
|
+
@timestamps.each_key do |file|
|
90
|
+
self.reload(file, force)
|
91
|
+
end
|
92
|
+
check_directories
|
93
|
+
end
|
94
|
+
|
95
|
+
# Add directories to be watched.
|
96
|
+
def self.watch_directory(dir)
|
97
|
+
@watched_dirs << dir
|
98
|
+
end
|
99
|
+
|
100
|
+
# Reload any new files in the watched directories.
|
101
|
+
def self.check_directories
|
102
|
+
@watched_dirs.each do |dir|
|
103
|
+
Dir.glob("#{dir}/**/*.rb").each do |fn|
|
104
|
+
if @timestamps.include? fn
|
105
|
+
reload(fn)
|
106
|
+
else
|
107
|
+
require(fn)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Overwrite 'require' to register the time stamps instead.
|
116
|
+
module Kernel # :nodoc:
|
117
|
+
alias old_require require
|
118
|
+
|
119
|
+
def require(file)
|
120
|
+
Rish::Autoreload.timestamp(file)
|
121
|
+
old_require(file)
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Copyright (c) 2010 by Mikio L. Braun
|
2
|
+
# rish is distributed under a BSD-style license. See COPYING
|
3
|
+
|
4
|
+
module Rish
|
5
|
+
# Collects commands which are available trough extensions.
|
6
|
+
module Commands
|
7
|
+
module_function
|
8
|
+
|
9
|
+
# Show help for a command, or just the builtin commands.
|
10
|
+
def help(word=nil)
|
11
|
+
if word
|
12
|
+
puts %x{qri #{word}}
|
13
|
+
else
|
14
|
+
puts <<EOS
|
15
|
+
Rish builtin-commands
|
16
|
+
|
17
|
+
@p <expr> profile expression (requires --debug on JRuby)
|
18
|
+
?<expr> show help for command expr (doesn't work so well on IRB :( )
|
19
|
+
@h show this help
|
20
|
+
!<cmd> Run cmd in a shell
|
21
|
+
!<cmd> & Run cmd in background
|
22
|
+
!&<cmd> Same as above (version for IRB which doesn't like an "&"
|
23
|
+
as last element on line)
|
24
|
+
EOS
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/rish/hook.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# Copyright (c) 2010 by Mikio L. Braun
|
2
|
+
# rish is distributed under a BSD-style license. See COPYING
|
3
|
+
|
4
|
+
require 'profiler'
|
5
|
+
require 'rish/autoreload'
|
6
|
+
require 'rish/commands'
|
7
|
+
|
8
|
+
module Rish
|
9
|
+
# The main Hook class.
|
10
|
+
#
|
11
|
+
# This adds the main functionality realized through before
|
12
|
+
# and after hooks.
|
13
|
+
#
|
14
|
+
# If you want to add further capabilities, here is the place to do
|
15
|
+
# so.
|
16
|
+
class Hook
|
17
|
+
@profile = false
|
18
|
+
|
19
|
+
# Called with each input line.
|
20
|
+
#
|
21
|
+
# If a special command is recognized, the input line is changed
|
22
|
+
# accordingly. For example, "!ls" becomes "%x{ls}"
|
23
|
+
def before(line)
|
24
|
+
Autoreload::reload_all
|
25
|
+
if line[0] == ?!
|
26
|
+
if line[1] == ?&
|
27
|
+
line = line[2..-1] + "&"
|
28
|
+
end
|
29
|
+
if line[-1] == ?&
|
30
|
+
"Thread.new { %x{#{line[1...-1]}} };"
|
31
|
+
else
|
32
|
+
"%x{#{line[1..-1]}}"
|
33
|
+
end
|
34
|
+
elsif line[0] == ?? and line.size > 2
|
35
|
+
"Rish::Commands.help \"#{line[1..-1]}\""
|
36
|
+
elsif line[0] == ?@
|
37
|
+
if line[1] == ?p
|
38
|
+
Profiler__::start_profile
|
39
|
+
@profile = true
|
40
|
+
line = line[2..-1]
|
41
|
+
elsif line[1] == ?h
|
42
|
+
'Rish::Commands.help'
|
43
|
+
else
|
44
|
+
line
|
45
|
+
end
|
46
|
+
else
|
47
|
+
line
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Called on the result of an evaluation.
|
52
|
+
#
|
53
|
+
# Used here mainly to clean up after the profiler.
|
54
|
+
def after(result)
|
55
|
+
if @profile
|
56
|
+
Profiler__::stop_profile
|
57
|
+
Profiler__::print_profile($stdout)
|
58
|
+
@profile = false
|
59
|
+
end
|
60
|
+
result
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
# Copyright (c) 2010 by Mikio L. Braun
|
2
|
+
# rish is distributed under a BSD-style license. See COPYING
|
3
|
+
|
4
|
+
require 'readline'
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
module Rish
|
8
|
+
# Rish's own interactive mode.
|
9
|
+
#
|
10
|
+
# Similar to IRB, but much smaller. The advantage it has is that it
|
11
|
+
# doesn't look for line continuations and works better with rish's
|
12
|
+
# built-in commands (well, is this a feature or a bug?)
|
13
|
+
#
|
14
|
+
# Also, if the line ends in ";", the result is not plotted, just as in
|
15
|
+
# matlab.
|
16
|
+
class Interactive
|
17
|
+
# Start an interactive shell.
|
18
|
+
def run
|
19
|
+
read_history
|
20
|
+
|
21
|
+
#binding = Workspace.new.binding
|
22
|
+
binding = Object::TOPLEVEL_BINDING
|
23
|
+
|
24
|
+
Readline.completion_proc = proc do |s|
|
25
|
+
if /([a-zA-Z_]+)(::|\.)([^.]*)/ =~ s
|
26
|
+
prefix = $1
|
27
|
+
sep = $2
|
28
|
+
s = $3
|
29
|
+
|
30
|
+
candidates = get_candidates(binding, prefix + sep)
|
31
|
+
else
|
32
|
+
prefix = ''
|
33
|
+
sep = ''
|
34
|
+
|
35
|
+
candidates = get_candidates(binding)
|
36
|
+
end
|
37
|
+
|
38
|
+
candidates = candidates.select {|m| starts_with(m, s)}
|
39
|
+
candidates.map! {|c| prefix + sep + c}
|
40
|
+
end
|
41
|
+
|
42
|
+
thread = Thread.current
|
43
|
+
|
44
|
+
state = :input
|
45
|
+
|
46
|
+
trap('SIGINT') do
|
47
|
+
case state
|
48
|
+
when :input
|
49
|
+
puts "Exiting..."
|
50
|
+
thread.raise Interrupt
|
51
|
+
exit
|
52
|
+
when :calc
|
53
|
+
thread.raise Interrupt
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
lineno = 0
|
58
|
+
s = 'okay'
|
59
|
+
while s
|
60
|
+
lineno += 1
|
61
|
+
state = :input
|
62
|
+
s = Readline.readline("interactive:#{lineno}> ", true)
|
63
|
+
#print "interactive:#{lineno}> "
|
64
|
+
#s = gets.chomp
|
65
|
+
break if (s.nil? or s == 'exit' or s == 'quit')
|
66
|
+
begin
|
67
|
+
s = @hook.before(s) if @hook
|
68
|
+
state = :calc
|
69
|
+
result = eval(s, binding, 'interactive', lineno)
|
70
|
+
state = :input
|
71
|
+
result = @hook.after(result) if @hook
|
72
|
+
if s[-1] != ?;
|
73
|
+
print_result(result)
|
74
|
+
$ans = result
|
75
|
+
end
|
76
|
+
rescue SyntaxError => e
|
77
|
+
puts "SyntaxError: #{e}"
|
78
|
+
rescue StandardError, ScriptError => e
|
79
|
+
puts "#{e.class}: #{e.to_s[0..1000]}"
|
80
|
+
print_backtrace e.backtrace
|
81
|
+
rescue SignalException => e
|
82
|
+
puts "Caught #{e.class}"
|
83
|
+
print_backtrace e.backtrace
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
write_history
|
88
|
+
exit
|
89
|
+
end
|
90
|
+
|
91
|
+
# Add a hook which is called before and after each line.
|
92
|
+
#
|
93
|
+
# The hook object as to have a +before+ and +after+ method.
|
94
|
+
# The +before+ method is called with the input line
|
95
|
+
# and has to return it or a changed version. Likewise,
|
96
|
+
# the +after+ method gets the result of the evaluation and
|
97
|
+
# has to return the value or a changed version.
|
98
|
+
def hook=(h)
|
99
|
+
@hook = h
|
100
|
+
end
|
101
|
+
|
102
|
+
#######
|
103
|
+
private
|
104
|
+
#######
|
105
|
+
|
106
|
+
def history_file
|
107
|
+
File.join(ENV['HOME'], '.rish_history')
|
108
|
+
end
|
109
|
+
|
110
|
+
def print_result(result)
|
111
|
+
puts result.inspect unless result.nil?
|
112
|
+
end
|
113
|
+
|
114
|
+
def read_history
|
115
|
+
begin
|
116
|
+
open(history_file, 'r').each do |l|
|
117
|
+
Readline::HISTORY << l.chomp
|
118
|
+
end
|
119
|
+
rescue Errno::ENOENT
|
120
|
+
# do nothing
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def write_history
|
125
|
+
open(history_file, 'w') do |f|
|
126
|
+
Readline::HISTORY.each {|l| f.puts l }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# For cleanin up JRuby's stack traces.
|
131
|
+
BACKTRACE_HIDE = [ 'sun/', 'java/', 'org/jruby', 'interactive', ':', __FILE__ ]
|
132
|
+
|
133
|
+
def print_backtrace(bt)
|
134
|
+
bt.each do |t|
|
135
|
+
unless BACKTRACE_HIDE.inject(false) do |flag,h|
|
136
|
+
flag ||= starts_with(t, h)
|
137
|
+
end
|
138
|
+
puts " #{t}"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def starts_with(long, short)
|
144
|
+
long[0...short.length] == short
|
145
|
+
end
|
146
|
+
|
147
|
+
def get_candidates(binding, where='')
|
148
|
+
candidates = []
|
149
|
+
%w(methods constants local_variables).each do |m|
|
150
|
+
begin
|
151
|
+
candidates += eval(where + m, binding)
|
152
|
+
rescue
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
if where == ''
|
157
|
+
eval('self.class.ancestors', binding).each do |an|
|
158
|
+
%w(methods constants).each do |m|
|
159
|
+
begin
|
160
|
+
candidates += an.send(m)
|
161
|
+
rescue
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
return candidates.sort.uniq
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
if __FILE__ == $0
|
173
|
+
include M
|
174
|
+
|
175
|
+
puts "Interactive with a before and after hook"
|
176
|
+
class MyInteractive < Interactive # :nodoc:
|
177
|
+
def process_line(line)
|
178
|
+
puts "This line is great: #{line}"
|
179
|
+
line
|
180
|
+
end
|
181
|
+
|
182
|
+
def process_result(result)
|
183
|
+
print " => "
|
184
|
+
result
|
185
|
+
end
|
186
|
+
end
|
187
|
+
MyInteractive.new.run
|
188
|
+
end
|
data/lib/rish/irb.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# Copyright (c) 2010 by Mikio L. Braun
|
2
|
+
# rish is distributed under a BSD-style license. See COPYING
|
3
|
+
|
4
|
+
require 'irb'
|
5
|
+
|
6
|
+
module IRB
|
7
|
+
# Start a rish-shell.
|
8
|
+
#
|
9
|
+
# This code is basically the same as IRB.start with the
|
10
|
+
# irb object replaced by our own version.
|
11
|
+
def IRB.rish_start(ap_path=nil, hook=nil)
|
12
|
+
$0 = File::basename(ap_path, ".rb") if ap_path
|
13
|
+
|
14
|
+
IRB.setup(ap_path)
|
15
|
+
|
16
|
+
if @CONF[:SCRIPT]
|
17
|
+
irb = Rish::Irb::RishIrb.new(nil, @CONF[:SCRIPT])
|
18
|
+
else
|
19
|
+
irb = Rish::Irb::RishIrb.new
|
20
|
+
end
|
21
|
+
|
22
|
+
irb.hook = hook
|
23
|
+
|
24
|
+
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
25
|
+
@CONF[:MAIN_CONTEXT] = irb.context
|
26
|
+
|
27
|
+
trap("SIGINT") do
|
28
|
+
irb.signal_handle
|
29
|
+
end
|
30
|
+
|
31
|
+
catch(:IRB_EXIT) do
|
32
|
+
irb.eval_input
|
33
|
+
end
|
34
|
+
# print "\n"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
module Rish
|
39
|
+
# Rish's irb extensions.
|
40
|
+
#
|
41
|
+
# This module defines two classes derived from IRB::Irb and
|
42
|
+
# IRB::Context which basically add after and before hooks
|
43
|
+
# to the evaluation to implement automatic reloading and
|
44
|
+
# profiling.
|
45
|
+
module Irb
|
46
|
+
# Our version of IRB::Irb which uses a RishContext.
|
47
|
+
class RishIrb < IRB::Irb
|
48
|
+
# Create new object.
|
49
|
+
#
|
50
|
+
# Overwrites @context to RishContext.
|
51
|
+
def initialize(workspace = nil, input_method = nil, output_method = nil)
|
52
|
+
super(workspace, input_method, output_method)
|
53
|
+
@context = RishContext.new(self, workspace, input_method, output_method)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Add a hook in the context object.
|
57
|
+
def hook=(h)
|
58
|
+
@context.hook = h
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Our version of IRB::Context which adds before and after hooks
|
63
|
+
# to evaluate.
|
64
|
+
class RishContext < IRB::Context
|
65
|
+
# Create new context object.
|
66
|
+
|
67
|
+
def initialize(irb, workspace = nil, input_method = nil, output_method = nil)
|
68
|
+
super(irb, workspace, input_method, output_method)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Add a hook.
|
72
|
+
def hook=(h)
|
73
|
+
@hook = h
|
74
|
+
end
|
75
|
+
|
76
|
+
# Overwritten version of evaluate which calls the +before+ and
|
77
|
+
# +after+ methods of the hook, if present. +before+ gets the
|
78
|
+
# input line and may return a changed version, +after+ gets the
|
79
|
+
# result and may return a changed version.
|
80
|
+
def evaluate(line, line_no)
|
81
|
+
line = @hook.before(line) if @hook
|
82
|
+
val = super(line, line_no)
|
83
|
+
val = @hook.after(val) if @hook
|
84
|
+
val
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
if __FILE__ == $0
|
91
|
+
class RishHook # :nodoc:
|
92
|
+
def before(line)
|
93
|
+
puts "Before"
|
94
|
+
line
|
95
|
+
end
|
96
|
+
|
97
|
+
def after(val)
|
98
|
+
puts "After"
|
99
|
+
val
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
IRB.rish_start(nil, RishHook.new)
|
104
|
+
end
|
data/lib/rish/shell.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Copyright (c) 2010 by Mikio L. Braun
|
2
|
+
# rish is distributed under a BSD-style license. See COPYING
|
3
|
+
|
4
|
+
require 'profiler'
|
5
|
+
|
6
|
+
require 'rish/hook'
|
7
|
+
require 'rish/irb'
|
8
|
+
require 'rish/interactive'
|
9
|
+
|
10
|
+
# The Rish main module.
|
11
|
+
#
|
12
|
+
# Call Rish.shell to start a shell.
|
13
|
+
module Rish
|
14
|
+
module_function
|
15
|
+
|
16
|
+
# Start a new Rish shell. Supported types are :irb and :rish.
|
17
|
+
def shell(type=:irb)
|
18
|
+
hook = Hook.new
|
19
|
+
case type
|
20
|
+
when :irb
|
21
|
+
IRB.rish_start(nil, hook)
|
22
|
+
when :rish
|
23
|
+
i = Interactive.new
|
24
|
+
i.hook = hook
|
25
|
+
i.run
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rish
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
version: "0.1"
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- Mikio L. Braun
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain: []
|
15
|
+
|
16
|
+
date: 2010-04-14 00:00:00 +02:00
|
17
|
+
default_executable:
|
18
|
+
dependencies:
|
19
|
+
- !ruby/object:Gem::Dependency
|
20
|
+
name: fastri
|
21
|
+
prerelease: false
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
segments:
|
27
|
+
- 0
|
28
|
+
version: "0"
|
29
|
+
type: :runtime
|
30
|
+
version_requirements: *id001
|
31
|
+
description: |
|
32
|
+
An interactive Ruby shell with auto-reloading, shell-outs, profiling,
|
33
|
+
and integrated help.
|
34
|
+
|
35
|
+
email: mikiobraun@gmail.com
|
36
|
+
executables:
|
37
|
+
- rish
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files: []
|
41
|
+
|
42
|
+
files:
|
43
|
+
- bin/rish
|
44
|
+
- lib/rish/commands.rb
|
45
|
+
- lib/rish/autoreload.rb
|
46
|
+
- lib/rish/irb.rb
|
47
|
+
- lib/rish/hook.rb
|
48
|
+
- lib/rish/interactive.rb
|
49
|
+
- lib/rish/shell.rb
|
50
|
+
has_rdoc: true
|
51
|
+
homepage: http://github.com/mikiobraun/rish
|
52
|
+
licenses: []
|
53
|
+
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 1.3.6
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: Ruby interactive shell
|
80
|
+
test_files: []
|
81
|
+
|