Skip to content

Improve support for hovering over a gem in Gemfile #3344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions lib/ruby_lsp/listeners/hover.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ def initialize(response_builder, global_state, uri, node_context, dispatcher, so

#: (Prism::StringNode node) -> void
def on_string_node_enter(node)
if @path && File.basename(@path) == GEMFILE_NAME
call_node = @node_context.call_node
if call_node && call_node.name == :gem && call_node.arguments&.arguments&.first == node
generate_gem_hover(call_node)
return
end
end

generate_heredoc_hover(node)
end

Expand Down Expand Up @@ -123,11 +131,6 @@ def on_constant_path_node_enter(node)

#: (Prism::CallNode node) -> void
def on_call_node_enter(node)
if @path && File.basename(@path) == GEMFILE_NAME && node.name == :gem
generate_gem_hover(node)
return
end

return if @sorbet_level.true_or_higher? && self_receiver?(node)

message = node.message
Expand Down
31 changes: 23 additions & 8 deletions test/requests/hover_expectations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -273,17 +273,16 @@ class A
end
end

def test_hovering_over_gemfile_dependency
def test_hovering_over_gemfile_dependency_name
source = <<~RUBY
gem 'rake'
RUBY

# We need to pretend that Sorbet is not a dependency or else we can't properly test
with_server(source, URI("file:///Gemfile"), stub_no_typechecker: true) do |server, uri|
with_server(source, URI("file:///Gemfile")) do |server, uri|
server.process_message(
id: 1,
method: "textDocument/hover",
params: { textDocument: { uri: uri }, position: { character: 0, line: 0 } },
params: { textDocument: { uri: uri }, position: { character: 5, line: 0 } },
)

response = server.pop_response.response
Expand All @@ -295,13 +294,30 @@ def test_hovering_over_gemfile_dependency
end
end

def test_hovering_over_gemfile_dependency_triggers_only_for_first_arg
source = <<~RUBY
gem 'rake', '~> 1.0'
RUBY

with_server(source, URI("file:///Gemfile")) do |server, uri|
server.process_message(
id: 1,
method: "textDocument/hover",
params: { textDocument: { uri: uri }, position: { character: 13, line: 0 } },
)

response = server.pop_response.response

assert_nil(response)
end
end

def test_hovering_over_gemfile_dependency_with_missing_argument
source = <<~RUBY
gem()
RUBY

# We need to pretend that Sorbet is not a dependency or else we can't properly test
with_server(source, URI("file:///Gemfile"), stub_no_typechecker: true) do |server, uri|
with_server(source, URI("file:///Gemfile")) do |server, uri|
server.process_message(
id: 1,
method: "textDocument/hover",
Expand All @@ -317,8 +333,7 @@ def test_hovering_over_gemfile_dependency_with_non_gem_argument
gem(method_call)
RUBY

# We need to pretend that Sorbet is not a dependency or else we can't properly test
with_server(source, URI("file:///Gemfile"), stub_no_typechecker: true) do |server, uri|
with_server(source, URI("file:///Gemfile")) do |server, uri|
server.process_message(
id: 1,
method: "textDocument/hover",
Expand Down