ruff server now supports commands for auto-fixing, organizing imports, and formatting (#10654)

## Summary

This builds off of the work in
https://github.com/astral-sh/ruff/pull/10652 to implement a command
executor, backwards compatible with the commands from the previous LSP
(`ruff.applyAutofix`, `ruff.applyFormat` and
`ruff.applyOrganizeImports`).

This involved a lot of refactoring and tweaks to the code action
resolution code - the most notable change is that workspace edits are
specified in a slightly different way, using the more general `changes`
field instead of the `document_changes` field (which isn't supported on
all LSP clients). Additionally, the API for synchronous request handlers
has been updated to include access to the `Requester`, which we use to
send a `workspace/applyEdit` request to the client.

## Test Plan



7932e30f-d944-4e35-b828-1d81aa56c087
This commit is contained in:
Jane Lewis 2024-04-05 16:27:35 -07:00 committed by GitHub
parent 1b31d4e9f1
commit c11e6d709c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 379 additions and 96 deletions

View file

@ -41,6 +41,7 @@ pub(super) fn request<'a>(req: server::Request) -> Task<'a> {
BackgroundSchedule::LatencySensitive,
)
}
request::ExecuteCommand::METHOD => local_request_task::<request::ExecuteCommand>(req),
request::Format::METHOD => {
background_request_task::<request::Format>(req, BackgroundSchedule::Fmt)
}
@ -87,13 +88,12 @@ pub(super) fn notification<'a>(notif: server::Notification) -> Task<'a> {
})
}
#[allow(dead_code)]
fn local_request_task<'a, R: traits::SyncRequestHandler>(
req: server::Request,
) -> super::Result<Task<'a>> {
let (id, params) = cast_request::<R>(req)?;
Ok(Task::local(|session, notifier, responder| {
let result = R::run(session, notifier, params);
Ok(Task::local(|session, notifier, requester, responder| {
let result = R::run(session, notifier, requester, params);
respond::<R>(id, result, &responder);
}))
}
@ -119,7 +119,7 @@ fn local_notification_task<'a, N: traits::SyncNotificationHandler>(
notif: server::Notification,
) -> super::Result<Task<'a>> {
let (id, params) = cast_notification::<N>(notif)?;
Ok(Task::local(move |session, notifier, _| {
Ok(Task::local(move |session, notifier, _, _| {
if let Err(err) = N::run(session, notifier, params) {
tracing::error!("An error occurred while running {id}: {err}");
}