Detailed changes
@@ -0,0 +1,109 @@
+{
+ // The name of the Zed theme to use for the UI
+ "theme": "cave-dark",
+
+ // The name of a font to use for rendering text in the editor
+ "buffer_font_family": "Zed Mono",
+
+ // The default font size for text in the editor
+ "buffer_font_size": 15,
+
+ // Whether to enable vim modes and key bindings
+ "vim_mode": false,
+
+ // Whether to show the informational hover box when moving the mouse
+ // over symbols in the editor.
+ "hover_popover_enabled": true,
+
+ // Whether new projects should start out 'online'. Online projects
+ // appear in the contacts panel under your name, so that your contacts
+ // can see which projects you are working on. Regardless of this
+ // setting, projects keep their last online status when you reopen them.
+ "projects_online_by_default": true,
+
+ // Whether to use language servers to provide code intelligence.
+ "enable_language_server": true,
+
+ // When to automatically save edited buffers. This setting can
+ // take four values.
+ //
+ // 1. Never automatically save:
+ // "autosave": "off",
+ // 2. Save when changing focus away from the Zed window:
+ // "autosave": "on_window_change",
+ // 3. Save when changing focus away from a specific buffer:
+ // "autosave": "on_focus_change",
+ // 4. Save when idle for a certain amount of time:
+ // "autosave": { "after_delay": {"milliseconds": 500} },
+ "autosave": "off",
+
+ // How to auto-format modified buffers when saving them. This
+ // setting can take three values:
+ //
+ // 1. Don't format code
+ // "format_on_save": "off"
+ // 2. Format code using the current language server:
+ // "format_on_save": "language_server"
+ // 3. Format code using an external command:
+ // "format_on_save": {
+ // "external": {
+ // "command": "sed",
+ // "arguments": ["-e", "s/ *$//"]
+ // }
+ // },
+ "format_on_save": "language_server",
+
+ // How to soft-wrap long lines of text. This setting can take
+ // three values:
+ //
+ // 1. Do not soft wrap.
+ // "soft_wrap": "none",
+ // 2. Soft wrap lines that overflow the editor:
+ // "soft_wrap": "editor_width",
+ // 2. Soft wrap lines at the preferred line length
+ // "soft_wrap": "preferred_line_length",
+ "soft_wrap": "none",
+
+ // The column at which to soft-wrap lines, for buffers where soft-wrap
+ // is enabled.
+ "preferred_line_length": 80,
+
+ // Whether to indent lines using tab characters, as opposed to multiple
+ // spaces.
+ "hard_tabs": false,
+
+ // How many columns a tab should occupy.
+ "tab_size": 4,
+
+ // Different settings for specific languages.
+ "languages": {
+ "Plain Text": {
+ "soft_wrap": "preferred_line_length"
+ },
+ "C": {
+ "tab_size": 2
+ },
+ "C++": {
+ "tab_size": 2
+ },
+ "Go": {
+ "tab_size": 4,
+ "hard_tabs": true
+ },
+ "Markdown": {
+ "soft_wrap": "preferred_line_length"
+ },
+ "Rust": {
+ "tab_size": 4
+ },
+ "JavaScript": {
+ "tab_size": 2
+ },
+ "TypeScript": {
+ "tab_size": 2
+ },
+ "TSX": {
+ "tab_size": 2
+ }
+ }
+}
@@ -0,0 +1,8 @@
+// Zed settings
+//
+// For information on how to configure Zed, see the Zed
+// documentation: https://zed.dev/docs/configuring-zed
+//
+// To see all of Zed's default settings without changing your
+// custom settings, run the `open default settings` command
+// from the command palette or from `Zed` application menu.
@@ -2010,7 +2010,7 @@ async fn test_formatting_buffer(cx_a: &mut TestAppContext, cx_b: &mut TestAppCon
// host's configuration is honored as opposed to using the guest's settings.
cx_a.update(|cx| {
cx.update_global(|settings: &mut Settings, _| {
- settings.language_settings.format_on_save = Some(FormatOnSave::External {
+ settings.editor_defaults.format_on_save = Some(FormatOnSave::External {
command: "awk".to_string(),
arguments: vec!["{sub(/two/,\"{buffer_path}\")}1".to_string()],
});
@@ -983,7 +983,7 @@ pub mod tests {
language.set_theme(&theme);
cx.update(|cx| {
let mut settings = Settings::test(cx);
- settings.language_settings.tab_size = Some(2.try_into().unwrap());
+ settings.editor_defaults.tab_size = Some(2.try_into().unwrap());
cx.set_global(settings);
});
@@ -6236,7 +6236,7 @@ mod tests {
use language::{FakeLspAdapter, LanguageConfig};
use lsp::FakeLanguageServer;
use project::FakeFs;
- use settings::LanguageSettings;
+ use settings::EditorSettings;
use std::{cell::RefCell, rc::Rc, time::Instant};
use text::Point;
use unindent::Unindent;
@@ -7613,7 +7613,7 @@ mod tests {
let mut cx = EditorTestContext::new(cx).await;
cx.update(|cx| {
cx.update_global::<Settings, _, _>(|settings, _| {
- settings.language_settings.hard_tabs = Some(true);
+ settings.editor_overrides.hard_tabs = Some(true);
});
});
@@ -7696,14 +7696,14 @@ mod tests {
Settings::test(cx)
.with_language_defaults(
"TOML",
- LanguageSettings {
+ EditorSettings {
tab_size: Some(2.try_into().unwrap()),
..Default::default()
},
)
.with_language_defaults(
"Rust",
- LanguageSettings {
+ EditorSettings {
tab_size: Some(4.try_into().unwrap()),
..Default::default()
},
@@ -9380,7 +9380,7 @@ mod tests {
cx.update_global::<Settings, _, _>(|settings, _| {
settings.language_overrides.insert(
"Rust".into(),
- LanguageSettings {
+ EditorSettings {
tab_size: Some(8.try_into().unwrap()),
..Default::default()
},
@@ -9496,7 +9496,7 @@ mod tests {
cx.update_global::<Settings, _, _>(|settings, _| {
settings.language_overrides.insert(
"Rust".into(),
- LanguageSettings {
+ EditorSettings {
tab_size: Some(8.try_into().unwrap()),
..Default::default()
},
@@ -883,7 +883,7 @@ async fn test_toggling_enable_language_server(
cx.update_global(|settings: &mut Settings, _| {
settings.language_overrides.insert(
Arc::from("Rust"),
- settings::LanguageSettings {
+ settings::EditorSettings {
enable_language_server: Some(false),
..Default::default()
},
@@ -900,14 +900,14 @@ async fn test_toggling_enable_language_server(
cx.update_global(|settings: &mut Settings, _| {
settings.language_overrides.insert(
Arc::from("Rust"),
- settings::LanguageSettings {
+ settings::EditorSettings {
enable_language_server: Some(true),
..Default::default()
},
);
settings.language_overrides.insert(
Arc::from("JavaScript"),
- settings::LanguageSettings {
+ settings::EditorSettings {
enable_language_server: Some(false),
..Default::default()
},
@@ -608,8 +608,11 @@ mod tests {
let fonts = cx.font_cache();
let mut theme = gpui::fonts::with_font_cache(fonts.clone(), || theme::Theme::default());
theme.search.match_background = Color::red();
- let settings = Settings::new("Courier", &fonts, Arc::new(theme)).unwrap();
- cx.update(|cx| cx.set_global(settings));
+ cx.update(|cx| {
+ let mut settings = Settings::test(cx);
+ settings.theme = Arc::new(theme);
+ cx.set_global(settings)
+ });
let buffer = cx.add_model(|cx| {
Buffer::new(
@@ -911,8 +911,11 @@ mod tests {
let fonts = cx.font_cache();
let mut theme = gpui::fonts::with_font_cache(fonts.clone(), || theme::Theme::default());
theme.search.match_background = Color::red();
- let settings = Settings::new("Courier", &fonts, Arc::new(theme)).unwrap();
- cx.update(|cx| cx.set_global(settings));
+ cx.update(|cx| {
+ let mut settings = Settings::test(cx);
+ settings.theme = Arc::new(theme);
+ cx.set_global(settings)
+ });
let fs = FakeFs::new(cx.background());
fs.insert_tree(
@@ -1,17 +1,18 @@
mod keymap_file;
use anyhow::Result;
-use gpui::font_cache::{FamilyId, FontCache};
+use gpui::{
+ font_cache::{FamilyId, FontCache},
+ AssetSource,
+};
use schemars::{
gen::{SchemaGenerator, SchemaSettings},
- schema::{
- InstanceType, ObjectValidation, Schema, SchemaObject, SingleOrVec, SubschemaValidation,
- },
+ schema::{InstanceType, ObjectValidation, Schema, SchemaObject, SingleOrVec},
JsonSchema,
};
use serde::{de::DeserializeOwned, Deserialize};
use serde_json::Value;
-use std::{collections::HashMap, num::NonZeroU32, sync::Arc};
+use std::{collections::HashMap, num::NonZeroU32, str, sync::Arc};
use theme::{Theme, ThemeRegistry};
use util::ResultExt as _;
@@ -26,14 +27,15 @@ pub struct Settings {
pub hover_popover_enabled: bool,
pub vim_mode: bool,
pub autosave: Autosave,
- pub language_settings: LanguageSettings,
- pub language_defaults: HashMap<Arc<str>, LanguageSettings>,
- pub language_overrides: HashMap<Arc<str>, LanguageSettings>,
+ pub editor_defaults: EditorSettings,
+ pub editor_overrides: EditorSettings,
+ pub language_defaults: HashMap<Arc<str>, EditorSettings>,
+ pub language_overrides: HashMap<Arc<str>, EditorSettings>,
pub theme: Arc<Theme>,
}
#[derive(Clone, Debug, Default, Deserialize, JsonSchema)]
-pub struct LanguageSettings {
+pub struct EditorSettings {
pub tab_size: Option<NonZeroU32>,
pub hard_tabs: Option<bool>,
pub soft_wrap: Option<SoftWrap>,
@@ -83,44 +85,61 @@ pub struct SettingsFileContent {
#[serde(default)]
pub vim_mode: Option<bool>,
#[serde(default)]
- pub format_on_save: Option<FormatOnSave>,
- #[serde(default)]
pub autosave: Option<Autosave>,
- #[serde(default)]
- pub enable_language_server: Option<bool>,
#[serde(flatten)]
- pub editor: LanguageSettings,
+ pub editor: EditorSettings,
#[serde(default)]
- pub language_overrides: HashMap<Arc<str>, LanguageSettings>,
+ #[serde(alias = "language_overrides")]
+ pub languages: HashMap<Arc<str>, EditorSettings>,
#[serde(default)]
pub theme: Option<String>,
}
impl Settings {
- pub fn new(
- buffer_font_family: &str,
+ pub fn defaults(
+ assets: impl AssetSource,
font_cache: &FontCache,
- theme: Arc<Theme>,
- ) -> Result<Self> {
- Ok(Self {
- buffer_font_family: font_cache.load_family(&[buffer_font_family])?,
- buffer_font_size: 15.,
- default_buffer_font_size: 15.,
- hover_popover_enabled: true,
- vim_mode: false,
- autosave: Autosave::Off,
- language_settings: Default::default(),
- language_defaults: Default::default(),
+ themes: &ThemeRegistry,
+ ) -> Self {
+ fn required<T>(value: Option<T>) -> Option<T> {
+ assert!(value.is_some(), "missing default setting value");
+ value
+ }
+
+ let defaults: SettingsFileContent = parse_json_with_comments(
+ str::from_utf8(assets.load("settings/default.json").unwrap().as_ref()).unwrap(),
+ )
+ .unwrap();
+
+ Self {
+ buffer_font_family: font_cache
+ .load_family(&[defaults.buffer_font_family.as_ref().unwrap()])
+ .unwrap(),
+ buffer_font_size: defaults.buffer_font_size.unwrap(),
+ default_buffer_font_size: defaults.buffer_font_size.unwrap(),
+ hover_popover_enabled: defaults.hover_popover_enabled.unwrap(),
+ projects_online_by_default: defaults.projects_online_by_default.unwrap(),
+ vim_mode: defaults.vim_mode.unwrap(),
+ autosave: defaults.autosave.unwrap(),
+ editor_defaults: EditorSettings {
+ tab_size: required(defaults.editor.tab_size),
+ hard_tabs: required(defaults.editor.hard_tabs),
+ soft_wrap: required(defaults.editor.soft_wrap),
+ preferred_line_length: required(defaults.editor.preferred_line_length),
+ format_on_save: required(defaults.editor.format_on_save),
+ enable_language_server: required(defaults.editor.enable_language_server),
+ },
+ language_defaults: defaults.languages,
+ editor_overrides: Default::default(),
language_overrides: Default::default(),
- projects_online_by_default: true,
- theme,
- })
+ theme: themes.get(&defaults.theme.unwrap()).unwrap(),
+ }
}
pub fn with_language_defaults(
mut self,
language_name: impl Into<Arc<str>>,
- overrides: LanguageSettings,
+ overrides: EditorSettings,
) -> Self {
self.language_defaults
.insert(language_name.into(), overrides);
@@ -129,48 +148,37 @@ impl Settings {
pub fn tab_size(&self, language: Option<&str>) -> NonZeroU32 {
self.language_setting(language, |settings| settings.tab_size)
- .unwrap_or(4.try_into().unwrap())
}
pub fn hard_tabs(&self, language: Option<&str>) -> bool {
self.language_setting(language, |settings| settings.hard_tabs)
- .unwrap_or(false)
}
pub fn soft_wrap(&self, language: Option<&str>) -> SoftWrap {
self.language_setting(language, |settings| settings.soft_wrap)
- .unwrap_or(SoftWrap::None)
}
pub fn preferred_line_length(&self, language: Option<&str>) -> u32 {
self.language_setting(language, |settings| settings.preferred_line_length)
- .unwrap_or(80)
}
pub fn format_on_save(&self, language: Option<&str>) -> FormatOnSave {
self.language_setting(language, |settings| settings.format_on_save.clone())
- .unwrap_or(FormatOnSave::LanguageServer)
}
pub fn enable_language_server(&self, language: Option<&str>) -> bool {
self.language_setting(language, |settings| settings.enable_language_server)
- .unwrap_or(true)
}
- fn language_setting<F, R>(&self, language: Option<&str>, f: F) -> Option<R>
+ fn language_setting<F, R>(&self, language: Option<&str>, f: F) -> R
where
- F: Fn(&LanguageSettings) -> Option<R>,
+ F: Fn(&EditorSettings) -> Option<R>,
{
- let mut language_override = None;
- let mut language_default = None;
- if let Some(language) = language {
- language_override = self.language_overrides.get(language).and_then(&f);
- language_default = self.language_defaults.get(language).and_then(&f);
- }
-
- language_override
- .or_else(|| f(&self.language_settings))
- .or(language_default)
+ None.or_else(|| language.and_then(|l| self.language_overrides.get(l).and_then(&f)))
+ .or_else(|| f(&self.editor_overrides))
+ .or_else(|| language.and_then(|l| self.language_defaults.get(l).and_then(&f)))
+ .or_else(|| f(&self.editor_defaults))
+ .expect("missing default")
}
#[cfg(any(test, feature = "test-support"))]
@@ -182,7 +190,15 @@ impl Settings {
hover_popover_enabled: true,
vim_mode: false,
autosave: Autosave::Off,
- language_settings: Default::default(),
+ editor_defaults: EditorSettings {
+ tab_size: Some(4.try_into().unwrap()),
+ hard_tabs: Some(false),
+ soft_wrap: Some(SoftWrap::None),
+ preferred_line_length: Some(80),
+ format_on_save: Some(FormatOnSave::LanguageServer),
+ enable_language_server: Some(true),
+ },
+ editor_overrides: Default::default(),
language_defaults: Default::default(),
language_overrides: Default::default(),
projects_online_by_default: true,
@@ -224,22 +240,23 @@ impl Settings {
merge(&mut self.hover_popover_enabled, data.hover_popover_enabled);
merge(&mut self.vim_mode, data.vim_mode);
merge(&mut self.autosave, data.autosave);
+
merge_option(
- &mut self.language_settings.format_on_save,
- data.format_on_save.clone(),
+ &mut self.editor_overrides.format_on_save,
+ data.editor.format_on_save.clone(),
);
merge_option(
- &mut self.language_settings.enable_language_server,
- data.enable_language_server,
+ &mut self.editor_overrides.enable_language_server,
+ data.editor.enable_language_server,
);
- merge_option(&mut self.language_settings.soft_wrap, data.editor.soft_wrap);
- merge_option(&mut self.language_settings.tab_size, data.editor.tab_size);
+ merge_option(&mut self.editor_overrides.soft_wrap, data.editor.soft_wrap);
+ merge_option(&mut self.editor_overrides.tab_size, data.editor.tab_size);
merge_option(
- &mut self.language_settings.preferred_line_length,
+ &mut self.editor_overrides.preferred_line_length,
data.editor.preferred_line_length,
);
- for (language_name, settings) in data.language_overrides.clone().into_iter() {
+ for (language_name, settings) in data.languages.clone().into_iter() {
let target = self
.language_overrides
.entry(language_name.into())
@@ -270,77 +287,61 @@ pub fn settings_file_json_schema(
let generator = SchemaGenerator::new(settings);
let mut root_schema = generator.into_root_schema_for::<SettingsFileContent>();
- // Construct theme names reference type
- let theme_names = theme_names
- .into_iter()
- .map(|name| Value::String(name))
- .collect();
- let theme_names_schema = Schema::Object(SchemaObject {
+ // Create a schema for a theme name.
+ let theme_name_schema = SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
- enum_values: Some(theme_names),
+ enum_values: Some(
+ theme_names
+ .into_iter()
+ .map(|name| Value::String(name))
+ .collect(),
+ ),
..Default::default()
- });
- root_schema
- .definitions
- .insert("ThemeName".to_owned(), theme_names_schema);
+ };
- // Construct language settings reference type
- let language_settings_schema_reference = Schema::Object(SchemaObject {
- reference: Some("#/definitions/LanguageSettings".to_owned()),
- ..Default::default()
- });
- let language_settings_properties = language_names
- .into_iter()
- .map(|name| {
- (
- name,
- Schema::Object(SchemaObject {
- subschemas: Some(Box::new(SubschemaValidation {
- all_of: Some(vec![language_settings_schema_reference.clone()]),
- ..Default::default()
- })),
- ..Default::default()
- }),
- )
- })
- .collect();
- let language_overrides_schema = Schema::Object(SchemaObject {
+ // Create a schema for a 'languages overrides' object, associating editor
+ // settings with specific langauges.
+ assert!(root_schema.definitions.contains_key("EditorSettings"));
+ let languages_object_schema = SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
object: Some(Box::new(ObjectValidation {
- properties: language_settings_properties,
+ properties: language_names
+ .into_iter()
+ .map(|name| (name, Schema::new_ref("#/definitions/EditorSettings".into())))
+ .collect(),
..Default::default()
})),
..Default::default()
- });
+ };
+
+ // Add these new schemas as definitions, and modify properties of the root
+ // schema to reference them.
+ root_schema.definitions.extend([
+ ("ThemeName".into(), theme_name_schema.into()),
+ ("Languages".into(), languages_object_schema.into()),
+ ]);
root_schema
- .definitions
- .insert("LanguageOverrides".to_owned(), language_overrides_schema);
+ .schema
+ .object
+ .as_mut()
+ .unwrap()
+ .properties
+ .extend([
+ (
+ "theme".to_owned(),
+ Schema::new_ref("#/definitions/ThemeName".into()),
+ ),
+ (
+ "languages".to_owned(),
+ Schema::new_ref("#/definitions/Languages".into()),
+ ),
+ // For backward compatibility
+ (
+ "language_overrides".to_owned(),
+ Schema::new_ref("#/definitions/Languages".into()),
+ ),
+ ]);
- // Modify theme property to use new theme reference type
- let settings_file_schema = root_schema.schema.object.as_mut().unwrap();
- let language_overrides_schema_reference = Schema::Object(SchemaObject {
- reference: Some("#/definitions/ThemeName".to_owned()),
- ..Default::default()
- });
- settings_file_schema.properties.insert(
- "theme".to_owned(),
- Schema::Object(SchemaObject {
- subschemas: Some(Box::new(SubschemaValidation {
- all_of: Some(vec![language_overrides_schema_reference]),
- ..Default::default()
- })),
- ..Default::default()
- }),
- );
-
- // Modify language_overrides property to use LanguageOverrides reference
- settings_file_schema.properties.insert(
- "language_overrides".to_owned(),
- Schema::Object(SchemaObject {
- reference: Some("#/definitions/LanguageOverrides".to_owned()),
- ..Default::default()
- }),
- );
serde_json::to_value(root_schema).unwrap()
}
@@ -12,8 +12,6 @@ use std::{collections::HashMap, sync::Arc};
pub use theme_registry::*;
-pub const DEFAULT_THEME_NAME: &'static str = "cave-dark";
-
#[derive(Deserialize, Default)]
pub struct Theme {
#[serde(default)]
@@ -38,7 +38,7 @@ use std::{
time::Duration,
};
use terminal;
-use theme::{ThemeRegistry, DEFAULT_THEME_NAME};
+use theme::ThemeRegistry;
use util::{ResultExt, TryFutureExt};
use workspace::{self, AppState, NewFile, OpenPaths};
use zed::{
@@ -72,73 +72,7 @@ fn main() {
let fs = Arc::new(RealFs);
let themes = ThemeRegistry::new(Assets, app.font_cache());
- let theme = themes.get(DEFAULT_THEME_NAME).unwrap();
- let default_settings = Settings::new("Zed Mono", &app.font_cache(), theme)
- .unwrap()
- .with_language_defaults(
- languages::PLAIN_TEXT.name(),
- settings::LanguageSettings {
- soft_wrap: Some(settings::SoftWrap::PreferredLineLength),
- ..Default::default()
- },
- )
- .with_language_defaults(
- "C",
- settings::LanguageSettings {
- tab_size: Some(2.try_into().unwrap()),
- ..Default::default()
- },
- )
- .with_language_defaults(
- "C++",
- settings::LanguageSettings {
- tab_size: Some(2.try_into().unwrap()),
- ..Default::default()
- },
- )
- .with_language_defaults(
- "Go",
- settings::LanguageSettings {
- tab_size: Some(4.try_into().unwrap()),
- hard_tabs: Some(true),
- ..Default::default()
- },
- )
- .with_language_defaults(
- "Markdown",
- settings::LanguageSettings {
- soft_wrap: Some(settings::SoftWrap::PreferredLineLength),
- ..Default::default()
- },
- )
- .with_language_defaults(
- "Rust",
- settings::LanguageSettings {
- tab_size: Some(4.try_into().unwrap()),
- ..Default::default()
- },
- )
- .with_language_defaults(
- "JavaScript",
- settings::LanguageSettings {
- tab_size: Some(2.try_into().unwrap()),
- ..Default::default()
- },
- )
- .with_language_defaults(
- "TypeScript",
- settings::LanguageSettings {
- tab_size: Some(2.try_into().unwrap()),
- ..Default::default()
- },
- )
- .with_language_defaults(
- "TSX",
- settings::LanguageSettings {
- tab_size: Some(2.try_into().unwrap()),
- ..Default::default()
- },
- );
+ let default_settings = Settings::defaults(Assets, &app.font_cache(), &themes);
let config_files = load_config_files(&app, fs.clone());
@@ -26,6 +26,10 @@ pub fn menus() -> Vec<Menu<'static>> {
name: "Open Key Bindings",
action: Box::new(super::OpenKeymap),
},
+ MenuItem::Action {
+ name: "Open Default Settings",
+ action: Box::new(super::OpenDefaultSettings),
+ },
MenuItem::Action {
name: "Open Default Key Bindings",
action: Box::new(super::OpenDefaultKeymap),
@@ -93,7 +93,7 @@ pub async fn watch_keymap_file(
mod tests {
use super::*;
use project::FakeFs;
- use settings::{LanguageSettings, SoftWrap};
+ use settings::{EditorSettings, SoftWrap};
#[gpui::test]
async fn test_settings_from_files(cx: &mut gpui::TestAppContext) {
@@ -128,7 +128,7 @@ mod tests {
let settings = cx.read(Settings::test).with_language_defaults(
"JavaScript",
- LanguageSettings {
+ EditorSettings {
tab_size: Some(2.try_into().unwrap()),
..Default::default()
},
@@ -18,8 +18,9 @@ use gpui::{
geometry::vector::vec2f,
impl_actions,
platform::{WindowBounds, WindowOptions},
- AsyncAppContext, ViewContext,
+ AssetSource, AsyncAppContext, ViewContext,
};
+use language::Rope;
use lazy_static::lazy_static;
pub use lsp;
pub use project::{self, fs};
@@ -52,6 +53,7 @@ actions!(
DebugElements,
OpenSettings,
OpenKeymap,
+ OpenDefaultSettings,
OpenDefaultKeymap,
IncreaseBufferFontSize,
DecreaseBufferFontSize,
@@ -99,39 +101,48 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
cx.add_action({
let app_state = app_state.clone();
move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext<Workspace>| {
- open_config_file(&SETTINGS_PATH, app_state.clone(), cx);
+ open_config_file(&SETTINGS_PATH, app_state.clone(), cx, || {
+ let header = Assets.load("settings/header-comments.json").unwrap();
+ let json = Assets.load("settings/default.json").unwrap();
+ let header = str::from_utf8(header.as_ref()).unwrap();
+ let json = str::from_utf8(json.as_ref()).unwrap();
+ let mut content = Rope::new();
+ content.push(header);
+ content.push(json);
+ content
+ });
}
});
cx.add_action({
let app_state = app_state.clone();
move |_: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext<Workspace>| {
- open_config_file(&KEYMAP_PATH, app_state.clone(), cx);
+ open_config_file(&KEYMAP_PATH, app_state.clone(), cx, || Default::default());
}
});
cx.add_action({
let app_state = app_state.clone();
move |workspace: &mut Workspace, _: &OpenDefaultKeymap, cx: &mut ViewContext<Workspace>| {
- workspace.with_local_workspace(cx, app_state.clone(), |workspace, cx| {
- let project = workspace.project().clone();
- let buffer = project.update(cx, |project, cx| {
- let text = Assets::get("keymaps/default.json").unwrap().data;
- let text = str::from_utf8(text.as_ref()).unwrap();
- project
- .create_buffer(text, project.languages().get_language("JSON"), cx)
- .expect("creating buffers on a local workspace always succeeds")
- });
- let buffer = cx.add_model(|cx| {
- MultiBuffer::singleton(buffer, cx).with_title("Default Key Bindings".into())
- });
- workspace.add_item(
- Box::new(
- cx.add_view(|cx| {
- Editor::for_multibuffer(buffer, Some(project.clone()), cx)
- }),
- ),
- cx,
- );
- });
+ open_bundled_config_file(
+ workspace,
+ app_state.clone(),
+ "keymaps/default.json",
+ "Default Key Bindings",
+ cx,
+ );
+ }
+ });
+ cx.add_action({
+ let app_state = app_state.clone();
+ move |workspace: &mut Workspace,
+ _: &OpenDefaultSettings,
+ cx: &mut ViewContext<Workspace>| {
+ open_bundled_config_file(
+ workspace,
+ app_state.clone(),
+ "settings/default.json",
+ "Default Settings",
+ cx,
+ );
}
});
cx.add_action(
@@ -366,12 +377,15 @@ fn open_config_file(
path: &'static Path,
app_state: Arc<AppState>,
cx: &mut ViewContext<Workspace>,
+ default_content: impl 'static + Send + FnOnce() -> Rope,
) {
cx.spawn(|workspace, mut cx| async move {
let fs = &app_state.fs;
if !fs.is_file(path).await {
fs.create_dir(&ROOT_PATH).await?;
fs.create_file(path, Default::default()).await?;
+ fs.save(path, &default_content(), Default::default())
+ .await?;
}
workspace
@@ -386,6 +400,30 @@ fn open_config_file(
.detach_and_log_err(cx)
}
+fn open_bundled_config_file(
+ workspace: &mut Workspace,
+ app_state: Arc<AppState>,
+ asset_path: &'static str,
+ title: &str,
+ cx: &mut ViewContext<Workspace>,
+) {
+ workspace.with_local_workspace(cx, app_state.clone(), |workspace, cx| {
+ let project = workspace.project().clone();
+ let buffer = project.update(cx, |project, cx| {
+ let text = Assets::get(asset_path).unwrap().data;
+ let text = str::from_utf8(text.as_ref()).unwrap();
+ project
+ .create_buffer(text, project.languages().get_language("JSON"), cx)
+ .expect("creating buffers on a local workspace always succeeds")
+ });
+ let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx).with_title(title.into()));
+ workspace.add_item(
+ Box::new(cx.add_view(|cx| Editor::for_multibuffer(buffer, Some(project.clone()), cx))),
+ cx,
+ );
+ });
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -400,7 +438,7 @@ mod tests {
collections::HashSet,
path::{Path, PathBuf},
};
- use theme::{Theme, ThemeRegistry, DEFAULT_THEME_NAME};
+ use theme::ThemeRegistry;
use workspace::{
open_paths, pane, Item, ItemHandle, NewFile, Pane, SplitDirection, WorkspaceHandle,
};
@@ -1530,23 +1568,29 @@ mod tests {
}
#[gpui::test]
- fn test_bundled_themes(cx: &mut MutableAppContext) {
+ fn test_bundled_settings_and_themes(cx: &mut MutableAppContext) {
+ cx.platform()
+ .fonts()
+ .add_fonts(&[
+ Assets
+ .load("fonts/zed-sans/zed-sans-extended.ttf")
+ .unwrap()
+ .to_vec()
+ .into(),
+ Assets
+ .load("fonts/zed-mono/zed-mono-extended.ttf")
+ .unwrap()
+ .to_vec()
+ .into(),
+ ])
+ .unwrap();
let themes = ThemeRegistry::new(Assets, cx.font_cache().clone());
-
- lazy_static::lazy_static! {
- static ref DEFAULT_THEME: parking_lot::Mutex<Option<Arc<Theme>>> = Default::default();
- static ref FONTS: Vec<Arc<Vec<u8>>> = vec![
- Assets.load("fonts/zed-sans/zed-sans-extended.ttf").unwrap().to_vec().into(),
- Assets.load("fonts/zed-mono/zed-mono-extended.ttf").unwrap().to_vec().into(),
- ];
- }
-
- cx.platform().fonts().add_fonts(&FONTS).unwrap();
+ let settings = Settings::defaults(Assets, cx.font_cache(), &themes);
let mut has_default_theme = false;
for theme_name in themes.list() {
let theme = themes.get(&theme_name).unwrap();
- if theme.name == DEFAULT_THEME_NAME {
+ if theme.name == settings.theme.name {
has_default_theme = true;
}
assert_eq!(theme.name, theme_name);