diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index b40a076c49..7b059652fa 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -425,12 +425,5 @@ "cmd-v": "terminal::Paste", "cmd-k": "terminal::Clear" } - }, - { - "context": "ModalTerminal", - "bindings": { - "ctrl-cmd-space": "terminal::ShowCharacterPalette", - "shift-escape": "terminal::DeployModal" - } } ] \ No newline at end of file diff --git a/assets/keymaps/experiments/modal_terminal.json b/assets/keymaps/experiments/modal_terminal.json new file mode 100644 index 0000000000..427f3e1a70 --- /dev/null +++ b/assets/keymaps/experiments/modal_terminal.json @@ -0,0 +1,9 @@ +[ + { + "context": "ModalTerminal", + "bindings": { + "ctrl-cmd-space": "terminal::ShowCharacterPalette", + "shift-escape": "terminal::DeployModal" + } + } +] \ No newline at end of file diff --git a/crates/settings/src/keymap_file.rs b/crates/settings/src/keymap_file.rs index c1d5db32bb..c7cff92721 100644 --- a/crates/settings/src/keymap_file.rs +++ b/crates/settings/src/keymap_file.rs @@ -1,4 +1,4 @@ -use crate::parse_json_with_comments; +use crate::{parse_json_with_comments, Settings}; use anyhow::{Context, Result}; use assets::Assets; use collections::BTreeMap; @@ -10,6 +10,7 @@ use schemars::{ }; use serde::Deserialize; use serde_json::{value::RawValue, Value}; +use util::ResultExt; #[derive(Deserialize, Default, Clone, JsonSchema)] #[serde(transparent)] @@ -41,7 +42,9 @@ struct ActionWithData(Box, Box); impl KeymapFileContent { pub fn load_defaults(cx: &mut MutableAppContext) { - for path in ["keymaps/default.json", "keymaps/vim.json"] { + let mut paths = vec!["keymaps/default.json", "keymaps/vim.json"]; + paths.extend(cx.global::().experiments.keymap_files()); + for path in paths { Self::load(path, cx).unwrap(); } } @@ -56,26 +59,27 @@ impl KeymapFileContent { for KeymapBlock { context, bindings } in self.0 { let bindings = bindings .into_iter() - .map(|(keystroke, action)| { + .filter_map(|(keystroke, action)| { let action = action.0.get(); // This is a workaround for a limitation in serde: serde-rs/json#497 // We want to deserialize the action data as a `RawValue` so that we can // deserialize the action itself dynamically directly from the JSON // string. But `RawValue` currently does not work inside of an untagged enum. - let action = if action.starts_with('[') { - let ActionWithData(name, data) = serde_json::from_str(action)?; + if action.starts_with('[') { + let ActionWithData(name, data) = serde_json::from_str(action).log_err()?; cx.deserialize_action(&name, Some(data.get())) } else { - let name = serde_json::from_str(action)?; + let name = serde_json::from_str(action).log_err()?; cx.deserialize_action(name, None) } .with_context(|| { format!( "invalid binding value for keystroke {keystroke}, context {context:?}" ) - })?; - Binding::load(&keystroke, action, context.as_deref()) + }) + .log_err() + .map(|action| Binding::load(&keystroke, action, context.as_deref())) }) .collect::>>()?; diff --git a/crates/settings/src/settings.rs b/crates/settings/src/settings.rs index 2b97cb0b10..1ac1bf0cc3 100644 --- a/crates/settings/src/settings.rs +++ b/crates/settings/src/settings.rs @@ -20,6 +20,7 @@ pub use keymap_file::{keymap_file_json_schema, KeymapFileContent}; #[derive(Clone)] pub struct Settings { + pub experiments: FeatureFlags, pub projects_online_by_default: bool, pub buffer_font_family: FamilyId, pub default_buffer_font_size: f32, @@ -38,6 +39,25 @@ pub struct Settings { pub theme: Arc, } +#[derive(Copy, Clone, Debug, Default, Deserialize, JsonSchema)] +pub struct FeatureFlags { + modal_terminal: Option, +} + +impl FeatureFlags { + pub fn keymap_files(&self) -> Vec<&'static str> { + let mut res = vec![]; + if self.modal_terminal() { + res.push("keymaps/experiments/modal_terminal.json") + } + res + } + + pub fn modal_terminal(&self) -> bool { + self.modal_terminal.unwrap_or_default() + } +} + #[derive(Clone, Debug, Default, Deserialize, JsonSchema)] pub struct EditorSettings { pub tab_size: Option, @@ -139,6 +159,7 @@ pub enum WorkingDirectory { #[derive(Clone, Debug, Default, Deserialize, JsonSchema)] pub struct SettingsFileContent { + pub experiments: Option, #[serde(default)] pub projects_online_by_default: Option, #[serde(default)] @@ -189,6 +210,7 @@ impl Settings { .unwrap(); Self { + experiments: FeatureFlags::default(), buffer_font_family: font_cache .load_family(&[defaults.buffer_font_family.as_ref().unwrap()]) .unwrap(), @@ -247,6 +269,7 @@ impl Settings { ); merge(&mut self.vim_mode, data.vim_mode); merge(&mut self.autosave, data.autosave); + merge(&mut self.experiments, data.experiments); // Ensure terminal font is loaded, so we can request it in terminal_element layout if let Some(terminal_font) = &data.terminal.font_family { @@ -308,6 +331,7 @@ impl Settings { #[cfg(any(test, feature = "test-support"))] pub fn test(cx: &gpui::AppContext) -> Settings { Settings { + experiments: FeatureFlags::default(), buffer_font_family: cx.font_cache().load_family(&["Monaco"]).unwrap(), buffer_font_size: 14., default_buffer_font_size: 14., diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 25e952d591..134e5af7cc 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -46,7 +46,10 @@ use crate::mappings::{ ///Initialize and register all of our action handlers pub fn init(cx: &mut MutableAppContext) { - cx.add_action(deploy_modal); + let settings = cx.global::(); + if settings.experiments.modal_terminal() { + cx.add_action(deploy_modal); + } terminal_view::init(cx); connected_view::init(cx); diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index aa2f0b7ada..0bec005998 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -95,6 +95,11 @@ fn main() { .spawn(languages::init(languages.clone(), cx.background().clone())); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx)); + let (settings_file, keymap_file) = cx.background().block(config_files).unwrap(); + + watch_settings_file(default_settings, settings_file, themes.clone(), cx); + watch_keymap_file(keymap_file, cx); + context_menu::init(cx); project::Project::init(&client); client::Channel::init(&client); @@ -114,10 +119,6 @@ fn main() { terminal::init(cx); let db = cx.background().block(db); - let (settings_file, keymap_file) = cx.background().block(config_files).unwrap(); - - watch_settings_file(default_settings, settings_file, themes.clone(), cx); - watch_keymap_file(keymap_file, cx); cx.spawn(|cx| watch_themes(fs.clone(), themes.clone(), cx)) .detach();