Support .editorconfig (#19455)

Closes https://github.com/zed-industries/zed/issues/8534
Supersedes https://github.com/zed-industries/zed/pull/16349

Potential concerns:
* we do not follow up to the `/` when looking for `.editorconfig`, only
up to the worktree root.
Seems fine for most of the cases, and the rest should be solved
generically later, as the same issue exists for settings.json
* `fn language` in `AllLanguageSettings` is very hot, called very
frequently during rendering. We accumulate and parse all `.editorconfig`
file contents beforehand, but have to go over globs and match these
against the path given + merge the properties still.
This does not seem to be very bad, but needs more testing and
potentially some extra caching.


Release Notes:

- Added .editorconfig support

---------

Co-authored-by: Ulysse Buonomo <buonomo.ulysse@gmail.com>
This commit is contained in:
Kirill Bulatov 2024-10-21 13:05:30 +03:00 committed by GitHub
parent d95a4f8671
commit d3cb08bf35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 869 additions and 263 deletions

View file

@ -5,7 +5,7 @@ use gpui::{AppContext, AsyncAppContext, BorrowAppContext, EventEmitter, Model, M
use language::LanguageServerName;
use paths::{
local_settings_file_relative_path, local_tasks_file_relative_path,
local_vscode_tasks_file_relative_path,
local_vscode_tasks_file_relative_path, EDITORCONFIG_NAME,
};
use rpc::{proto, AnyProtoClient, TypedEnvelope};
use schemars::JsonSchema;
@ -287,14 +287,29 @@ impl SettingsObserver {
let store = cx.global::<SettingsStore>();
for worktree in self.worktree_store.read(cx).worktrees() {
let worktree_id = worktree.read(cx).id().to_proto();
for (path, kind, content) in store.local_settings(worktree.read(cx).id()) {
for (path, content) in store.local_settings(worktree.read(cx).id()) {
downstream_client
.send(proto::UpdateWorktreeSettings {
project_id,
worktree_id,
path: path.to_string_lossy().into(),
content: Some(content),
kind: Some(local_settings_kind_to_proto(kind).into()),
kind: Some(
local_settings_kind_to_proto(LocalSettingsKind::Settings).into(),
),
})
.log_err();
}
for (path, content, _) in store.local_editorconfig_settings(worktree.read(cx).id()) {
downstream_client
.send(proto::UpdateWorktreeSettings {
project_id,
worktree_id,
path: path.to_string_lossy().into(),
content: Some(content),
kind: Some(
local_settings_kind_to_proto(LocalSettingsKind::Editorconfig).into(),
),
})
.log_err();
}
@ -453,6 +468,11 @@ impl SettingsObserver {
.unwrap(),
);
(settings_dir, LocalSettingsKind::Tasks)
} else if path.ends_with(EDITORCONFIG_NAME) {
let Some(settings_dir) = path.parent().map(Arc::from) else {
continue;
};
(settings_dir, LocalSettingsKind::Editorconfig)
} else {
continue;
};