Fix language too
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
use super::*;
|
||||
use crate::Buffer;
|
||||
use crate::language_settings::{AllLanguageSettingsContent, LanguageSettingsContent};
|
||||
use clock::ReplicaId;
|
||||
use collections::BTreeMap;
|
||||
use futures::FutureExt as _;
|
||||
@@ -11,6 +10,7 @@ use proto::deserialize_operation;
|
||||
use rand::prelude::*;
|
||||
use regex::RegexBuilder;
|
||||
use settings::SettingsStore;
|
||||
use settings::{AllLanguageSettingsContent, LanguageSettingsContent};
|
||||
use std::collections::BTreeSet;
|
||||
use std::{
|
||||
env,
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
use crate::{
|
||||
CachedLspAdapter, File, Language, LanguageConfig, LanguageId, LanguageMatcher,
|
||||
LanguageServerName, LspAdapter, ManifestName, PLAIN_TEXT, ToolchainLister,
|
||||
language_settings::{
|
||||
AllLanguageSettingsContent, LanguageSettingsContent, all_language_settings,
|
||||
},
|
||||
task_context::ContextProvider,
|
||||
with_parser,
|
||||
language_settings::all_language_settings, task_context::ContextProvider, with_parser,
|
||||
};
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use collections::{FxHashMap, HashMap, HashSet, hash_map};
|
||||
use settings::{AllLanguageSettingsContent, LanguageSettingsContent};
|
||||
|
||||
use futures::{
|
||||
Future,
|
||||
@@ -1175,7 +1172,7 @@ impl LanguageRegistryState {
|
||||
language.set_theme(theme.syntax());
|
||||
}
|
||||
self.language_settings.languages.0.insert(
|
||||
language.name(),
|
||||
language.name().0,
|
||||
LanguageSettingsContent {
|
||||
tab_size: language.config.tab_size,
|
||||
hard_tabs: language.config.hard_tabs,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@ pub struct AllLanguageSettingsContent {
|
||||
/// Settings for associating file extensions and filenames
|
||||
/// with languages.
|
||||
#[serde(default)]
|
||||
pub file_types: HashMap<SharedString, Vec<String>>,
|
||||
pub file_types: HashMap<Arc<str>, Vec<String>>,
|
||||
}
|
||||
|
||||
/// The settings for enabling/disabling features.
|
||||
@@ -37,13 +37,13 @@ pub struct AllLanguageSettingsContent {
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct FeaturesContent {
|
||||
/// Determines which edit prediction provider to use.
|
||||
pub edit_prediction_provider: Option<EditPredictionProviderContent>,
|
||||
pub edit_prediction_provider: Option<EditPredictionProvider>,
|
||||
}
|
||||
|
||||
/// The provider that supplies edit predictions.
|
||||
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum EditPredictionProviderContent {
|
||||
pub enum EditPredictionProvider {
|
||||
None,
|
||||
#[default]
|
||||
Copilot,
|
||||
@@ -62,7 +62,7 @@ pub struct EditPredictionSettingsContent {
|
||||
/// The mode used to display edit predictions in the buffer.
|
||||
/// Provider support required.
|
||||
#[serde(default)]
|
||||
pub mode: EditPredictionsModeContent,
|
||||
pub mode: EditPredictionsMode,
|
||||
/// Settings specific to GitHub Copilot.
|
||||
#[serde(default)]
|
||||
pub copilot: CopilotSettingsContent,
|
||||
@@ -98,7 +98,7 @@ pub struct CopilotSettingsContent {
|
||||
/// The mode in which edit predictions should be displayed.
|
||||
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum EditPredictionsModeContent {
|
||||
pub enum EditPredictionsMode {
|
||||
/// If provider supports it, display inline when holding modifier key (e.g., alt).
|
||||
/// Otherwise, eager preview is used.
|
||||
#[serde(alias = "auto")]
|
||||
@@ -112,7 +112,7 @@ pub enum EditPredictionsModeContent {
|
||||
/// Controls the soft-wrapping behavior in the editor.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SoftWrapContent {
|
||||
pub enum SoftWrap {
|
||||
/// Prefer a single line generally, unless an overly long line is encountered.
|
||||
None,
|
||||
/// Deprecated: use None instead. Left to avoid breaking existing users' configs.
|
||||
@@ -144,7 +144,7 @@ pub struct LanguageSettingsContent {
|
||||
///
|
||||
/// Default: none
|
||||
#[serde(default)]
|
||||
pub soft_wrap: Option<SoftWrapContent>,
|
||||
pub soft_wrap: Option<SoftWrap>,
|
||||
/// The column at which to soft-wrap lines, for buffers where soft-wrap
|
||||
/// is enabled.
|
||||
///
|
||||
@@ -166,7 +166,7 @@ pub struct LanguageSettingsContent {
|
||||
pub wrap_guides: Option<Vec<usize>>,
|
||||
/// Indent guide related settings.
|
||||
#[serde(default)]
|
||||
pub indent_guides: Option<IndentGuideSettingsContent>,
|
||||
pub indent_guides: Option<IndentGuideSettings>,
|
||||
/// Whether or not to perform a buffer format before saving.
|
||||
///
|
||||
/// Default: on
|
||||
@@ -379,6 +379,8 @@ pub struct JsxTagAutoCloseSettings {
|
||||
}
|
||||
|
||||
/// The settings for inlay hints.
|
||||
/// todo(settings_refactor) the fields of this struct should likely be optional,
|
||||
/// and a similar struct exposed from the language crate.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
pub struct InlayHintSettings {
|
||||
/// Global switch to toggle hints on and off.
|
||||
@@ -437,6 +439,54 @@ pub struct InlayHintSettings {
|
||||
pub toggle_on_modifiers_press: Option<Modifiers>,
|
||||
}
|
||||
|
||||
impl InlayHintSettings {
|
||||
/// Returns the kinds of inlay hints that are enabled based on the settings.
|
||||
pub fn enabled_inlay_hint_kinds(&self) -> HashSet<Option<InlayHintKind>> {
|
||||
let mut kinds = HashSet::default();
|
||||
if self.show_type_hints {
|
||||
kinds.insert(Some(InlayHintKind::Type));
|
||||
}
|
||||
if self.show_parameter_hints {
|
||||
kinds.insert(Some(InlayHintKind::Parameter));
|
||||
}
|
||||
if self.show_other_hints {
|
||||
kinds.insert(None);
|
||||
}
|
||||
kinds
|
||||
}
|
||||
}
|
||||
|
||||
/// The kind of an inlay hint.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum InlayHintKind {
|
||||
/// An inlay hint for a type.
|
||||
Type,
|
||||
/// An inlay hint for a parameter.
|
||||
Parameter,
|
||||
}
|
||||
|
||||
impl InlayHintKind {
|
||||
/// Returns the [`InlayHintKind`] from the given name.
|
||||
///
|
||||
/// Returns `None` if `name` does not match any of the expected
|
||||
/// string representations.
|
||||
pub fn from_name(name: &str) -> Option<Self> {
|
||||
match name {
|
||||
"type" => Some(InlayHintKind::Type),
|
||||
"parameter" => Some(InlayHintKind::Parameter),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the name of this [`InlayHintKind`].
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
InlayHintKind::Type => "type",
|
||||
InlayHintKind::Parameter => "parameter",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn edit_debounce_ms() -> u64 {
|
||||
700
|
||||
}
|
||||
@@ -775,7 +825,7 @@ pub enum Formatter {
|
||||
|
||||
/// The settings for indent guides.
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct IndentGuideSettingsContent {
|
||||
pub struct IndentGuideSettings {
|
||||
/// Whether to display indent guides in the editor.
|
||||
///
|
||||
/// Default: true
|
||||
@@ -881,3 +931,47 @@ pub enum IndentGuideBackgroundColoring {
|
||||
/// Use a different color for each indentation level.
|
||||
IndentAware,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_formatter_deserialization() {
|
||||
let raw_auto = "{\"formatter\": \"auto\"}";
|
||||
let settings: LanguageSettingsContent = serde_json::from_str(raw_auto).unwrap();
|
||||
assert_eq!(settings.formatter, Some(SelectedFormatter::Auto));
|
||||
let raw = "{\"formatter\": \"language_server\"}";
|
||||
let settings: LanguageSettingsContent = serde_json::from_str(raw).unwrap();
|
||||
assert_eq!(
|
||||
settings.formatter,
|
||||
Some(SelectedFormatter::List(FormatterList::Single(
|
||||
Formatter::LanguageServer { name: None }
|
||||
)))
|
||||
);
|
||||
let raw = "{\"formatter\": [{\"language_server\": {\"name\": null}}]}";
|
||||
let settings: LanguageSettingsContent = serde_json::from_str(raw).unwrap();
|
||||
assert_eq!(
|
||||
settings.formatter,
|
||||
Some(SelectedFormatter::List(FormatterList::Vec(vec![
|
||||
Formatter::LanguageServer { name: None }
|
||||
])))
|
||||
);
|
||||
let raw = "{\"formatter\": [{\"language_server\": {\"name\": null}}, \"prettier\"]}";
|
||||
let settings: LanguageSettingsContent = serde_json::from_str(raw).unwrap();
|
||||
assert_eq!(
|
||||
settings.formatter,
|
||||
Some(SelectedFormatter::List(FormatterList::Vec(vec![
|
||||
Formatter::LanguageServer { name: None },
|
||||
Formatter::Prettier
|
||||
])))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_formatter_deserialization_invalid() {
|
||||
let raw_auto = "{\"formatter\": {}}";
|
||||
let result: Result<LanguageSettingsContent, _> = serde_json::from_str(raw_auto);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ struct SettingValue<T> {
|
||||
trait AnySettingValue: 'static + Send + Sync {
|
||||
fn setting_type_name(&self) -> &'static str;
|
||||
|
||||
fn from_file(&self, s: &SettingsContent, cx: &mut App) -> Option<Box<dyn Any>>;
|
||||
fn from_default(&self, s: &SettingsContent, cx: &mut App) -> Option<Box<dyn Any>>;
|
||||
fn refine(&self, value: &mut dyn Any, s: &[&SettingsContent], cx: &mut App);
|
||||
|
||||
fn value_for_path(&self, path: Option<SettingsLocation>) -> &dyn Any;
|
||||
@@ -279,7 +279,7 @@ impl SettingsStore {
|
||||
}
|
||||
let Some(mut value) = T::from_default(&self.default_settings, cx) else {
|
||||
panic!(
|
||||
"{}::from_file return None for default.json",
|
||||
"{}::from_default return None for default.json",
|
||||
type_name::<T>()
|
||||
)
|
||||
};
|
||||
@@ -387,7 +387,7 @@ impl SettingsStore {
|
||||
cx: &mut App,
|
||||
update: impl FnOnce(&mut SettingsContent),
|
||||
) {
|
||||
let mut content = self.user_settings.as_ref().unwrap().content.clone();
|
||||
let mut content = self.user_settings.clone().unwrap_or_default().content;
|
||||
update(&mut content);
|
||||
let new_text = serde_json::to_string(&UserSettingsContent {
|
||||
content,
|
||||
@@ -864,7 +864,9 @@ impl SettingsStore {
|
||||
for setting_value in self.setting_values.values_mut() {
|
||||
// If the global settings file changed, reload the global value for the field.
|
||||
if changed_local_path.is_none() {
|
||||
let mut value = setting_value.from_file(&self.default_settings, cx).unwrap();
|
||||
let mut value = setting_value
|
||||
.from_default(&self.default_settings, cx)
|
||||
.unwrap();
|
||||
setting_value.refine(value.as_mut(), &refinements, cx);
|
||||
setting_value.set_global_value(value);
|
||||
}
|
||||
@@ -896,7 +898,9 @@ impl SettingsStore {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut value = setting_value.from_file(&self.default_settings, cx).unwrap();
|
||||
let mut value = setting_value
|
||||
.from_default(&self.default_settings, cx)
|
||||
.unwrap();
|
||||
setting_value.refine(value.as_mut(), &refinements, cx);
|
||||
setting_value.refine(value.as_mut(), &project_settings_stack, cx);
|
||||
setting_value.set_local_value(*root_id, directory_path.clone(), value);
|
||||
@@ -980,7 +984,7 @@ impl Debug for SettingsStore {
|
||||
}
|
||||
|
||||
impl<T: Settings> AnySettingValue for SettingValue<T> {
|
||||
fn from_file(&self, s: &SettingsContent, cx: &mut App) -> Option<Box<dyn Any>> {
|
||||
fn from_default(&self, s: &SettingsContent, cx: &mut App) -> Option<Box<dyn Any>> {
|
||||
T::from_default(s, cx).map(|result| Box::new(result) as _)
|
||||
}
|
||||
|
||||
|
||||
@@ -798,6 +798,7 @@ fn font_fallbacks_from_settings(
|
||||
impl settings::Settings for ThemeSettings {
|
||||
fn from_default(content: &settings::SettingsContent, cx: &mut App) -> Option<Self> {
|
||||
let content = &content.theme;
|
||||
dbg!(&content);
|
||||
let themes = ThemeRegistry::default_global(cx);
|
||||
let system_appearance = SystemAppearance::default_global(cx);
|
||||
let theme_selection: ThemeSelection = content.theme.clone()?.into();
|
||||
@@ -832,7 +833,7 @@ impl settings::Settings for ThemeSettings {
|
||||
.get_icon_theme(icon_theme_selection.icon_theme(*system_appearance))
|
||||
.ok()?,
|
||||
icon_theme_selection: Some(icon_theme_selection),
|
||||
ui_density: content.ui_density?.into(),
|
||||
ui_density: content.ui_density.unwrap_or_default().into(),
|
||||
unnecessary_code_fade: content.unnecessary_code_fade?,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user