mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:43 +00:00
Make completions an opt-in LSP feature (#17921)
## Summary We now expect the client to send initialization options to opt-in to experimental (but LSP-standardized) features, like completion support. Specifically, the client should set `"experimental.completions.enable": true`. Closes https://github.com/astral-sh/ty/issues/74.
This commit is contained in:
parent
82d31a6014
commit
51e2effd2d
4 changed files with 49 additions and 18 deletions
|
@ -6,6 +6,7 @@ use ruff_text_size::TextSize;
|
||||||
|
|
||||||
use crate::Db;
|
use crate::Db;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct Completion {
|
pub struct Completion {
|
||||||
pub label: String,
|
pub label: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use lsp_types::{
|
||||||
|
|
||||||
use self::connection::{Connection, ConnectionInitializer};
|
use self::connection::{Connection, ConnectionInitializer};
|
||||||
use self::schedule::event_loop_thread;
|
use self::schedule::event_loop_thread;
|
||||||
use crate::session::{AllSettings, ClientSettings, Session};
|
use crate::session::{AllSettings, ClientSettings, Experimental, Session};
|
||||||
use crate::PositionEncoding;
|
use crate::PositionEncoding;
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
|
@ -41,19 +41,6 @@ impl Server {
|
||||||
|
|
||||||
let (id, init_params) = connection.initialize_start()?;
|
let (id, init_params) = connection.initialize_start()?;
|
||||||
|
|
||||||
let client_capabilities = init_params.capabilities;
|
|
||||||
let position_encoding = Self::find_best_position_encoding(&client_capabilities);
|
|
||||||
let server_capabilities = Self::server_capabilities(position_encoding);
|
|
||||||
|
|
||||||
let connection = connection.initialize_finish(
|
|
||||||
id,
|
|
||||||
&server_capabilities,
|
|
||||||
crate::SERVER_NAME,
|
|
||||||
crate::version(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
crate::message::init_messenger(connection.make_sender());
|
|
||||||
|
|
||||||
let AllSettings {
|
let AllSettings {
|
||||||
global_settings,
|
global_settings,
|
||||||
mut workspace_settings,
|
mut workspace_settings,
|
||||||
|
@ -63,6 +50,19 @@ impl Server {
|
||||||
.unwrap_or_else(|| serde_json::Value::Object(serde_json::Map::default())),
|
.unwrap_or_else(|| serde_json::Value::Object(serde_json::Map::default())),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let client_capabilities = init_params.capabilities;
|
||||||
|
let position_encoding = Self::find_best_position_encoding(&client_capabilities);
|
||||||
|
let server_capabilities =
|
||||||
|
Self::server_capabilities(position_encoding, global_settings.experimental.as_ref());
|
||||||
|
|
||||||
|
let connection = connection.initialize_finish(
|
||||||
|
id,
|
||||||
|
&server_capabilities,
|
||||||
|
crate::SERVER_NAME,
|
||||||
|
crate::version(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
crate::message::init_messenger(connection.make_sender());
|
||||||
crate::logging::init_logging(
|
crate::logging::init_logging(
|
||||||
global_settings.tracing.log_level.unwrap_or_default(),
|
global_settings.tracing.log_level.unwrap_or_default(),
|
||||||
global_settings.tracing.log_file.as_deref(),
|
global_settings.tracing.log_file.as_deref(),
|
||||||
|
@ -206,7 +206,10 @@ impl Server {
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn server_capabilities(position_encoding: PositionEncoding) -> ServerCapabilities {
|
fn server_capabilities(
|
||||||
|
position_encoding: PositionEncoding,
|
||||||
|
experimental: Option<&Experimental>,
|
||||||
|
) -> ServerCapabilities {
|
||||||
ServerCapabilities {
|
ServerCapabilities {
|
||||||
position_encoding: Some(position_encoding.into()),
|
position_encoding: Some(position_encoding.into()),
|
||||||
diagnostic_provider: Some(DiagnosticServerCapabilities::Options(DiagnosticOptions {
|
diagnostic_provider: Some(DiagnosticServerCapabilities::Options(DiagnosticOptions {
|
||||||
|
@ -226,9 +229,11 @@ impl Server {
|
||||||
inlay_hint_provider: Some(lsp_types::OneOf::Right(
|
inlay_hint_provider: Some(lsp_types::OneOf::Right(
|
||||||
InlayHintServerCapabilities::Options(InlayHintOptions::default()),
|
InlayHintServerCapabilities::Options(InlayHintOptions::default()),
|
||||||
)),
|
)),
|
||||||
completion_provider: Some(lsp_types::CompletionOptions {
|
completion_provider: experimental
|
||||||
..Default::default()
|
.is_some_and(Experimental::is_completions_enabled)
|
||||||
}),
|
.then_some(lsp_types::CompletionOptions {
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ pub(crate) use self::capabilities::ResolvedClientCapabilities;
|
||||||
pub use self::index::DocumentQuery;
|
pub use self::index::DocumentQuery;
|
||||||
pub(crate) use self::settings::AllSettings;
|
pub(crate) use self::settings::AllSettings;
|
||||||
pub use self::settings::ClientSettings;
|
pub use self::settings::ClientSettings;
|
||||||
|
pub(crate) use self::settings::Experimental;
|
||||||
|
|
||||||
mod capabilities;
|
mod capabilities;
|
||||||
pub(crate) mod index;
|
pub(crate) mod index;
|
||||||
|
|
|
@ -7,11 +7,35 @@ use serde::Deserialize;
|
||||||
/// Maps a workspace URI to its associated client settings. Used during server initialization.
|
/// Maps a workspace URI to its associated client settings. Used during server initialization.
|
||||||
pub(crate) type WorkspaceSettingsMap = FxHashMap<Url, ClientSettings>;
|
pub(crate) type WorkspaceSettingsMap = FxHashMap<Url, ClientSettings>;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Default)]
|
||||||
|
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct Completions {
|
||||||
|
enable: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Default)]
|
||||||
|
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub(crate) struct Experimental {
|
||||||
|
completions: Option<Completions>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Experimental {
|
||||||
|
/// Returns `true` if completions are enabled in the settings.
|
||||||
|
pub(crate) fn is_completions_enabled(&self) -> bool {
|
||||||
|
self.completions
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|completions| completions.enable.unwrap_or_default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This is a direct representation of the settings schema sent by the client.
|
/// This is a direct representation of the settings schema sent by the client.
|
||||||
#[derive(Debug, Deserialize, Default)]
|
#[derive(Debug, Deserialize, Default)]
|
||||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ClientSettings {
|
pub struct ClientSettings {
|
||||||
|
pub(crate) experimental: Option<Experimental>,
|
||||||
// These settings are only needed for tracing, and are only read from the global configuration.
|
// These settings are only needed for tracing, and are only read from the global configuration.
|
||||||
// These will not be in the resolved settings.
|
// These will not be in the resolved settings.
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue