1use std::fmt::{Display, Formatter};
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5use settings::{Settings, SettingsSources};
6
7/// Base key bindings scheme. Base keymaps can be overridden with user keymaps.
8///
9/// Default: VSCode
10#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
11pub enum BaseKeymap {
12 #[default]
13 VSCode,
14 JetBrains,
15 SublimeText,
16 Atom,
17 TextMate,
18 None,
19}
20
21impl Display for BaseKeymap {
22 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
23 match self {
24 BaseKeymap::VSCode => write!(f, "VSCode"),
25 BaseKeymap::JetBrains => write!(f, "JetBrains"),
26 BaseKeymap::SublimeText => write!(f, "Sublime Text"),
27 BaseKeymap::Atom => write!(f, "Atom"),
28 BaseKeymap::TextMate => write!(f, "TextMate"),
29 BaseKeymap::None => write!(f, "None"),
30 }
31 }
32}
33
34impl BaseKeymap {
35 #[cfg(target_os = "macos")]
36 pub const OPTIONS: [(&'static str, Self); 5] = [
37 ("VSCode (Default)", Self::VSCode),
38 ("Atom", Self::Atom),
39 ("JetBrains", Self::JetBrains),
40 ("Sublime Text", Self::SublimeText),
41 ("TextMate", Self::TextMate),
42 ];
43
44 #[cfg(not(target_os = "macos"))]
45 pub const OPTIONS: [(&'static str, Self); 4] = [
46 ("VSCode (Default)", Self::VSCode),
47 ("Atom", Self::Atom),
48 ("JetBrains", Self::JetBrains),
49 ("Sublime Text", Self::SublimeText),
50 ];
51
52 pub fn asset_path(&self) -> Option<&'static str> {
53 #[cfg(target_os = "macos")]
54 match self {
55 BaseKeymap::JetBrains => Some("keymaps/macos/jetbrains.json"),
56 BaseKeymap::SublimeText => Some("keymaps/macos/sublime_text.json"),
57 BaseKeymap::Atom => Some("keymaps/macos/atom.json"),
58 BaseKeymap::TextMate => Some("keymaps/macos/textmate.json"),
59 BaseKeymap::VSCode => None,
60 BaseKeymap::None => None,
61 }
62
63 #[cfg(not(target_os = "macos"))]
64 match self {
65 BaseKeymap::JetBrains => Some("keymaps/linux/jetbrains.json"),
66 BaseKeymap::SublimeText => Some("keymaps/linux/sublime_text.json"),
67 BaseKeymap::Atom => Some("keymaps/linux/atom.json"),
68 BaseKeymap::TextMate => None,
69 BaseKeymap::VSCode => None,
70 BaseKeymap::None => None,
71 }
72 }
73
74 pub fn names() -> impl Iterator<Item = &'static str> {
75 Self::OPTIONS.iter().map(|(name, _)| *name)
76 }
77
78 pub fn from_names(option: &str) -> BaseKeymap {
79 Self::OPTIONS
80 .iter()
81 .copied()
82 .find_map(|(name, value)| (name == option).then_some(value))
83 .unwrap_or_default()
84 }
85}
86
87impl Settings for BaseKeymap {
88 const KEY: Option<&'static str> = Some("base_keymap");
89
90 type FileContent = Option<Self>;
91
92 fn load(
93 sources: SettingsSources<Self::FileContent>,
94 _: &mut gpui::AppContext,
95 ) -> anyhow::Result<Self> {
96 if let Some(Some(user_value)) = sources.user.copied() {
97 return Ok(user_value);
98 }
99 if let Some(Some(server_value)) = sources.server.copied() {
100 return Ok(server_value);
101 }
102 sources.default.ok_or_else(Self::missing_default)
103 }
104}