Skip to content

LSP: trigger completions after a '.' - #6327

Merged
pchiusano merged 3 commits into
unisonweb:trunkfrom
Baccata:06e/lsp-dot-completion-trigger
Nov 10, 2026
Merged

pchiusano merged 3 commits into
unisonweb:trunkfrom
Baccata:06e/lsp-dot-completion-trigger

Conversation

@Baccata

@Baccata Baccata commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Problem

In the LSP, typing a . after an already-complete name never triggers an autocomplete request. For example, given a saved file:

foo =
  List

adding a . after List does not trigger a completion request. But with:

foo =
  Lis

adding a t to make List does.

Cause

Editors only auto-request completions when you type an identifier character — that's why extending Lis with t works. A . is not an identifier character, so per the LSP spec the client only requests completions after it if the server declares . as a completion trigger character. lspOptions never set optCompletionTriggerCharacters, so it defaulted to Nothing and no trigger characters were registered.

Fix

Register . as a completion trigger character:

optCompletionTriggerCharacters = Just ['.']

The downstream prefix handling already copes with a trailing dot (the completion handler strips it before querying), so once the request fires it resolves correctly.

Tests

Factored the pure prefix-splitting logic out of identifierSplitAtPosition into splitIdentifierAtChar :: Int -> Text -> (Text, Text) and added unit tests for the dotted-name cases — including the List. case this fixes — so the behaviour that makes the trigger useful is guarded against regression.

Also tested manually. Works as expected in vscode.

🤖 (partially) Generated with Claude Code

Editors only auto-request completions on identifier characters, so typing
a '.' after an already-complete name (e.g. `List.`) never fired a
completion request — the '.' isn't an identifier character and we hadn't
registered it as a completion trigger character. Typing a letter after a
partial name (`Lis` -> `List`) worked because each keystroke is an
identifier character.

Register '.' via `optCompletionTriggerCharacters` in `lspOptions` so the
client sends a completion request after a dot. The downstream prefix
handling already copes with a trailing dot (the handler strips it before
querying).

Also factor the pure prefix-splitting logic out of
`identifierSplitAtPosition` into `splitIdentifierAtChar :: Int -> Text ->
(Text, Text)` and add unit tests covering the dotted-name cases, including
the `List.` case this fixes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-- as one identifier, so a trailing '.' is kept in the prefix (e.g. @"List."@) — this is what a
-- completion request after a '.' keys off of.
splitIdentifierAtChar :: Int -> Text -> (Text, Text)
splitIdentifierAtChar char fullLine =

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extracting this to avoid having to build a virtual file just for testing completions

# Conflicts:
#	.github/workflows/proofs/formatting/8ad68cc3f38f2f6b24ed27be2296cf5e0103e7e297adbe6fed0b0c9d4ab4ade2.txt
#	.github/workflows/proofs/formatting/95fd4ada8473d3dc6adb88e59c5c03679521dc16f1c9c037e675718bb793ead6.txt
#	.github/workflows/proofs/formatting/bd11ddb59891b087f2c811cab985274edd5bbcb55d9979cedfb9871eebaaf674.txt
#	.github/workflows/proofs/tests/8026d114dd0e3b0fb906e80ceec8815faab36715c897676745dcbf77babdbf48.txt
#	.github/workflows/proofs/tests/aa51d247e309217754bfb10a16ced7678198c450d0e5aa076981ebf65228434b.txt
#	.github/workflows/proofs/tests/bb0202a570361097cedaee9fd0ca47d7fd82377ec5a8aaf3ec165472cf441c9a.txt
#	.github/workflows/proofs/transcripts/8d05120a4e366f177c0f201787c24cde07eac2d4c7eb7f1a7b543b3e861cdb36.txt
#	.github/workflows/proofs/transcripts/9471280c6bf21863e91149f85d1156bedfc9a9e484b6be3d3aa4752c94727465.txt
#	.github/workflows/proofs/transcripts/f808028cc53059ecabfea2403dee2bd06f6c1b3c8ac2577b0a54d99e3fab4856.txt
@pchiusano
pchiusano added this pull request to the merge queue Nov 10, 2026
Merged via the queue into unisonweb:trunk with commit aa9b478 Nov 10, 2026
10 checks passed
@Baccata
Baccata deleted the 06e/lsp-dot-completion-trigger branch November 10, 2026 16:38
pchiusano added a commit to Baccata/unison that referenced this pull request Nov 10, 2026
…akes one for a rename of another

Every attestation file of a check held the same line (the infrastructure hash
and the verdict), so git's rename detection paired a deleted attestation with
an added one at 100% similarity. Two pull requests that both re-attested then
renamed the same file to different names, a rename/rename conflict (unisonweb#6326
against trunk after unisonweb#6327 merged).

The file now holds a 16-character prefix of the infrastructure hash, the
verdict, and the hash it attests. Readers use the first two fields as before
and compare the infrastructure hash by prefix, so existing files still read.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants