rib 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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