mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:37 +00:00
Refactor workspace logic into workspace.rs
(#16295)
## Summary This is just a small refactor to move workspace related structs and impl out from `server.rs` where `Server` is defined and into a new `workspace.rs`.
This commit is contained in:
parent
793264db13
commit
c2b9fa84f7
5 changed files with 132 additions and 128 deletions
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
pub use edit::{DocumentKey, NotebookDocument, PositionEncoding, TextDocument};
|
pub use edit::{DocumentKey, NotebookDocument, PositionEncoding, TextDocument};
|
||||||
use lsp_types::CodeActionKind;
|
use lsp_types::CodeActionKind;
|
||||||
pub use server::{Server, Workspace, Workspaces};
|
pub use server::Server;
|
||||||
pub use session::{ClientSettings, DocumentQuery, DocumentSnapshot, Session};
|
pub use session::{ClientSettings, DocumentQuery, DocumentSnapshot, Session};
|
||||||
|
pub use workspace::{Workspace, Workspaces};
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod message;
|
mod message;
|
||||||
|
@ -16,6 +17,7 @@ mod logging;
|
||||||
mod resolve;
|
mod resolve;
|
||||||
mod server;
|
mod server;
|
||||||
mod session;
|
mod session;
|
||||||
|
mod workspace;
|
||||||
|
|
||||||
pub(crate) const SERVER_NAME: &str = "ruff";
|
pub(crate) const SERVER_NAME: &str = "ruff";
|
||||||
pub(crate) const DIAGNOSTIC_NAME: &str = "Ruff";
|
pub(crate) const DIAGNOSTIC_NAME: &str = "Ruff";
|
||||||
|
|
|
@ -3,14 +3,11 @@
|
||||||
use lsp_server as lsp;
|
use lsp_server as lsp;
|
||||||
use lsp_types as types;
|
use lsp_types as types;
|
||||||
use lsp_types::InitializeParams;
|
use lsp_types::InitializeParams;
|
||||||
use lsp_types::WorkspaceFolder;
|
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::ops::Deref;
|
|
||||||
// The new PanicInfoHook name requires MSRV >= 1.82
|
// The new PanicInfoHook name requires MSRV >= 1.82
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
use std::panic::PanicInfo;
|
use std::panic::PanicInfo;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use thiserror::Error;
|
|
||||||
use types::ClientCapabilities;
|
use types::ClientCapabilities;
|
||||||
use types::CodeActionKind;
|
use types::CodeActionKind;
|
||||||
use types::CodeActionOptions;
|
use types::CodeActionOptions;
|
||||||
|
@ -24,7 +21,6 @@ use types::OneOf;
|
||||||
use types::TextDocumentSyncCapability;
|
use types::TextDocumentSyncCapability;
|
||||||
use types::TextDocumentSyncKind;
|
use types::TextDocumentSyncKind;
|
||||||
use types::TextDocumentSyncOptions;
|
use types::TextDocumentSyncOptions;
|
||||||
use types::Url;
|
|
||||||
use types::WorkDoneProgressOptions;
|
use types::WorkDoneProgressOptions;
|
||||||
use types::WorkspaceFoldersServerCapabilities;
|
use types::WorkspaceFoldersServerCapabilities;
|
||||||
|
|
||||||
|
@ -34,9 +30,8 @@ use self::schedule::event_loop_thread;
|
||||||
use self::schedule::Scheduler;
|
use self::schedule::Scheduler;
|
||||||
use self::schedule::Task;
|
use self::schedule::Task;
|
||||||
use crate::session::AllSettings;
|
use crate::session::AllSettings;
|
||||||
use crate::session::ClientSettings;
|
|
||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
use crate::session::WorkspaceSettingsMap;
|
use crate::workspace::Workspaces;
|
||||||
use crate::PositionEncoding;
|
use crate::PositionEncoding;
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
|
@ -447,122 +442,3 @@ impl FromStr for SupportedCommand {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Workspaces(Vec<Workspace>);
|
|
||||||
|
|
||||||
impl Workspaces {
|
|
||||||
pub fn new(workspaces: Vec<Workspace>) -> Self {
|
|
||||||
Self(workspaces)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create the workspaces from the provided workspace folders as provided by the client during
|
|
||||||
/// initialization.
|
|
||||||
fn from_workspace_folders(
|
|
||||||
workspace_folders: Option<Vec<WorkspaceFolder>>,
|
|
||||||
mut workspace_settings: WorkspaceSettingsMap,
|
|
||||||
) -> std::result::Result<Workspaces, WorkspacesError> {
|
|
||||||
let mut client_settings_for_url = |url: &Url| {
|
|
||||||
workspace_settings.remove(url).unwrap_or_else(|| {
|
|
||||||
tracing::info!(
|
|
||||||
"No workspace settings found for {}, using default settings",
|
|
||||||
url
|
|
||||||
);
|
|
||||||
ClientSettings::default()
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let workspaces =
|
|
||||||
if let Some(folders) = workspace_folders.filter(|folders| !folders.is_empty()) {
|
|
||||||
folders
|
|
||||||
.into_iter()
|
|
||||||
.map(|folder| {
|
|
||||||
let settings = client_settings_for_url(&folder.uri);
|
|
||||||
Workspace::new(folder.uri).with_settings(settings)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
let current_dir = std::env::current_dir().map_err(WorkspacesError::Io)?;
|
|
||||||
tracing::info!(
|
|
||||||
"No workspace(s) were provided during initialization. \
|
|
||||||
Using the current working directory as a default workspace: {}",
|
|
||||||
current_dir.display()
|
|
||||||
);
|
|
||||||
let uri = Url::from_file_path(current_dir)
|
|
||||||
.map_err(|()| WorkspacesError::InvalidCurrentDir)?;
|
|
||||||
let settings = client_settings_for_url(&uri);
|
|
||||||
vec![Workspace::default(uri).with_settings(settings)]
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Workspaces(workspaces))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for Workspaces {
|
|
||||||
type Target = [Workspace];
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
enum WorkspacesError {
|
|
||||||
#[error(transparent)]
|
|
||||||
Io(#[from] std::io::Error),
|
|
||||||
#[error("Failed to create a URL from the current working directory")]
|
|
||||||
InvalidCurrentDir,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Workspace {
|
|
||||||
/// The [`Url`] pointing to the root of the workspace.
|
|
||||||
url: Url,
|
|
||||||
/// The client settings for this workspace.
|
|
||||||
settings: Option<ClientSettings>,
|
|
||||||
/// Whether this is the default workspace as created by the server. This will be the case when
|
|
||||||
/// no workspace folders were provided during initialization.
|
|
||||||
is_default: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Workspace {
|
|
||||||
/// Create a new workspace with the given root URL.
|
|
||||||
pub fn new(url: Url) -> Self {
|
|
||||||
Self {
|
|
||||||
url,
|
|
||||||
settings: None,
|
|
||||||
is_default: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new default workspace with the given root URL.
|
|
||||||
pub fn default(url: Url) -> Self {
|
|
||||||
Self {
|
|
||||||
url,
|
|
||||||
settings: None,
|
|
||||||
is_default: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the client settings for this workspace.
|
|
||||||
#[must_use]
|
|
||||||
pub fn with_settings(mut self, settings: ClientSettings) -> Self {
|
|
||||||
self.settings = Some(settings);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the root URL of the workspace.
|
|
||||||
pub(crate) fn url(&self) -> &Url {
|
|
||||||
&self.url
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the client settings for this workspace.
|
|
||||||
pub(crate) fn settings(&self) -> Option<&ClientSettings> {
|
|
||||||
self.settings.as_ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if this is the default workspace.
|
|
||||||
pub(crate) fn is_default(&self) -> bool {
|
|
||||||
self.is_default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use lsp_types::{ClientCapabilities, FileEvent, NotebookDocumentCellChange, Url};
|
||||||
use settings::ResolvedClientSettings;
|
use settings::ResolvedClientSettings;
|
||||||
|
|
||||||
use crate::edit::{DocumentKey, DocumentVersion, NotebookDocument};
|
use crate::edit::{DocumentKey, DocumentVersion, NotebookDocument};
|
||||||
use crate::server::Workspaces;
|
use crate::workspace::Workspaces;
|
||||||
use crate::{PositionEncoding, TextDocument};
|
use crate::{PositionEncoding, TextDocument};
|
||||||
|
|
||||||
pub(crate) use self::capabilities::ResolvedClientCapabilities;
|
pub(crate) use self::capabilities::ResolvedClientCapabilities;
|
||||||
|
|
|
@ -11,7 +11,7 @@ use thiserror::Error;
|
||||||
pub(crate) use ruff_settings::RuffSettings;
|
pub(crate) use ruff_settings::RuffSettings;
|
||||||
|
|
||||||
use crate::edit::LanguageId;
|
use crate::edit::LanguageId;
|
||||||
use crate::server::{Workspace, Workspaces};
|
use crate::workspace::{Workspace, Workspaces};
|
||||||
use crate::{
|
use crate::{
|
||||||
edit::{DocumentKey, DocumentVersion, NotebookDocument},
|
edit::{DocumentKey, DocumentVersion, NotebookDocument},
|
||||||
PositionEncoding, TextDocument,
|
PositionEncoding, TextDocument,
|
||||||
|
|
126
crates/ruff_server/src/workspace.rs
Normal file
126
crates/ruff_server/src/workspace.rs
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use lsp_types::{Url, WorkspaceFolder};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use crate::session::WorkspaceSettingsMap;
|
||||||
|
use crate::ClientSettings;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Workspaces(Vec<Workspace>);
|
||||||
|
|
||||||
|
impl Workspaces {
|
||||||
|
pub fn new(workspaces: Vec<Workspace>) -> Self {
|
||||||
|
Self(workspaces)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create the workspaces from the provided workspace folders as provided by the client during
|
||||||
|
/// initialization.
|
||||||
|
pub(crate) fn from_workspace_folders(
|
||||||
|
workspace_folders: Option<Vec<WorkspaceFolder>>,
|
||||||
|
mut workspace_settings: WorkspaceSettingsMap,
|
||||||
|
) -> std::result::Result<Workspaces, WorkspacesError> {
|
||||||
|
let mut client_settings_for_url = |url: &Url| {
|
||||||
|
workspace_settings.remove(url).unwrap_or_else(|| {
|
||||||
|
tracing::info!(
|
||||||
|
"No workspace settings found for {}, using default settings",
|
||||||
|
url
|
||||||
|
);
|
||||||
|
ClientSettings::default()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let workspaces =
|
||||||
|
if let Some(folders) = workspace_folders.filter(|folders| !folders.is_empty()) {
|
||||||
|
folders
|
||||||
|
.into_iter()
|
||||||
|
.map(|folder| {
|
||||||
|
let settings = client_settings_for_url(&folder.uri);
|
||||||
|
Workspace::new(folder.uri).with_settings(settings)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
let current_dir = std::env::current_dir().map_err(WorkspacesError::Io)?;
|
||||||
|
tracing::info!(
|
||||||
|
"No workspace(s) were provided during initialization. \
|
||||||
|
Using the current working directory as a default workspace: {}",
|
||||||
|
current_dir.display()
|
||||||
|
);
|
||||||
|
let uri = Url::from_file_path(current_dir)
|
||||||
|
.map_err(|()| WorkspacesError::InvalidCurrentDir)?;
|
||||||
|
let settings = client_settings_for_url(&uri);
|
||||||
|
vec![Workspace::default(uri).with_settings(settings)]
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Workspaces(workspaces))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Workspaces {
|
||||||
|
type Target = [Workspace];
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub(crate) enum WorkspacesError {
|
||||||
|
#[error(transparent)]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
#[error("Failed to create a URL from the current working directory")]
|
||||||
|
InvalidCurrentDir,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Workspace {
|
||||||
|
/// The [`Url`] pointing to the root of the workspace.
|
||||||
|
url: Url,
|
||||||
|
/// The client settings for this workspace.
|
||||||
|
settings: Option<ClientSettings>,
|
||||||
|
/// Whether this is the default workspace as created by the server. This will be the case when
|
||||||
|
/// no workspace folders were provided during initialization.
|
||||||
|
is_default: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Workspace {
|
||||||
|
/// Create a new workspace with the given root URL.
|
||||||
|
pub fn new(url: Url) -> Self {
|
||||||
|
Self {
|
||||||
|
url,
|
||||||
|
settings: None,
|
||||||
|
is_default: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new default workspace with the given root URL.
|
||||||
|
pub fn default(url: Url) -> Self {
|
||||||
|
Self {
|
||||||
|
url,
|
||||||
|
settings: None,
|
||||||
|
is_default: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the client settings for this workspace.
|
||||||
|
#[must_use]
|
||||||
|
pub fn with_settings(mut self, settings: ClientSettings) -> Self {
|
||||||
|
self.settings = Some(settings);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the root URL of the workspace.
|
||||||
|
pub(crate) fn url(&self) -> &Url {
|
||||||
|
&self.url
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the client settings for this workspace.
|
||||||
|
pub(crate) fn settings(&self) -> Option<&ClientSettings> {
|
||||||
|
self.settings.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if this is the default workspace.
|
||||||
|
pub(crate) fn is_default(&self) -> bool {
|
||||||
|
self.is_default
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue