base_keymap_setting.rs

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