From bb6a99d81574204fa79b54a9ef33f56b9dbeff47 Mon Sep 17 00:00:00 2001 From: tomoya ishida Date: Sun, 6 Oct 2024 20:10:09 +0900 Subject: [PATCH] Change default completor from regexp to auto, try TypeCompletor and fallback to RegexpCompletor. (#1010) --- lib/irb/context.rb | 14 ++++++++++---- lib/irb/init.rb | 2 +- test/irb/test_context.rb | 2 ++ test/irb/test_init.rb | 10 +++++++--- test/irb/test_type_completor.rb | 16 ++++++++++++++++ 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/lib/irb/context.rb b/lib/irb/context.rb index 668a823f5..505bed80a 100644 --- a/lib/irb/context.rb +++ b/lib/irb/context.rb @@ -176,11 +176,17 @@ def use_loader=(val) private def build_completor completor_type = IRB.conf[:COMPLETOR] + + # Gem repl_type_completor is added to bundled gems in Ruby 3.4. + # Use :type as default completor only in Ruby 3.4 or later. + verbose = !!completor_type + completor_type ||= RUBY_VERSION >= '3.4' ? :type : :regexp + case completor_type when :regexp return RegexpCompletor.new when :type - completor = build_type_completor + completor = build_type_completor(verbose: verbose) return completor if completor else warn "Invalid value for IRB.conf[:COMPLETOR]: #{completor_type}" @@ -189,17 +195,17 @@ def use_loader=(val) RegexpCompletor.new end - private def build_type_completor + private def build_type_completor(verbose:) if RUBY_ENGINE == 'truffleruby' # Avoid SyntaxError. truffleruby does not support endless method definition yet. - warn 'TypeCompletor is not supported on TruffleRuby yet' + warn 'TypeCompletor is not supported on TruffleRuby yet' if verbose return end begin require 'repl_type_completor' rescue LoadError => e - warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}" + warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}" if verbose return end diff --git a/lib/irb/init.rb b/lib/irb/init.rb index 7dc08912e..d474bd41d 100644 --- a/lib/irb/init.rb +++ b/lib/irb/init.rb @@ -80,7 +80,7 @@ def IRB.init_config(ap_path) @CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod) @CONF[:USE_COLORIZE] = (nc = ENV['NO_COLOR']).nil? || nc.empty? @CONF[:USE_AUTOCOMPLETE] = ENV.fetch("IRB_USE_AUTOCOMPLETE", "true") != "false" - @CONF[:COMPLETOR] = ENV.fetch("IRB_COMPLETOR", "regexp").to_sym + @CONF[:COMPLETOR] = ENV["IRB_COMPLETOR"]&.to_sym @CONF[:INSPECT_MODE] = true @CONF[:USE_TRACER] = false @CONF[:USE_LOADER] = false diff --git a/test/irb/test_context.rb b/test/irb/test_context.rb index 7ad8fd2fc..9fa23ccce 100644 --- a/test/irb/test_context.rb +++ b/test/irb/test_context.rb @@ -705,6 +705,8 @@ def test_irb_path_setter def test_build_completor verbose, $VERBOSE = $VERBOSE, nil original_completor = IRB.conf[:COMPLETOR] + IRB.conf[:COMPLETOR] = nil + assert_match /IRB::(Regexp|Type)Completor/, @context.send(:build_completor).class.name IRB.conf[:COMPLETOR] = :regexp assert_equal 'IRB::RegexpCompletor', @context.send(:build_completor).class.name IRB.conf[:COMPLETOR] = :unknown diff --git a/test/irb/test_init.rb b/test/irb/test_init.rb index 3e8d01c5c..f7168e02f 100644 --- a/test/irb/test_init.rb +++ b/test/irb/test_init.rb @@ -167,9 +167,10 @@ def test_completor_environment_variable orig_use_autocomplete_env = ENV['IRB_COMPLETOR'] orig_use_autocomplete_conf = IRB.conf[:COMPLETOR] + # Default value is nil: auto-detect ENV['IRB_COMPLETOR'] = nil IRB.setup(__FILE__) - assert_equal(:regexp, IRB.conf[:COMPLETOR]) + assert_equal(nil, IRB.conf[:COMPLETOR]) ENV['IRB_COMPLETOR'] = 'regexp' IRB.setup(__FILE__) @@ -193,10 +194,12 @@ def test_completor_environment_variable def test_completor_setup_with_argv orig_completor_conf = IRB.conf[:COMPLETOR] + orig_completor_env = ENV['IRB_COMPLETOR'] + ENV['IRB_COMPLETOR'] = nil - # Default is :regexp + # Default value is nil: auto-detect IRB.setup(__FILE__, argv: []) - assert_equal :regexp, IRB.conf[:COMPLETOR] + assert_equal nil, IRB.conf[:COMPLETOR] IRB.setup(__FILE__, argv: ['--type-completor']) assert_equal :type, IRB.conf[:COMPLETOR] @@ -205,6 +208,7 @@ def test_completor_setup_with_argv assert_equal :regexp, IRB.conf[:COMPLETOR] ensure IRB.conf[:COMPLETOR] = orig_completor_conf + ENV['IRB_COMPLETOR'] = orig_completor_env end def test_noscript diff --git a/test/irb/test_type_completor.rb b/test/irb/test_type_completor.rb index 412d7c696..3d0e25d19 100644 --- a/test/irb/test_type_completor.rb +++ b/test/irb/test_type_completor.rb @@ -27,6 +27,22 @@ def empty_binding binding end + def test_build_completor + IRB.init_config(nil) + verbose, $VERBOSE = $VERBOSE, nil + original_completor = IRB.conf[:COMPLETOR] + workspace = IRB::WorkSpace.new(Object.new) + @context = IRB::Context.new(nil, workspace, TestInputMethod.new) + IRB.conf[:COMPLETOR] = nil + expected_default_completor = RUBY_VERSION >= '3.4' ? 'IRB::TypeCompletor' : 'IRB::RegexpCompletor' + assert_equal expected_default_completor, @context.send(:build_completor).class.name + IRB.conf[:COMPLETOR] = :type + assert_equal 'IRB::TypeCompletor', @context.send(:build_completor).class.name + ensure + $VERBOSE = verbose + IRB.conf[:COMPLETOR] = original_completor + end + def assert_completion(preposing, target, binding: empty_binding, include: nil, exclude: nil) raise ArgumentError if include.nil? && exclude.nil? candidates = @completor.completion_candidates(preposing, target, '', bind: binding)