Class: Rigor::LanguageServer::HoverProvider
- Inherits:
-
Object
- Object
- Rigor::LanguageServer::HoverProvider
- Includes:
- BufferResolution
- Defined in:
- lib/rigor/language_server/hover_provider.rb
Overview
Answers textDocument/hover requests by running the same NodeLocator + ScopeIndexer + Scope#type_of
chain that rigor type-of already drives. The LSP wraps the result in a Hover payload with markdown
contents.
Per LSP spec § "Position":
lineandcharacterare 0-based.charactercounts UTF-16 code units; v1 emits byte counts for ASCII source (UTF-16 conversion is queued, see design doc § "Open questions").
Instance Method Summary collapse
-
#initialize(buffer_table:, project_context:, renderer: HoverRenderer.new) ⇒ HoverProvider
constructor
A new instance of HoverProvider.
-
#provide(uri:, line:, character:) ⇒ Hash?
An LSP
Hoverpayload or nil when no expression sits at the queried position.
Constructor Details
#initialize(buffer_table:, project_context:, renderer: HoverRenderer.new) ⇒ HoverProvider
Returns a new instance of HoverProvider.
26 27 28 29 30 |
# File 'lib/rigor/language_server/hover_provider.rb', line 26 def initialize(buffer_table:, project_context:, renderer: HoverRenderer.new) @buffer_table = buffer_table @project_context = project_context @renderer = renderer end |
Instance Method Details
#provide(uri:, line:, character:) ⇒ Hash?
Returns an LSP Hover payload or nil when no
expression sits at the queried position. Returning nil
maps to result: null per the LSP spec — clients
suppress the hover popup in that case.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/rigor/language_server/hover_provider.rb', line 36 def provide(uri:, line:, character:) path, entry = buffer_for(uri) return nil if entry.nil? parse_result = Prism.parse(entry.bytes, filepath: path, version: @project_context.configuration.target_ruby) return nil unless parse_result.errors.empty? # Rigor's NodeLocator uses 1-based line / column; LSP uses 0-based. Translate at the boundary. node = locate_node(source: entry.bytes, root: parse_result.value, line: line + 1, character: character + 1) return nil if node.nil? scope = base_scope(path) index = Inference::ScopeIndexer.index(parse_result.value, default_scope: scope) node_scope = index[node] type = node_scope.type_of(node) @renderer.render(node: node, type: type, node_scope_lookup: index) end |