[前][次][番号順一覧][スレッド一覧]

ruby-changes:64481

From: aycabta <ko1@a...>
Date: Wed, 23 Dec 2020 06:08:43 +0900 (JST)
Subject: [ruby-changes:64481] 841d22ea47 (master): [ruby/reline] [ruby/irb] Handle multiple newlines in a token correctly

https://git.ruby-lang.org/ruby.git/commit/?id=841d22ea47

From 841d22ea479f37ab03d3f6c575997a2dd1b6d0a8 Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@g...>
Date: Wed, 23 Dec 2020 02:18:32 +0900
Subject: [ruby/reline] [ruby/irb] Handle multiple newlines in a token
 correctly

Co-authored-by: manga_osyo <manga.osyo@g...>
Co-authored-by: ima1zumi <mariimaizumi5@g...>

https://github.com/ruby/irb/commit/c59a9be82f

https://github.com/ruby/reline/commit/a7922da16b

diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb
index 7114522..b070278 100644
--- a/lib/irb/ruby-lex.rb
+++ b/lib/irb/ruby-lex.rb
@@ -66,14 +66,19 @@ class RubyLex https://github.com/ruby/ruby/blob/trunk/lib/irb/ruby-lex.rb#L66
         unprocessed_tokens = []
         line_num_offset = 0
         tokens.each do |t|
-          code << t[2]
           partial_tokens << t
           unprocessed_tokens << t
           if t[2].include?("\n")
-            ltype, indent, continue, code_block_open = check_state(code, partial_tokens)
-            result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
-            line_num_offset += 1
+            t_str = t[2]
+            t_str.each_line("\n") do |s|
+              code << s << "\n"
+              ltype, indent, continue, code_block_open = check_state(code, partial_tokens)
+              result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
+              line_num_offset += 1
+            end
             unprocessed_tokens = []
+          else
+            code << t[2]
           end
         end
         unless unprocessed_tokens.empty?
diff --git a/test/irb/test_ruby_lex.rb b/test/irb/test_ruby_lex.rb
index 25f037e..255a5a1 100644
--- a/test/irb/test_ruby_lex.rb
+++ b/test/irb/test_ruby_lex.rb
@@ -7,7 +7,7 @@ module TestIRB https://github.com/ruby/ruby/blob/trunk/test/irb/test_ruby_lex.rb#L7
   class TestRubyLex < Test::Unit::TestCase
     Row = Struct.new(:content, :current_line_spaces, :new_line_spaces, :nesting_level)
 
-    class MockIO
+    class MockIO_AutoIndent
       def initialize(params, &assertion)
         @params = params
         @assertion = assertion
@@ -25,7 +25,7 @@ module TestIRB https://github.com/ruby/ruby/blob/trunk/test/irb/test_ruby_lex.rb#L25
       byte_pointer = lines.last.length
 
       ruby_lex = RubyLex.new()
-      io = MockIO.new([lines, last_line_index, byte_pointer, add_new_line]) do |auto_indent|
+      io = MockIO_AutoIndent.new([lines, last_line_index, byte_pointer, add_new_line]) do |auto_indent|
         error_message = "Calculated the wrong number of spaces for:\n #{lines.join("\n")}"
         assert_equal(correct_space_count, auto_indent, error_message)
       end
@@ -262,5 +262,56 @@ module TestIRB https://github.com/ruby/ruby/blob/trunk/test/irb/test_ruby_lex.rb#L262
         assert_nesting_level(lines, row.nesting_level)
       end
     end
+
+    PromptRow = Struct.new(:prompt, :content)
+
+    class MockIO_DynamicPrompt
+      def initialize(params, &assertion)
+        @params = params
+        @assertion = assertion
+      end
+
+      def dynamic_prompt(&block)
+        result = block.call(@params)
+        @assertion.call(result)
+      end
+    end
+
+    def assert_dynamic_prompt(lines, expected_prompt_list)
+      skip if RUBY_ENGINE == 'truffleruby'
+      ruby_lex = RubyLex.new()
+      io = MockIO_DynamicPrompt.new(lines) do |prompt_list|
+        error_message = "Calculated the wrong number of spaces for:\n #{lines.join("\n")}"
+        assert_equal(expected_prompt_list, prompt_list)
+      end
+      ruby_lex.set_prompt do |ltype, indent, continue, line_no|
+        '%03d:%01d:%1s:%s ' % [line_no, indent, ltype, continue ? '*' : '>']
+      end
+      ruby_lex.set_input(io)
+    end
+
+    def test_dyanmic_prompt
+      input_with_prompt = [
+        PromptRow.new('001:1: :* ', %q(def hoge)),
+        PromptRow.new('002:1: :* ', %q(  3)),
+        PromptRow.new('003:0: :> ', %q(end)),
+      ]
+
+      lines = input_with_prompt.map(&:content)
+      expected_prompt_list = input_with_prompt.map(&:prompt)
+      assert_dynamic_prompt(lines, expected_prompt_list)
+    end
+
+    def test_dyanmic_prompt_with_blank_line
+      input_with_prompt = [
+        PromptRow.new('001:0:]:* ', %q(%w[)),
+        PromptRow.new('002:0:]:* ', %q()),
+        PromptRow.new('003:0: :> ', %q(])),
+      ]
+
+      lines = input_with_prompt.map(&:content)
+      expected_prompt_list = input_with_prompt.map(&:prompt)
+      assert_dynamic_prompt(lines, expected_prompt_list)
+    end
   end
 end
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]