keymap_file.rs

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