rib 0.1.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -4
- data/CHANGES.md +6 -0
- data/README +107 -113
- data/README.md +107 -113
- data/Rakefile +5 -3
- data/TODO.md +6 -0
- data/bin/rib-all +5 -0
- data/bin/rib-auto +9 -0
- data/bin/rib-min +5 -0
- data/bin/rib-rails +9 -0
- data/bin/rib-ramaze +9 -0
- data/lib/rib.rb +70 -6
- data/lib/rib/all.rb +0 -1
- data/lib/rib/api.rb +60 -64
- data/lib/rib/app/auto.rb +25 -0
- data/lib/rib/app/rails.rb +41 -0
- data/lib/rib/app/ramaze.rb +25 -0
- data/lib/rib/config.rb +3 -0
- data/lib/rib/core.rb +13 -1
- data/lib/rib/core/completion.rb +15 -3
- data/lib/rib/core/history.rb +56 -0
- data/lib/rib/core/multiline.rb +104 -0
- data/lib/rib/core/readline.rb +3 -1
- data/lib/rib/core/squeeze_history.rb +45 -0
- data/lib/rib/core/strip_backtrace.rb +45 -0
- data/lib/rib/core/underscore.rb +17 -8
- data/lib/rib/debug.rb +2 -1
- data/lib/rib/dep/hirb.rb +24 -0
- data/lib/rib/more.rb +4 -3
- data/lib/rib/more/anchor.rb +85 -0
- data/lib/rib/more/color.rb +44 -43
- data/lib/rib/{zore → more}/edit.rb +3 -3
- data/lib/rib/more/multiline_history.rb +24 -12
- data/lib/rib/more/multiline_history_file.rb +7 -3
- data/lib/rib/plugin.rb +2 -4
- data/lib/rib/runner.rb +84 -49
- data/lib/rib/shell.rb +4 -2
- data/lib/rib/test.rb +55 -2
- data/lib/rib/test/multiline.rb +140 -0
- data/lib/rib/version.rb +1 -1
- data/rib.gemspec +54 -22
- data/screenshot.png +0 -0
- data/task/gemgem.rb +3 -1
- data/test/core/{test_history_file.rb → test_history.rb} +29 -19
- data/test/core/test_multiline.rb +22 -0
- data/test/core/test_readline.rb +13 -8
- data/test/{more → core}/test_squeeze_history.rb +24 -18
- data/test/core/test_underscore.rb +32 -21
- data/test/more/test_multiline_history.rb +42 -0
- data/test/test_shell.rb +13 -8
- metadata +72 -27
- data/2011-02-28.md +0 -203
- data/CHANGES +0 -86
- data/TODO +0 -6
- data/lib/rib/core/history_file.rb +0 -38
- data/lib/rib/more/multiline.rb +0 -77
- data/lib/rib/more/squeeze_history.rb +0 -37
- data/lib/rib/more/strip_backtrace.rb +0 -43
- data/lib/rib/zore.rb +0 -3
- data/lib/rib/zore/anchor.rb +0 -69
data/lib/rib/config.rb
ADDED
data/lib/rib/core.rb
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
|
2
|
+
# before session starts
|
2
3
|
require 'rib/core/completion'
|
3
|
-
|
4
|
+
|
5
|
+
# upon session ends
|
6
|
+
require 'rib/core/history'
|
7
|
+
|
8
|
+
# upon formatting output
|
9
|
+
require 'rib/core/strip_backtrace'
|
10
|
+
|
11
|
+
# upon input
|
4
12
|
require 'rib/core/readline'
|
13
|
+
require 'rib/core/multiline'
|
14
|
+
require 'rib/core/squeeze_history'
|
15
|
+
|
16
|
+
# special tools
|
5
17
|
require 'rib/core/underscore'
|
data/lib/rib/core/completion.rb
CHANGED
@@ -1,22 +1,34 @@
|
|
1
1
|
|
2
2
|
require 'rib'
|
3
|
-
require 'bond'
|
4
3
|
|
5
4
|
module Rib::Completion
|
6
5
|
include Rib::Plugin
|
7
6
|
Shell.use(self)
|
8
7
|
|
8
|
+
# --------------- Rib API ---------------
|
9
|
+
|
9
10
|
def before_loop
|
10
11
|
return super if Completion.disabled?
|
11
12
|
config[:completion] ||= {}
|
12
|
-
config[:completion][:eval_binding] ||=
|
13
|
+
config[:completion][:eval_binding] ||= method(:eval_binding).to_proc
|
13
14
|
(config[:completion][:gems] ||= []).concat(ripl_plugins)
|
14
|
-
Bond.start(config[:completion])
|
15
|
+
Rib.silence{Bond.start(config[:completion]) unless Bond.started?}
|
15
16
|
super
|
16
17
|
end
|
17
18
|
|
19
|
+
|
20
|
+
|
18
21
|
private
|
19
22
|
def ripl_plugins
|
20
23
|
$LOADED_FEATURES.map{ |e| e[/ripl\/[^\/]+$/] }.compact
|
21
24
|
end
|
22
25
|
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
Rib.silence{require 'bond'}
|
29
|
+
rescue LoadError
|
30
|
+
Rib.warn("Please install bond to use completion plugin:\n",
|
31
|
+
" gem install bond\n",
|
32
|
+
"Or add bond to Gemfile if that's the case")
|
33
|
+
Rib::Completion.disable
|
34
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
|
2
|
+
require 'rib'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Rib::History
|
6
|
+
include Rib::Plugin
|
7
|
+
Shell.use(self)
|
8
|
+
|
9
|
+
# --------------- Rib API ---------------
|
10
|
+
|
11
|
+
def before_loop
|
12
|
+
return super if History.disabled?
|
13
|
+
config[:history_file] ||= '~/.config/rib/history.rb'
|
14
|
+
config[:history_size] ||= 500
|
15
|
+
FileUtils.mkdir_p(File.dirname(history_file_path))
|
16
|
+
read_history
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def after_loop
|
21
|
+
return super if History.disabled?
|
22
|
+
write_history
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_input
|
27
|
+
return super if History.disabled?
|
28
|
+
(history << super).last
|
29
|
+
end
|
30
|
+
|
31
|
+
# --------------- Plugin API ---------------
|
32
|
+
|
33
|
+
# The history data
|
34
|
+
def history; config[:history] ||= []; end
|
35
|
+
|
36
|
+
# Read config[:history_file] into #history, handled in history_file plugin
|
37
|
+
def read_history
|
38
|
+
return super if History.disabled?
|
39
|
+
File.exist?(history_file_path) && history.empty? &&
|
40
|
+
File.readlines(history_file_path).each{ |e| history << e.chomp }
|
41
|
+
end
|
42
|
+
|
43
|
+
# Write #history into config[:history_file], handled in history_file plugin
|
44
|
+
def write_history
|
45
|
+
return super if History.disabled?
|
46
|
+
File.open(history_file_path, 'w'){ |f|
|
47
|
+
f.puts(history.to_a.last(config[:history_size]).join("\n")) }
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
private
|
53
|
+
def history_file_path
|
54
|
+
config[:history_file_path] ||= File.expand_path(config[:history_file])
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
|
2
|
+
require 'rib'
|
3
|
+
|
4
|
+
# from https://github.com/janlelis/ripl-multi_line
|
5
|
+
module Rib::Multiline
|
6
|
+
include Rib::Plugin
|
7
|
+
Shell.use(self)
|
8
|
+
|
9
|
+
engine = if Object.const_defined?(:RUBY_ENGINE)
|
10
|
+
RUBY_ENGINE
|
11
|
+
else
|
12
|
+
'ruby'
|
13
|
+
end
|
14
|
+
|
15
|
+
# test those:
|
16
|
+
# ruby -e '"'
|
17
|
+
# ruby -e '{'
|
18
|
+
# ruby -e '['
|
19
|
+
# ruby -e '('
|
20
|
+
# ruby -e '/'
|
21
|
+
# ruby -e 'class C'
|
22
|
+
# ruby -e 'def f'
|
23
|
+
# ruby -e 'begin'
|
24
|
+
ERROR_REGEXP = case engine
|
25
|
+
when 'ruby' ; Regexp.new(
|
26
|
+
[ # string or regexp
|
27
|
+
"unterminated \\w+ meets end of file",
|
28
|
+
# mri and rubinius
|
29
|
+
"syntax error, unexpected \\$end"] .join('|'))
|
30
|
+
when 'rbx' ; Regexp.new(
|
31
|
+
[ # string or regexp
|
32
|
+
"unterminated \\w+ meets end of file",
|
33
|
+
# mri and rubinius
|
34
|
+
"syntax error, unexpected \\$end" ,
|
35
|
+
# rubinius
|
36
|
+
"expecting '.+'( or '.+')*" ,
|
37
|
+
"missing '.+' for '.+' started on line \\d+"].join('|'))
|
38
|
+
when 'jruby'; Regexp.new(
|
39
|
+
[ # string or regexp
|
40
|
+
"unterminated \\w+ meets end of file",
|
41
|
+
# jruby
|
42
|
+
"syntax error, unexpected end-of-file"] .join('|'))
|
43
|
+
end
|
44
|
+
|
45
|
+
# --------------- Rib API ---------------
|
46
|
+
|
47
|
+
def loop_once
|
48
|
+
return super if Multiline.disabled?
|
49
|
+
result = nil
|
50
|
+
catch(:rib_multiline) do
|
51
|
+
result = super
|
52
|
+
multiline_buffer.clear
|
53
|
+
end
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
def loop_eval input
|
58
|
+
return super if Multiline.disabled?
|
59
|
+
multiline_buffer << input
|
60
|
+
super(multiline_buffer.join("\n"))
|
61
|
+
end
|
62
|
+
|
63
|
+
def print_eval_error err
|
64
|
+
return super if Multiline.disabled?
|
65
|
+
if multiline?(err)
|
66
|
+
throw :rib_multiline
|
67
|
+
else
|
68
|
+
super
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def prompt
|
73
|
+
return super if Multiline.disabled?
|
74
|
+
if multiline_buffer.empty?
|
75
|
+
super
|
76
|
+
else
|
77
|
+
"#{' '*(config[:prompt].size-2)}| "
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def handle_interrupt
|
82
|
+
return super if Multiline.disabled?
|
83
|
+
if multiline_buffer.empty?
|
84
|
+
super
|
85
|
+
else
|
86
|
+
print "[removed this line: #{multiline_buffer.pop}]"
|
87
|
+
super
|
88
|
+
throw :rib_multiline
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# --------------- Plugin API ---------------
|
93
|
+
|
94
|
+
def multiline? err
|
95
|
+
err.is_a?(SyntaxError) && err.message =~ ERROR_REGEXP
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
private
|
101
|
+
def multiline_buffer
|
102
|
+
@multiline_buffer ||= []
|
103
|
+
end
|
104
|
+
end
|
data/lib/rib/core/readline.rb
CHANGED
@@ -6,9 +6,11 @@ module Rib::Readline
|
|
6
6
|
include Rib::Plugin
|
7
7
|
Shell.use(self)
|
8
8
|
|
9
|
+
# --------------- Rib API ---------------
|
10
|
+
|
9
11
|
def before_loop
|
10
12
|
return super if Readline.disabled?
|
11
|
-
|
13
|
+
config[:history] = ::Readline::HISTORY
|
12
14
|
super
|
13
15
|
end
|
14
16
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
require 'rib/core/history'
|
3
|
+
|
4
|
+
module Rib::SqueezeHistory
|
5
|
+
include Rib::Plugin
|
6
|
+
Shell.use(self)
|
7
|
+
|
8
|
+
# --------------- Rib API ---------------
|
9
|
+
|
10
|
+
# squeeze history in memory too
|
11
|
+
def loop_once
|
12
|
+
return super if SqueezeHistory.disabled?
|
13
|
+
begin
|
14
|
+
input, last_input = history[-1], history[-2]
|
15
|
+
rescue IndexError # EditLine is really broken, to_a is needed for it
|
16
|
+
array = history.to_a
|
17
|
+
input, last_input = array[-1], array[-2]
|
18
|
+
end
|
19
|
+
history.pop if input.to_s.strip == '' ||
|
20
|
+
(history.size > 1 && input == last_input)
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
# --------------- Plugin API ---------------
|
25
|
+
|
26
|
+
# write squeezed history
|
27
|
+
def write_history
|
28
|
+
return super if SqueezeHistory.disabled?
|
29
|
+
config[:history] = squeezed_history
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
private
|
36
|
+
def squeezed_history
|
37
|
+
history.to_a.inject([]){ |result, item|
|
38
|
+
if result.last == item || item.strip == ''
|
39
|
+
result
|
40
|
+
else
|
41
|
+
result << item
|
42
|
+
end
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
require 'rib'
|
3
|
+
|
4
|
+
module Rib::StripBacktrace
|
5
|
+
include Rib::Plugin
|
6
|
+
Shell.use(self)
|
7
|
+
|
8
|
+
# --------------- Rib API ---------------
|
9
|
+
|
10
|
+
# strip backtrace until ripl
|
11
|
+
def format_error err
|
12
|
+
return super if StripBacktrace.disabled?
|
13
|
+
message, backtrace = get_error(err, strip_backtrace(err))
|
14
|
+
"#{message}\n #{backtrace.join("\n ")}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# --------------- Plugin API ---------------
|
18
|
+
|
19
|
+
def get_error err, backtrace=err.backtrace
|
20
|
+
return super if StripBacktrace.disabled?
|
21
|
+
["#{err.class}: #{err.message}", backtrace]
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
private
|
27
|
+
def strip_backtrace err
|
28
|
+
strip_home_backtrace(strip_cwd_backtrace(strip_lib_backtrace(err)))
|
29
|
+
end
|
30
|
+
|
31
|
+
def strip_home_backtrace backtrace
|
32
|
+
backtrace.map{ |path| path.sub(ENV['HOME'], '~') }
|
33
|
+
end
|
34
|
+
|
35
|
+
def strip_cwd_backtrace backtrace
|
36
|
+
backtrace.map{ |path| path.sub(Dir.pwd, '.') }
|
37
|
+
end
|
38
|
+
|
39
|
+
def strip_lib_backtrace err
|
40
|
+
return [] if err.kind_of?(SyntaxError)
|
41
|
+
err.backtrace[
|
42
|
+
0..
|
43
|
+
err.backtrace.rindex{ |l| l =~ /\(#{name}\):\d+:in `.+?'/ } || -1]
|
44
|
+
end
|
45
|
+
end
|
data/lib/rib/core/underscore.rb
CHANGED
@@ -8,6 +8,8 @@ module Rib::Underscore
|
|
8
8
|
IVAR = {:_ => :@__rib_result__,
|
9
9
|
:__ => :@__rib_exception__}
|
10
10
|
|
11
|
+
# --------------- Rib API ---------------
|
12
|
+
|
11
13
|
def before_loop
|
12
14
|
return super if Underscore.disabled?
|
13
15
|
eliminate_warnings
|
@@ -15,17 +17,26 @@ module Rib::Underscore
|
|
15
17
|
super
|
16
18
|
end
|
17
19
|
|
18
|
-
def
|
20
|
+
def print_result result
|
19
21
|
return super if Underscore.disabled?
|
20
|
-
bound_object.instance_variable_set(:@__rib_result__,
|
22
|
+
bound_object.instance_variable_set(:@__rib_result__, result)
|
23
|
+
super
|
21
24
|
end
|
22
25
|
|
23
|
-
def print_eval_error
|
26
|
+
def print_eval_error err
|
24
27
|
return super if Underscore.disabled?
|
25
|
-
bound_object.instance_variable_set(:@__rib_exception__,
|
28
|
+
bound_object.instance_variable_set(:@__rib_exception__, err)
|
26
29
|
super
|
27
30
|
end
|
28
31
|
|
32
|
+
# --------------- Plugin API ---------------
|
33
|
+
|
34
|
+
def bound_object
|
35
|
+
config[:bound_object] ||= eval_binding.eval('self', __FILE__, __LINE__)
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
29
40
|
private
|
30
41
|
def eliminate_warnings
|
31
42
|
IVAR.values.each{ |ivar| bound_object.instance_variable_set(ivar, nil) }
|
@@ -37,6 +48,8 @@ module Rib::Underscore
|
|
37
48
|
instance_variable_get(v)
|
38
49
|
} unless bound_object.respond_to?(k) # only inject for innocences
|
39
50
|
}
|
51
|
+
rescue TypeError
|
52
|
+
# can't define singleton method for immediate value
|
40
53
|
end
|
41
54
|
|
42
55
|
def bound_singleton
|
@@ -46,8 +59,4 @@ module Rib::Underscore
|
|
46
59
|
class << bound_object; self; end
|
47
60
|
end
|
48
61
|
end
|
49
|
-
|
50
|
-
def bound_object
|
51
|
-
config[:binding].eval('self')
|
52
|
-
end
|
53
62
|
end
|
data/lib/rib/debug.rb
CHANGED
data/lib/rib/dep/hirb.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
require 'rib'
|
3
|
+
|
4
|
+
module Rib::Hirb
|
5
|
+
include Rib::Plugin
|
6
|
+
Shell.use(self)
|
7
|
+
|
8
|
+
def format_result result
|
9
|
+
return super if Hirb.disabled?
|
10
|
+
::Hirb::View.view_or_page_output(result) || super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
begin
|
15
|
+
Rib.silence{
|
16
|
+
require 'hirb'
|
17
|
+
::Hirb.enable
|
18
|
+
}
|
19
|
+
rescue LoadError
|
20
|
+
Rib.warn("Please install hirb to use hirb plugin:\n",
|
21
|
+
" gem install hirb\n",
|
22
|
+
"Or add hirb to Gemfile if that's the case")
|
23
|
+
Rib::Hirb.disable
|
24
|
+
end
|
data/lib/rib/more.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
|
2
2
|
# upon session ends
|
3
|
-
require 'rib/more/squeeze_history'
|
4
3
|
require 'rib/more/multiline_history_file'
|
5
4
|
|
6
5
|
# upon formatting output
|
7
|
-
require 'rib/more/strip_backtrace'
|
8
6
|
require 'rib/more/color'
|
9
7
|
|
10
8
|
# upon input
|
11
|
-
require 'rib/more/multiline'
|
12
9
|
require 'rib/more/multiline_history'
|
10
|
+
|
11
|
+
# special tools
|
12
|
+
require 'rib/more/anchor'
|
13
|
+
require 'rib/more/edit'
|
@@ -0,0 +1,85 @@
|
|
1
|
+
|
2
|
+
require 'rib'
|
3
|
+
|
4
|
+
module Rib::Anchor
|
5
|
+
include Rib::Plugin
|
6
|
+
Shell.use(self)
|
7
|
+
|
8
|
+
# --------------- Rib API ---------------
|
9
|
+
|
10
|
+
def loop_eval str
|
11
|
+
return super if Rib::Anchor.disabled?
|
12
|
+
if eval_binding.kind_of?(Binding)
|
13
|
+
super
|
14
|
+
else
|
15
|
+
eval_binding.instance_eval(str, "(#{name})", line)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def prompt
|
20
|
+
return super if Rib::Anchor.disabled?
|
21
|
+
return super unless config[:anchor]
|
22
|
+
|
23
|
+
level = "(#{Rib.shells.size - 1})"
|
24
|
+
if Rib.const_defined?(:Color) &&
|
25
|
+
kind_of?(Rib::Color) &&
|
26
|
+
Rib::Color.enabled?
|
27
|
+
|
28
|
+
"#{format_color(eval_binding, prompt_anchor)}#{level}#{super}"
|
29
|
+
else
|
30
|
+
"#{prompt_anchor}#{level}#{super}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# --------------- Plugin API ---------------
|
35
|
+
|
36
|
+
# override Underscore#bound_object
|
37
|
+
def bound_object
|
38
|
+
return super if Rib::Anchor.disabled?
|
39
|
+
return super if eval_binding.kind_of?(Binding)
|
40
|
+
eval_binding
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
private
|
46
|
+
def prompt_anchor
|
47
|
+
@prompt_anchor ||=
|
48
|
+
if eval_binding.kind_of?(Binding)
|
49
|
+
eval_binding.eval('self', __FILE__, __LINE__)
|
50
|
+
else
|
51
|
+
eval_binding
|
52
|
+
end.inspect[0..9]
|
53
|
+
end
|
54
|
+
|
55
|
+
module Imp
|
56
|
+
def anchor obj_or_binding
|
57
|
+
return if Rib::Anchor.disabled?
|
58
|
+
|
59
|
+
if Rib.shell.running?
|
60
|
+
Rib.shells << Rib::Shell.new(
|
61
|
+
Rib.shell.config.merge( :binding => obj_or_binding,
|
62
|
+
:anchor => true ))
|
63
|
+
else
|
64
|
+
Rib.shell.config.merge!(:binding => obj_or_binding,
|
65
|
+
:anchor => true )
|
66
|
+
end
|
67
|
+
|
68
|
+
Rib.shell.loop
|
69
|
+
|
70
|
+
# we can't use ensure block here because we need to do something
|
71
|
+
# (i.e. throw :rib_skip) if there's no exception. this can't be
|
72
|
+
# done via ensure because then we don't know if there's an
|
73
|
+
# exception or not, and ensure block is always executed last
|
74
|
+
rescue
|
75
|
+
Rib.shells.pop
|
76
|
+
raise
|
77
|
+
else
|
78
|
+
# only skip printing anchor result while there's another shell running
|
79
|
+
Rib.shells.pop
|
80
|
+
throw :rib_skip if Rib.shell.running?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
Rib.extend(Imp)
|
85
|
+
end
|