Fix subdirectory .editorconfig files being ignored in certain directory structures (#48203)

Closes #48187

The bug occurred when iterating internal_configs (a BTreeMap sorted by
path): the code would `break` on the first non-matching path, causing
configs with lexicographically later paths to be skipped.

For example, when querying "d/d.rs" with configs ["", "b", "d"],
iteration would break at "b" (since "d/d.rs" doesn't start with "b"),
preventing "d"'s config from being applied.

This PR replaces `break` with `continue` to skip non-ancestors, and adds
a minor early-exit optimization when `config_path > for_path` since
later paths can't be ancestors.

Release Notes:

- Fixed subdirectory `.editorconfig` files being ignored in certain
directory structures
This commit is contained in:
ᴀᴍᴛᴏᴀᴇʀ 2026-02-03 12:51:41 +08:00 committed by GitHub
parent 14621b66b8
commit b951bd3d6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 14 additions and 3 deletions

View file

@ -215,6 +215,13 @@ async fn test_editorconfig_support(cx: &mut gpui::TestAppContext) {
"b.rs": "fn b() {\n B\n}",
},
"c.js": "def c\n C\nend",
"d": {
".editorconfig": r#"
[*.rs]
indent_size = 1
"#,
"d.rs": "fn d() {\n D\n}",
},
"README.json": "tabs are better\n",
}));
@ -252,6 +259,7 @@ async fn test_editorconfig_support(cx: &mut gpui::TestAppContext) {
let settings_a = settings_for("a.rs");
let settings_b = settings_for("b/b.rs");
let settings_c = settings_for("c.js");
let settings_d = settings_for("d/d.rs");
let settings_readme = settings_for("README.json");
// .editorconfig overrides .zed/settings
@ -261,8 +269,9 @@ async fn test_editorconfig_support(cx: &mut gpui::TestAppContext) {
assert_eq!(settings_a.remove_trailing_whitespace_on_save, true);
assert_eq!(settings_a.preferred_line_length, 120);
// .editorconfig in b/ overrides .editorconfig in root
// .editorconfig in subdirectory overrides .editorconfig in root
assert_eq!(Some(settings_b.tab_size), NonZeroU32::new(2));
assert_eq!(Some(settings_d.tab_size), NonZeroU32::new(1));
// "indent_size" is not set, so "tab_width" is used
assert_eq!(Some(settings_c.tab_size), NonZeroU32::new(10));

View file

@ -345,9 +345,11 @@ impl EditorconfigStore {
}
for (directory_with_config, _, parsed_editorconfig) in self.internal_configs(for_worktree) {
if directory_with_config > for_path {
break;
}
if !for_path.starts_with(directory_with_config) {
properties.use_fallbacks();
return Some(properties);
continue;
}
let parsed_editorconfig = parsed_editorconfig?;
if parsed_editorconfig.is_root {