base_keymap_setting.rs

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