Class: Rigor::LanguageServer::CompletionProvider
- Inherits:
-
Object
- Object
- Rigor::LanguageServer::CompletionProvider
- Includes:
- BufferResolution
- Defined in:
- lib/rigor/language_server/completion_provider.rb
Overview
Answers textDocument/completion requests. Provides method completion for obj.| (known-type receiver
→ RBS-known methods), constant-path completion, hash-key completion, Union / Intersection / Refined /
Shape receiver handling, and parse-recovery fallback for malformed buffers (sentinel injection).
LSP CompletionItemKind values used:
- 2 = Method, 5 = Field, 7 = Class, 9 = Module, 21 = Constant.
Constant Summary collapse
- KIND_METHOD =
2- KIND_FIELD =
5- KIND_CLASS =
7- KIND_MODULE =
9- KIND_CONSTANT =
21
Instance Method Summary collapse
-
#initialize(buffer_table:, project_context:) ⇒ CompletionProvider
constructor
A new instance of CompletionProvider.
-
#provide(uri:, line:, character:, trigger_character: nil) ⇒ Array<Hash>?
LSP
CompletionItem[]or nil when the cursor isn't at a position the provider can enumerate completions for.
Constructor Details
#initialize(buffer_table:, project_context:) ⇒ CompletionProvider
Returns a new instance of CompletionProvider.
39 40 41 42 |
# File 'lib/rigor/language_server/completion_provider.rb', line 39 def initialize(buffer_table:, project_context:) @buffer_table = buffer_table @project_context = project_context end |
Instance Method Details
#provide(uri:, line:, character:, trigger_character: nil) ⇒ Array<Hash>?
Returns LSP CompletionItem[] or nil
when the cursor isn't at a position the provider can
enumerate completions for. Returning nil maps to
result: null per the LSP spec — clients treat it as
"no completions available," distinct from [] which
means "we tried and got nothing".
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/rigor/language_server/completion_provider.rb', line 50 def provide(uri:, line:, character:, trigger_character: nil) _ = trigger_character # Trigger info logged-not-routed in v1. path, entry = buffer_for(uri) return nil if entry.nil? # Slice B4 — parse recovery. The common mid-edit buffer (`obj.` / `Foo::`) doesn't parse cleanly; try # inserting a sentinel name at the cursor before falling through. bytes_to_parse, locate_at = parse_attempt_bytes(entry.bytes, line, character) parse_result = Prism.parse(bytes_to_parse, 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. node = locate_node(source: bytes_to_parse, root: parse_result.value, line: locate_at[0] + 1, character: locate_at[1] + 1) return nil if node.nil? case node when Prism::CallNode # `hash[:|` patches to `hash[:KEY_SENTINEL]`, an index access call whose argument is the sentinel # symbol; NodeLocator at the sentinel returns the inner CallNode for `[]`. Hash-key completion wins # when the call is an index access on a HashShape carrier; otherwise fall through to method # completion. hash_key_completion_for(node, parse_result.value, path) || method_completion_for(node, parse_result.value, path) when Prism::SymbolNode # The sentinel symbol's NodeLocator hit; walk up via the AST to find the enclosing `[]` call. hash_key_completion_for_symbol(node, parse_result.value, path) when Prism::ConstantPathNode constant_path_completion_for(node, path) end end |