rib 0.1.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/.gitignore +0 -4
  2. data/CHANGES.md +6 -0
  3. data/README +107 -113
  4. data/README.md +107 -113
  5. data/Rakefile +5 -3
  6. data/TODO.md +6 -0
  7. data/bin/rib-all +5 -0
  8. data/bin/rib-auto +9 -0
  9. data/bin/rib-min +5 -0
  10. data/bin/rib-rails +9 -0
  11. data/bin/rib-ramaze +9 -0
  12. data/lib/rib.rb +70 -6
  13. data/lib/rib/all.rb +0 -1
  14. data/lib/rib/api.rb +60 -64
  15. data/lib/rib/app/auto.rb +25 -0
  16. data/lib/rib/app/rails.rb +41 -0
  17. data/lib/rib/app/ramaze.rb +25 -0
  18. data/lib/rib/config.rb +3 -0
  19. data/lib/rib/core.rb +13 -1
  20. data/lib/rib/core/completion.rb +15 -3
  21. data/lib/rib/core/history.rb +56 -0
  22. data/lib/rib/core/multiline.rb +104 -0
  23. data/lib/rib/core/readline.rb +3 -1
  24. data/lib/rib/core/squeeze_history.rb +45 -0
  25. data/lib/rib/core/strip_backtrace.rb +45 -0
  26. data/lib/rib/core/underscore.rb +17 -8
  27. data/lib/rib/debug.rb +2 -1
  28. data/lib/rib/dep/hirb.rb +24 -0
  29. data/lib/rib/more.rb +4 -3
  30. data/lib/rib/more/anchor.rb +85 -0
  31. data/lib/rib/more/color.rb +44 -43
  32. data/lib/rib/{zore → more}/edit.rb +3 -3
  33. data/lib/rib/more/multiline_history.rb +24 -12
  34. data/lib/rib/more/multiline_history_file.rb +7 -3
  35. data/lib/rib/plugin.rb +2 -4
  36. data/lib/rib/runner.rb +84 -49
  37. data/lib/rib/shell.rb +4 -2
  38. data/lib/rib/test.rb +55 -2
  39. data/lib/rib/test/multiline.rb +140 -0
  40. data/lib/rib/version.rb +1 -1
  41. data/rib.gemspec +54 -22
  42. data/screenshot.png +0 -0
  43. data/task/gemgem.rb +3 -1
  44. data/test/core/{test_history_file.rb → test_history.rb} +29 -19
  45. data/test/core/test_multiline.rb +22 -0
  46. data/test/core/test_readline.rb +13 -8
  47. data/test/{more → core}/test_squeeze_history.rb +24 -18
  48. data/test/core/test_underscore.rb +32 -21
  49. data/test/more/test_multiline_history.rb +42 -0
  50. data/test/test_shell.rb +13 -8
  51. metadata +72 -27
  52. data/2011-02-28.md +0 -203
  53. data/CHANGES +0 -86
  54. data/TODO +0 -6
  55. data/lib/rib/core/history_file.rb +0 -38
  56. data/lib/rib/more/multiline.rb +0 -77
  57. data/lib/rib/more/squeeze_history.rb +0 -37
  58. data/lib/rib/more/strip_backtrace.rb +0 -43
  59. data/lib/rib/zore.rb +0 -3
  60. data/lib/rib/zore/anchor.rb +0 -69
data/lib/rib/config.rb ADDED
@@ -0,0 +1,3 @@
1
+
2
+ require 'rib'
3
+ Rib.require_config
data/lib/rib/core.rb CHANGED
@@ -1,5 +1,17 @@
1
1
 
2
+ # before session starts
2
3
  require 'rib/core/completion'
3
- require 'rib/core/history_file'
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'
@@ -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] ||= lambda{ config[: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
@@ -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
- @history = ::Readline::HISTORY
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
@@ -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 loop_eval input
20
+ def print_result result
19
21
  return super if Underscore.disabled?
20
- bound_object.instance_variable_set(:@__rib_result__, super)
22
+ bound_object.instance_variable_set(:@__rib_result__, result)
23
+ super
21
24
  end
22
25
 
23
- def print_eval_error e
26
+ def print_eval_error err
24
27
  return super if Underscore.disabled?
25
- bound_object.instance_variable_set(:@__rib_exception__, e)
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
@@ -1,3 +1,4 @@
1
1
 
2
- require 'rib/zore/anchor'
2
+ require 'rib/config'
3
+ require 'rib/more/anchor'
3
4
  Rib::Anchor.disable
@@ -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