Add a setting for custom associations between languages and files (#9290)

Closes #5178

Release Notes:

- Added a `file_types` setting that can be used to associate languages
with file names and file extensions. For example, to interpret all `.c`
files as C++, and files called `MyLockFile` as TOML, add the following
to `settings.json`:

    ```json
    {
      "file_types": {
        "C++": ["c"],
        "TOML": ["MyLockFile"]
      }
    }
    ```

As with most zed settings, this can be configured on a per-directory
basis by including a local `.zed/settings.json` file in that directory.

---------

Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
Max Brunsfeld 2024-03-13 10:23:30 -07:00 committed by GitHub
parent 77de5689a3
commit 724c19a223
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 640 additions and 415 deletions

View file

@ -10,9 +10,18 @@ use schemars::{
JsonSchema,
};
use serde::{Deserialize, Serialize};
use settings::Settings;
use settings::{Settings, SettingsLocation};
use std::{num::NonZeroU32, path::Path, sync::Arc};
impl<'a> Into<SettingsLocation<'a>> for &'a dyn File {
fn into(self) -> SettingsLocation<'a> {
SettingsLocation {
worktree_id: self.worktree_id(),
path: self.path().as_ref(),
}
}
}
/// Initializes the language settings.
pub fn init(cx: &mut AppContext) {
AllLanguageSettings::register(cx);
@ -33,7 +42,7 @@ pub fn all_language_settings<'a>(
file: Option<&Arc<dyn File>>,
cx: &'a AppContext,
) -> &'a AllLanguageSettings {
let location = file.map(|f| (f.worktree_id(), f.path().as_ref()));
let location = file.map(|f| f.as_ref().into());
AllLanguageSettings::get(location, cx)
}
@ -44,6 +53,7 @@ pub struct AllLanguageSettings {
pub copilot: CopilotSettings,
defaults: LanguageSettings,
languages: HashMap<Arc<str>, LanguageSettings>,
pub(crate) file_types: HashMap<Arc<str>, Vec<String>>,
}
/// The settings for a particular language.
@ -121,6 +131,10 @@ pub struct AllLanguageSettingsContent {
/// The settings for individual languages.
#[serde(default, alias = "language_overrides")]
pub languages: HashMap<Arc<str>, LanguageSettingsContent>,
/// Settings for associating file extensions and filenames
/// with languages.
#[serde(default)]
pub file_types: HashMap<Arc<str>, Vec<String>>,
}
/// The settings for a particular language.
@ -502,6 +516,16 @@ impl settings::Settings for AllLanguageSettings {
}
}
let mut file_types: HashMap<Arc<str>, Vec<String>> = HashMap::default();
for user_file_types in user_settings.iter().map(|s| &s.file_types) {
for (language, suffixes) in user_file_types {
file_types
.entry(language.clone())
.or_default()
.extend_from_slice(suffixes);
}
}
Ok(Self {
copilot: CopilotSettings {
feature_enabled: copilot_enabled,
@ -512,6 +536,7 @@ impl settings::Settings for AllLanguageSettings {
},
defaults,
languages,
file_types,
})
}