diff --git a/.changeset/full-grapes-sleep.md b/.changeset/full-grapes-sleep.md new file mode 100644 index 000000000000..049708907e7c --- /dev/null +++ b/.changeset/full-grapes-sleep.md @@ -0,0 +1,5 @@ +--- +"@biomejs/biome": patch +--- + +Fixed [#7138](https://github.com/biomejs/biome/issues/7138). Now the Biome language server correctly handles the `configurationPath` setting coming from the editor extension. diff --git a/crates/biome_lsp/src/handlers/text_document.rs b/crates/biome_lsp/src/handlers/text_document.rs index d99e8b8c127e..bc0abc87aac0 100644 --- a/crates/biome_lsp/src/handlers/text_document.rs +++ b/crates/biome_lsp/src/handlers/text_document.rs @@ -37,49 +37,57 @@ pub(crate) async fn did_open( None => { info!("No open project for path: {path:?}. Opening new project."); - let project_path = path - .parent() - .map(|parent| parent.to_path_buf()) - .unwrap_or_default(); - - // First check if the current file belongs to any registered workspace folder. - // If so, return that folder; otherwise, use the folder computed by did_open. - let project_path = if let Some(workspace_folders) = session.get_workspace_folders() { - if let Some(ws_root) = workspace_folders - .iter() - .filter_map(|folder| { - folder.uri.to_file_path().map(|p| { - Utf8PathBuf::from_path_buf(p.to_path_buf()) - .expect("To have a valid UTF-8 path") - }) - }) - .find(|ws| project_path.starts_with(ws)) - { - ws_root - } else { - project_path.clone() - } - } else if let Some(base_path) = session.base_path() { - if project_path.starts_with(&base_path) { - base_path - } else { - project_path.clone() - } - } else { - project_path - }; - session.set_configuration_status(ConfigurationStatus::Loading); - eprintln!( - "Loading configuration from text_document {:?}", - &project_path - ); if !session.has_initialized() { session.load_extension_settings().await; } - let status = session - .load_biome_configuration_file(ConfigurationPathHint::FromLsp(project_path), false) - .await; + + let status = if let Some(path) = session.get_settings_configuration_path() { + info!("Loading user configuration from text_document {}", &path); + session + .load_biome_configuration_file(ConfigurationPathHint::FromUser(path), false) + .await + } else { + let project_path = path + .parent() + .map(|parent| parent.to_path_buf()) + .unwrap_or_default(); + info!("Loading configuration from text_document {}", &project_path); + // First check if the current file belongs to any registered workspace folder. + // If so, return that folder; otherwise, use the folder computed by did_open. + let project_path = if let Some(workspace_folders) = session.get_workspace_folders() + { + if let Some(ws_root) = workspace_folders + .iter() + .filter_map(|folder| { + folder.uri.to_file_path().map(|p| { + Utf8PathBuf::from_path_buf(p.to_path_buf()) + .expect("To have a valid UTF-8 path") + }) + }) + .find(|ws| project_path.starts_with(ws)) + { + ws_root + } else { + project_path.clone() + } + } else if let Some(base_path) = session.base_path() { + if project_path.starts_with(&base_path) { + base_path + } else { + project_path.clone() + } + } else { + project_path + }; + + session + .load_biome_configuration_file( + ConfigurationPathHint::FromLsp(project_path), + false, + ) + .await + }; session.set_configuration_status(status); diff --git a/crates/biome_lsp/src/session.rs b/crates/biome_lsp/src/session.rs index 844a77b6d82a..fda1bb78276e 100644 --- a/crates/biome_lsp/src/session.rs +++ b/crates/biome_lsp/src/session.rs @@ -666,16 +666,19 @@ impl Session { self.initialized.load(Ordering::Relaxed) } + /// Returns the configuration path set by the user in the extension settings + pub(crate) fn get_settings_configuration_path(&self) -> Option { + self.extension_settings + .read() + .ok() + .and_then(|s| s.configuration_path()) + } + /// This function attempts to read the `biome.json` configuration file from /// the root URI and update the workspace settings accordingly #[tracing::instrument(level = "debug", skip(self))] pub(crate) async fn load_workspace_settings(self: &Arc, reload: bool) { - if let Some(config_path) = self - .extension_settings - .read() - .ok() - .and_then(|s| s.configuration_path()) - { + if let Some(config_path) = self.get_settings_configuration_path() { info!("Detected configuration path in the workspace settings."); self.set_configuration_status(ConfigurationStatus::Loading); @@ -899,10 +902,21 @@ impl Session { // If the configuration from the LSP or the workspace, the directory path is used as // the working directory. Otherwise, the base path of the session is used, then the current // working directory is used as the last resort. + debug!("Configuration path provided {:?}", &base_path); let path = match &base_path { ConfigurationPathHint::FromLsp(path) | ConfigurationPathHint::FromWorkspace(path) => { path.to_path_buf() } + ConfigurationPathHint::FromUser(path) => { + if path.is_file() { + path.parent() + .map_or(fs.working_directory().unwrap_or_default(), |p| { + p.to_path_buf() + }) + } else { + path.to_path_buf() + } + } _ => self .base_path() .or_else(|| fs.working_directory()) diff --git a/crates/biome_service/src/workspace.rs b/crates/biome_service/src/workspace.rs index 805a4b99e446..67d9ce388d09 100644 --- a/crates/biome_service/src/workspace.rs +++ b/crates/biome_service/src/workspace.rs @@ -234,7 +234,7 @@ impl FeaturesSupported { self.insert(FeatureKind::HtmlFullSupport, SupportKind::Supported); } - debug!("The file has the following feature sets: {:?}", &self); + debug!("The file has the following feature sets: {}", &self); self } diff --git a/crates/biome_service/src/workspace/server.rs b/crates/biome_service/src/workspace/server.rs index 6506e8bbe215..7d19d39ea392 100644 --- a/crates/biome_service/src/workspace/server.rs +++ b/crates/biome_service/src/workspace/server.rs @@ -1147,22 +1147,22 @@ impl Workspace for WorkspaceServer { .read_file_from_path(gitignore.as_ref()) .ok() .or_else(|| self.fs.read_file_from_path(ignore.as_ref()).ok()); - let content = match result { - Some(content) => content, + match result { + Some(content) => { + let lines: Vec<_> = content.lines().collect(); + settings.vcs_settings.store_root_ignore_patterns( + directory.as_ref(), + lines.as_slice(), + )?; + } None => { diagnostics.push(biome_diagnostics::serde::Diagnostic::new( VcsDiagnostic::NoIgnoreFileFound(NoIgnoreFileFound { path: directory.to_string(), }), )); - return Ok(UpdateSettingsResult { diagnostics }); } }; - - let lines: Vec<_> = content.lines().collect(); - settings - .vcs_settings - .store_root_ignore_patterns(directory.as_ref(), lines.as_slice())?; } } }