ripl-multi_line 0.2.4 → 0.3.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.
data/.gemspec CHANGED
@@ -11,7 +11,11 @@ Gem::Specification.new do |s|
11
11
  s.summary = "A ripl plugin for multi-line eval."
12
12
  s.description = "This ripl plugin allows you to evaluate multiple lines of Ruby code."
13
13
  s.required_rubygems_version = ">= 1.3.6"
14
- s.add_dependency 'ripl', '>= 0.3.2'
14
+ s.add_dependency 'ripl', '>= 0.3.6'
15
+ s.add_development_dependency 'bacon', '>= 1.1.0'
16
+ s.add_development_dependency 'bacon-bits'
17
+ s.add_development_dependency 'bacon-rr'
18
+ s.add_development_dependency 'rr'
15
19
  s.files = Dir.glob(%w[{lib,test}/**/*.rb bin/* [A-Z]*.{txt,rdoc} ext/**/*.{rb,c} **/deps.rip]) + %w{Rakefile .gemspec}
16
20
  s.extra_rdoc_files = ["README.rdoc", "LICENSE.txt"]
17
21
  s.license = 'MIT'
@@ -1,3 +1,13 @@
1
+ == 0.3.0
2
+ * comes with five different multi-line implementations: live_error, error_check, irb, ripper and ruby_parser
3
+ * can be changed with config[:multi_line_engine], default is :live_error
4
+ * add :multi_line_history option (default: compact), based on https://gist.github.com/939846
5
+ * support =begin...=end comments
6
+ * add Shell#multiline? method to check if input should be handled as multi-line input
7
+ * separate Ruby-specific multi-line stuff from general implementation
8
+ * add some basic tests
9
+ * force multi-line with ; after input
10
+
1
11
  == 0.2.4
2
12
  * fix 1.8 warning
3
13
 
@@ -13,7 +23,7 @@
13
23
 
14
24
  == 0.2.0
15
25
  * store buffer in an array instead of a string
16
- * added ctrl+c to remove last line in multi-line situation
26
+ * added ctrl+c to remove last line in multi-line situations
17
27
 
18
28
  == 0.1.4
19
29
  * be compatible with 0.2.4 (undo monkey patch)
@@ -4,25 +4,59 @@ This {ripl}[https://github.com/cldwalker/ripl] plugin allows you to evaluate mul
4
4
  == Install
5
5
  Install the gem with
6
6
 
7
- gem install ripl-multi_line
7
+ gem install ripl-multi_line
8
8
 
9
9
  == Usage
10
-
11
10
  Add the following line to your <tt>~/.riplrc</tt>
12
11
 
13
12
  require 'ripl/multi_line'
14
13
 
14
+ <b>Hint:</b> In multi-line situations, you can press <tt>ctrl+c</tt> and the last line will be removed.
15
+
16
+ == Options
15
17
  You can customize your multi-line prompt with the <tt>:multi_line_prompt</tt> option. For example, put this into your <tt>~/.riplrc</tt>:
16
18
 
17
19
  Ripl.config[:multi_line_prompt] = ' > '
18
20
 
19
- If you are in multi-line situation, you can press <tt>ctrl+c</tt> and the last line will be removed.
21
+ It also takes a proc as value.
22
+
23
+ Then there is the <tt>:multi_line_history</tt> option. The default value is <tt>:compact</tt> which tries to squeeze your last multi-line block into one line (works best in mri, in about 98% of all cases).
24
+
25
+ >> def some_multi_line_block
26
+ | 42
27
+ | end #=> nil
28
+ # Press <UP>
29
+ >> def some_multi_line_block; 42; end
30
+
31
+ Another value is <tt>:block</tt>, which joins the multi-line block with new-lines.
32
+
33
+ To leave the history untouched, set it to <tt>:plain</tt> or a false value.
20
34
 
21
35
  == AutoIndent
22
- There is also an indention plugin available: {ripl-auto_indent}[https://github.com/janlelis/ripl-auto_indent]
36
+ Check out the {ripl-auto_indent}[https://github.com/janlelis/ripl-auto_indent] plugin to get ruby syntax indention.
37
+
38
+ == MultiLine detection
39
+ To use your own multi-line detection engine, implement your version at <tt>lib/ripl/multi_line/your_correct_detection.rb</tt> in which you overwrite <tt>Shell#multiline?</tt> in a <tt>Ripl::MultiLine</tt> sub-module named <tt>YourCorrectDetection</tt> and set <tt>Ripl.config[:multi_line_engine]</tt> to <tt>:your_correct_detection</tt>. See <tt>lib/ripl/multi_line/*.rb</tt> for examples.
40
+
41
+ Currently available engines:
42
+ * <tt>:live_error</tt> (<b>default</b>) - Simply evaluate expression, if it throws a multi-line syntax error, fall back to multi-line input mode. Sounds scary, but works pretty well in practice.
43
+ * <tt>:error_check</tt> - Same principle as :live_error, but don't do it live
44
+ * <tt>:ripper</tt> - Analyze input with Ripper (comes with 1.9, but there is also a 1.8 gem).
45
+ * <tt>:ruby_parser</tt> - Use ruby_parser gem (1.8 only)
46
+ * <tt>:irb</tt> - You left irb, but you are still used to its multi-line behaviour? Use irb's RubyLex!
47
+
48
+ None of the above solutions is perfect, so... maybe it's time to roll your own ;)
49
+
50
+ == Troubleshooting
51
+ <i>Problem:</i> "I've required <tt>ripl-multi_line</tt>, but it doesn't work"
52
+
53
+ <i>Answer:</i> This is probably caused by a plugin, which overwrites <tt>:before_loop</tt>, but does not call <tt>super</tt> (or you are using ripl-profiles older than 0.2.0). You can manually work around this issue with this snippet (but you should fix the general problem):
54
+
55
+ require 'ripl/multi_line/live_error.rb'
56
+ Ripl::MultiLine.engine = Ripl::MultiLine::LiveError
57
+ Ripl::Shell.include Ripl::MultiLine.engine
23
58
 
24
- == Planned for version 0.3.0
25
- * Tests :)
26
- * Replaceable check if syntax is valid (then, the plugin can be used for other languages than Ruby)
59
+ == Credits
60
+ Contributions & influences by cldwalker and godfat.
27
61
 
28
62
  J-_-L
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ def gemspec
6
6
  end
7
7
 
8
8
  desc "Build the gem"
9
- task :gem=>:gemspec do
9
+ task :gem => :gemspec do
10
10
  sh "gem build .gemspec"
11
11
  FileUtils.mkdir_p 'pkg'
12
12
  FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg'
@@ -14,7 +14,7 @@ end
14
14
 
15
15
  desc "Install the gem locally"
16
16
  task :install => :gem do
17
- sh %{gem install pkg/#{gemspec.name}-#{gemspec.version}}
17
+ sh %{gem install pkg/#{gemspec.name}-#{gemspec.version} --no-rdoc --no-ri}
18
18
  end
19
19
 
20
20
  desc "Generate the gemspec"
@@ -2,27 +2,27 @@ require 'ripl'
2
2
 
3
3
  module Ripl
4
4
  module MultiLine
5
- VERSION = '0.2.4'
6
- ERROR_REGEXP = /#{
7
- [ %q%unexpected \$end%,
8
- %q%unterminated [a-z]+ meets end of file%,
9
- # rubinius
10
- %q%expecting '\\n' or ';'%,
11
- %q%missing 'end'%,
12
- %q%expecting '\}'%,
13
- # jruby
14
- %q%syntax error, unexpected end-of-file%,
15
- ]*'|' }/
5
+ VERSION = '0.3.0'
6
+
7
+ class << self
8
+ attr_accessor :engine
9
+ end
16
10
 
17
11
  def before_loop
12
+ @buffer = @buffer_info = nil
13
+ # include CamelCased implementation
14
+ require File.join( 'ripl', 'multi_line', config[:multi_line_engine].to_s )
15
+ Ripl::MultiLine.engine = Ripl::MultiLine.const_get(
16
+ config[:multi_line_engine].to_s.gsub(/(^|_)(\w)/){ $2.capitalize }
17
+ )
18
+ Ripl::Shell.include Ripl::MultiLine.engine
18
19
  super
19
- @buffer = nil
20
20
  end
21
21
 
22
22
  def prompt
23
23
  if @buffer
24
24
  config[:multi_line_prompt].respond_to?(:call) ?
25
- config[:multi_line_prompt].call :
25
+ config[:multi_line_prompt].call( *@buffer_info[-1] ) :
26
26
  config[:multi_line_prompt]
27
27
  else
28
28
  super
@@ -35,49 +35,87 @@ module Ripl
35
35
  def loop_once
36
36
  catch(:multiline) do
37
37
  super
38
- @buffer = nil
38
+ if config[:multi_line_history] && @buffer && @input
39
+ (@buffer.size + 1).times{ history.pop }
40
+
41
+ if config[:multi_line_history] == :compact
42
+ history_entry = ''
43
+ @buffer.zip(@buffer_info){ |str, type|
44
+ history_entry << str
45
+ history_entry << case
46
+ when !type.is_a?(Array)
47
+ "\n" # fallback to :block for unsure
48
+ when type[0] == :statement
49
+ '; '
50
+ when type[0] == :literal && ( type[1] == :string || type[1] == :regexp )
51
+ '\n'
52
+ else
53
+ ''
54
+ end
55
+ }
56
+ history_entry << @input
57
+ history << history_entry
58
+ else # true or :block
59
+ history << (@buffer << @input).join("\n")
60
+ end
61
+ end
62
+
63
+ @buffer = @buffer_info = nil
39
64
  end
40
65
  end
41
66
 
42
- def print_eval_error(e)
43
- if e.is_a?(SyntaxError) && e.message =~ ERROR_REGEXP
44
- @buffer ||= []
45
- @buffer << @input
46
- throw :multiline
47
- else
48
- super
49
- end
67
+ # This method is overwritten by a multi-line implementation in lib/multi_line/*.rb
68
+ # It should return a true value for a string that is unfinished and a false one
69
+ # for complete expressions, which should get evaluated.
70
+ # It's also possible (and encouraged) to return an array of symbols describing
71
+ # what's the reason for continuing the expression (this is used in the :compact
72
+ # history and gets passed to the prompt proc.
73
+ def multiline?(eval_string)
74
+ false
75
+ end
76
+
77
+ def handle_multiline(type = [:statement]) # MAYBE: add second arg for specific information
78
+ @buffer ||= []
79
+ @buffer_info ||= []
80
+ @buffer << @input
81
+ @buffer_info << type
82
+ throw :multiline
50
83
  end
51
84
 
52
85
  def loop_eval(input)
53
- if @buffer
54
- super @buffer*"\n" + "\n" + input
55
- else
56
- super input
86
+ eval_string = if @buffer then @buffer*"\n" + "\n" + input else input end
87
+ if type = multiline?(eval_string)
88
+ handle_multiline(type)
57
89
  end
90
+ super eval_string
58
91
  end
59
92
 
60
93
  # remove last line from buffer
61
- # TODO: nicer interface (rewriting?)
94
+ # MAYBE: terminal rewriting
62
95
  def handle_interrupt
63
96
  if @buffer
64
- @buffer.pop
97
+ @buffer.pop; @buffer_info.pop; history.pop
65
98
  if @buffer.empty?
66
- @buffer = nil
99
+ @buffer = @buffer_info = nil
100
+ print '[buffer empty]'
67
101
  return super
68
102
  else
69
- puts "[previous line removed]"
103
+ puts "[previous line removed|#{@buffer.size}]"
70
104
  throw :multiline
71
105
  end
72
106
  else
73
107
  super
74
108
  end
75
109
  end
110
+
76
111
  end
77
112
  end
78
113
 
79
- Ripl::Shell.include Ripl::MultiLine
80
- Ripl.config[:multi_line_prompt] ||= proc do # you can also use a plain string here
114
+ Ripl::Shell.include Ripl::MultiLine # implementation gets included in before_loop
115
+ Ripl.config[:multi_line_engine] ||= :live_error # not satisfied? try :ripper, :irb or implement your own
116
+ Ripl.config[:multi_line_history] ||= :compact # possible other values: :block, :blank
117
+
118
+ Ripl.config[:multi_line_prompt] ||= proc do # you can also use a plain string here
81
119
  '|' + ' '*(Ripl.shell.instance_variable_get(:@prompt).size-1) # '| '
82
120
  end
83
121
 
@@ -0,0 +1,31 @@
1
+ require 'ripl'
2
+
3
+ Ripl.config[:multi_line_engine] ||= :error_check
4
+ require 'ripl/multi_line'
5
+ require 'ripl/multi_line/live_error'
6
+
7
+ # # # #
8
+ # This multi-line implementation uses IRB's RubyLex parser
9
+ # works on: 1.9 1.8 jruby rbx
10
+ # analyze features: see live_error.rb
11
+ # known issues: see live_error.rb
12
+ module Ripl::MultiLine::ErrorCheck
13
+ VERSION = '0.1.0'
14
+
15
+ ruby_engine = defined?(RUBY_ENGINE) && RUBY_ENGINE.downcase.to_sym
16
+ ruby_engine = :ruby if !Ripl::MultiLine::LiveError::ERROR_MESSAGES.keys.include?(ruby_engine)
17
+
18
+ define_method(:multiline?) do |string|
19
+ break [:forced] if string =~ /;\s*\Z/ # force multi line with ;
20
+
21
+ begin
22
+ eval "if nil; #{string}; end"
23
+ rescue SyntaxError => e
24
+ Ripl::MultiLine::LiveError::ERROR_MESSAGES[ruby_engine].each{ |type, message|
25
+ break type if message === e.message
26
+ }
27
+ end
28
+ end
29
+ end
30
+
31
+ # J-_-L
@@ -0,0 +1,59 @@
1
+ require 'ripl'
2
+ require 'irb/ruby-lex'
3
+ require 'stringio'
4
+
5
+ Ripl.config[:multi_line_engine] ||= :irb
6
+ require 'ripl/multi_line'
7
+
8
+ # # # #
9
+ # This multi-line implementation uses IRB's RubyLex parser
10
+ # works on: 1.9 1.8 jruby rbx
11
+ # analyze features: none
12
+ module Ripl::MultiLine::Irb
13
+ VERSION = '0.1.0'
14
+
15
+ class << self
16
+ attr_reader :scanner
17
+ end
18
+
19
+ # create scanner and patch it to our needs
20
+ @scanner = RubyLex.new
21
+
22
+ def @scanner.multiline?
23
+ initialize_input
24
+ @continue = false
25
+ @found_eof = false
26
+
27
+ while line = lex
28
+ @line << line
29
+ @continue = false
30
+ end
31
+
32
+ !!( !@found_eof or @ltype or @continue or @indent > 0 )
33
+ end
34
+
35
+ def @scanner.lex
36
+ until (((tk = token).kind_of?(RubyLex::TkNL) || tk.kind_of?(RubyLex::TkEND_OF_SCRIPT)) &&
37
+ !@continue or
38
+ tk.nil?)
39
+ #p tk
40
+ #p @lex_state
41
+ #p self
42
+ end
43
+ @found_eof = true if tk.kind_of?(RubyLex::TkEND_OF_SCRIPT)
44
+ line = get_readed
45
+ # print self.inspect
46
+ if line == "" and tk.kind_of?(RubyLex::TkEND_OF_SCRIPT) || tk.nil?
47
+ nil
48
+ else
49
+ line
50
+ end
51
+ end
52
+
53
+ def multiline?(string)
54
+ Ripl::MultiLine::Irb.scanner.set_input StringIO.new(string + "\0")
55
+ Ripl::MultiLine::Irb.scanner.multiline?
56
+ end
57
+ end
58
+
59
+ # J-_-L
@@ -0,0 +1,73 @@
1
+ require 'ripl'
2
+
3
+ Ripl.config[:multi_line_engine] ||= :live_error
4
+ require 'ripl/multi_line'
5
+
6
+ # # # #
7
+ # This multi-line implementation uses IRB's RubyLex parser
8
+ # works on: 1.9 1.8 jruby rbx
9
+ # analyze features: [:literal, :string]
10
+ # [:literal, :regexp]
11
+ # [:literal, :array] (mri only)
12
+ # [:literal, :hash] (mri only)
13
+ # [:statement]
14
+ # [:forced]
15
+ # notes: rbx support buggy (depends on rubinius error messages)
16
+ module Ripl::MultiLine::LiveError
17
+ VERSION = "0.1.0"
18
+
19
+ ERROR_MESSAGES = {
20
+ :ruby => [
21
+ [[:literal, :string], /unterminated string meets end of file/],
22
+ [[:literal, :regexp], /unterminated regexp meets end of file/],
23
+ [[:literal, :array], /syntax error, unexpected \$end, expecting '\]'/],
24
+ [[:literal, :hash], /syntax error, unexpected \$end, expecting '\}'/], # does not work for ranges or {5=>
25
+ [[:statement], /syntax error, unexpected \$end/],
26
+ ],
27
+ :jruby => [
28
+ [[:literal, :string], /unterminated string meets end of file/],
29
+ [[:literal, :regexp], /unterminated regexp meets end of file/], # array or hash cannot be detected
30
+ [[:statement], /syntax error, unexpected end-of-file/],
31
+ ],
32
+ :rbx => [
33
+ [[:literal, :string], /unterminated [a-z]+ meets end of file/], # no extra message for regexes
34
+ [[:literal], /expecting '\\n' or ';'/], # TODO: better rbx regexes or rbx bug report
35
+ [[:literal, :hash], /expecting '\}'/],
36
+ # [:literal, /expecting '\]'/],
37
+ # [:literal, /expecting '\)'/],
38
+ [[:statement], /syntax error, unexpected \$end/],
39
+ [[:statement], /missing 'end'/], # for i in [2,3,4] do;
40
+ ],
41
+ }
42
+ ruby_engine = defined?(RUBY_ENGINE) && RUBY_ENGINE.downcase.to_sym
43
+ ruby_engine = :ruby if !ERROR_MESSAGES.keys.include?(ruby_engine)
44
+
45
+ define_method(:print_eval_error) do |e|
46
+ if e.is_a? SyntaxError
47
+ ERROR_MESSAGES[ruby_engine].each{ |type, message|
48
+ handle_multiline(type) if message === e.message
49
+ }
50
+ end
51
+ super(e)
52
+ end
53
+
54
+ def eval_input(input)
55
+ if input =~ /;\s*\Z/ # force multi line with ;
56
+ handle_multiline(:forced)
57
+ elsif input =~ /^=begin(\s.*)?$/ && !@buffer
58
+ @ignore_mode = true # MAYBE: change prompt
59
+ elsif !@ignore_mode
60
+ super
61
+ end
62
+ end
63
+
64
+ def print_result(result)
65
+ if @ignore_mode && @input == '=end'
66
+ @ignore_mode = false
67
+ elsif !@ignore_mode
68
+ super
69
+ end
70
+ end
71
+ end
72
+
73
+ # J-_-L
@@ -0,0 +1,50 @@
1
+ # see https://github.com/cldwalker/ripl-ripper/blob/master/lib/ripl/ripper.rb for a different (standalone) plugin
2
+ require 'ripl'
3
+ require 'ripper'
4
+
5
+ Ripl.config[:multi_line_engine] ||= :ripper
6
+ require 'ripl/multi_line'
7
+
8
+ # # # #
9
+ # This multi-line implementation uses IRB's RubyLex parser
10
+ # works on: 1.9 1.8(gem)
11
+ # analyze features: [:literal, :string]
12
+ # [:literal, :regexp]
13
+ # [:literal, :array] (mri only)
14
+ # [:literal, :hash] (mri only)
15
+ # [:statement]
16
+ # [:forced]
17
+ # notes: statement could also be [
18
+ module Ripl::MultiLine::Ripper
19
+ VERSION = '0.1.0'
20
+
21
+ def multiline?(string)
22
+ return [:forced] if string =~ /;\s*\Z/
23
+
24
+ expr = ::Ripper::SexpBuilder.new(string).parse
25
+
26
+ return [:statement] if !expr # not always statements...
27
+
28
+ # literals are problematic..
29
+ last_expr = expr[-1][-1]
30
+
31
+ return [:literal, :regexp] if last_expr == [:regexp_literal, [:regexp_new], nil]
32
+
33
+ delimiters = %q_(?:[\[<({][\]>)}]|(.)\1)_
34
+
35
+ return [:literal, :string] if last_expr == [:string_literal, [:string_content]] &&
36
+ string !~ /(?:""|''|%q?#{delimiters})\s*\Z/i # empty literal at $
37
+
38
+ return [:literal, :string] if last_expr == [:xstring_literal, [:xstring_new]] &&
39
+ string !~ /(?:``|%x#{delimiters})\s*\Z/i
40
+
41
+ return [:literal, :string] if last_expr == [:words_new] &&
42
+ string !~ /%W#{delimiters}\s*\Z/
43
+
44
+ return [:literal, :string] if last_expr == [:qwords_new] &&
45
+ string !~ /%w#{delimiters}\s*\Z/
46
+ end
47
+ end
48
+
49
+
50
+ # J-_-L
@@ -0,0 +1,39 @@
1
+ require 'ripl'
2
+ require 'ruby_parser'
3
+
4
+ Ripl.config[:multi_line_engine] ||= :ruby_parser
5
+ require 'ripl/multi_line'
6
+
7
+ # # # #
8
+ # This multi-line implementation uses IRB's RubyLex parser
9
+ # works on: 1.8
10
+ # analyze features: [:literal, :string]
11
+ # [:literal, :hash]
12
+ # [:statement]
13
+ # [:forced]
14
+ # notes: statement could also be [
15
+ module Ripl::MultiLine::RubyParser
16
+ VERSION = '0.1.0'
17
+
18
+ ERROR_MESSAGES = [
19
+ [[:literal, :string], /unterminated string meets end of file/],
20
+ # [[:literal, :regexp], /unterminated regexp meets end of file/], #-> string
21
+ # [[:literal, :array], /syntax error, unexpected \$end, expecting '\]'/], #-> ParseError
22
+ [[:literal, :hash], /syntax error, unexpected \$end, expecting '\}'/], # {45
23
+ ]
24
+
25
+ def multiline?(string)
26
+ return [:forced] if string =~ /;\s*\Z/ # force multi line with ;
27
+ ::RubyParser.new.parse(string)
28
+ false # string was parsable, no multi-line
29
+ rescue ::Racc::ParseError
30
+ [:statement]
31
+ rescue SyntaxError => e
32
+ ERROR_MESSAGES.each{ |type, message|
33
+ return type if message === e.message
34
+ }
35
+ false # syntax error not multi-line relevant
36
+ end
37
+ end
38
+
39
+ # J-_-L
@@ -0,0 +1,32 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ describe "Shell" do
4
+ before { reset_ripl }
5
+
6
+ def shell(options={})
7
+ Ripl.shell(options)
8
+ end
9
+
10
+ describe "multi-line behaviour" do
11
+ should_eval %| "m" * 2 |
12
+ should_eval %| "8989" |
13
+ should_eval %| "zzz" |
14
+
15
+ should_not_eval %| "m" * |
16
+
17
+ should_not_eval %| " |
18
+ should_not_eval %| ' |
19
+ should_not_eval %| / |
20
+
21
+ should_not_eval %| [ |
22
+ should_not_eval %| { |
23
+ should_not_eval %| ( |
24
+
25
+ should_not_eval %| def hey |
26
+ should_not_eval %| def hey; 89 |
27
+ should_not_eval %| begin |
28
+ should_eval %| for x in [2,3,4];7;end |
29
+ end
30
+
31
+ # TODO add misc real tests for everything
32
+ end
@@ -0,0 +1,83 @@
1
+ require 'bacon'
2
+ require 'bacon/bits'
3
+ require 'rr'
4
+ require 'bacon/rr'
5
+ require 'stringio'
6
+ require 'ripl'
7
+ require 'ripl/multi_line'
8
+ include Ripl
9
+
10
+ module Helpers
11
+ def ripl(*args)
12
+ options = args[-1].is_a?(Hash) ? args.pop : {}
13
+ mock_riplrc unless options[:riplrc] == false
14
+ mock(Ripl.shell).loop unless options[:loop] == false
15
+ capture_stdout { Ripl::Runner.run(args) }
16
+ end
17
+
18
+ def mock_riplrc(&block)
19
+ mock(Runner).load_rc(Ripl.config[:riplrc], &block)
20
+ end
21
+
22
+ def mock_shell(&block)
23
+ mock(Shell).create(anything) {|e|
24
+ shell = Shell.new(e)
25
+ block ? block.call(shell) : mock(shell).loop
26
+ shell
27
+ }
28
+ end
29
+
30
+ def reset_ripl
31
+ Ripl.instance_eval "@config = @shell = @riplrc = nil"
32
+ end
33
+
34
+ def reset_shell
35
+ Ripl.send(:remove_const, :Shell)
36
+ $".delete $".grep(/shell\.rb/)[0]
37
+ require 'ripl/shell'
38
+ Ripl::Shell.include Ripl::History
39
+ end
40
+
41
+ def reset_config
42
+ Ripl.config.merge! :history => '~/.irb_history', :completion => {}
43
+ end
44
+
45
+ def capture_stdout(&block)
46
+ original_stdout = $stdout
47
+ $stdout = fake = StringIO.new
48
+ begin
49
+ yield
50
+ ensure
51
+ $stdout = original_stdout
52
+ end
53
+ fake.string
54
+ end
55
+
56
+ def capture_stderr(&block)
57
+ original_stderr = $stderr
58
+ $stderr = fake = StringIO.new
59
+ begin
60
+ yield
61
+ ensure
62
+ $stderr = original_stderr
63
+ end
64
+ fake.string
65
+ end
66
+
67
+ # multi_line stuff
68
+ def should_eval(input)
69
+ it "should evaluate " + input do
70
+ mock(shell).get_input { input }
71
+ capture_stderr { capture_stdout { shell.loop_once }.should.not == '' }
72
+ end
73
+ end
74
+
75
+ def should_not_eval(input)
76
+ it "should not evaluate " + input do
77
+ mock(shell).get_input { input }
78
+ capture_stderr { capture_stdout { shell.loop_once }.should == '' }
79
+ end
80
+ end
81
+ end
82
+
83
+ Bacon::Context.send :include, Helpers
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: ripl-multi_line
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.4
5
+ version: 0.3.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jan Lelis
@@ -10,8 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-10 00:00:00 +01:00
14
- default_executable:
13
+ date: 2011-04-28 00:00:00 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: ripl
@@ -21,9 +20,53 @@ dependencies:
21
20
  requirements:
22
21
  - - ">="
23
22
  - !ruby/object:Gem::Version
24
- version: 0.3.2
23
+ version: 0.3.6
25
24
  type: :runtime
26
25
  version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: bacon
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 1.1.0
35
+ type: :development
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: bacon-bits
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: bacon-rr
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: rr
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :development
69
+ version_requirements: *id005
27
70
  description: This ripl plugin allows you to evaluate multiple lines of Ruby code.
28
71
  email: mail@janlelis.de
29
72
  executables: []
@@ -35,13 +78,19 @@ extra_rdoc_files:
35
78
  - LICENSE.txt
36
79
  files:
37
80
  - lib/ripl/multi_line.rb
81
+ - lib/ripl/multi_line/live_error.rb
82
+ - lib/ripl/multi_line/error_check.rb
83
+ - lib/ripl/multi_line/ripper.rb
84
+ - lib/ripl/multi_line/ruby_parser.rb
85
+ - lib/ripl/multi_line/irb.rb
86
+ - test/test_helper.rb
87
+ - test/shell_test.rb
38
88
  - LICENSE.txt
39
89
  - README.rdoc
40
90
  - CHANGELOG.rdoc
41
91
  - deps.rip
42
92
  - Rakefile
43
93
  - .gemspec
44
- has_rdoc: true
45
94
  homepage: http://github.com/janlelis/ripl-multi_line
46
95
  licenses:
47
96
  - MIT
@@ -65,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
114
  requirements: []
66
115
 
67
116
  rubyforge_project:
68
- rubygems_version: 1.5.2
117
+ rubygems_version: 1.7.2
69
118
  signing_key:
70
119
  specification_version: 3
71
120
  summary: A ripl plugin for multi-line eval.