From ed9a2516bac3ed9739407efb0e56d28b6967caac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lek=C3=AB=20Mula?= Date: Sat, 18 Jan 2025 20:57:02 +0100 Subject: [PATCH] Complete global methods from a file inside namespaces (#714) --- lib/solargraph/source_map/clip.rb | 9 +++++++++ spec/source_map/clip_spec.rb | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/lib/solargraph/source_map/clip.rb b/lib/solargraph/source_map/clip.rb index a7dbc76e..533cbc2b 100644 --- a/lib/solargraph/source_map/clip.rb +++ b/lib/solargraph/source_map/clip.rb @@ -17,6 +17,7 @@ def initialize api_map, cursor def define return [] if cursor.comment? || cursor.chain.literal? result = cursor.chain.define(api_map, block, locals) + result.concat file_global_methods result.concat((source_map.pins + source_map.locals).select{ |p| p.name == cursor.word && p.location.range.contain?(cursor.position) }) if result.empty? result end @@ -219,6 +220,7 @@ def code_complete return package_completions(api_map.get_global_variable_pins) end result.concat locals + result.concat file_global_methods unless block.binder.namespace.empty? result.concat api_map.get_constants(context_pin.context.namespace, *gates) result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected]) result.concat api_map.get_methods('Kernel') @@ -229,6 +231,13 @@ def code_complete end package_completions(result) end + + def file_global_methods + return [] if cursor.word.empty? + source_map.pins.select do |pin| + pin.is_a?(Pin::Method) && pin.namespace == '' && pin.name.start_with?(cursor.word) + end + end end end end diff --git a/spec/source_map/clip_spec.rb b/spec/source_map/clip_spec.rb index a40b70a3..69a49dcd 100644 --- a/spec/source_map/clip_spec.rb +++ b/spec/source_map/clip_spec.rb @@ -1506,4 +1506,22 @@ def foo; end string_names = api_map.clip_at('test.rb', [6, 22]).complete.pins.map(&:name) expect(string_names).to eq(["upcase", "upcase!", "upto"]) end + + it 'completes global methods defined in top level scope inside class when referenced inside a namespace' do + source = Solargraph::Source.load_string(%( + def some_method;end + + class Thing + def foo + some_ + end + end + some_ + ), 'test.rb') + api_map = Solargraph::ApiMap.new.map(source) + pin_names = api_map.clip_at('test.rb', [5, 15]).complete.pins.map(&:name) + expect(pin_names).to eq(["some_method"]) + pin_names = api_map.clip_at('test.rb', [8, 5]).complete.pins.map(&:name) + expect(pin_names).to include("some_method") + end end