summaryrefslogtreecommitdiff
path: root/src/config
diff options
context:
space:
mode:
Diffstat (limited to 'src/config')
-rw-r--r--src/config/constants.rs23
-rw-r--r--src/config/mod.rs37
-rw-r--r--src/config/theme/colorpair.rs106
-rw-r--r--src/config/theme/mod.rs30
-rw-r--r--src/config/theme/sheetview.rs69
5 files changed, 265 insertions, 0 deletions
diff --git a/src/config/constants.rs b/src/config/constants.rs
new file mode 100644
index 0000000..5a8283a
--- /dev/null
+++ b/src/config/constants.rs
@@ -0,0 +1,23 @@
+use lazy_static::lazy_static;
+
+lazy_static! {
+ pub static ref USER_CONFIG_DIR: String = {
+ match dirs::config_local_dir() {
+ Some(mut d) => {
+ d.push("neosheet");
+ d.as_path().to_str().unwrap_or("").to_string()
+ }
+ None => String::new(),
+ }
+ };
+ pub static ref USER_RC_PATH: String = {
+ match dirs::config_local_dir() {
+ Some(mut d) => {
+ d.push("neosheet");
+ d.push("init.lua");
+ d.as_path().to_str().unwrap_or("").to_string()
+ }
+ None => String::new(),
+ }
+ };
+}
diff --git a/src/config/mod.rs b/src/config/mod.rs
new file mode 100644
index 0000000..e6c4952
--- /dev/null
+++ b/src/config/mod.rs
@@ -0,0 +1,37 @@
+use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
+
+use mlua::{UserData, UserDataFields};
+
+use self::theme::Theme;
+
+pub mod theme;
+pub mod constants;
+
+pub struct GlobalConfig {
+ pub theme: Theme,
+}
+
+static GLOBAL_CONFIG: RwLock<GlobalConfig> = RwLock::new(GlobalConfig::new());
+const DUMMY_CONFIG: GlobalConfig = GlobalConfig::new();
+
+impl GlobalConfig {
+ pub const fn new() -> Self {
+ Self {
+ theme: Theme::new(),
+ }
+ }
+
+ pub fn instance() -> RwLockReadGuard<'static, Self> {
+ GLOBAL_CONFIG.read().unwrap()
+ }
+
+ pub fn instance_mut() -> RwLockWriteGuard<'static, Self> {
+ GLOBAL_CONFIG.write().unwrap()
+ }
+}
+
+impl UserData for GlobalConfig {
+ fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) {
+ fields.add_field_function_get("theme", |_, _| Ok(DUMMY_CONFIG.theme))
+ }
+}
diff --git a/src/config/theme/colorpair.rs b/src/config/theme/colorpair.rs
new file mode 100644
index 0000000..77e6af4
--- /dev/null
+++ b/src/config/theme/colorpair.rs
@@ -0,0 +1,106 @@
+use std::str::FromStr;
+
+use mlua::{FromLua, IntoLua};
+use ratatui::style::{Color, Styled, Stylize};
+
+#[derive(Clone)]
+pub struct ColorPair {
+ pub fg: Color,
+ pub bg: Color,
+}
+
+impl ColorPair {
+ pub const fn new(fg: Color, bg: Color) -> Self {
+ ColorPair { bg, fg }
+ }
+
+ pub fn apply<S, I>(&self, s: S) -> <I as Styled>::Item
+ where
+ S: Styled<Item = I>,
+ I: Styled,
+ {
+ s.bg(self.bg).fg(self.fg)
+ }
+}
+
+impl<'lua> FromLua<'lua> for ColorPair {
+ fn from_lua(
+ value: mlua::prelude::LuaValue<'lua>,
+ _lua: &'lua mlua::prelude::Lua,
+ ) -> mlua::prelude::LuaResult<Self> {
+ if value.is_table() {
+ let table = value.as_table().unwrap();
+ if let Ok(fg) = table.get::<_, LuaColor>(1) {
+ if let Ok(bg) = table.get::<_, LuaColor>(2) {
+ return Ok(ColorPair::new(fg.into(), bg.into()));
+ }
+ } else if let Ok(fg) = table.get::<_, LuaColor>("fg") {
+ if let Ok(bg) = table.get::<_, LuaColor>("bg") {
+ return Ok(ColorPair::new(fg.into(), bg.into()));
+ }
+ }
+ }
+
+ return Err(mlua::Error::runtime("could not parse colorpair"));
+ }
+}
+
+impl<'lua> IntoLua<'lua> for ColorPair {
+ fn into_lua(
+ self,
+ lua: &'lua mlua::prelude::Lua,
+ ) -> mlua::prelude::LuaResult<mlua::prelude::LuaValue<'lua>> {
+ let table = lua.create_table()?;
+ table.set("fg", LuaColor::from(self.fg))?;
+ table.set("bg", LuaColor::from(self.bg))?;
+ Ok(table.into_lua(lua)?)
+ }
+}
+
+struct LuaColor {
+ color: Color,
+}
+
+impl LuaColor {
+ fn new(color: Color) -> Self {
+ Self { color }
+ }
+}
+
+impl From<Color> for LuaColor {
+ fn from(value: Color) -> Self {
+ LuaColor::new(value)
+ }
+}
+
+impl Into<Color> for LuaColor {
+ fn into(self) -> Color {
+ self.color
+ }
+}
+
+impl<'lua> FromLua<'lua> for LuaColor {
+ fn from_lua(
+ value: mlua::prelude::LuaValue<'lua>,
+ _lua: &'lua mlua::prelude::Lua,
+ ) -> mlua::prelude::LuaResult<Self> {
+ if value.is_string() {
+ let str = value.as_str().unwrap();
+ match Color::from_str(str) {
+ Ok(color) => Ok(color.into()),
+ Err(_) => Err(mlua::Error::runtime("color has wrong format")),
+ }
+ } else {
+ Err(mlua::Error::runtime("color has wrong format"))
+ }
+ }
+}
+
+impl<'lua> IntoLua<'lua> for LuaColor {
+ fn into_lua(
+ self,
+ lua: &'lua mlua::prelude::Lua,
+ ) -> mlua::prelude::LuaResult<mlua::prelude::LuaValue<'lua>> {
+ Ok(self.color.to_string().to_lowercase().into_lua(lua)?)
+ }
+}
diff --git a/src/config/theme/mod.rs b/src/config/theme/mod.rs
new file mode 100644
index 0000000..b7baf3a
--- /dev/null
+++ b/src/config/theme/mod.rs
@@ -0,0 +1,30 @@
+
+use mlua::UserData;
+
+use self::sheetview::SheetViewTheme;
+
+use super::DUMMY_CONFIG;
+
+pub mod colorpair;
+pub mod sheetview;
+
+#[derive(Clone)]
+pub struct Theme {
+ pub sheetview: SheetViewTheme,
+}
+
+impl Theme {
+ pub const fn new() -> Self {
+ Self {
+ sheetview: SheetViewTheme::new(),
+ }
+ }
+}
+
+impl UserData for Theme {
+ fn add_fields<'lua, F: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) {
+ fields.add_field_function_get("sheetview", |_, _| {
+ Ok(DUMMY_CONFIG.theme.sheetview)
+ })
+ }
+}
diff --git a/src/config/theme/sheetview.rs b/src/config/theme/sheetview.rs
new file mode 100644
index 0000000..de5751a
--- /dev/null
+++ b/src/config/theme/sheetview.rs
@@ -0,0 +1,69 @@
+use mlua::{IntoLua, Table, UserData};
+use ratatui::style::Color;
+
+use crate::config::GlobalConfig;
+
+use super::colorpair::ColorPair;
+
+#[derive(Clone)]
+pub struct SheetViewTheme {
+ pub cursor: ColorPair,
+ pub selection: ColorPair,
+ pub cell: (ColorPair, ColorPair),
+}
+
+impl SheetViewTheme {
+ pub const fn new() -> Self {
+ Self {
+ cursor: ColorPair::new(Color::Black, Color::White),
+ selection: ColorPair::new(Color::White, Color::DarkGray),
+ cell: (
+ ColorPair::new(Color::White, Color::Black),
+ ColorPair::new(Color::White, Color::DarkGray),
+ ),
+ }
+ }
+}
+
+macro_rules! cfg {
+ () => {
+ GlobalConfig::instance().theme.sheetview
+ };
+}
+
+macro_rules! cfg_mut {
+ () => {
+ GlobalConfig::instance_mut().theme.sheetview
+ };
+}
+
+impl UserData for SheetViewTheme {
+ fn add_fields<'lua, F: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) {
+ fields.add_field_function_get("cursor", |_, _| Ok(cfg!().cursor.clone()));
+
+ fields.add_field_function_set("cursor", |_, _, pair: ColorPair| {
+ cfg_mut!().cursor = pair;
+ Ok(())
+ });
+
+ fields.add_field_function_get("selection", |_, _| Ok(cfg!().selection.clone()));
+
+ fields.add_field_function_set("selection", |_, _, pair: ColorPair| {
+ cfg_mut!().selection = pair;
+ Ok(())
+ });
+
+ fields.add_field_function_get("cell", |lua, _| {
+ let table = lua.create_table()?;
+ let sel = cfg!().cell.clone();
+ table.set(1, sel.0)?;
+ table.set(2, sel.1)?;
+ Ok(table.into_lua(lua)?)
+ });
+
+ fields.add_field_function_set("cell", |_, _, pair: Table| {
+ cfg_mut!().cell = (pair.get(1)?, pair.get(2)?);
+ Ok(())
+ });
+ }
+}