## Summary Fixes #11059 Several major editors don't support [pull diagnostics](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_pullDiagnostics), a method of sending diagnostics to the client that was introduced in version `0.3.17` of the specification. Until now, `ruff server` has only used pull diagnostics, which resulted in diagnostics not being available on Neovim and Helix, which don't support pull diagnostics yet (though Neovim `10.0` will have support for this). `ruff server` will now utilize the older method of sending diagnostics, known as 'publish diagnostics', when pull diagnostics aren't supported by the client. This involves re-linting a document every time it is opened or modified, and then sending the diagnostics generated from that lint to the client via the `textDocument/publishDiagnostics` notification. ## Test Plan The easiest way to test that this PR works is to check if diagnostics show up on Neovim `<=0.9`.
68 lines
2.4 KiB
Rust
68 lines
2.4 KiB
Rust
use lsp_types::ClientCapabilities;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
|
#[allow(clippy::struct_excessive_bools)]
|
|
pub(crate) struct ResolvedClientCapabilities {
|
|
pub(crate) code_action_deferred_edit_resolution: bool,
|
|
pub(crate) apply_edit: bool,
|
|
pub(crate) document_changes: bool,
|
|
pub(crate) workspace_refresh: bool,
|
|
pub(crate) pull_diagnostics: bool,
|
|
}
|
|
|
|
impl ResolvedClientCapabilities {
|
|
pub(super) fn new(client_capabilities: &ClientCapabilities) -> Self {
|
|
let code_action_settings = client_capabilities
|
|
.text_document
|
|
.as_ref()
|
|
.and_then(|doc_settings| doc_settings.code_action.as_ref());
|
|
let code_action_data_support = code_action_settings
|
|
.and_then(|code_action_settings| code_action_settings.data_support)
|
|
.unwrap_or_default();
|
|
let code_action_edit_resolution = code_action_settings
|
|
.and_then(|code_action_settings| code_action_settings.resolve_support.as_ref())
|
|
.is_some_and(|resolve_support| resolve_support.properties.contains(&"edit".into()));
|
|
|
|
let apply_edit = client_capabilities
|
|
.workspace
|
|
.as_ref()
|
|
.and_then(|workspace| workspace.apply_edit)
|
|
.unwrap_or_default();
|
|
|
|
let document_changes = client_capabilities
|
|
.workspace
|
|
.as_ref()
|
|
.and_then(|workspace| workspace.workspace_edit.as_ref())
|
|
.and_then(|workspace_edit| workspace_edit.document_changes)
|
|
.unwrap_or_default();
|
|
|
|
let workspace_refresh = true;
|
|
|
|
// TODO(jane): Once the bug involving workspace.diagnostic(s) deserialization has been fixed,
|
|
// uncomment this.
|
|
/*
|
|
let workspace_refresh = client_capabilities
|
|
.workspace
|
|
.as_ref()
|
|
.and_then(|workspace| workspace.diagnostic.as_ref())
|
|
.and_then(|diagnostic| diagnostic.refresh_support)
|
|
.unwrap_or_default();
|
|
*/
|
|
|
|
let pull_diagnostics = client_capabilities
|
|
.text_document
|
|
.as_ref()
|
|
.and_then(|text_document| text_document.diagnostic.as_ref())
|
|
.is_some();
|
|
|
|
Self {
|
|
code_action_deferred_edit_resolution: code_action_data_support
|
|
&& code_action_edit_resolution,
|
|
apply_edit,
|
|
document_changes,
|
|
workspace_refresh,
|
|
pull_diagnostics,
|
|
}
|
|
}
|
|
}
|