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,31 @@
1
+
2
+ require 'rib/more/multiline' # dependency
3
+
4
+ module Rib::MultilineHistory
5
+ include Rib::Plugin
6
+ Shell.use(self)
7
+
8
+ def loop_eval input
9
+ return super if MultilineHistory.disabled?
10
+ value = super
11
+ rescue Exception
12
+ # might be multiline editing, ignore
13
+ raise
14
+ else
15
+ if multiline_buffer.size > 1
16
+ # so multiline editing is considering done here
17
+ (multiline_buffer.size + (@multiline_trash || 0)).times{ history.pop }
18
+ history << "\n" + multiline_buffer.join("\n")
19
+ end
20
+ value
21
+ end
22
+
23
+ def handle_interrupt
24
+ return super if MultilineHistory.disabled?
25
+ if multiline_buffer.size > 1
26
+ @multiline_trash ||= 0
27
+ @multiline_trash += 1
28
+ end
29
+ super
30
+ end
31
+ end
@@ -0,0 +1,37 @@
1
+
2
+ require 'rib/more/multiline_history'
3
+
4
+ module Rib::MultilineHistoryFile
5
+ include Rib::Plugin
6
+ Shell.use(self)
7
+
8
+ def before_loop
9
+ return super if MultilineHistoryFile.disabled?
10
+ config[:multiline_history_file_token] ||= ' '
11
+ super
12
+ end
13
+
14
+ def read_history
15
+ return super if MultilineHistoryFile.disabled?
16
+ buffer = []
17
+ File.exist?(history_file) && history.empty? &&
18
+ IO.readlines(history_file).each{ |line|
19
+ if line.end_with?(
20
+ "#{config[:multiline_history_file_token]}\n")
21
+ buffer << line[0...
22
+ -config[:multiline_history_file_token].size-1] + "\n"
23
+ else
24
+ history << (buffer.join + line).chomp
25
+ buffer = []
26
+ end
27
+ }
28
+ end
29
+
30
+ def write_history
31
+ return super if MultilineHistoryFile.disabled?
32
+ @history = history.to_a.map{ |line|
33
+ line.gsub("\n", "#{config[:multiline_history_file_token]}\n")
34
+ }
35
+ super
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+
2
+ require 'rib/core/history_file'
3
+
4
+ module Rib::SqueezeHistory
5
+ include Rib::Plugin
6
+ Shell.use(self)
7
+
8
+ # squeeze history on memory too
9
+ def eval_input input
10
+ return super if SqueezeHistory.disabled?
11
+ history.pop if input.strip == '' ||
12
+ (history.size > 1 && input == history.to_a[-2])
13
+ # EditLine is really broken, to_a is needed for it
14
+ super
15
+ end
16
+
17
+ # write squeezed history
18
+ def write_history
19
+ return super if SqueezeHistory.disabled?
20
+ @history = P.squeeze_history(history)
21
+ super
22
+ end
23
+
24
+ module Imp
25
+ def squeeze_history history
26
+ history.to_a.inject([]){ |result, item|
27
+ if result.last == item || item.strip == ''
28
+ result
29
+ else
30
+ result << item
31
+ end
32
+ }
33
+ end
34
+ end
35
+
36
+ Plugin.extend(Imp)
37
+ end
@@ -0,0 +1,43 @@
1
+
2
+ require 'rib'
3
+
4
+ module Rib::StripBacktrace
5
+ include Rib::Plugin
6
+ Shell.use(self)
7
+
8
+ # strip backtrace until ripl
9
+ def format_error e
10
+ return super if StripBacktrace.disabled?
11
+ message, backtrace = get_error(e, P.strip_backtrace(e, config[:name]))
12
+ "#{message}\n #{backtrace.join("\n ")}"
13
+ end
14
+
15
+ def get_error e, backtrace=e.backtrace
16
+ return super if StripBacktrace.disabled?
17
+ ["#{e.class}: #{e.message}", backtrace]
18
+ end
19
+
20
+ private
21
+ module Imp
22
+ def strip_backtrace e, name
23
+ home(cwd(snip(e, name)))
24
+ end
25
+
26
+ def home b
27
+ b.map{ |p| p.sub(ENV['HOME'], '~') }
28
+ end
29
+
30
+ def cwd b
31
+ b.map{ |p| p.sub(Dir.pwd, '.') }
32
+ end
33
+
34
+ def snip e, name
35
+ return [] if e.kind_of?(SyntaxError)
36
+ e.backtrace[
37
+ 0..
38
+ e.backtrace.rindex{ |l| l =~ /\(#{name}\):\d+:in `.+?'/ } || -1]
39
+ end
40
+ end
41
+
42
+ Plugin.extend(Imp)
43
+ end
@@ -0,0 +1,56 @@
1
+
2
+ module Rib; end
3
+ module Rib::Plugin
4
+ Rib::P = self
5
+
6
+ def self.included mod
7
+ mod.send(:include, Rib)
8
+
9
+ class << mod
10
+ attr_accessor :disabled
11
+
12
+ def enable
13
+ self.disabled = false
14
+ if block_given? then yield else enabled? end
15
+ end
16
+
17
+ def disable
18
+ self.disabled = true
19
+ if block_given? then yield else enabled? end
20
+ end
21
+
22
+ def enabled?
23
+ !disabled
24
+ end
25
+
26
+ def disabled?
27
+ !!disabled
28
+ end
29
+ end
30
+
31
+ snake_name = mod.name[/::\w+$/].tr(':', ''). # remove namespaces
32
+ gsub(/([A-Z][a-z]*)/, '\\1_').downcase[0..-2]
33
+
34
+ code = (%w[enable disable].map{ |meth|
35
+ <<-RUBY
36
+ def #{meth}_#{snake_name} &block
37
+ #{mod.name}.#{meth}(&block)
38
+ end
39
+ RUBY
40
+ } + %w[enabled? disabled?].map{ |meth|
41
+ <<-RUBY
42
+ def #{snake_name}_#{meth} &block
43
+ #{mod.name}.#{meth}(&block)
44
+ end
45
+ RUBY
46
+ }).join("\n")
47
+
48
+ meta_rib = if respond_to?(:singleton_class)
49
+ Rib.singleton_class
50
+ else
51
+ class << Rib; self; end
52
+ end
53
+
54
+ meta_rib.module_eval(code, __FILE__, __LINE__)
55
+ end
56
+ end
@@ -0,0 +1,106 @@
1
+
2
+ require 'rib'
3
+
4
+ module Rib::Runner
5
+ module_function
6
+ def name
7
+ File.basename($PROGRAM_NAME)
8
+ end
9
+
10
+ def options
11
+ { # Ruby OPTIONS
12
+ '-e, --eval LINE' =>
13
+ 'Evaluate a LINE of code' ,
14
+
15
+ '-d, --debug' =>
16
+ 'Set debugging flags (set $DEBUG to true)' ,
17
+
18
+ '-w, --warn' =>
19
+ 'Turn warnings on for your script (set $-w to true)' ,
20
+
21
+ '-I, --include PATH' =>
22
+ 'Specify $LOAD_PATH (may be used more than once)' ,
23
+
24
+ '-r, --require LIBRARY' =>
25
+ 'Require the library, before executing your script' ,
26
+
27
+ # Rib OPTIONS
28
+ '-c, --config FILE' => 'Load config from FILE' ,
29
+ '-n, --no-config' => 'Suppress loading ~/.config/rib/config.rb',
30
+ '-h, --help' => 'Print this message' ,
31
+ '-v, --version' => 'Print the version' }
32
+ end
33
+
34
+ def run argv=ARGV
35
+ if command = argv.find{ |a| a =~ /^[^-]/ }
36
+ argv.delete(command)
37
+ plugin = "rib-#{command}"
38
+ path = `which #{plugin}`.strip
39
+ if path == ''
40
+ puts("Can't find `#{plugin}' in $PATH.\n" \
41
+ "Please make sure `#{plugin}' is installed.\n" \
42
+ "e.g. run `gem install #{plugin}`")
43
+ else
44
+ load(path)
45
+ end
46
+ else
47
+ start(*argv)
48
+ end
49
+ end
50
+
51
+ def start *argv
52
+ unused = parse(argv.dup)
53
+ warn "#{name}: Unused arguments: #{unused.inspect}" unless unused.empty?
54
+ Rib.shell.loop
55
+ end
56
+
57
+ def parse argv
58
+ unused = []
59
+ until argv.empty?
60
+ case arg = argv.shift
61
+ when /-e=?(.*)/, /--eval=?(.*)/
62
+ eval($1 || argv.shift, __FILE__, __LINE__)
63
+
64
+ when '-d', '--debug'
65
+ $DEBUG = true
66
+
67
+ when '-w', '--warn'
68
+ $-w = true
69
+
70
+ when /-I=?(.*)/, /--include=?(.*)/
71
+ paths = ($1 || argv.shift).split(':')
72
+ $LOAD_PATH.unshift(*paths)
73
+
74
+ when /-r=?(.*)/, /--require=?(.*)/
75
+ require($1 || argv.shift)
76
+
77
+ when /-c=?(.*)/, /--config=?(.*)/
78
+ Rib.config[:config] = $1 || argv.shift
79
+
80
+ when '-n', '--no-config'
81
+ Rib.config.delete(:config)
82
+
83
+ when '-h', '--help'
84
+ puts(help)
85
+ exit
86
+
87
+ when '-v', '--version'
88
+ require 'rib/version'
89
+ puts(Rib::VERSION)
90
+ exit
91
+
92
+ else
93
+ unused << arg
94
+ end
95
+ end
96
+ unused
97
+ end
98
+
99
+ def help
100
+ maxn = options.keys .map(&:size).max
101
+ maxd = options.values.map(&:size).max
102
+ "Usage: #{name} [Ruby OPTIONS] [Rib COMMAND] [Rib OPTIONS]\n" +
103
+ options.map{ |name, desc|
104
+ sprintf(" %-*s %-*s", maxn, name, maxd, desc) }.join("\n")
105
+ end
106
+ end
@@ -0,0 +1,43 @@
1
+
2
+ require 'rib/plugin'
3
+ require 'rib/api'
4
+
5
+ class Rib::Shell
6
+ include Rib::API
7
+ trap('INT'){ raise Interrupt }
8
+
9
+ def self.use mod
10
+ include mod
11
+ end
12
+
13
+ attr_reader :config
14
+ def initialize(config={})
15
+ self.config = {
16
+ :name => 'rib' ,
17
+ :result_prompt => '=> ' ,
18
+ :prompt => '>> ' ,
19
+ :binding => TOPLEVEL_BINDING ,
20
+ :exit => [nil, 'exit', 'quit'] ,
21
+ :line => 1
22
+ }.merge(config)
23
+ end
24
+
25
+ # Loops shell until user exits
26
+ def loop
27
+ before_loop
28
+ @running = true
29
+ in_loop
30
+ self
31
+ ensure
32
+ @running = false
33
+ after_loop
34
+ end
35
+
36
+ def running?
37
+ !!@running
38
+ end
39
+
40
+ protected
41
+ attr_writer :config
42
+ attr_accessor :error_raised
43
+ end
@@ -0,0 +1,25 @@
1
+
2
+ require 'bacon'
3
+ require 'rr'
4
+ require 'fileutils'
5
+ Bacon.summary_on_exit
6
+ include RR::Adapters::RRMethods
7
+
8
+ require 'rib'
9
+
10
+ shared :rib do
11
+ before do
12
+ Rib.disable_plugins
13
+ end
14
+
15
+ after do
16
+ RR.verify
17
+ Rib.enable_plugins
18
+ end
19
+ end
20
+
21
+ module Kernel
22
+ def eq? rhs
23
+ self == rhs
24
+ end
25
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module Rib
3
+ VERSION = '0.1.0'
4
+ end
@@ -0,0 +1,3 @@
1
+
2
+ require 'rib/zore/anchor'
3
+ require 'rib/zore/edit'
@@ -0,0 +1,69 @@
1
+
2
+ require 'rib'
3
+
4
+ module Rib::Anchor
5
+ include Rib::Plugin
6
+ Shell.use(self)
7
+
8
+ def loop_eval(str)
9
+ case obj_or_binding = (Rib.vars[:anchor] ||= []).last
10
+ when NilClass
11
+ super
12
+
13
+ when Binding
14
+ @binding = obj_or_binding
15
+ super
16
+
17
+ else
18
+ obj_or_binding.instance_eval(str, "(#{config[:name]})", config[:line])
19
+ end
20
+ end
21
+
22
+ def prompt
23
+ if Rib.const_defined?(:Color) && kind_of?(Rib::Color) &&
24
+ obj_or_binding = (Rib.vars[:anchor] ||= []).last
25
+
26
+ super.sub(config[:name], format_color(obj_or_binding, config[:name]))
27
+ else
28
+ super
29
+ end
30
+ end
31
+
32
+ # if the object is the same, then we're exiting from an anchor,
33
+ # so don't print anything.
34
+ def print_result result
35
+ super unless !result.nil? &&
36
+ result.object_id == Rib.vars[:anchor_last].object_id
37
+ end
38
+
39
+ module Imp
40
+ def short_inspect obj_or_binding
41
+ obj_or_binding.inspect[0..9]
42
+ end
43
+ end
44
+
45
+ module AnchorImp
46
+ def anchor obj_or_binding
47
+ return if Rib::Anchor.disabled?
48
+
49
+ (Rib.vars[:anchor] ||= []) << obj_or_binding
50
+ name = Rib::P.short_inspect(obj_or_binding)
51
+
52
+ Rib.shells <<
53
+ Rib::Shell.new(Rib.config.merge(
54
+ :name => name,
55
+ :prompt => "#{name}(#{Rib.vars[:anchor].size})" +
56
+ (Rib.config[:prompt] || '>> ')))
57
+
58
+ Rib.shell.loop
59
+
60
+ ensure
61
+ # stores to check if we're exiting from an anchor
62
+ Rib.vars[:anchor_last] = Rib.vars[:anchor].pop
63
+ Rib.shells.pop
64
+ end
65
+ end
66
+
67
+ Plugin.extend(Imp)
68
+ Rib .extend(AnchorImp)
69
+ end