keymap_file.rs

 1use anyhow::{Context, Result};
 2use assets::Assets;
 3use collections::BTreeMap;
 4use gpui::{keymap::Binding, MutableAppContext};
 5use serde::Deserialize;
 6use serde_json::value::RawValue;
 7
 8#[derive(Deserialize)]
 9struct ActionWithData<'a>(#[serde(borrow)] &'a str, #[serde(borrow)] &'a RawValue);
10type ActionSetsByContext<'a> = BTreeMap<&'a str, ActionsByKeystroke<'a>>;
11type ActionsByKeystroke<'a> = BTreeMap<&'a str, &'a RawValue>;
12
13pub fn load_built_in_keymaps(cx: &mut MutableAppContext) {
14    for path in ["keymaps/default.json", "keymaps/vim.json"] {
15        load_keymap(
16            cx,
17            std::str::from_utf8(Assets::get(path).unwrap().data.as_ref()).unwrap(),
18        )
19        .unwrap();
20    }
21}
22
23pub fn load_keymap(cx: &mut MutableAppContext, content: &str) -> Result<()> {
24    let actions: ActionSetsByContext = serde_json::from_str(content)?;
25    for (context, actions) in actions {
26        let context = if context.is_empty() {
27            None
28        } else {
29            Some(context)
30        };
31        cx.add_bindings(
32            actions
33                .into_iter()
34                .map(|(keystroke, action)| {
35                    let action = action.get();
36                    let action = if action.starts_with('[') {
37                        let ActionWithData(name, data) = serde_json::from_str(action)?;
38                        cx.deserialize_action(name, Some(data.get()))
39                    } else {
40                        let name = serde_json::from_str(action)?;
41                        cx.deserialize_action(name, None)
42                    }
43                    .with_context(|| {
44                        format!(
45                            "invalid binding value for keystroke {keystroke}, context {context:?}"
46                        )
47                    })?;
48                    Binding::load(keystroke, action, context)
49                })
50                .collect::<Result<Vec<_>>>()?,
51        )
52    }
53    Ok(())
54}