rib 0.1.0 → 0.9.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 (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