Skip to content

[red-knot] add auto-completion MVP to LSP#17744

Merged
BurntSushi merged 1 commit intomainfrom
ag/completion-end-to-end-mvp
May 1, 2025
Merged

[red-knot] add auto-completion MVP to LSP#17744
BurntSushi merged 1 commit intomainfrom
ag/completion-end-to-end-mvp

Conversation

@BurntSushi
Copy link
Member

@BurntSushi BurntSushi commented Apr 30, 2025

This PR does the wiring necessary to respond to completion requests from
LSP clients.

As far as the actual completion results go, they are nearly about the
dumbest and simplest thing we can do: we simply return a de-duplicated
list of all identifiers from the current module.

Ref astral-sh/ty#86

@BurntSushi
Copy link
Member Author

Demo:

red-knot-auto-completion-mvp.mp4

@BurntSushi BurntSushi added the ty Multi-file analysis & type inference label Apr 30, 2025
@BurntSushi BurntSushi requested review from dhruvmanila and removed request for AlexWaygood, carljm, dcreager and sharkdp April 30, 2025 18:24
@BurntSushi BurntSushi changed the title red_knot_server: add auto-completion MVP [red-knot] red_knot_server: add auto-completion MVP Apr 30, 2025
@BurntSushi BurntSushi added the server Related to the LSP server label Apr 30, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Apr 30, 2025

mypy_primer results

No ecosystem changes detected ✅

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

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

Looks reasonable to me, but I'd rather have @dhruvmanila or @MichaReiser look at the LSP side.

My main concern here is that I would probably prefer to release the alpha with no autocomplete than with autocomplete that doesn't make use of type information. But we can always ship a quick diff to turn it off right before the alpha release, if we don't get far enough.

@BurntSushi
Copy link
Member Author

@carljm Would you be okay to have it disabled by default, but allow an env var or some other undocumented toggle enable it? Just for practical purposes of keeping it in tree and being able to iterate.

@carljm
Copy link
Contributor

carljm commented Apr 30, 2025

@carljm Would you be okay to have it disabled by default, but allow an env var or some other undocumented toggle enable it? Just for practical purposes of keeping it in tree and being able to iterate.

Oh for sure, that's what I was imagining, definitely not that we'd rip out the code entirely. I'm fine with doing that now, or waiting and seeing where we're at with it end of next week.

@BurntSushi
Copy link
Member Author

SGTM!

@dhruvmanila
Copy link
Member

dhruvmanila commented Apr 30, 2025

We could do something similar to what r-a does with their "experimental" capabilities which requires explicit opt-in from client side. Refer to the first paragraph in https://github.com/rust-lang/rust-analyzer/blob/master/docs/book/src/contributing/lsp-extensions.md#lsp-extensions:

All capabilities are enabled via the experimental field of ClientCapabilities or ServerCapabilities.

Specifically, here they send the capabilities that the VS Code extension supports.

So, for us it could look like below which would be sent when during the server initialization process:

"capabilities": {
	"experimental": {
		"completions": {
			"enabled": true
		}
	}
} 

Copy link
Member

@dhruvmanila dhruvmanila left a comment

Choose a reason for hiding this comment

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

Looks good!

@MichaReiser MichaReiser changed the title [red-knot] red_knot_server: add auto-completion MVP [red-knot] add auto-completion MVP to LSP May 1, 2025
.collect()
}

fn identifiers(node: AnyNodeRef) -> Vec<String> {
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't have to be as part of this PR because I think it would require fleshing out some API for it but we could do this by resolving the semantic_index, iterating over all scopes, and collecting the names from every scope.

This would be a nice stepping stone to the next step where you'd identify in which scope you are and only suggest the names from that or its ancestor scopes.

Copy link
Member

Choose a reason for hiding this comment

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

we could do this by resolving the semantic_index, iterating over all scopes, and collecting the names from every scope.

we already have a query that basically does that in https://github.com/astral-sh/ruff/blob/main/crates/red_knot_python_semantic/src/semantic_index/re_exports.rs (but it only visits the global scope, currently at least)

Copy link
Member Author

Choose a reason for hiding this comment

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

This sounds great, thank you for the idea. I didn't know about this! This looks like a next good step.

Comment on lines +9 to +11
pub struct Completion {
pub label: String,
}
Copy link
Member

Choose a reason for hiding this comment

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

This could, probably return a &'db str but I'm fine with a String.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah it eventually has to get turned into a String anyway. And I figured this would all be refactored soon anyway.

Comment on lines +230 to +232
completion_provider: Some(lsp_types::CompletionOptions {
..Default::default()
}),
Copy link
Member

Choose a reason for hiding this comment

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

Nit: We probably want to tinker with the options here in the future

Copy link
Member Author

@BurntSushi BurntSushi May 1, 2025

Choose a reason for hiding this comment

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

Yup I looked, but they all seemed pretty in the weeds. I also noticed that even if I didn't set this, the client still tried to send completion requests. But this seemed the "most correct" given what exists now.

@BurntSushi
Copy link
Member Author

Thank you @dhruvmanila for the tip about an experimental opt-in! I created an issue tracking that for the alpha milestone: astral-sh/ty#74

This PR does the wiring necessary to respond to completion requests from
LSP clients.

As far as the actual completion results go, they are nearly about the
dumbest and simplest thing we can do: we simply return a de-duplicated
list of all identifiers from the current module.
@BurntSushi BurntSushi force-pushed the ag/completion-end-to-end-mvp branch from 02a0f38 to 179e546 Compare May 1, 2025 12:58
@BurntSushi BurntSushi merged commit b7ce694 into main May 1, 2025
35 checks passed
@BurntSushi BurntSushi deleted the ag/completion-end-to-end-mvp branch May 1, 2025 16:08
@MichaReiser MichaReiser mentioned this pull request May 2, 2025
13 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

server Related to the LSP server ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants