@@ -54,10 +54,151 @@ impl SettingsFile {
#[cfg(test)]
mod tests {
use super::*;
- use crate::{watched_json::watch_settings_file, EditorSettings, Settings, SoftWrap};
+ use crate::{
+ watch_files, watched_json::watch_settings_file, EditorSettings, Settings, SoftWrap,
+ };
use fs::FakeFs;
+ use gpui::{actions, Action};
use theme::ThemeRegistry;
+ #[gpui::test]
+ async fn test_base_keymap(cx: &mut gpui::TestAppContext) {
+ let executor = cx.background();
+ let fs = FakeFs::new(executor.clone());
+ let font_cache = cx.font_cache();
+
+ actions!(test, [A, B]);
+ // From the Atom keymap
+ actions!(workspace, [ActivatePreviousPane]);
+ // From the JetBrains keymap
+ actions!(pane, [ActivatePrevItem]);
+
+ fs.save(
+ "/settings.json".as_ref(),
+ &r#"
+ {
+ "base_keymap": "Atom"
+ }
+ "#
+ .into(),
+ Default::default(),
+ )
+ .await
+ .unwrap();
+
+ fs.save(
+ "/keymap.json".as_ref(),
+ &r#"
+ [
+ {
+ "bindings": {
+ "backspace": "test::A"
+ }
+ }
+ ]
+ "#
+ .into(),
+ Default::default(),
+ )
+ .await
+ .unwrap();
+
+ let settings_file =
+ WatchedJsonFile::new(fs.clone(), &executor, "/settings.json".as_ref()).await;
+ let keymaps_file =
+ WatchedJsonFile::new(fs.clone(), &executor, "/keymap.json".as_ref()).await;
+
+ let default_settings = cx.read(Settings::test);
+
+ cx.update(|cx| {
+ cx.add_global_action(|_: &A, _cx| {
+ });
+ cx.add_global_action(|_: &B, _cx| {
+ });
+ cx.add_global_action(|_: &ActivatePreviousPane, _cx| {
+ });
+ cx.add_global_action(|_: &ActivatePrevItem, _cx| {
+ });
+ watch_files(
+ default_settings,
+ settings_file,
+ ThemeRegistry::new((), font_cache),
+ keymaps_file,
+ cx,
+ )
+ });
+
+ cx.foreground().run_until_parked();
+
+ // Test loading the keymap base at all
+ cx.update(|cx| {
+ assert_keybindings_for(cx, vec![("backspace", &A), ("k", &ActivatePreviousPane)], line!());
+ });
+
+ // Test modifying the users keymap, while retaining the base keymap
+ fs.save(
+ "/keymap.json".as_ref(),
+ &r#"
+ [
+ {
+ "bindings": {
+ "backspace": "test::B"
+ }
+ }
+ ]
+ "#
+ .into(),
+ Default::default(),
+ )
+ .await
+ .unwrap();
+
+ cx.foreground().run_until_parked();
+
+ cx.update(|cx| {
+ assert_keybindings_for(cx, vec![("backspace", &B), ("k", &ActivatePreviousPane)], line!());
+ });
+
+ // Test modifying the base, while retaining the users keymap
+ fs.save(
+ "/settings.json".as_ref(),
+ &r#"
+ {
+ "base_keymap": "JetBrains"
+ }
+ "#
+ .into(),
+ Default::default(),
+ )
+ .await
+ .unwrap();
+
+ cx.foreground().run_until_parked();
+
+ cx.update(|cx| {
+ assert_keybindings_for(cx, vec![("backspace", &B), ("[", &ActivatePrevItem)], line!());
+ });
+ }
+
+ fn assert_keybindings_for<'a>(
+ cx: &mut MutableAppContext,
+ actions: Vec<(&'static str, &'a dyn Action)>,
+ line: u32,
+ ) {
+
+ for (key, action) in actions {
+ // assert that...
+ assert!(cx.available_actions(0, 0).any(|(_, bound_action, b)| {
+ // action names match...
+ bound_action.name() == action.name()
+ && bound_action.namespace() == action.namespace()
+ // and key strokes contain the given key
+ && b.iter()
+ .any(|binding| binding.keystrokes().iter().any(|k| k.key == key))
+ }), "On {} Failed to find {} with keybinding {}", line, action.name(), key);
+ }
+ }
+
#[gpui::test]
async fn test_watch_settings_files(cx: &mut gpui::TestAppContext) {
let executor = cx.background();