class RubyLsp::Requests::Hover
: [ResponseType = Interface::Hover?]
displays the documentation for the symbol currently under the cursor.
The [hover request](microsoft.github.io/language-server-protocol/specification#textDocument_hover)
def initialize(document, global_state, position, dispatcher, sorbet_level)
def initialize(document, global_state, position, dispatcher, sorbet_level) super() char_position, _ = document.find_index_by_position(position) delegate_request_if_needed!(global_state, document, char_position) node_context = RubyDocument.locate( document.ast, char_position, node_types: Listeners::Hover::ALLOWED_TARGETS, code_units_cache: document.code_units_cache, ) target = node_context.node parent = node_context.parent if should_refine_target?(parent, target) target = determine_target( target, #: as !nil parent, #: as !nil position, ) elsif position_outside_target?(position, target) target = nil end # Don't need to instantiate any listeners if there's no target return unless target @target = target #: Prism::Node? uri = document.uri @response_builder = ResponseBuilders::Hover.new #: ResponseBuilders::Hover Listeners::Hover.new(@response_builder, global_state, uri, node_context, dispatcher, sorbet_level) Addon.addons.each do |addon| addon.create_hover_listener(@response_builder, node_context, dispatcher) end @dispatcher = dispatcher end
def perform
@override
def perform return unless @target @dispatcher.dispatch_once(@target) return if @response_builder.empty? Interface::Hover.new( contents: Interface::MarkupContent.new( kind: "markdown", value: @response_builder.response, ), ) end
def position_outside_target?(position, target)
def position_outside_target?(position, target) case target when Prism::GlobalVariableAndWriteNode, Prism::GlobalVariableOperatorWriteNode, Prism::GlobalVariableOrWriteNode, Prism::GlobalVariableWriteNode !covers_position?(target.name_loc, position) when Prism::CallNode !covers_position?(target.message_loc, position) else false end end
def provider
def provider Interface::HoverOptions.new end
def should_refine_target?(parent, target)
def should_refine_target?(parent, target) (Listeners::Hover::ALLOWED_TARGETS.include?(parent.class) && !Listeners::Hover::ALLOWED_TARGETS.include?(target.class)) || (parent.is_a?(Prism::ConstantPathNode) && target.is_a?(Prism::ConstantReadNode)) end