Detailed changes
@@ -379,7 +379,7 @@ pub trait LspAdapterDelegate: Send + Sync {
fn http_client(&self) -> Arc<dyn HttpClient>;
fn worktree_id(&self) -> WorktreeId;
fn worktree_root_path(&self) -> &Path;
- fn resolve_executable_path(&self, path: PathBuf) -> PathBuf;
+ fn resolve_relative_path(&self, path: PathBuf) -> PathBuf;
fn update_status(&self, language: LanguageServerName, status: BinaryStatus);
fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>>;
async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>>;
@@ -296,7 +296,7 @@ impl LspAdapter for JsonLspAdapter {
});
let project_options = cx.update(|cx| {
language_server_settings(delegate.as_ref(), &self.name(), cx)
- .and_then(|s| s.settings.clone())
+ .and_then(|s| worktree_root(delegate, s.settings.clone()))
});
if let Some(override_options) = project_options {
@@ -320,6 +320,40 @@ impl LspAdapter for JsonLspAdapter {
}
}
+fn worktree_root(delegate: &Arc<dyn LspAdapterDelegate>, settings: Option<Value>) -> Option<Value> {
+ let Some(Value::Object(mut settings_map)) = settings else {
+ return settings;
+ };
+
+ let Some(Value::Object(json_config)) = settings_map.get_mut("json") else {
+ return Some(Value::Object(settings_map));
+ };
+
+ let Some(Value::Array(schemas)) = json_config.get_mut("schemas") else {
+ return Some(Value::Object(settings_map));
+ };
+
+ for schema in schemas.iter_mut() {
+ let Value::Object(schema_map) = schema else {
+ continue;
+ };
+ let Some(Value::String(url)) = schema_map.get_mut("url") else {
+ continue;
+ };
+
+ if !url.starts_with(".") && !url.starts_with("~") {
+ continue;
+ }
+
+ *url = delegate
+ .resolve_relative_path(url.clone().into())
+ .to_string_lossy()
+ .into_owned();
+ }
+
+ Some(Value::Object(settings_map))
+}
+
async fn get_cached_server_binary(
container_dir: PathBuf,
node: &NodeRuntime,
@@ -156,7 +156,7 @@ impl LspAdapter for YamlLspAdapter {
let project_options = cx.update(|cx| {
language_server_settings(delegate.as_ref(), &Self::SERVER_NAME, cx)
- .and_then(|s| s.settings.clone())
+ .and_then(|s| worktree_root(delegate, s.settings.clone()))
});
if let Some(override_options) = project_options {
merge_json_value_into(override_options, &mut options);
@@ -165,6 +165,38 @@ impl LspAdapter for YamlLspAdapter {
}
}
+fn worktree_root(delegate: &Arc<dyn LspAdapterDelegate>, settings: Option<Value>) -> Option<Value> {
+ let Some(Value::Object(mut settings_map)) = settings else {
+ return settings;
+ };
+
+ let Some(Value::Object(yaml_config)) = settings_map.get_mut("yaml") else {
+ return Some(Value::Object(settings_map));
+ };
+
+ let Some(Value::Object(schemas)) = yaml_config.remove("schemas") else {
+ return Some(Value::Object(settings_map));
+ };
+
+ let schemas = schemas
+ .into_iter()
+ .map(|(url, v)| {
+ if !url.starts_with(".") && !url.starts_with("~") {
+ (url, v)
+ } else {
+ let resolved_url = delegate
+ .resolve_relative_path(url.into())
+ .to_string_lossy()
+ .into_owned();
+ (resolved_url, v)
+ }
+ })
+ .collect::<serde_json::Map<String, Value>>();
+
+ yaml_config.insert("schemas".into(), Value::Object(schemas));
+ Some(Value::Object(settings_map))
+}
+
async fn get_cached_server_binary(
container_dir: PathBuf,
node: &NodeRuntime,
@@ -265,7 +265,7 @@ impl DapStore {
DapBinary::Default => None,
DapBinary::Custom(binary) => {
let path = PathBuf::from(binary);
- Some(worktree.read(cx).resolve_executable_path(path))
+ Some(worktree.read(cx).resolve_relative_path(path))
}
});
let user_args = dap_settings.and_then(|s| s.args.clone());
@@ -713,7 +713,7 @@ impl LocalLspStore {
env.extend(settings.env.unwrap_or_default());
Ok(LanguageServerBinary {
- path: delegate.resolve_executable_path(path),
+ path: delegate.resolve_relative_path(path),
env: Some(env),
arguments: settings
.arguments
@@ -14069,8 +14069,8 @@ impl LspAdapterDelegate for LocalLspAdapterDelegate {
self.worktree.abs_path().as_ref()
}
- fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
- self.worktree.resolve_executable_path(path)
+ fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
+ self.worktree.resolve_relative_path(path)
}
async fn shell_env(&self) -> HashMap<String, String> {
@@ -2495,7 +2495,7 @@ impl Snapshot {
///
/// Relative paths that do not exist in the worktree may
/// still be found using the `PATH` environment variable.
- pub fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
+ pub fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
if let Some(path_str) = path.to_str() {
if let Some(remaining_path) = path_str.strip_prefix("~/") {
return home_dir().join(remaining_path);