Skip to content

Commit

Permalink
feat: add completion for global variables
Browse files Browse the repository at this point in the history
  • Loading branch information
snutij committed Oct 21, 2024
1 parent dd376e9 commit 6361649
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
24 changes: 24 additions & 0 deletions lib/ruby_lsp/listeners/completion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ def initialize( # rubocop:disable Metrics/ParameterLists
:on_constant_path_node_enter,
:on_constant_read_node_enter,
:on_call_node_enter,
:on_global_variable_read_node_enter,
:on_instance_variable_read_node_enter,
:on_instance_variable_write_node_enter,
:on_instance_variable_and_write_node_enter,
Expand Down Expand Up @@ -180,6 +181,29 @@ def on_call_node_enter(node)
end
end

sig { params(node: Prism::GlobalVariableReadNode).void }
def on_global_variable_read_node_enter(node)
candidates = @index.prefix_search(node.name.to_s)

return if candidates.none?

range = range_from_location(node.location)

candidates.flatten.each do |entry|
entry_name = entry.name

@response_builder << Interface::CompletionItem.new(
label: entry_name,
filter_text: entry_name,
label_details: Interface::CompletionItemLabelDetails.new(
description: entry.file_name,
),
text_edit: Interface::TextEdit.new(range: range, new_text: entry_name),
kind: Constant::CompletionItemKind::VARIABLE,
)
end
end

sig { params(node: Prism::InstanceVariableReadNode).void }
def on_instance_variable_read_node_enter(node)
handle_instance_variable_completion(node.name.to_s, node.location)
Expand Down
3 changes: 2 additions & 1 deletion lib/ruby_lsp/requests/completion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class << self
def provider
Interface::CompletionOptions.new(
resolve_provider: true,
trigger_characters: ["/", "\"", "'", ":", "@", ".", "=", "<"],
trigger_characters: ["/", "\"", "'", ":", "@", ".", "=", "<", "$"],
completion_item: {
labelDetailsSupport: true,
},
Expand Down Expand Up @@ -50,6 +50,7 @@ def initialize(document, global_state, params, sorbet_level, dispatcher)
Prism::CallNode,
Prism::ConstantReadNode,
Prism::ConstantPathNode,
Prism::GlobalVariableReadNode,
Prism::InstanceVariableReadNode,
Prism::InstanceVariableAndWriteNode,
Prism::InstanceVariableOperatorWriteNode,
Expand Down
28 changes: 28 additions & 0 deletions test/requests/completion_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1431,6 +1431,34 @@ def test_guessed_type_name_is_only_included_for_guessed_types
end
end

def test_completion_for_global_variables
source = <<~RUBY
$
$LOAD
RUBY

with_server(source) do |server, uri|
index = server.instance_variable_get(:@global_state).index
RubyIndexer::RBSIndexer.new(index).index_ruby_core

server.process_message(id: 1, method: "textDocument/completion", params: {
textDocument: { uri: uri },
position: { line: 0, character: 1 },
})
items = server.pop_response.response
assert_operator(items.size, :>, 40)

server.process_message(id: 1, method: "textDocument/completion", params: {
textDocument: { uri: uri },
position: { line: 1, character: 1 },
})
items = server.pop_response.response
assert_operator(items.size, :>=, 2)
assert_includes(items.map(&:label), "$LOADED_FEATURES")
assert_includes(items.map(&:label), "$LOAD_PATH")
end
end

private

def with_file_structure(server, &block)
Expand Down

0 comments on commit 6361649

Please sign in to comment.