summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStan Lo <[email protected]>2024-07-05 18:25:06 +0100
committergit <[email protected]>2024-07-05 17:51:17 +0000
commit32ba86c9be79c6f67caafbf71004e5a508db1a88 (patch)
treef764774866f08ec67a46647e0c15ce686e0856ae
parent1afcaa3e4b4338191cdc337ed43bc92637be26b5 (diff)
[ruby/irb] Return only commands when completing help command's
argument (https://github.com/ruby/irb/pull/973) The command only takes command names as arguments, so we should only return command names as candidates. This will help users find a command faster as completion will be another useful hint too. https://github.com/ruby/irb/commit/7b6557cc24
-rw-r--r--lib/irb/completion.rb38
-rw-r--r--test/irb/test_completion.rb10
-rw-r--r--test/irb/test_type_completor.rb5
3 files changed, 42 insertions, 11 deletions
diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb
index a3d89373c3..7f102dcdf4 100644
--- a/lib/irb/completion.rb
+++ b/lib/irb/completion.rb
@@ -33,6 +33,8 @@ module IRB
yield
]
+ HELP_COMMAND_PREPOSING = /\Ahelp\s+/
+
def completion_candidates(preposing, target, postposing, bind:)
raise NotImplementedError
end
@@ -86,8 +88,8 @@ module IRB
)
end
- def command_completions(preposing, target)
- if preposing.empty? && !target.empty?
+ def command_candidates(target)
+ if !target.empty?
IRB::Command.command_names.select { _1.start_with?(target) }
else
[]
@@ -111,8 +113,18 @@ module IRB
end
def completion_candidates(preposing, target, _postposing, bind:)
- commands = command_completions(preposing, target)
+ # When completing the argument of `help` command, only commands should be candidates
+ return command_candidates(target) if preposing.match?(HELP_COMMAND_PREPOSING)
+
+ commands = if preposing.empty?
+ command_candidates(target)
+ # It doesn't make sense to propose commands with other preposing
+ else
+ []
+ end
+
result = ReplTypeCompletor.analyze(preposing + target, binding: bind, filename: @context.irb_path)
+
return commands unless result
commands | result.completion_candidates.map { target + _1 }
@@ -187,12 +199,20 @@ module IRB
end
def completion_candidates(preposing, target, postposing, bind:)
- if preposing && postposing
- result = complete_require_path(target, preposing, postposing)
- return result if result
+ if result = complete_require_path(target, preposing, postposing)
+ return result
end
- commands = command_completions(preposing || '', target)
- commands | retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) }
+
+ commands = command_candidates(target)
+
+ # When completing the argument of `help` command, only commands should be candidates
+ return commands if preposing.match?(HELP_COMMAND_PREPOSING)
+
+ # It doesn't make sense to propose commands with other preposing
+ commands = [] unless preposing.empty?
+
+ completion_data = retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) }
+ commands | completion_data
end
def doc_namespace(_preposing, matched, _postposing, bind:)
@@ -470,7 +490,7 @@ module IRB
end
end
CompletionProc = ->(target, preposing = nil, postposing = nil) {
- regexp_completor.completion_candidates(preposing, target, postposing, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding)
+ regexp_completor.completion_candidates(preposing || '', target, postposing || '', bind: IRB.conf[:MAIN_CONTEXT].workspace.binding)
}
end
deprecate_constant :InputCompletor
diff --git a/test/irb/test_completion.rb b/test/irb/test_completion.rb
index 5fe7952b3d..c9a0eafa3d 100644
--- a/test/irb/test_completion.rb
+++ b/test/irb/test_completion.rb
@@ -16,8 +16,14 @@ module TestIRB
class CommandCompletionTest < CompletionTest
def test_command_completion
- assert_include(IRB::RegexpCompletor.new.completion_candidates('', 'show_s', '', bind: binding), 'show_source')
- assert_not_include(IRB::RegexpCompletor.new.completion_candidates(';', 'show_s', '', bind: binding), 'show_source')
+ completor = IRB::RegexpCompletor.new
+ binding.eval("some_var = 1")
+ # completion for help command's argument should only include command names
+ assert_include(completor.completion_candidates('help ', 's', '', bind: binding), 'show_source')
+ assert_not_include(completor.completion_candidates('help ', 's', '', bind: binding), 'some_var')
+
+ assert_include(completor.completion_candidates('', 'show_s', '', bind: binding), 'show_source')
+ assert_not_include(completor.completion_candidates(';', 'show_s', '', bind: binding), 'show_source')
end
end
diff --git a/test/irb/test_type_completor.rb b/test/irb/test_type_completor.rb
index 5ed8988b34..412d7c696d 100644
--- a/test/irb/test_type_completor.rb
+++ b/test/irb/test_type_completor.rb
@@ -56,6 +56,11 @@ module TestIRB
end
def test_command_completion
+ binding.eval("some_var = 1")
+ # completion for help command's argument should only include command names
+ assert_include(@completor.completion_candidates('help ', 's', '', bind: binding), 'show_source')
+ assert_not_include(@completor.completion_candidates('help ', 's', '', bind: binding), 'some_var')
+
assert_include(@completor.completion_candidates('', 'show_s', '', bind: binding), 'show_source')
assert_not_include(@completor.completion_candidates(';', 'show_s', '', bind: binding), 'show_source')
end