Fix json-language-server not considering `file_types` from project settings (#46991)

Kirill Bulatov created

Release Notes:

- Fixed json-language-server not considering `file_types` from project
settings

Change summary

crates/json_schema_store/src/json_schema_store.rs |  7 ++-
crates/languages/src/json.rs                      | 27 +++++++++++++++-
2 files changed, 28 insertions(+), 6 deletions(-)

Detailed changes

crates/json_schema_store/src/json_schema_store.rs 🔗

@@ -3,10 +3,10 @@ use std::sync::{Arc, LazyLock};
 use anyhow::{Context as _, Result};
 use collections::HashMap;
 use gpui::{App, AsyncApp, BorrowAppContext as _, Entity, Task, WeakEntity};
-use language::{LanguageRegistry, LspAdapterDelegate, language_settings::all_language_settings};
+use language::{LanguageRegistry, LspAdapterDelegate, language_settings::AllLanguageSettings};
 use parking_lot::RwLock;
 use project::{LspStore, lsp_store::LocalLspAdapterDelegate};
-use settings::LSP_SETTINGS_SCHEMA_URL_PREFIX;
+use settings::{LSP_SETTINGS_SCHEMA_URL_PREFIX, Settings as _, SettingsLocation};
 use util::schemars::{AllowTrailingCommas, DefaultDenyUnknownFields};
 
 const SCHEMA_URI_PREFIX: &str = "zed://schemas/";
@@ -311,6 +311,7 @@ const JSONC_LANGUAGE_NAME: &str = "JSONC";
 
 pub fn all_schema_file_associations(
     languages: &Arc<LanguageRegistry>,
+    path: Option<SettingsLocation<'_>>,
     cx: &mut App,
 ) -> serde_json::Value {
     let extension_globs = languages
@@ -320,7 +321,7 @@ pub fn all_schema_file_associations(
         .flatten()
         // Path suffixes can be entire file names or just their extensions.
         .flat_map(|path_suffix| [format!("*.{path_suffix}"), path_suffix]);
-    let override_globs = all_language_settings(None, cx)
+    let override_globs = AllLanguageSettings::get(path, cx)
         .file_types
         .get(JSONC_LANGUAGE_NAME)
         .into_iter()

crates/languages/src/json.rs 🔗

@@ -15,11 +15,13 @@ use node_runtime::{NodeRuntime, VersionStrategy};
 use project::lsp_store::language_server_settings;
 use semver::Version;
 use serde_json::{Value, json};
+use settings::SettingsLocation;
 use smol::{
     fs::{self},
     io::BufReader,
 };
 use std::{
+    borrow::Cow,
     env::consts,
     ffi::OsString,
     path::{Path, PathBuf},
@@ -29,7 +31,7 @@ use std::{
 use task::{TaskTemplate, TaskTemplates, VariableName};
 use util::{
     ResultExt, archive::extract_zip, fs::remove_matching, maybe, merge_json_value_into,
-    rel_path::RelPath,
+    paths::PathStyle, rel_path::RelPath,
 };
 
 use crate::PackageJsonData;
@@ -253,11 +255,30 @@ impl LspAdapter for JsonLspAdapter {
         self: Arc<Self>,
         delegate: &Arc<dyn LspAdapterDelegate>,
         _: Option<Toolchain>,
-        _: Option<Uri>,
+        requested_uri: Option<Uri>,
         cx: &mut AsyncApp,
     ) -> Result<Value> {
+        let requested_path = requested_uri.as_ref().and_then(|uri| {
+            (uri.scheme() == "file")
+                .then(|| uri.to_file_path().ok())
+                .flatten()
+        });
+        let path_in_worktree = requested_path
+            .as_ref()
+            .and_then(|abs_path| {
+                let rel_path = abs_path.strip_prefix(delegate.worktree_root_path()).ok()?;
+                RelPath::new(rel_path, PathStyle::local()).ok()
+            })
+            .unwrap_or_else(|| Cow::Borrowed(RelPath::empty()));
         let mut config = cx.update(|cx| {
-            let schemas = json_schema_store::all_schema_file_associations(&self.languages, cx);
+            let schemas = json_schema_store::all_schema_file_associations(
+                &self.languages,
+                Some(SettingsLocation {
+                    worktree_id: delegate.worktree_id(),
+                    path: path_in_worktree.as_ref(),
+                }),
+                cx,
+            );
 
             // This can be viewed via `dev: open language server logs` -> `json-language-server` ->
             // `Server Info`