Class: RubyLsp::Requests::Hover

Inherits:
RubyLsp::Request 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) } }

Instance Attribute Summary

Attributes inherited from Message

#message, #params

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document, index, position, dispatcher, typechecker_enabled) ⇒ Hover

Returns a new instance of Hover.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/ruby_lsp/requests/hover.rb', line 42

def initialize(document, index, position, dispatcher, typechecker_enabled)
  super()
  target, parent, nesting = document.locate_node(
    position,
    node_types: Listeners::Hover::ALLOWED_TARGETS,
  )

  if (Listeners::Hover::ALLOWED_TARGETS.include?(parent.class) &&
      !Listeners::Hover::ALLOWED_TARGETS.include?(target.class)) ||
      (parent.is_a?(Prism::ConstantPathNode) && target.is_a?(Prism::ConstantReadNode))
    target = parent
  end

  @listeners = T.let([], T::Array[Listener[ResponseType]])

  # Don't need to instantiate any listeners if there's no target
  return unless target

  uri = document.uri
  @listeners = T.let(
    [Listeners::Hover.new(uri, nesting, index, dispatcher, typechecker_enabled)],
    T::Array[Listener[ResponseType]],
  )
  Addon.addons.each do |addon|
    addon_listener = addon.create_hover_listener(nesting, index, dispatcher)
    @listeners << addon_listener if addon_listener
  end

  @target = T.let(target, Prism::Node)
  @dispatcher = dispatcher
end

Class Method Details

.providerObject



26
27
28
# File 'lib/ruby_lsp/requests/hover.rb', line 26

def provider
  Interface::HoverClientCapabilities.new(dynamic_registration: false)
end

Instance Method Details

#performObject



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/ruby_lsp/requests/hover.rb', line 75

def perform
  @dispatcher.dispatch_once(@target)
  responses = @listeners.map(&:response).compact

  first_response, *other_responses = responses

  return unless first_response

  # TODO: other_responses should never be nil. Check Sorbet
  T.must(other_responses).each do |other_response|
    first_response.contents.value << "\n\n" << other_response.contents.value
  end

  first_response
end