From 07e4d540cc1b1680fccedb1100866cb5e53151de Mon Sep 17 00:00:00 2001 From: tomoya ishida Date: Sun, 19 Nov 2023 02:49:01 +0900 Subject: [PATCH] Fix irb crash on `{}.` completion (#764) --- lib/irb/completion.rb | 8 ++++---- lib/irb/input-method.rb | 3 +++ test/irb/test_completion.rb | 4 ++-- test/irb/yamatanooroti/test_rendering.rb | 15 +++++++++++++++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb index e3ebe4abf..9b29a787b 100644 --- a/lib/irb/completion.rb +++ b/lib/irb/completion.rb @@ -210,16 +210,16 @@ def retrieve_completion_data(input, bind:, doc_namespace:) end when /^([^\}]*\})\.([^.]*)$/ - # Proc or Hash + # Hash or Proc receiver = $1 message = $2 if doc_namespace - ["Proc.#{message}", "Hash.#{message}"] + ["Hash.#{message}", "Proc.#{message}"] else - proc_candidates = Proc.instance_methods.collect{|m| m.to_s} hash_candidates = Hash.instance_methods.collect{|m| m.to_s} - select_message(receiver, message, proc_candidates | hash_candidates) + proc_candidates = Proc.instance_methods.collect{|m| m.to_s} + select_message(receiver, message, hash_candidates | proc_candidates) end when /^(:[^:.]+)$/ diff --git a/lib/irb/input-method.rb b/lib/irb/input-method.rb index 94ad28cd6..b74974b92 100644 --- a/lib/irb/input-method.rb +++ b/lib/irb/input-method.rb @@ -312,6 +312,9 @@ def show_doc_dialog_proc return nil if result.nil? or pointer.nil? or pointer < 0 name = doc_namespace.call(result[pointer]) + # Use first one because document dialog does not support multiple namespaces. + name = name.first if name.is_a?(Array) + show_easter_egg = name&.match?(/\ARubyVM/) && !ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER'] options = {} diff --git a/test/irb/test_completion.rb b/test/irb/test_completion.rb index d96752681..0625c9697 100644 --- a/test/irb/test_completion.rb +++ b/test/irb/test_completion.rb @@ -37,11 +37,11 @@ def test_complete_array def test_complete_hash_and_proc # hash assert_include(completion_candidates("{}.an", binding), "{}.any?") - assert_equal(["Proc.any?", "Hash.any?"], doc_namespace("{}.any?", binding)) + assert_equal(["Hash.any?", "Proc.any?"], doc_namespace("{}.any?", binding)) # proc assert_include(completion_candidates("{}.bin", binding), "{}.binding") - assert_equal(["Proc.binding", "Hash.binding"], doc_namespace("{}.binding", binding)) + assert_equal(["Hash.binding", "Proc.binding"], doc_namespace("{}.binding", binding)) end def test_complete_numeric diff --git a/test/irb/yamatanooroti/test_rendering.rb b/test/irb/yamatanooroti/test_rendering.rb index b1a7a4087..96051ee43 100644 --- a/test/irb/yamatanooroti/test_rendering.rb +++ b/test/irb/yamatanooroti/test_rendering.rb @@ -203,6 +203,21 @@ def test_symbol_with_backtick EOC end + def test_autocomplete_with_multiple_doc_namespaces + write_irbrc <<~'LINES' + puts 'start IRB' + LINES + start_terminal(4, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB') + write("{}.__id_") + write("\C-i") + close + assert_screen(<<~EOC) + start IRB + irb(main):001> {}.__id__ + }.__id__ + EOC + end + def test_autocomplete_with_showdoc_in_gaps_on_narrow_screen_right rdoc_dir = File.join(@tmpdir, 'rdoc') system("bundle exec rdoc -r -o #{rdoc_dir}")