fix(lsp): position inlay hints from the document being edited - #6092
Open
tripleaceme wants to merge 1 commit into
Open
tripleaceme wants to merge 1 commit into
tripleaceme wants to merge 1 commit into
Conversation
Inlay hint positions came from the model held by the LSP context, whose query carries the token positions of the file as it was last loaded. The context is only reloaded on didSave, so while the user edits a column name the hint is placed at the offset the name used to end at, which renders the type cast inside the name being typed (`zip::TEXT_code`). It corrects itself on save, render or reopen because those reload the context. Parse the text the editor currently holds and take the hint positions from that, looking column types up by name on the loaded model. A column that isn't on the model yet gets no hint until the next reload, and text that doesn't parse yet gets none at all, rather than hints at offsets that no longer match the document. Fixes SQLMesh#5630 Signed-off-by: Adegbite Ayoade <tripleaceme@gmail.com>
Contributor
Author
|
@cmgoffena13 — closes #5630. The cause turned out to be simpler than the symptom suggests: the LSP has no Three judgement calls are listed at the end of the description — mainly that hints now disappear while a column is being renamed rather than rendering inside the word. Also worth knowing: diagnostics come from the same reload-on-save context, so they are probably stale in the same way. I have not investigated that and it is out of scope here. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Closes #5630.
Inlay hints render inside a column name while it is being typed —
zip_codeshows aszip::TEXT_code— and correct themselves on save, re-render or reopening the file.The cause is not a race, debouncing, or a document-version mismatch.
sqlmesh/lsp/main.pyregistersdid_openanddid_saveand notextDocument/didChangehandler, so the server's parsed model is frozen until the file is saved.get_hintsderives every hint'scharacterfrom sqlglot token metadata onlsp_context.context.get_model(...).query, which is the model parsed from disk at the last load. VS Code invalidates and re-requests hints on every change, so it is asking correctly; the server answers with last-saved offsets.Version-stamping the responses would not have helped — the server has no correct answer at any version, it would simply withhold a wrong one.
get_hintsnow takes the document text and reads positions from parsing that, usingsqlmesh.core.dialect.parseplus_split_sql_model_statements, which is the loader's own query-extraction rule, so macro-union and jinja models behave as before. Types are still resolved by name against the loaded model.main.pypassesls.workspace.get_text_document(...).source, which pygls keeps in sync withdidChange.Behaviour, all covered by tests:
A second symptom of the same cause, not reported in the issue: inserting a line above shifted all the text but not the hints, so they attached to the wrong columns with the wrong types.
Three things for your judgement
normalize_identifiers(query.copy())already done per request, but I have not benchmarked it against a large model._split_sql_model_statementsis private. I imported it rather than re-implementing the rule, so the two cannot drift.sqlmesh/lsp/already reaches into internals such ascontext._modelsandtarget._path, so this seemed in keeping, but you may prefer it promoted or duplicated.Out of scope here, but worth flagging: diagnostics are published from the same reload-on-save context, so they are likely stale between saves in the same way. I have not investigated.
Test Plan
Two tests in
tests/lsp/test_hints.py:test_hints_are_positioned_from_the_edited_document— a column renamed in the buffer but not saved produces no hint inside the name, and the remaining hints stay correct.test_hints_for_unparseable_document— mid-edit text that does not parse yields no hints rather than stale ones.Both fail without the change, and the failure prints the bug verbatim:
ruff check,ruff format --checkandmypyclean on the changed files. No TypeScript touched — the extension has no inlay-hint code, it uses the stockvscode-languageclientprovider.Checklist
make styleand fixed any issuesmake fast-test)git commit -s) per the DCO