Class: RubyLsp::Requests::Hover

Inherits:
ExtensibleListener
  • Object
show all
Extended by:
T::Generic, T::Sig
Defined in:
lib/ruby_lsp/requests/hover.rb

Overview

![Hover demo](../../hover.gif)

The [hover request](microsoft.github.io/language-server-protocol/specification#textDocument_hover) displays the documentation for the symbol currently under the cursor.

# Example

“‘ruby String # -> Hovering over the class reference will show all declaration locations and the documentation “`

Constant Summary collapse

ResponseType =
type_member { { fixed: T.nilable(Interface::Hover) } }
ALLOWED_TARGETS =
T.let(
  [
    Prism::CallNode,
    Prism::ConstantReadNode,
    Prism::ConstantWriteNode,
    Prism::ConstantPathNode,
  ],
  T::Array[T.class_of(Prism::Node)],
)

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Listener

#response

Methods included from Support::Common

#create_code_lens, #defined_in_gem?, #markdown_from_index_entries, #range_from_location, #range_from_node, #self_receiver?, #visible?

Constructor Details

#initialize(index, nesting, dispatcher, message_queue) ⇒ Hover

Returns a new instance of Hover.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/ruby_lsp/requests/hover.rb', line 43

def initialize(index, nesting, dispatcher, message_queue)
  @index = index
  @nesting = nesting
  @_response = T.let(nil, ResponseType)

  super(dispatcher, message_queue)
  dispatcher.register(
    self,
    :on_constant_read_node_enter,
    :on_constant_write_node_enter,
    :on_constant_path_node_enter,
    :on_call_node_enter,
  )
end

Instance Attribute Details

#_responseObject (readonly)

Returns the value of attribute _response.



33
34
35
# File 'lib/ruby_lsp/requests/hover.rb', line 33

def _response
  @_response
end

Instance Method Details

#initialize_external_listener(addon) ⇒ Object



59
60
61
# File 'lib/ruby_lsp/requests/hover.rb', line 59

def initialize_external_listener(addon)
  addon.create_hover_listener(@nesting, @index, @dispatcher, @message_queue)
end

#merge_response!(other) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/ruby_lsp/requests/hover.rb', line 65

def merge_response!(other)
  other_response = other.response
  return self unless other_response

  if @_response.nil?
    @_response = other.response
  else
    @_response.contents.value << "\n\n" << other_response.contents.value
  end

  self
end

#on_call_node_enter(node) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/ruby_lsp/requests/hover.rb', line 100

def on_call_node_enter(node)
  return if DependencyDetector.instance.typechecker
  return unless self_receiver?(node)

  message = node.message
  return unless message

  target_method = @index.resolve_method(message, @nesting.join("::"))
  return unless target_method

  location = target_method.location

  @_response = Interface::Hover.new(
    range: range_from_location(location),
    contents: markdown_from_index_entries(message, target_method),
  )
end

#on_constant_path_node_enter(node) ⇒ Object



93
94
95
96
97
# File 'lib/ruby_lsp/requests/hover.rb', line 93

def on_constant_path_node_enter(node)
  return if DependencyDetector.instance.typechecker

  generate_hover(node.slice, node.location)
end

#on_constant_read_node_enter(node) ⇒ Object



79
80
81
82
83
# File 'lib/ruby_lsp/requests/hover.rb', line 79

def on_constant_read_node_enter(node)
  return if DependencyDetector.instance.typechecker

  generate_hover(node.slice, node.location)
end

#on_constant_write_node_enter(node) ⇒ Object



86
87
88
89
90
# File 'lib/ruby_lsp/requests/hover.rb', line 86

def on_constant_write_node_enter(node)
  return if DependencyDetector.instance.typechecker

  generate_hover(node.name.to_s, node.name_loc)
end