cosmic-edit/src/config.rs

152 lines
4.3 KiB
Rust
Raw Normal View History

2023-11-03 16:16:24 -06:00
use cosmic::{
cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, CosmicConfigEntry},
iced::keyboard::{KeyCode, Modifiers},
};
2023-11-03 15:58:26 -06:00
use cosmic_text::Metrics;
2023-11-03 16:16:24 -06:00
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fmt};
use crate::{ContextPage, Message};
2023-11-03 18:45:03 -06:00
pub const CONFIG_VERSION: u64 = 1;
2023-11-03 16:16:24 -06:00
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub enum Action {
Copy,
2023-11-06 09:41:29 -07:00
Cut,
2023-11-03 16:16:24 -06:00
NewFile,
NewWindow,
OpenFileDialog,
2023-11-06 09:41:29 -07:00
Paste,
2023-11-03 16:16:24 -06:00
Quit,
2023-11-06 09:41:29 -07:00
Save,
SelectAll,
2023-11-03 16:16:24 -06:00
ToggleSettingsPage,
ToggleWordWrap,
}
impl Action {
pub fn message(&self) -> Message {
match self {
Self::Copy => Message::Copy,
2023-11-06 09:41:29 -07:00
Self::Cut => Message::Cut,
2023-11-03 16:16:24 -06:00
Self::NewFile => Message::NewFile,
Self::NewWindow => Message::NewWindow,
Self::OpenFileDialog => Message::OpenFileDialog,
2023-11-06 09:41:29 -07:00
Self::Paste => Message::Paste,
2023-11-03 16:16:24 -06:00
Self::Quit => Message::Quit,
2023-11-06 09:41:29 -07:00
Self::Save => Message::Save,
Self::SelectAll => Message::SelectAll,
2023-11-03 16:16:24 -06:00
Self::ToggleSettingsPage => Message::ToggleContextPage(ContextPage::Settings),
Self::ToggleWordWrap => Message::ToggleWordWrap,
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub enum Modifier {
Super,
Ctrl,
Alt,
Shift,
}
2023-11-01 08:50:05 -06:00
2023-11-03 16:16:24 -06:00
#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub struct KeyBind {
2023-11-03 16:16:24 -06:00
pub modifiers: Vec<Modifier>,
pub key_code: KeyCode,
}
impl KeyBind {
//TODO: load from config
2023-11-03 16:16:24 -06:00
pub fn load() -> HashMap<KeyBind, Action> {
let mut keybinds = HashMap::new();
macro_rules! bind {
2023-11-03 16:16:24 -06:00
([$($modifier:ident),+ $(,)?], $key_code:ident, $action:ident) => {{
keybinds.insert(
KeyBind {
2023-11-03 16:16:24 -06:00
modifiers: vec![$(Modifier::$modifier),+],
key_code: KeyCode::$key_code,
},
2023-11-03 16:16:24 -06:00
Action::$action,
);
}};
}
2023-11-03 16:16:24 -06:00
bind!([Ctrl], X, Cut);
bind!([Ctrl], C, Copy);
bind!([Ctrl], V, Paste);
bind!([Ctrl], N, NewFile);
bind!([Ctrl, Shift], N, NewWindow);
bind!([Ctrl], O, OpenFileDialog);
bind!([Ctrl], Q, Quit);
2023-11-06 09:41:29 -07:00
bind!([Ctrl], S, Save);
bind!([Ctrl], A, SelectAll);
2023-11-03 16:16:24 -06:00
bind!([Ctrl], Comma, ToggleSettingsPage);
bind!([Alt], Z, ToggleWordWrap);
keybinds
}
2023-11-03 16:16:24 -06:00
pub fn matches(&self, modifiers: Modifiers, key_code: KeyCode) -> bool {
self.key_code == key_code
&& modifiers.logo() == self.modifiers.contains(&Modifier::Super)
&& modifiers.control() == self.modifiers.contains(&Modifier::Ctrl)
&& modifiers.alt() == self.modifiers.contains(&Modifier::Alt)
&& modifiers.shift() == self.modifiers.contains(&Modifier::Shift)
}
}
impl fmt::Display for KeyBind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2023-11-03 16:16:24 -06:00
for modifier in self.modifiers.iter() {
write!(f, "{:?} + ", modifier)?;
}
write!(f, "{:?}", self.key_code)
}
}
2023-11-03 16:16:24 -06:00
#[derive(Clone, CosmicConfigEntry, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Config {
2023-11-03 19:00:41 -06:00
pub font_name: String,
2023-11-03 15:58:26 -06:00
pub font_size: u16,
pub syntax_theme_dark: String,
pub syntax_theme_light: String,
pub vim_bindings: bool,
2023-11-01 09:44:11 -06:00
pub word_wrap: bool,
2023-11-03 16:16:24 -06:00
pub keybinds: HashMap<KeyBind, Action>,
}
2023-11-03 16:16:24 -06:00
impl Default for Config {
fn default() -> Self {
Self {
2023-11-03 19:00:41 -06:00
font_name: "Fira Mono".to_string(),
2023-11-03 15:58:26 -06:00
font_size: 14,
2023-11-03 18:45:03 -06:00
syntax_theme_dark: "gruvbox-dark".to_string(),
syntax_theme_light: "gruvbox-light".to_string(),
vim_bindings: false,
2023-11-01 09:44:11 -06:00
word_wrap: false,
keybinds: KeyBind::load(),
}
}
2023-11-03 16:16:24 -06:00
}
2023-11-03 16:16:24 -06:00
impl Config {
2023-11-03 15:58:26 -06:00
// Calculate metrics from font size
pub fn metrics(&self) -> Metrics {
2023-11-03 19:00:41 -06:00
let font_size = self.font_size.max(1) as f32;
2023-11-03 15:58:26 -06:00
let line_height = (font_size * 1.4).ceil();
Metrics::new(font_size, line_height)
}
// Get current syntax theme based on dark mode
pub fn syntax_theme(&self, dark: bool) -> &str {
if dark {
&self.syntax_theme_dark
} else {
&self.syntax_theme_light
}
}
}