rib 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.gitignore +6 -0
  2. data/.gitmodules +3 -0
  3. data/.travis.yml +9 -0
  4. data/2011-02-28.md +203 -0
  5. data/CHANGES +86 -0
  6. data/CONTRIBUTORS +2 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +201 -0
  9. data/README +190 -0
  10. data/README.md +190 -0
  11. data/Rakefile +20 -0
  12. data/TODO +6 -0
  13. data/lib/rib.rb +42 -0
  14. data/lib/rib/all.rb +4 -0
  15. data/lib/rib/api.rb +105 -0
  16. data/lib/rib/core.rb +5 -0
  17. data/lib/rib/core/completion.rb +22 -0
  18. data/lib/rib/core/history_file.rb +38 -0
  19. data/lib/rib/core/readline.rb +19 -0
  20. data/lib/rib/core/underscore.rb +53 -0
  21. data/lib/rib/debug.rb +3 -0
  22. data/lib/rib/more.rb +12 -0
  23. data/lib/rib/more/color.rb +98 -0
  24. data/lib/rib/more/multiline.rb +77 -0
  25. data/lib/rib/more/multiline_history.rb +31 -0
  26. data/lib/rib/more/multiline_history_file.rb +37 -0
  27. data/lib/rib/more/squeeze_history.rb +37 -0
  28. data/lib/rib/more/strip_backtrace.rb +43 -0
  29. data/lib/rib/plugin.rb +56 -0
  30. data/lib/rib/runner.rb +106 -0
  31. data/lib/rib/shell.rb +43 -0
  32. data/lib/rib/test.rb +25 -0
  33. data/lib/rib/version.rb +4 -0
  34. data/lib/rib/zore.rb +3 -0
  35. data/lib/rib/zore/anchor.rb +69 -0
  36. data/lib/rib/zore/edit.rb +33 -0
  37. data/rib.gemspec +104 -0
  38. data/screenshot.png +0 -0
  39. data/task/.gitignore +1 -0
  40. data/task/gemgem.rb +182 -0
  41. data/test/core/test_completion.rb +18 -0
  42. data/test/core/test_history_file.rb +57 -0
  43. data/test/core/test_readline.rb +21 -0
  44. data/test/core/test_underscore.rb +41 -0
  45. data/test/more/test_color.rb +28 -0
  46. data/test/more/test_squeeze_history.rb +43 -0
  47. data/test/test_api.rb +20 -0
  48. data/test/test_plugin.rb +38 -0
  49. data/test/test_shell.rb +82 -0
  50. metadata +77 -13
@@ -0,0 +1,4 @@
1
+
2
+ require 'rib/core'
3
+ require 'rib/more'
4
+ require 'rib/zore'
@@ -0,0 +1,105 @@
1
+
2
+ module Rib; end
3
+ module Rib::API
4
+ def before_loop
5
+ read_history
6
+ self
7
+ end
8
+
9
+ def in_loop
10
+ input = catch(:rib_exit){ loop_once while true }
11
+ puts if input == nil
12
+ end
13
+
14
+ # Runs through one loop iteration: gets input, evals and prints result
15
+ def loop_once
16
+ self.error_raised = nil
17
+ input = get_input
18
+ throw(:rib_exit, input) if config[:exit].include?(input)
19
+ if input.strip == ''
20
+ eval_input(input)
21
+ else
22
+ print_result(eval_input(input))
23
+ end
24
+ rescue Interrupt
25
+ handle_interrupt
26
+ end
27
+
28
+ # Handles interrupt (Control-C) by printing a newline
29
+ def handle_interrupt() puts end
30
+
31
+ # Sets @result to result of evaling input and print unexpected errors
32
+ def eval_input(input)
33
+ loop_eval(input)
34
+ rescue Exception => e
35
+ self.error_raised = true
36
+ print_eval_error(e)
37
+ ensure
38
+ config[:line] += 1
39
+ end
40
+
41
+ # When extending this method, ensure your plugin disables readline:
42
+ # Readline.config[:readline] = false.
43
+ # @return [String, nil] Prints #prompt and returns input given by user
44
+ def get_input
45
+ print(prompt)
46
+ if input = $stdin.gets
47
+ input.chomp
48
+ else
49
+ nil
50
+ end
51
+ end
52
+
53
+ # @return [String]
54
+ def prompt
55
+ config[:prompt]
56
+ end
57
+
58
+ def read_history
59
+ end
60
+
61
+ def write_history
62
+ end
63
+
64
+ def history
65
+ @history ||= []
66
+ end
67
+
68
+ # Evals user input using @binding, @name and @line
69
+ def loop_eval(input)
70
+ config[:binding].eval(input, "(#{config[:name]})", config[:line])
71
+ end
72
+
73
+ # Prints error formatted by #format_error to STDERR. Could be extended to
74
+ # handle certain exceptions.
75
+ # @param [Exception]
76
+ def print_eval_error(err)
77
+ warn format_error(err)
78
+ end
79
+
80
+ # Prints result using #format_result
81
+ def print_result(result)
82
+ puts(format_result(result)) unless error_raised
83
+ rescue StandardError, SyntaxError => e
84
+ warn "#{config[:name]}: Error while printing result:\n" \
85
+ "#{format_error(e)}"
86
+ end
87
+
88
+ # Formats errors raised by eval of user input
89
+ # @param [Exception]
90
+ # @return [String]
91
+ def format_error(e)
92
+ "#{e.class}: #{e.message}\n #{e.backtrace.join("\n ")}"
93
+ end
94
+
95
+ # @return [String] Formats result using result_prompt
96
+ def format_result(result)
97
+ config[:result_prompt] + result.inspect
98
+ end
99
+
100
+ # Called after shell finishes looping.
101
+ def after_loop
102
+ write_history
103
+ self
104
+ end
105
+ end
@@ -0,0 +1,5 @@
1
+
2
+ require 'rib/core/completion'
3
+ require 'rib/core/history_file'
4
+ require 'rib/core/readline'
5
+ require 'rib/core/underscore'
@@ -0,0 +1,22 @@
1
+
2
+ require 'rib'
3
+ require 'bond'
4
+
5
+ module Rib::Completion
6
+ include Rib::Plugin
7
+ Shell.use(self)
8
+
9
+ def before_loop
10
+ return super if Completion.disabled?
11
+ config[:completion] ||= {}
12
+ config[:completion][:eval_binding] ||= lambda{ config[:binding] }
13
+ (config[:completion][:gems] ||= []).concat(ripl_plugins)
14
+ Bond.start(config[:completion])
15
+ super
16
+ end
17
+
18
+ private
19
+ def ripl_plugins
20
+ $LOADED_FEATURES.map{ |e| e[/ripl\/[^\/]+$/] }.compact
21
+ end
22
+ end
@@ -0,0 +1,38 @@
1
+
2
+ require 'rib'
3
+ require 'fileutils'
4
+
5
+ module Rib::HistoryFile
6
+ include Rib::Plugin
7
+ Shell.use(self)
8
+
9
+ def before_loop
10
+ return super if HistoryFile.disabled?
11
+ config[:history_file] ||= '~/.config/rib/history.rb'
12
+ config[:history_size] ||= 500
13
+ FileUtils.mkdir_p(File.dirname(history_file))
14
+ super
15
+ end
16
+
17
+ def get_input
18
+ return super if HistoryFile.disabled?
19
+ (history << super).last
20
+ end
21
+
22
+ def read_history
23
+ return super if HistoryFile.disabled?
24
+ File.exist?(history_file) && history.empty? &&
25
+ File.readlines(history_file).each{ |e| history << e.chomp }
26
+ end
27
+
28
+ def write_history
29
+ return super if HistoryFile.disabled?
30
+ File.open(history_file, 'w'){ |f|
31
+ f.puts(history.to_a.last(config[:history_size]).join("\n")) }
32
+ end
33
+
34
+ private
35
+ def history_file
36
+ @history_file ||= File.expand_path(config[:history_file])
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+
2
+ require 'rib'
3
+ require 'readline'
4
+
5
+ module Rib::Readline
6
+ include Rib::Plugin
7
+ Shell.use(self)
8
+
9
+ def before_loop
10
+ return super if Readline.disabled?
11
+ @history = ::Readline::HISTORY
12
+ super
13
+ end
14
+
15
+ def get_input
16
+ return super if Readline.disabled?
17
+ ::Readline.readline(prompt, true)
18
+ end
19
+ end
@@ -0,0 +1,53 @@
1
+
2
+ require 'rib'
3
+
4
+ module Rib::Underscore
5
+ include Rib::Plugin
6
+ Shell.use(self)
7
+
8
+ IVAR = {:_ => :@__rib_result__,
9
+ :__ => :@__rib_exception__}
10
+
11
+ def before_loop
12
+ return super if Underscore.disabled?
13
+ eliminate_warnings
14
+ inject_inspecter
15
+ super
16
+ end
17
+
18
+ def loop_eval input
19
+ return super if Underscore.disabled?
20
+ bound_object.instance_variable_set(:@__rib_result__, super)
21
+ end
22
+
23
+ def print_eval_error e
24
+ return super if Underscore.disabled?
25
+ bound_object.instance_variable_set(:@__rib_exception__, e)
26
+ super
27
+ end
28
+
29
+ private
30
+ def eliminate_warnings
31
+ IVAR.values.each{ |ivar| bound_object.instance_variable_set(ivar, nil) }
32
+ end
33
+
34
+ def inject_inspecter
35
+ IVAR.each{ |k, v|
36
+ bound_singleton.send(:define_method, k){
37
+ instance_variable_get(v)
38
+ } unless bound_object.respond_to?(k) # only inject for innocences
39
+ }
40
+ end
41
+
42
+ def bound_singleton
43
+ if respond_to?(:singleton_class)
44
+ bound_object.singleton_class
45
+ else
46
+ class << bound_object; self; end
47
+ end
48
+ end
49
+
50
+ def bound_object
51
+ config[:binding].eval('self')
52
+ end
53
+ end
@@ -0,0 +1,3 @@
1
+
2
+ require 'rib/zore/anchor'
3
+ Rib::Anchor.disable
@@ -0,0 +1,12 @@
1
+
2
+ # upon session ends
3
+ require 'rib/more/squeeze_history'
4
+ require 'rib/more/multiline_history_file'
5
+
6
+ # upon formatting output
7
+ require 'rib/more/strip_backtrace'
8
+ require 'rib/more/color'
9
+
10
+ # upon input
11
+ require 'rib/more/multiline'
12
+ require 'rib/more/multiline_history'
@@ -0,0 +1,98 @@
1
+
2
+ require 'rib'
3
+
4
+ module Rib::Color
5
+ include Rib::Plugin
6
+ Shell.use(self)
7
+
8
+ def before_loop
9
+ config[:color] ||= {
10
+ Numeric => :red ,
11
+ String => :green ,
12
+ Symbol => :cyan ,
13
+ Array => :blue ,
14
+ Hash => :blue ,
15
+ NilClass => :magenta,
16
+ TrueClass => :magenta,
17
+ FalseClass => :magenta,
18
+ Exception => :magenta,
19
+ Object => :yellow
20
+ }
21
+ super
22
+ end
23
+
24
+ def format_result result
25
+ return super if Color.disabled?
26
+ config[:result_prompt] + format_color(result)
27
+ end
28
+
29
+ private
30
+ def colors
31
+ config[:color]
32
+ end
33
+
34
+ def format_color result, display=result.inspect
35
+ case result
36
+ when String ; P.send(colors[String ]){ display }
37
+ when Numeric; P.send(colors[Numeric]){ display }
38
+ when Symbol ; P.send(colors[Symbol ]){ display }
39
+
40
+ when Array ; P.send(colors[Array ]){ '[' } +
41
+ result.map{ |e | format_color(e) }.
42
+ join(P.send(colors[Array ]){ ', ' }) +
43
+ P.send(colors[Array ]){ ']' }
44
+
45
+ when Hash ; P.send(colors[Hash ]){ '{' } +
46
+ result.map{ |k, v| format_color(k) +
47
+ P.send(colors[Hash ]){ '=>' } +
48
+ format_color(v) }.
49
+ join(P.send(colors[Hash ]){ ', ' }) +
50
+ P.send(colors[Hash ]){ '}' }
51
+
52
+ else ; if color = P.find_color(colors, result)
53
+ P.send(color){ display }
54
+ else
55
+ P.send(colors[Object ]){ display }
56
+ end
57
+ end
58
+ end
59
+
60
+ def get_error e, backtrace=e.backtrace
61
+ return super if Color.disabled?
62
+ [format_color(e, "#{e.class.to_s}: #{e.message}"),
63
+ backtrace.map{ |b|
64
+ path, rest = ::File.split(b)
65
+ name, msgs = rest.split(':', 2)
66
+ msg = msgs.sub(/(\d+):/){P.red{$1}+':'}.sub(/`.+?'/){P.green{$&}}
67
+
68
+ "#{path+'/'}#{P.yellow{name}}:#{msg}"
69
+ }]
70
+ end
71
+
72
+ module Imp
73
+ def find_color colors, value
74
+ (colors.sort{ |(k1, v1), (k2, v2)|
75
+ # Class <=> Class
76
+ if k1 < k2 then -1
77
+ elsif k1 > k2 then 1
78
+ else 0
79
+ end}.find{ |(klass, _)| value.kind_of?(klass) } || []).last
80
+ end
81
+
82
+ def color rgb
83
+ "\x1b[#{rgb}m" + (block_given? ? "#{yield}#{reset}" : '')
84
+ end
85
+
86
+ def black &block; color(30, &block); end
87
+ def red &block; color(31, &block); end
88
+ def green &block; color(32, &block); end
89
+ def yellow &block; color(33, &block); end
90
+ def blue &block; color(34, &block); end
91
+ def magenta &block; color(35, &block); end
92
+ def cyan &block; color(36, &block); end
93
+ def white &block; color(37, &block); end
94
+ def reset &block; color('', &block); end
95
+ end
96
+
97
+ Plugin.extend(Imp)
98
+ end
@@ -0,0 +1,77 @@
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
+ # test those:
10
+ # ruby -e '"'
11
+ # ruby -e '{'
12
+ # ruby -e '['
13
+ # ruby -e '('
14
+ # ruby -e '/'
15
+ # ruby -e 'class C'
16
+ # ruby -e 'def f'
17
+ # ruby -e 'begin'
18
+ ERROR_REGEXP = Regexp.new(
19
+ [ # string or regexp
20
+ "unterminated \\w+ meets end of file",
21
+ # mri and rubinius
22
+ "syntax error, unexpected \\$end",
23
+ # rubinius
24
+ "expecting '.+'( or '.+')*",
25
+ # jruby
26
+ "syntax error, unexpected end-of-file",
27
+ ].join('|'))
28
+
29
+ def prompt
30
+ return super if Multiline.disabled?
31
+ if multiline_buffer.empty?
32
+ super
33
+ else
34
+ "#{' '*(config[:prompt].size-2)}| "
35
+ end
36
+ end
37
+
38
+ def loop_once
39
+ return super if Multiline.disabled?
40
+ catch(:multiline_cont) do
41
+ super
42
+ multiline_buffer.clear
43
+ end
44
+ end
45
+
46
+ def loop_eval(input)
47
+ return super if Multiline.disabled?
48
+ multiline_buffer << input
49
+ super(multiline_buffer.join("\n"))
50
+ end
51
+
52
+ def print_eval_error(e)
53
+ return super if Multiline.disabled?
54
+ if e.is_a?(SyntaxError) && e.message =~ ERROR_REGEXP
55
+ throw :multiline_cont
56
+ else
57
+ super
58
+ end
59
+ end
60
+
61
+ def handle_interrupt
62
+ return super if Multiline.disabled?
63
+ if multiline_buffer.empty?
64
+ super
65
+ else
66
+ line = multiline_buffer.pop
67
+ print "[removed this line: #{line}]"
68
+ super
69
+ throw :multiline_cont
70
+ end
71
+ end
72
+
73
+ private
74
+ def multiline_buffer
75
+ @multiline_buffer ||= []
76
+ end
77
+ end