1use std::fmt::{Display, Formatter};
2
3use crate::{
4 self as settings,
5 settings_content::{BaseKeymapContent, SettingsContent},
6};
7use gpui::App;
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use settings::{Settings, VsCodeSettings};
11
12/// Base key bindings scheme. Base keymaps can be overridden with user keymaps.
13///
14/// Default: VSCode
15#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
16pub enum BaseKeymap {
17 #[default]
18 VSCode,
19 JetBrains,
20 SublimeText,
21 Atom,
22 TextMate,
23 Emacs,
24 Cursor,
25 None,
26}
27
28impl From<BaseKeymapContent> for BaseKeymap {
29 fn from(value: BaseKeymapContent) -> Self {
30 match value {
31 BaseKeymapContent::VSCode => Self::VSCode,
32 BaseKeymapContent::JetBrains => Self::JetBrains,
33 BaseKeymapContent::SublimeText => Self::SublimeText,
34 BaseKeymapContent::Atom => Self::Atom,
35 BaseKeymapContent::TextMate => Self::TextMate,
36 BaseKeymapContent::Emacs => Self::Emacs,
37 BaseKeymapContent::Cursor => Self::Cursor,
38 BaseKeymapContent::None => Self::None,
39 }
40 }
41}
42impl Into<BaseKeymapContent> for BaseKeymap {
43 fn into(self) -> BaseKeymapContent {
44 match self {
45 BaseKeymap::VSCode => BaseKeymapContent::VSCode,
46 BaseKeymap::JetBrains => BaseKeymapContent::JetBrains,
47 BaseKeymap::SublimeText => BaseKeymapContent::SublimeText,
48 BaseKeymap::Atom => BaseKeymapContent::Atom,
49 BaseKeymap::TextMate => BaseKeymapContent::TextMate,
50 BaseKeymap::Emacs => BaseKeymapContent::Emacs,
51 BaseKeymap::Cursor => BaseKeymapContent::Cursor,
52 BaseKeymap::None => BaseKeymapContent::None,
53 }
54 }
55}
56
57impl Display for BaseKeymap {
58 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
59 match self {
60 BaseKeymap::VSCode => write!(f, "VSCode"),
61 BaseKeymap::JetBrains => write!(f, "JetBrains"),
62 BaseKeymap::SublimeText => write!(f, "Sublime Text"),
63 BaseKeymap::Atom => write!(f, "Atom"),
64 BaseKeymap::TextMate => write!(f, "TextMate"),
65 BaseKeymap::Emacs => write!(f, "Emacs (beta)"),
66 BaseKeymap::Cursor => write!(f, "Cursor (beta)"),
67 BaseKeymap::None => write!(f, "None"),
68 }
69 }
70}
71
72impl BaseKeymap {
73 #[cfg(target_os = "macos")]
74 pub const OPTIONS: [(&'static str, Self); 7] = [
75 ("VSCode (Default)", Self::VSCode),
76 ("Atom", Self::Atom),
77 ("JetBrains", Self::JetBrains),
78 ("Sublime Text", Self::SublimeText),
79 ("Emacs (beta)", Self::Emacs),
80 ("TextMate", Self::TextMate),
81 ("Cursor", Self::Cursor),
82 ];
83
84 #[cfg(not(target_os = "macos"))]
85 pub const OPTIONS: [(&'static str, Self); 6] = [
86 ("VSCode (Default)", Self::VSCode),
87 ("Atom", Self::Atom),
88 ("JetBrains", Self::JetBrains),
89 ("Sublime Text", Self::SublimeText),
90 ("Emacs (beta)", Self::Emacs),
91 ("Cursor", Self::Cursor),
92 ];
93
94 pub fn asset_path(&self) -> Option<&'static str> {
95 #[cfg(target_os = "macos")]
96 match self {
97 BaseKeymap::JetBrains => Some("keymaps/macos/jetbrains.json"),
98 BaseKeymap::SublimeText => Some("keymaps/macos/sublime_text.json"),
99 BaseKeymap::Atom => Some("keymaps/macos/atom.json"),
100 BaseKeymap::TextMate => Some("keymaps/macos/textmate.json"),
101 BaseKeymap::Emacs => Some("keymaps/macos/emacs.json"),
102 BaseKeymap::Cursor => Some("keymaps/macos/cursor.json"),
103 BaseKeymap::VSCode => None,
104 BaseKeymap::None => None,
105 }
106
107 #[cfg(not(target_os = "macos"))]
108 match self {
109 BaseKeymap::JetBrains => Some("keymaps/linux/jetbrains.json"),
110 BaseKeymap::SublimeText => Some("keymaps/linux/sublime_text.json"),
111 BaseKeymap::Atom => Some("keymaps/linux/atom.json"),
112 BaseKeymap::Emacs => Some("keymaps/linux/emacs.json"),
113 BaseKeymap::Cursor => Some("keymaps/linux/cursor.json"),
114 BaseKeymap::TextMate => None,
115 BaseKeymap::VSCode => None,
116 BaseKeymap::None => None,
117 }
118 }
119
120 pub fn names() -> impl Iterator<Item = &'static str> {
121 Self::OPTIONS.iter().map(|(name, _)| *name)
122 }
123
124 pub fn from_names(option: &str) -> BaseKeymap {
125 Self::OPTIONS
126 .iter()
127 .copied()
128 .find_map(|(name, value)| (name == option).then_some(value))
129 .unwrap_or_default()
130 }
131}
132
133impl Settings for BaseKeymap {
134 fn from_settings(s: &crate::settings_content::SettingsContent, _cx: &mut App) -> Self {
135 s.base_keymap.unwrap().into()
136 }
137
138 fn import_from_vscode(_vscode: &VsCodeSettings, current: &mut SettingsContent) {
139 current.base_keymap = Some(BaseKeymapContent::VSCode);
140 }
141}