Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: inlay hints for auto-implicits #6768

Merged
merged 6 commits into from
Feb 4, 2025

Conversation

mhuisi
Copy link
Contributor

@mhuisi mhuisi commented Jan 24, 2025

This PR adds preliminary support for inlay hints, as well as support for inlay hints that denote the auto-implicits of a function. Hovering over an auto-implicit displays its type and double-clicking the auto-implicit inserts it into the text document.

Inlay hints for auto-implicits

This PR is an extension of #3910.

Known issues

  • In VS Code, when inserting an inlay hint, the inlay hint may linger for a couple of seconds before it disappears. This is a defect of the VS Code implementation of inlay hints and cannot adequately be resolved by us.
  • When making a change to the document, it may take a couple of seconds until the inlay hints respond to the change. This is deliberate and intended to reduce the amount of inlay hint flickering while typing. VS Code has a mechanism of its own for this, but in my experience it is still far too sensitive without additional latency.
  • Inserting an auto-implicit inlay hint that depends on an auto-implicit meta-variable causes a "failed to infer binder type" error. We can't display these meta-variables in the inlay hint because they don't have a user-displayable name, so it is not clear how to resolve this problem.
  • Inlay hints are currently always resolved eagerly, i.e. we do not support the textDocument/inlayHint/resolve request yet. Implementing support for this request is future work.

Other changes

  • Axioms did not support auto-implicits due to an oversight in the implementation. This PR ensures they do.
  • In order to reduce the amount of inlay hint flickering when making a change to the document, the language server serves old inlay hints for parts of the file that have not been processed yet. This requires LSP request handler state (that sometimes must be invalidated on textDocument/didChange), so this PR introduces the notion of a stateful LSP request handler.
  • The partial response mechanism that we use for semantic tokens, where we simulate incremental LSP responses by periodically emitting refresh requests to the client, is generalized to accommodate both inlay hints and semantic tokens. Additionally, it is made more robust to ensure that we never emit refresh requests while a corresponding request is in flight, which causes VS Code to discard the respond of the request, as well as to ensure that we keep prompting VS Code to send another request if it spuriously decides not to respond to one of our refresh requests.
  • The synthetic identifier of an example had the full declaration as its (non-canonical synthetic) range. Since we need a reasonable position for the identifier to insert an inlay hint for the auto-implicits of an example, we change the (canonical synthetic) range of the synthetic identifier to that of the example keyword.
  • The semantic highlighting request handling is moved to a separate file.

Breaking changes

  • The semantic highlighting request handler is not a pure request handler anymore, but a stateful one. Notably, this means that clients that extend the semantic highlighting of the Lean language server with the chainLspRequestHandler function must now use the chainStatefulLspRequestHandler function instead.

@mhuisi mhuisi added the changelog-server Language server, widgets, and IDE extensions label Jan 24, 2025
@github-actions github-actions bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Jan 24, 2025
@leanprover-community-bot
Copy link
Collaborator

leanprover-community-bot commented Jan 24, 2025

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase c07f64a6212247ef789d4cef39e237b4a4b61696 --onto c70f4064b4041dee70925bddbef095ebb2b36d7d. (2025-01-24 17:38:13)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase c07f64a6212247ef789d4cef39e237b4a4b61696 --onto 832d7c500d709deb5e7f0a5a6fd0f01865d1a303. (2025-02-03 15:28:25)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase c07f64a6212247ef789d4cef39e237b4a4b61696 --onto 412389f71f8a24307e3adba69b38b4b685b04f72. (2025-02-04 16:46:15)

@mhuisi mhuisi requested a review from Kha February 3, 2025 15:03
src/Lean/Elab/Declaration.lean Show resolved Hide resolved
src/Lean/Elab/Term.lean Outdated Show resolved Hide resolved
src/Lean/Server/AsyncList.lean Outdated Show resolved Hide resolved
@mhuisi mhuisi added this pull request to the merge queue Feb 4, 2025
Merged via the queue into leanprover:master with commit 95aee36 Feb 4, 2025
16 checks passed
Julian added a commit to Julian/lean.nvim that referenced this pull request Feb 5, 2025
leanprover/lean4#6768 is now merged (hooray!) and means that Lean shows
useful information like the use of auto-implicits via inlay hints.
This functionality is already available on Lean4 HEAD, and will shortly
be available in nightlies (and then in a release candidate).

Note that Neovim does not enable them by default, but this is mostly
because exactly what is shown in inlay hints varies widely by language
-- and here, it seems more reasonable that they be enabled by default in
Lean.

We do so only buffer-locally, and users can opt out of this by setting
`enabled = false` in the new `inlay_hint` config table.

(This also shouldn't interfere if any user is calling
`vim.lsp.inlay_hint.enable()` themselves already).
github-merge-queue bot pushed a commit that referenced this pull request Feb 6, 2025
This PR implements a number of refinements for the auto-implicit inlay
hints implemented in #6768.
Specifically:
- In #6768, there was a bug where the inlay hint edit delay could
accumulate on successive edits, which meant that it could sometimes take
much longer for inlay hints to show up. This PR implements the basic
infrastructure for request cancellation and implements request
cancellation for semantic tokens and inlay hints to resolve the issue.
With this edit delay bug fixed, it made more sense to increase the edit
delay slightly from 2000ms to 3000ms.
- In #6768, we applied the edit delay to every single inlay hint request
in order to reduce the amount of inlay hint flickering. This meant that
the edit delay also had a significant effect on how far inlay hints
would lag behind the file progress bar. This PR adjusts the edit delay
logic so that it only affects requests sent directly after a
corresponding `didChange` notification. Once the edit delay is used up,
all further semantic token requests are responded to without delay, so
that the only latency that affects how far the inlay hints lag behind
the progress bar is how often we emit refresh requests and how long VS
Code takes to respond to them.
- For inlay hints, refresh requests are now emitted 500ms after a
response to an inlay hint request, not 2000ms, which means that after
the edit delay, inlay hints should only lag behind the progress bar by
about up to 500ms. This is justifiable for inlay hints because the
response should be much smaller than e.g. is the case for semantic
tokens.
- In #6768, 'Restart File' did not prompt a refresh, but it does now.
- VS Code does not immediately remove old inlay hints from the document
when they are applied. In #6768, this meant that inlay hints would
linger around for a bit once applied. To mitigate this issue, this PR
adjusts the inlay hint edit delay logic to identify edits sent from the
client as being inlay hint applications, and sets the edit delay to 0ms
for the inlay hint requests following it. This means that inlay hints
are now applied immediately.
- In #6768, hovering over single-letter auto-implicit inlay hints was a
bit finicky because VS Code uses the regular cursor icon on inlay hints,
not the thin text cursor icon, which means that it is easy to put the
cursor in the wrong spot. We now add the separation character (` ` or
`{`) preceding an auto-implicit to the hover range as well, which makes
hovering over inlay hints much smoother.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog-server Language server, widgets, and IDE extensions toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants