diff --git a/docs/SETTINGS.md b/docs/SETTINGS.md index c54e507..92e0bf2 100644 --- a/docs/SETTINGS.md +++ b/docs/SETTINGS.md @@ -290,7 +290,8 @@ The following app settings can be customized in the app settings: |------|------|-------------| |history_limit|usize|Maximum number of modifications that are stored in the undo/redo history.| |log_limit|usize|Maximum number of log messages that are stored in the log.| -|theme|Option|The name of the theme to use. The available themes are: `"auto"`, `"dark"`, `"light"`. `"auto"` chooses automatically between `"dark"` and `"light"` based on the background color of the terminal. By default, the theme is `"auto"`.| +|log_level|Verbosity|The minimum level of log messages that are shown. Can be `"info"`, `"debug"`, `"warning"` or `"error"`.| +|theme|ThemePreference|The theme to use, can be `"auto"`, `"light"` or `"dark"`.| ## Custom diff --git a/src/app/app.rs b/src/app/app.rs index 57afe32..f225fdb 100644 --- a/src/app/app.rs +++ b/src/app/app.rs @@ -126,6 +126,7 @@ impl App { } }; logger.change_limit(settings.app.log_limit); + logger.change_verbosity(settings.app.log_level); Self::print_loading_status( &settings.color, &format!("Opening \"{}\"...", args.path), diff --git a/src/app/log/logger.rs b/src/app/log/logger.rs index cd90df7..cd6c7c9 100644 --- a/src/app/log/logger.rs +++ b/src/app/log/logger.rs @@ -1,6 +1,6 @@ use std::{collections::VecDeque, ops::Index}; -use crate::app::App; +use crate::app::{settings::verbosity::Verbosity, App}; use super::{log_line::LogLine, notification::NotificationLevel}; @@ -8,24 +8,28 @@ use super::{log_line::LogLine, notification::NotificationLevel}; pub struct Logger { pub(super) limit: usize, pub(super) log: VecDeque, + pub(super) verbosity: Verbosity, pub(super) notification: NotificationLevel, } impl Logger { - pub fn with_limit(limit: usize) -> Self { + pub fn new(limit: usize, verbosity: Verbosity) -> Self { Self { limit, log: VecDeque::with_capacity(limit), + verbosity, notification: NotificationLevel::None, } } pub fn log(&mut self, level: NotificationLevel, message: &str) { - self.notification.bump_notification_level(level); - if self.log.len() >= self.limit && self.limit > 0 { - self.log.pop_front(); + if level >= self.verbosity.as_notification_level() { + self.notification.bump_notification_level(level); + if self.log.len() >= self.limit && self.limit > 0 { + self.log.pop_front(); + } + self.log.push_back(LogLine::new(level, message.to_string())); } - self.log.push_back(LogLine::new(level, message.to_string())); } pub fn clear(&mut self) { @@ -65,15 +69,25 @@ impl Logger { } } + pub fn change_verbosity(&mut self, verbosity: Verbosity) { + self.verbosity = verbosity; + for log_line in &self.log { + if log_line.level < verbosity.as_notification_level() { + self.notification.bump_notification_level(log_line.level); + } + } + if self.notification < verbosity.as_notification_level() { + self.notification = NotificationLevel::None; + } + } + pub fn merge(&mut self, other: &Self) { for log_line in &other.log { if self.log.len() >= self.limit && self.limit > 0 { self.log.pop_front(); } - self.log.push_back(log_line.clone()); + self.log(log_line.level, &log_line.message); } - self.notification - .bump_notification_level(other.notification); } } @@ -127,7 +141,7 @@ mod test { #[test] fn test_logger_with_limit() { - let mut logger = Logger::with_limit(5); + let mut logger = Logger::new(5, Verbosity::Debug); for i in 0..10 { logger.log( NotificationLevel::Error, @@ -141,7 +155,7 @@ mod test { #[test] fn test_logger_change_limit() { - let mut logger = Logger::with_limit(2); + let mut logger = Logger::new(2, Verbosity::Debug); logger.log(NotificationLevel::Error, "Test error message 1"); logger.log(NotificationLevel::Error, "Test error message 2"); logger.log(NotificationLevel::Error, "Test error message 3"); diff --git a/src/app/log/notification.rs b/src/app/log/notification.rs index 54fae65..81438de 100644 --- a/src/app/log/notification.rs +++ b/src/app/log/notification.rs @@ -1,13 +1,13 @@ use std::fmt::{Display, Formatter}; -#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord)] pub enum NotificationLevel { #[default] - None, - Debug, - Info, - Warning, - Error, + None = 0, + Debug = 1, + Info = 2, + Warning = 3, + Error = 4, } impl NotificationLevel { @@ -22,13 +22,7 @@ impl NotificationLevel { } pub fn notification_level_as_u8(&self) -> u8 { - match self { - NotificationLevel::None => 0, - NotificationLevel::Debug => 1, - NotificationLevel::Info => 2, - NotificationLevel::Warning => 3, - NotificationLevel::Error => 4, - } + *self as u8 } } diff --git a/src/app/mockup.rs b/src/app/mockup.rs index 00c3b9b..0dcf952 100644 --- a/src/app/mockup.rs +++ b/src/app/mockup.rs @@ -4,9 +4,11 @@ pub mod test { use ratatui::{backend::TestBackend, Terminal}; - use crate::app::App; + use crate::app::{settings::verbosity::Verbosity, App}; impl App { + /// Create a mockup of the app with the given data. + /// Sets the logger verbosity to debug. pub fn mockup(data: Vec) -> Self { let mut app = App::default(); let mut input_file = @@ -17,6 +19,7 @@ pub mod test { let mut terminal = Terminal::new(TestBackend::new(80, 25)).unwrap(); app.open_file(&input_file.path().to_string_lossy(), &mut terminal) .expect("Failed to open file for mockup."); + app.logger.change_verbosity(Verbosity::Debug); app } } diff --git a/src/app/settings/app_settings.rs b/src/app/settings/app_settings.rs index 162ea3d..c8e5184 100644 --- a/src/app/settings/app_settings.rs +++ b/src/app/settings/app_settings.rs @@ -1,14 +1,15 @@ use mlua::UserDataRegistry; use serde::{Deserialize, Serialize}; -use super::Settings; +use super::{theme_preference::ThemePreference, verbosity::Verbosity, Settings}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(default)] pub struct AppSettings { pub history_limit: usize, pub log_limit: usize, - pub theme: Option, + pub log_level: Verbosity, + pub theme: ThemePreference, } impl AppSettings { @@ -43,7 +44,8 @@ impl Default for AppSettings { Self { history_limit: 1024, log_limit: 1024, - theme: None, + log_level: Verbosity::default(), + theme: ThemePreference::default(), } } } diff --git a/src/app/settings/color_settings.rs b/src/app/settings/color_settings.rs index 3f62ef4..48eea79 100644 --- a/src/app/settings/color_settings.rs +++ b/src/app/settings/color_settings.rs @@ -8,6 +8,7 @@ use crate::app::App; use crate::{EditColorSettings, RegisterColorSettings}; use super::app_settings::AppSettings; +use super::theme_preference::ThemePreference; #[derive(Debug, Clone, PartialEq, Eq, Serialize)] #[derive(EditColorSettings!)] @@ -248,16 +249,9 @@ impl ColorSettings { terminal_theme: Theme, ) -> Result { let theme = match &app_settings.theme { - Some(theme) if theme.to_lowercase() == "light" => Theme::Light, - Some(theme) if theme.to_lowercase() == "dark" => Theme::Dark, - any => { - if let Some(theme) = any { - if theme.to_lowercase() != "auto" { - return Err(format!("Invalid theme: {}", theme)); - } - } - terminal_theme - } + ThemePreference::Light => Theme::Light, + ThemePreference::Dark => Theme::Dark, + ThemePreference::Auto => terminal_theme, }; let mut color_settings = Self::get_default_theme(theme); color_settings diff --git a/src/app/settings/mod.rs b/src/app/settings/mod.rs index 6adcdde..0b79cb7 100644 --- a/src/app/settings/mod.rs +++ b/src/app/settings/mod.rs @@ -11,3 +11,5 @@ pub mod register_color_settings_macro; #[macro_use] pub mod edit_color_settings; pub mod settings_value; +pub mod theme_preference; +pub mod verbosity; diff --git a/src/app/settings/theme_preference.rs b/src/app/settings/theme_preference.rs new file mode 100644 index 0000000..2ba2524 --- /dev/null +++ b/src/app/settings/theme_preference.rs @@ -0,0 +1,10 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)] +#[serde(rename_all = "lowercase")] +pub enum ThemePreference { + Light, + Dark, + #[default] + Auto, +} diff --git a/src/app/settings/verbosity.rs b/src/app/settings/verbosity.rs new file mode 100644 index 0000000..82a85fd --- /dev/null +++ b/src/app/settings/verbosity.rs @@ -0,0 +1,24 @@ +use serde::{Deserialize, Serialize}; + +use crate::app::log::NotificationLevel; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)] +#[serde(rename_all = "lowercase")] +pub enum Verbosity { + Debug, + #[default] + Info, + Warning, + Error, +} + +impl Verbosity { + pub fn as_notification_level(&self) -> NotificationLevel { + match self { + Verbosity::Debug => NotificationLevel::Debug, + Verbosity::Info => NotificationLevel::Info, + Verbosity::Warning => NotificationLevel::Warning, + Verbosity::Error => NotificationLevel::Error, + } + } +} diff --git a/test/default_settings.json b/test/default_settings.json index 8eb94ef..d817c36 100644 --- a/test/default_settings.json +++ b/test/default_settings.json @@ -588,7 +588,9 @@ }, "app": { "history_limit": 1024, - "log_limit": 1024 + "log_limit": 1024, + "log_level": "info", + "theme": "auto" }, "custom": {} } \ No newline at end of file