mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
Merge 5eaab414fc into 09165c15dc
This commit is contained in:
commit
5ce2b267fc
3 changed files with 97 additions and 23 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -9749,6 +9749,7 @@ dependencies = [
|
||||||
"settings",
|
"settings",
|
||||||
"snippet_provider",
|
"snippet_provider",
|
||||||
"task",
|
"task",
|
||||||
|
"tempfile",
|
||||||
"theme",
|
"theme",
|
||||||
"util",
|
"util",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ default = []
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gpui = { workspace = true, features = ["test-support"] }
|
gpui = { workspace = true, features = ["test-support"] }
|
||||||
settings = { workspace = true, features = ["test-support"] }
|
settings = { workspace = true, features = ["test-support"] }
|
||||||
|
tempfile.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -449,45 +449,48 @@ pub fn all_schema_file_associations(
|
||||||
.flat_map(|(_, glob_strings)| glob_strings)
|
.flat_map(|(_, glob_strings)| glob_strings)
|
||||||
.cloned();
|
.cloned();
|
||||||
let jsonc_globs = extension_globs.chain(override_globs).collect::<Vec<_>>();
|
let jsonc_globs = extension_globs.chain(override_globs).collect::<Vec<_>>();
|
||||||
|
let settings_file_matches = schema_file_match_entries(paths::settings_file());
|
||||||
|
let keymap_file_matches = schema_file_match_entries(paths::keymap_file());
|
||||||
|
let mut tasks_file_matches = schema_file_match_entries(paths::tasks_file());
|
||||||
|
tasks_file_matches.push(
|
||||||
|
paths::local_tasks_file_relative_path()
|
||||||
|
.as_unix_str()
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
let mut debug_file_matches = schema_file_match_entries(paths::debug_scenarios_file());
|
||||||
|
debug_file_matches.push(
|
||||||
|
paths::local_debug_file_relative_path()
|
||||||
|
.as_unix_str()
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
let snippet_file_matches =
|
||||||
|
schema_file_match_entries(paths::snippets_dir().join("*.json").as_path());
|
||||||
|
|
||||||
let mut file_associations = serde_json::json!([
|
let mut file_associations = serde_json::json!([
|
||||||
{
|
{
|
||||||
"fileMatch": [
|
"fileMatch": settings_file_matches,
|
||||||
schema_file_match(paths::settings_file()),
|
|
||||||
],
|
|
||||||
"url": format!("{SCHEMA_URI_PREFIX}settings"),
|
"url": format!("{SCHEMA_URI_PREFIX}settings"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fileMatch": [
|
"fileMatch": [
|
||||||
paths::local_settings_file_relative_path()],
|
paths::local_settings_file_relative_path()
|
||||||
|
],
|
||||||
"url": format!("{SCHEMA_URI_PREFIX}project_settings"),
|
"url": format!("{SCHEMA_URI_PREFIX}project_settings"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fileMatch": [schema_file_match(paths::keymap_file())],
|
"fileMatch": keymap_file_matches,
|
||||||
"url": format!("{SCHEMA_URI_PREFIX}keymap"),
|
"url": format!("{SCHEMA_URI_PREFIX}keymap"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fileMatch": [
|
"fileMatch": tasks_file_matches,
|
||||||
schema_file_match(paths::tasks_file()),
|
|
||||||
paths::local_tasks_file_relative_path()
|
|
||||||
],
|
|
||||||
"url": format!("{SCHEMA_URI_PREFIX}tasks"),
|
"url": format!("{SCHEMA_URI_PREFIX}tasks"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fileMatch": [
|
"fileMatch": debug_file_matches,
|
||||||
schema_file_match(paths::debug_scenarios_file()),
|
|
||||||
paths::local_debug_file_relative_path()
|
|
||||||
],
|
|
||||||
"url": format!("{SCHEMA_URI_PREFIX}debug_tasks"),
|
"url": format!("{SCHEMA_URI_PREFIX}debug_tasks"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fileMatch": [
|
"fileMatch": snippet_file_matches,
|
||||||
schema_file_match(
|
|
||||||
paths::snippets_dir()
|
|
||||||
.join("*.json")
|
|
||||||
.as_path()
|
|
||||||
)
|
|
||||||
],
|
|
||||||
"url": format!("{SCHEMA_URI_PREFIX}snippets"),
|
"url": format!("{SCHEMA_URI_PREFIX}snippets"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -619,11 +622,80 @@ fn root_schema_from_action_schema(
|
||||||
schema
|
schema
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build the LSP fileMatch entries for `path`.
|
||||||
|
///
|
||||||
|
/// The JSON LSP matches incoming file URIs against these glob patterns,
|
||||||
|
/// so we register both the symlinked location (if any) and the resolved
|
||||||
|
/// canonical path. Without this, opening `~/.config/zed/settings.json`
|
||||||
|
/// when it is a symlink to a file under a different directory no longer
|
||||||
|
/// binds the settings schema (zed-industries/zed#54888).
|
||||||
|
fn schema_file_match_entries(path: &std::path::Path) -> Vec<String> {
|
||||||
|
let mut out = Vec::with_capacity(2);
|
||||||
|
out.push(stripped_match(path));
|
||||||
|
if let Ok(canonical) = path.canonicalize() {
|
||||||
|
if canonical != path {
|
||||||
|
out.push(stripped_match(&canonical));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn schema_file_match(path: &std::path::Path) -> String {
|
fn stripped_match(path: &std::path::Path) -> String {
|
||||||
path.strip_prefix(path.parent().unwrap().parent().unwrap())
|
let parent = path.parent().and_then(|p| p.parent()).unwrap_or(path);
|
||||||
.unwrap()
|
path.strip_prefix(parent)
|
||||||
|
.unwrap_or(path)
|
||||||
.display()
|
.display()
|
||||||
.to_string()
|
.to_string()
|
||||||
.replace('\\', "/")
|
.replace('\\', "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn stripped_match_drops_two_parent_components() {
|
||||||
|
let path = PathBuf::from("/home/user/.config/zed/settings.json");
|
||||||
|
assert_eq!(stripped_match(&path), "zed/settings.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn schema_file_match_entries_returns_single_for_regular_file() {
|
||||||
|
let tmp = tempfile::TempDir::new().unwrap();
|
||||||
|
// Some platforms expose the temp directory through a symlinked prefix.
|
||||||
|
// Canonicalize the root so this test only covers non-symlinked files.
|
||||||
|
let root = tmp.path().canonicalize().unwrap();
|
||||||
|
let zed_dir = root.join("zed");
|
||||||
|
fs::create_dir(&zed_dir).unwrap();
|
||||||
|
let regular = zed_dir.join("settings.json");
|
||||||
|
fs::write(®ular, "{}").unwrap();
|
||||||
|
let entries = schema_file_match_entries(®ular);
|
||||||
|
assert_eq!(entries.len(), 1);
|
||||||
|
assert_eq!(entries[0], "zed/settings.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn schema_file_match_entries_returns_both_for_symlink() {
|
||||||
|
let tmp = tempfile::TempDir::new().unwrap();
|
||||||
|
let zed_dir = tmp.path().join("zed");
|
||||||
|
fs::create_dir(&zed_dir).unwrap();
|
||||||
|
let target = tmp.path().join("settings_target.json");
|
||||||
|
fs::write(&target, "{}").unwrap();
|
||||||
|
let link = zed_dir.join("settings.json");
|
||||||
|
#[cfg(unix)]
|
||||||
|
std::os::unix::fs::symlink(&target, &link).unwrap();
|
||||||
|
#[cfg(windows)]
|
||||||
|
std::os::windows::fs::symlink_file(&target, &link).unwrap();
|
||||||
|
let entries = schema_file_match_entries(&link);
|
||||||
|
assert!(entries.iter().any(|entry| entry == "zed/settings.json"));
|
||||||
|
assert!(
|
||||||
|
entries
|
||||||
|
.iter()
|
||||||
|
.any(|entry| entry.ends_with("settings_target.json"))
|
||||||
|
);
|
||||||
|
assert_eq!(entries.len(), 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue