Class: Rigor::LanguageServer::BufferTable
- Inherits:
-
Object
- Object
- Rigor::LanguageServer::BufferTable
- Defined in:
- lib/rigor/language_server/buffer_table.rb
Overview
Per-session virtual file table. The LSP server maintains the canonical view of every open buffer here; analysis (slice 4+) reads from this table instead of disk so in-flight edits are reflected immediately.
Keyed by DocumentUri (LSP file://... URIs). Sync is INCREMENTAL (LSP
TextDocumentSyncKind::Incremental = 2): a didChange carries range edits which #apply_changes splices
into the held text through IncrementalSync. The full-text form (#change, and a contentChanges entry
with no range) stays supported — it is still legal under incremental sync and is what didOpen and a
client-side resync send.
Defined Under Namespace
Classes: Entry
Instance Method Summary collapse
- #[](uri) ⇒ Object
-
#apply_changes(uri:, changes:, version:) ⇒ Boolean
Applies a
textDocument/didChangepayload under INCREMENTAL sync. -
#change(uri:, bytes:, version:) ⇒ Object
Records a full-text
textDocument/didChange. -
#close(uri:) ⇒ Object
Records a
textDocument/didCloseevent. -
#desynchronization_reason(uri) ⇒ String?
Why
uriis desynchronised, for the log line; nil when it is in sync. -
#desynchronized?(uri) ⇒ Boolean
True when the last
didChangeforuricould not be applied, so the held text no longer matches the editor's. -
#initialize ⇒ BufferTable
constructor
A new instance of BufferTable.
-
#open(uri:, bytes:, version:) ⇒ Object
Records a
textDocument/didOpenevent. - #open?(uri) ⇒ Boolean
- #size ⇒ Object
- #uris ⇒ Object
Constructor Details
#initialize ⇒ BufferTable
Returns a new instance of BufferTable.
21 22 23 24 |
# File 'lib/rigor/language_server/buffer_table.rb', line 21 def initialize @entries = {} @desynchronized = {} end |
Instance Method Details
#[](uri) ⇒ Object
79 80 81 |
# File 'lib/rigor/language_server/buffer_table.rb', line 79 def [](uri) @entries[uri] end |
#apply_changes(uri:, changes:, version:) ⇒ Boolean
Applies a textDocument/didChange payload under INCREMENTAL sync. Each entry of changes is applied
in order against the result of the previous one, per the LSP contract.
On success the entry is replaced with the spliced text at the new version. On failure — a malformed
change, or a range edit for a URI with no held buffer — the held text is left EXACTLY as it was and the
URI is marked desynchronised: the server's view and the editor's view have diverged, and every position
computed from the stale text would be wrong. Consumers check #desynchronized? and decline to answer
rather than answering wrongly; the mark clears on the next didOpen or full-text change.
52 53 54 55 56 57 58 59 60 |
# File 'lib/rigor/language_server/buffer_table.rb', line 52 def apply_changes(uri:, changes:, version:) text = IncrementalSync.apply_all(@entries[uri]&.bytes, changes) @desynchronized.delete(uri) @entries[uri] = Entry.new(uri: uri, bytes: text, version: version) true rescue IncrementalSync::UnappliableChange => e @desynchronized[uri] = e. false end |
#change(uri:, bytes:, version:) ⇒ Object
Records a full-text textDocument/didChange. The full new buffer text replaces the entry. If the
client sends a didChange for a URI that was never opened (spec violation), the entry is still
created — defensive.
37 38 39 40 |
# File 'lib/rigor/language_server/buffer_table.rb', line 37 def change(uri:, bytes:, version:) @desynchronized.delete(uri) @entries[uri] = Entry.new(uri: uri, bytes: bytes, version: version) end |
#close(uri:) ⇒ Object
Records a textDocument/didClose event. The entry is removed. Subsequent reads via #[] return nil.
74 75 76 77 |
# File 'lib/rigor/language_server/buffer_table.rb', line 74 def close(uri:) @desynchronized.delete(uri) @entries.delete(uri) end |
#desynchronization_reason(uri) ⇒ String?
Returns why uri is desynchronised, for the log line; nil when it is in sync.
69 70 71 |
# File 'lib/rigor/language_server/buffer_table.rb', line 69 def desynchronization_reason(uri) @desynchronized[uri] end |
#desynchronized?(uri) ⇒ Boolean
Returns true when the last didChange for uri could not be applied, so the held text no
longer matches the editor's.
64 65 66 |
# File 'lib/rigor/language_server/buffer_table.rb', line 64 def desynchronized?(uri) @desynchronized.key?(uri) end |
#open(uri:, bytes:, version:) ⇒ Object
Records a textDocument/didOpen event. Replaces any existing entry (LSP clients may re-open a
previously closed URI; the new version is authoritative) and clears any desynchronised mark — the
payload carries the client's full text, so the two views agree again.
29 30 31 32 |
# File 'lib/rigor/language_server/buffer_table.rb', line 29 def open(uri:, bytes:, version:) @desynchronized.delete(uri) @entries[uri] = Entry.new(uri: uri, bytes: bytes, version: version) end |
#open?(uri) ⇒ Boolean
83 84 85 |
# File 'lib/rigor/language_server/buffer_table.rb', line 83 def open?(uri) @entries.key?(uri) end |
#size ⇒ Object
87 88 89 |
# File 'lib/rigor/language_server/buffer_table.rb', line 87 def size @entries.size end |
#uris ⇒ Object
91 92 93 |
# File 'lib/rigor/language_server/buffer_table.rb', line 91 def uris @entries.keys end |