Skip to content

Commit 0a63274

Browse files
authored
ruff server refreshes diagnostics for open files when file configuration is changed (#10988)
## Summary The server now requests a [workspace diagnostic refresh](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh) when a configuration file gets changed. This means that diagnostics for all open files will be automatically re-requested by the client on a config change. ## Test Plan You can test this by opening several files in VS Code, setting `select` in your file configuration to `[]`, and observing that the diagnostics go away once the file is saved (besides any `Pylance` diagnostics). Restore it to what it was before, and you should see the diagnostics automatically return once a save happens.
1 parent 518b29a commit 0a63274

10 files changed

Lines changed: 42 additions & 10 deletions

File tree

crates/ruff_server/src/server/api.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ fn local_notification_task<'a, N: traits::SyncNotificationHandler>(
123123
notif: server::Notification,
124124
) -> super::Result<Task<'a>> {
125125
let (id, params) = cast_notification::<N>(notif)?;
126-
Ok(Task::local(move |session, notifier, _, _| {
127-
if let Err(err) = N::run(session, notifier, params) {
126+
Ok(Task::local(move |session, notifier, requester, _| {
127+
if let Err(err) = N::run(session, notifier, requester, params) {
128128
tracing::error!("An error occurred while running {id}: {err}");
129129
show_err_msg!("Ruff encountered a problem. Check the logs for more details.");
130130
}

crates/ruff_server/src/server/api/notifications/cancel.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::server::client::Notifier;
1+
use crate::server::client::{Notifier, Requester};
22
use crate::server::Result;
33
use crate::session::Session;
44
use lsp_types as types;
@@ -15,6 +15,7 @@ impl super::SyncNotificationHandler for Cancel {
1515
fn run(
1616
_session: &mut Session,
1717
_notifier: Notifier,
18+
_requester: &mut Requester,
1819
_params: types::CancelParams,
1920
) -> Result<()> {
2021
// TODO(jane): Handle this once we have task cancellation in the scheduler.

crates/ruff_server/src/server/api/notifications/did_change.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::server::api::LSPResult;
2-
use crate::server::client::Notifier;
2+
use crate::server::client::{Notifier, Requester};
33
use crate::server::Result;
44
use crate::session::Session;
55
use lsp_types as types;
@@ -16,6 +16,7 @@ impl super::SyncNotificationHandler for DidChange {
1616
fn run(
1717
session: &mut Session,
1818
_notifier: Notifier,
19+
_requester: &mut Requester,
1920
types::DidChangeTextDocumentParams {
2021
text_document:
2122
types::VersionedTextDocumentIdentifier {

crates/ruff_server/src/server/api/notifications/did_change_configuration.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::server::client::Notifier;
1+
use crate::server::client::{Notifier, Requester};
22
use crate::server::Result;
33
use crate::session::Session;
44
use lsp_types as types;
@@ -14,6 +14,7 @@ impl super::SyncNotificationHandler for DidChangeConfiguration {
1414
fn run(
1515
_session: &mut Session,
1616
_notifier: Notifier,
17+
_requester: &mut Requester,
1718
_params: types::DidChangeConfigurationParams,
1819
) -> Result<()> {
1920
// TODO(jane): get this wired up after the pre-release

crates/ruff_server/src/server/api/notifications/did_change_watched_files.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::server::api::LSPResult;
2-
use crate::server::client::Notifier;
2+
use crate::server::client::{Notifier, Requester};
3+
use crate::server::schedule::Task;
34
use crate::server::Result;
45
use crate::session::Session;
56
use lsp_types as types;
@@ -15,13 +16,21 @@ impl super::SyncNotificationHandler for DidChangeWatchedFiles {
1516
fn run(
1617
session: &mut Session,
1718
_notifier: Notifier,
19+
requester: &mut Requester,
1820
params: types::DidChangeWatchedFilesParams,
1921
) -> Result<()> {
20-
for change in params.changes {
22+
for change in &params.changes {
2123
session
2224
.reload_settings(&change.uri)
2325
.with_failure_code(lsp_server::ErrorCode::InternalError)?;
2426
}
27+
28+
if session.resolved_client_capabilities().workspace_refresh && !params.changes.is_empty() {
29+
requester
30+
.request::<types::request::WorkspaceDiagnosticRefresh>((), |()| Task::nothing())
31+
.with_failure_code(lsp_server::ErrorCode::InternalError)?;
32+
}
33+
2534
Ok(())
2635
}
2736
}

crates/ruff_server/src/server/api/notifications/did_change_workspace.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::server::api::LSPResult;
2-
use crate::server::client::Notifier;
2+
use crate::server::client::{Notifier, Requester};
33
use crate::server::Result;
44
use crate::session::Session;
55
use lsp_types as types;
@@ -15,6 +15,7 @@ impl super::SyncNotificationHandler for DidChangeWorkspace {
1515
fn run(
1616
session: &mut Session,
1717
_notifier: Notifier,
18+
_requester: &mut Requester,
1819
params: types::DidChangeWorkspaceFoldersParams,
1920
) -> Result<()> {
2021
for new in params.event.added {

crates/ruff_server/src/server/api/notifications/did_close.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::server::api::LSPResult;
2-
use crate::server::client::Notifier;
2+
use crate::server::client::{Notifier, Requester};
33
use crate::server::Result;
44
use crate::session::Session;
55
use lsp_types as types;
@@ -16,6 +16,7 @@ impl super::SyncNotificationHandler for DidClose {
1616
fn run(
1717
session: &mut Session,
1818
_notifier: Notifier,
19+
_requester: &mut Requester,
1920
types::DidCloseTextDocumentParams {
2021
text_document: types::TextDocumentIdentifier { uri },
2122
}: types::DidCloseTextDocumentParams,

crates/ruff_server/src/server/api/notifications/did_open.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::server::client::Notifier;
1+
use crate::server::client::{Notifier, Requester};
22
use crate::server::Result;
33
use crate::session::Session;
44
use lsp_types as types;
@@ -15,6 +15,7 @@ impl super::SyncNotificationHandler for DidOpen {
1515
fn run(
1616
session: &mut Session,
1717
_notifier: Notifier,
18+
_requester: &mut Requester,
1819
types::DidOpenTextDocumentParams {
1920
text_document:
2021
types::TextDocumentItem {

crates/ruff_server/src/server/api/traits.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ pub(super) trait SyncNotificationHandler: NotificationHandler {
5656
fn run(
5757
session: &mut Session,
5858
notifier: Notifier,
59+
requester: &mut Requester,
5960
params: <<Self as NotificationHandler>::NotificationType as LSPNotification>::Params,
6061
) -> super::Result<()>;
6162
}

crates/ruff_server/src/session/capabilities.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use lsp_types::ClientCapabilities;
22

33
#[derive(Debug, Clone, PartialEq, Eq, Default)]
4+
#[allow(clippy::struct_excessive_bools)]
45
pub(crate) struct ResolvedClientCapabilities {
56
pub(crate) code_action_deferred_edit_resolution: bool,
67
pub(crate) apply_edit: bool,
78
pub(crate) document_changes: bool,
9+
pub(crate) workspace_refresh: bool,
810
}
911

1012
impl ResolvedClientCapabilities {
@@ -33,11 +35,25 @@ impl ResolvedClientCapabilities {
3335
.and_then(|workspace_edit| workspace_edit.document_changes)
3436
.unwrap_or_default();
3537

38+
let workspace_refresh = true;
39+
40+
// TODO(jane): Once the bug involving workspace.diagnostic(s) deserialization has been fixed,
41+
// uncomment this.
42+
/*
43+
let workspace_refresh = client_capabilities
44+
.workspace
45+
.as_ref()
46+
.and_then(|workspace| workspace.diagnostic.as_ref())
47+
.and_then(|diagnostic| diagnostic.refresh_support)
48+
.unwrap_or_default();
49+
*/
50+
3651
Self {
3752
code_action_deferred_edit_resolution: code_action_data_support
3853
&& code_action_edit_resolution,
3954
apply_edit,
4055
document_changes,
56+
workspace_refresh,
4157
}
4258
}
4359
}

0 commit comments

Comments
 (0)