diff --git a/Cargo.lock b/Cargo.lock index b825467..116ae62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -921,6 +921,18 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "darrentsung_debug_parser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf488eca7807ce3c8e64bee95c3fbf8f1935c905b3b73835e75db16fc458fdc4" +dependencies = [ + "anyhow", + "html-escape", + "nom", + "ordered-float", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -1434,6 +1446,15 @@ version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" +[[package]] +name = "html-escape" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +dependencies = [ + "utf8-width", +] + [[package]] name = "html5ever" version = "0.27.0" @@ -2305,6 +2326,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + [[package]] name = "overload" version = "0.1.1" @@ -2522,6 +2552,16 @@ dependencies = [ "yansi", ] +[[package]] +name = "pretty_assertions_sorted" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa95d32882f2adbdfd30312733271b83c527ee8007bf78dc21afe510463ac6a0" +dependencies = [ + "darrentsung_debug_parser", + "pretty_assertions", +] + [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -4133,6 +4173,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -4702,7 +4748,7 @@ dependencies = [ "gag", "itertools 0.13.0", "log", - "pretty_assertions", + "pretty_assertions_sorted", "rat-text", "ratatui", "rodio", diff --git a/youtui/Cargo.toml b/youtui/Cargo.toml index 4034f16..738cf09 100644 --- a/youtui/Cargo.toml +++ b/youtui/Cargo.toml @@ -60,7 +60,7 @@ version = "0.20.1" features = ["symphonia-all"] [dev-dependencies] -pretty_assertions = "1.4.1" +pretty_assertions_sorted = "1.2.3" [lints] workspace = true diff --git a/youtui/config/config.toml b/youtui/config/config.toml index c82d120..045cab9 100644 --- a/youtui/config/config.toml +++ b/youtui/config/config.toml @@ -30,15 +30,15 @@ enter = "Playlist Action" [keybinds.browser] F5 = {action = "browser.view_playlist", visibility = "global"} F2 = {action = "browser.search", visibility = "global"} -# left = "browser.left" -# right = "browser.right" +left = "browser.left" +right = "browser.right" [keybinds.browser_artists] enter = "browser_artists.display_selected_artist_albums" [keybinds.browser_search] -down = "browser_search.prev_search_suggestion" -up = "browser_search.next_search_suggestion" +down = "browser_search.next_search_suggestion" +up = "browser_search.prev_search_suggestion" [keybinds.browser_songs] F3 = {action = "browser_songs.filter", visibility = "global"} diff --git a/youtui/src/app/keycommand.rs b/youtui/src/app/keycommand.rs index 4da0ade..7fe0cc0 100644 --- a/youtui/src/app/keycommand.rs +++ b/youtui/src/app/keycommand.rs @@ -25,6 +25,7 @@ pub struct KeyCommand { pub visibility: CommandVisibility, } #[derive(Hash, Eq, PartialEq, Debug, Deserialize, Clone, Serialize)] +#[cfg_attr(test, derive(PartialOrd))] #[serde(try_from = "String")] pub struct Keybind { pub code: KeyCode, diff --git a/youtui/src/config.rs b/youtui/src/config.rs index 3453ec6..225c0f0 100644 --- a/youtui/src/config.rs +++ b/youtui/src/config.rs @@ -1,4 +1,3 @@ -use crate::app::component::actionhandler::Action; use crate::get_config_dir; use crate::Result; use clap::ValueEnum; @@ -102,7 +101,7 @@ mod tests { config::{Config, ConfigIR, CONFIG_FILE_NAME}, get_config_dir, }; - use pretty_assertions::assert_eq; + use pretty_assertions_sorted::assert_eq_sorted; #[tokio::test] async fn test_deserialize_default_config_to_ir() { @@ -133,6 +132,6 @@ mod tests { let ir: ConfigIR = toml::from_str(&config_file).unwrap(); let output = Config::try_from(ir).unwrap(); let expected = Config::default(); - assert_eq!(output, expected); + assert_eq_sorted!(output, expected); } } diff --git a/youtui/src/config/keybinds.rs b/youtui/src/config/keybinds.rs index 794752c..5495bc7 100644 --- a/youtui/src/config/keybinds.rs +++ b/youtui/src/config/keybinds.rs @@ -10,7 +10,7 @@ use crate::app::{ BrowserAction, }, logger::LoggerAction, - playlist::PlaylistAction::{DeleteSelected, PlaySelected, ViewBrowser}, + playlist::PlaylistAction::{self, DeleteSelected, PlaySelected, ViewBrowser}, }, }; use crossterm::event::KeyModifiers; @@ -18,6 +18,7 @@ use serde::{Deserialize, Serialize}; use std::{collections::HashMap, convert::Infallible, str::FromStr}; #[derive(Debug, PartialEq)] +#[cfg_attr(test, derive(PartialOrd))] pub struct YoutuiKeymap { pub global: HashMap>, pub playlist: HashMap>, @@ -197,10 +198,17 @@ impl KeyEnum { visibility: Default::default(), }) } + fn new_key_with_visibility(action: A, visibility: CommandVisibility) -> Self { + Self::Key(KeyEnumKey { + action, + value: Default::default(), + visibility, + }) + } fn new_key(action: A, value: usize, visibility: CommandVisibility) -> Self { Self::Key(KeyEnumKey { action, - value, + value: Some(value), visibility, }) } @@ -235,7 +243,7 @@ pub struct KeyEnumKey { // mode. What happens here. pub action: A, #[serde(default)] - pub value: usize, + pub value: Option, #[serde(default)] pub visibility: CommandVisibility, } @@ -304,15 +312,15 @@ fn default_global_keybinds() -> HashMap> { ), ( Keybind::new_unmodified(crossterm::event::KeyCode::F(1)), - KeyEnum::new_key(AppAction::ToggleHelp, 1, CommandVisibility::Global), + KeyEnum::new_key_with_visibility(AppAction::ToggleHelp, CommandVisibility::Global), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::F(10)), - KeyEnum::new_key(AppAction::Quit, 1, CommandVisibility::Standard), + KeyEnum::new_key_with_visibility(AppAction::Quit, CommandVisibility::Global), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::F(12)), - KeyEnum::new_key(AppAction::ViewLogs, 1, CommandVisibility::Standard), + KeyEnum::new_key_with_visibility(AppAction::ViewLogs, CommandVisibility::Global), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::Char(' ')), @@ -328,22 +336,25 @@ fn default_playlist_keybinds() -> HashMap> { FromIterator::from_iter([ ( Keybind::new_unmodified(crossterm::event::KeyCode::F(5)), - KeyEnum::new_key_defaulted(AppAction::Playlist(ViewBrowser)), + KeyEnum::new_key_with_visibility( + AppAction::Playlist(ViewBrowser), + CommandVisibility::Global, + ), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::Enter), KeyEnum::new_mode([ ( Keybind::new_unmodified(crossterm::event::KeyCode::Enter), - KeyEnum::new_key_defaulted(AppAction::Playlist(PlaySelected)), + KeyEnum::new_key_defaulted(AppAction::Playlist(PlaylistAction::PlaySelected)), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::Char('d')), - KeyEnum::new_key_defaulted(AppAction::Playlist(DeleteSelected)), + KeyEnum::new_key_defaulted(AppAction::Playlist(PlaylistAction::DeleteSelected)), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::Char('D')), - KeyEnum::new_key_defaulted(AppAction::Playlist(DeleteSelected)), + KeyEnum::new_key_defaulted(AppAction::Playlist(PlaylistAction::DeleteAll)), ), ]), ), @@ -353,20 +364,26 @@ fn default_browser_keybinds() -> HashMap> { FromIterator::from_iter([ ( Keybind::new_unmodified(crossterm::event::KeyCode::F(5)), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::Browser(BrowserAction::ViewPlaylist), - 1, CommandVisibility::Global, ), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::F(2)), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::Browser(BrowserAction::Search), - 1, CommandVisibility::Global, ), ), + ( + Keybind::new_unmodified(crossterm::event::KeyCode::Left), + KeyEnum::new_key_defaulted(AppAction::Browser(BrowserAction::Left)), + ), + ( + Keybind::new_unmodified(crossterm::event::KeyCode::Right), + KeyEnum::new_key_defaulted(AppAction::Browser(BrowserAction::Right)), + ), ]) } fn default_browser_artists_keybinds() -> HashMap> { @@ -397,17 +414,15 @@ fn default_browser_songs_keybinds() -> HashMap> { FromIterator::from_iter([ ( Keybind::new_unmodified(crossterm::event::KeyCode::F(3)), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::BrowserSongs(BrowserSongsAction::Filter), - 1, CommandVisibility::Global, ), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::F(4)), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::BrowserSongs(BrowserSongsAction::Sort), - 1, CommandVisibility::Global, ), ), @@ -461,10 +476,9 @@ fn default_help_keybinds() -> HashMap> { KeyEnum::new_key_defaulted(AppAction::Help(HelpAction::Close)), ), ( - Keybind::new_unmodified(crossterm::event::KeyCode::Esc), - KeyEnum::new_key( + Keybind::new_unmodified(crossterm::event::KeyCode::F(1)), + KeyEnum::new_key_with_visibility( AppAction::Help(HelpAction::Close), - 1, CommandVisibility::Global, ), ), @@ -474,41 +488,36 @@ fn default_sort_keybinds() -> HashMap> { FromIterator::from_iter([ ( Keybind::new_unmodified(crossterm::event::KeyCode::Enter), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::Sort(SortAction::SortSelectedAsc), - 1, CommandVisibility::Global, ), ), ( Keybind::new(crossterm::event::KeyCode::Enter, KeyModifiers::ALT), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::Sort(SortAction::SortSelectedDesc), - 1, CommandVisibility::Global, ), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::Char('C')), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::Sort(SortAction::ClearSort), - 1, CommandVisibility::Global, ), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::Esc), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::Sort(SortAction::Close), - 1, CommandVisibility::Hidden, ), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::F(4)), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::Sort(SortAction::Close), - 1, CommandVisibility::Global, ), ), @@ -518,25 +527,22 @@ fn default_filter_keybinds() -> HashMap> { FromIterator::from_iter([ ( Keybind::new_unmodified(crossterm::event::KeyCode::Esc), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::Filter(FilterAction::Close), - 1, CommandVisibility::Hidden, ), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::F(3)), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::Filter(FilterAction::Close), - 1, CommandVisibility::Global, ), ), ( Keybind::new_unmodified(crossterm::event::KeyCode::F(6)), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::Filter(FilterAction::ClearFilter), - 1, CommandVisibility::Global, ), ), @@ -566,9 +572,8 @@ fn default_log_keybinds() -> HashMap> { FromIterator::from_iter([ ( Keybind::new_unmodified(crossterm::event::KeyCode::F(5)), - KeyEnum::new_key( + KeyEnum::new_key_with_visibility( AppAction::Log(LoggerAction::ViewBrowser), - 0, CommandVisibility::Global, ), ), @@ -612,14 +617,14 @@ fn default_log_keybinds() -> HashMap> { Keybind::new_unmodified(crossterm::event::KeyCode::Esc), KeyEnum::new_key_defaulted(AppAction::Log(LoggerAction::ExitPageMode)), ), - ( - Keybind::new_unmodified(crossterm::event::KeyCode::Char('h')), - KeyEnum::new_key_defaulted(AppAction::Log(LoggerAction::ToggleTargetSelector)), - ), ( Keybind::new_unmodified(crossterm::event::KeyCode::Char('f')), KeyEnum::new_key_defaulted(AppAction::Log(LoggerAction::ToggleTargetFocus)), ), + ( + Keybind::new_unmodified(crossterm::event::KeyCode::Char('h')), + KeyEnum::new_key_defaulted(AppAction::Log(LoggerAction::ToggleTargetSelector)), + ), ]) } fn default_list_keybinds() -> HashMap> {