base_keymap_setting.rs

  1use std::fmt::{Display, Formatter};
  2
  3use crate::{Settings, SettingsSources, VsCodeSettings};
  4use schemars::JsonSchema;
  5use serde::{Deserialize, Serialize};
  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    Emacs,
 19    Cursor,
 20    None,
 21}
 22
 23impl Display for BaseKeymap {
 24    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
 25        match self {
 26            BaseKeymap::VSCode => write!(f, "VSCode"),
 27            BaseKeymap::JetBrains => write!(f, "JetBrains"),
 28            BaseKeymap::SublimeText => write!(f, "Sublime Text"),
 29            BaseKeymap::Atom => write!(f, "Atom"),
 30            BaseKeymap::TextMate => write!(f, "TextMate"),
 31            BaseKeymap::Emacs => write!(f, "Emacs (beta)"),
 32            BaseKeymap::Cursor => write!(f, "Cursor (beta)"),
 33            BaseKeymap::None => write!(f, "None"),
 34        }
 35    }
 36}
 37
 38impl BaseKeymap {
 39    #[cfg(target_os = "macos")]
 40    pub const OPTIONS: [(&'static str, Self); 7] = [
 41        ("VSCode (Default)", Self::VSCode),
 42        ("Atom", Self::Atom),
 43        ("JetBrains", Self::JetBrains),
 44        ("Sublime Text", Self::SublimeText),
 45        ("Emacs (beta)", Self::Emacs),
 46        ("TextMate", Self::TextMate),
 47        ("Cursor", Self::Cursor),
 48    ];
 49
 50    #[cfg(not(target_os = "macos"))]
 51    pub const OPTIONS: [(&'static str, Self); 6] = [
 52        ("VSCode (Default)", Self::VSCode),
 53        ("Atom", Self::Atom),
 54        ("JetBrains", Self::JetBrains),
 55        ("Sublime Text", Self::SublimeText),
 56        ("Emacs (beta)", Self::Emacs),
 57        ("Cursor", Self::Cursor),
 58    ];
 59
 60    pub fn asset_path(&self) -> Option<&'static str> {
 61        #[cfg(target_os = "macos")]
 62        match self {
 63            BaseKeymap::JetBrains => Some("keymaps/macos/jetbrains.json"),
 64            BaseKeymap::SublimeText => Some("keymaps/macos/sublime_text.json"),
 65            BaseKeymap::Atom => Some("keymaps/macos/atom.json"),
 66            BaseKeymap::TextMate => Some("keymaps/macos/textmate.json"),
 67            BaseKeymap::Emacs => Some("keymaps/macos/emacs.json"),
 68            BaseKeymap::Cursor => Some("keymaps/macos/cursor.json"),
 69            BaseKeymap::VSCode => None,
 70            BaseKeymap::None => None,
 71        }
 72
 73        #[cfg(not(target_os = "macos"))]
 74        match self {
 75            BaseKeymap::JetBrains => Some("keymaps/linux/jetbrains.json"),
 76            BaseKeymap::SublimeText => Some("keymaps/linux/sublime_text.json"),
 77            BaseKeymap::Atom => Some("keymaps/linux/atom.json"),
 78            BaseKeymap::Emacs => Some("keymaps/linux/emacs.json"),
 79            BaseKeymap::Cursor => Some("keymaps/linux/cursor.json"),
 80            BaseKeymap::TextMate => None,
 81            BaseKeymap::VSCode => None,
 82            BaseKeymap::None => None,
 83        }
 84    }
 85
 86    pub fn names() -> impl Iterator<Item = &'static str> {
 87        Self::OPTIONS.iter().map(|(name, _)| *name)
 88    }
 89
 90    pub fn from_names(option: &str) -> BaseKeymap {
 91        Self::OPTIONS
 92            .iter()
 93            .copied()
 94            .find_map(|(name, value)| (name == option).then_some(value))
 95            .unwrap_or_default()
 96    }
 97}
 98
 99impl Settings for BaseKeymap {
100    const KEY: Option<&'static str> = Some("base_keymap");
101
102    type FileContent = Option<Self>;
103
104    fn load(
105        sources: SettingsSources<Self::FileContent>,
106        _: &mut gpui::App,
107    ) -> anyhow::Result<Self> {
108        if let Some(Some(user_value)) = sources.user.copied() {
109            return Ok(user_value);
110        }
111        if let Some(Some(server_value)) = sources.server.copied() {
112            return Ok(server_value);
113        }
114        sources.default.ok_or_else(Self::missing_default)
115    }
116
117    fn import_from_vscode(_vscode: &VsCodeSettings, current: &mut Self::FileContent) {
118        *current = Some(BaseKeymap::VSCode);
119    }
120}