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}