From 1dfcdf7e11069117ab798506a494f828fe04e21b Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Fri, 23 Feb 2024 08:36:35 -0500 Subject: [PATCH 01/37] Move application mode enum into modes submodule --- src/models/application/mod.rs | 19 +------------------ src/models/application/modes/mod.rs | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index d4500c30..3a192e8f 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -6,6 +6,7 @@ mod preferences; // Published API pub use self::clipboard::ClipboardContent; pub use self::event::Event; +pub use self::modes::Mode; pub use self::preferences::Preferences; use self::clipboard::Clipboard; @@ -22,24 +23,6 @@ use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::mpsc::{self, Receiver, Sender}; -pub enum Mode { - Confirm(ConfirmMode), - Command(CommandMode), - Exit, - Insert, - Jump(JumpMode), - LineJump(LineJumpMode), - Path(PathMode), - Normal, - Open(OpenMode), - Select(SelectMode), - SelectLine(SelectLineMode), - Search(SearchMode), - SymbolJump(SymbolJumpMode), - Syntax(SyntaxMode), - Theme(ThemeMode), -} - pub struct Application { pub mode: Mode, pub workspace: Workspace, diff --git a/src/models/application/modes/mod.rs b/src/models/application/modes/mod.rs index 12c55a76..e18dd9e3 100644 --- a/src/models/application/modes/mod.rs +++ b/src/models/application/modes/mod.rs @@ -12,6 +12,24 @@ mod symbol_jump; mod syntax; mod theme; +pub enum Mode { + Command(CommandMode), + Confirm(ConfirmMode), + Exit, + Insert, + Jump(JumpMode), + LineJump(LineJumpMode), + Normal, + Open(OpenMode), + Path(PathMode), + Search(SearchMode), + Select(SelectMode), + SelectLine(SelectLineMode), + SymbolJump(SymbolJumpMode), + Syntax(SyntaxMode), + Theme(ThemeMode), +} + pub use self::command::CommandMode; pub use self::confirm::ConfirmMode; pub use self::jump::JumpMode; From 638b00fc2cb790af2e17b8c01c466fb0690a8cb3 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Fri, 23 Feb 2024 08:43:47 -0500 Subject: [PATCH 02/37] Introduce ModeKey and mode storage --- src/models/application/mod.rs | 5 +++++ src/models/application/modes/mod.rs | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 3a192e8f..e879d782 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -18,13 +18,16 @@ use crate::view::View; use git2::Repository; use scribe::{Buffer, Workspace}; use std::cell::RefCell; +use std::collections::HashMap; use std::env; use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::mpsc::{self, Receiver, Sender}; pub struct Application { + pub current_mode: ModeKey, pub mode: Mode, + pub modes: HashMap, pub workspace: Workspace, pub search_query: Option, pub view: View, @@ -48,7 +51,9 @@ impl Application { let workspace = create_workspace(&mut view, &preferences.borrow(), args)?; Ok(Application { + current_mode: ModeKey::Normal, mode: Mode::Normal, + modes: HashMap::new(), workspace, search_query: None, view, diff --git a/src/models/application/modes/mod.rs b/src/models/application/modes/mod.rs index e18dd9e3..4fbf8f19 100644 --- a/src/models/application/modes/mod.rs +++ b/src/models/application/modes/mod.rs @@ -30,6 +30,25 @@ pub enum Mode { Theme(ThemeMode), } +#[derive(Eq, Hash, PartialEq)] +pub enum ModeKey { + Command, + Confirm, + Exit, + Insert, + Jump, + LineJump, + Normal, + Open, + Path, + Search, + Select, + SelectLine, + SymbolJump, + Syntax, + Theme, +} + pub use self::command::CommandMode; pub use self::confirm::ConfirmMode; pub use self::jump::JumpMode; From 76223955c255c4eddf64c11449fda3ca82f57bab Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Fri, 23 Feb 2024 08:56:15 -0500 Subject: [PATCH 03/37] Implement initial mode construction --- src/models/application/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index e879d782..c95344d5 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -53,7 +53,7 @@ impl Application { Ok(Application { current_mode: ModeKey::Normal, mode: Mode::Normal, - modes: HashMap::new(), + modes: create_modes(), workspace, search_query: None, view, @@ -298,6 +298,17 @@ fn create_workspace( Ok(workspace) } +fn create_modes() -> HashMap { + let mut modes = HashMap::new(); + + // Do the easy ones first. + modes.insert(ModeKey::Exit, Mode::Exit); + modes.insert(ModeKey::Insert, Mode::Insert); + modes.insert(ModeKey::Normal, Mode::Normal); + + return modes; +} + #[cfg(not(any(test, feature = "bench")))] fn user_syntax_path() -> Result> { Preferences::syntax_path().map(Some) From 6017c8ca0087bd405bdadbd20c1500a5bbf1dacd Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 25 Feb 2024 23:29:56 -0500 Subject: [PATCH 04/37] Initialize command mode --- src/models/application/mod.rs | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index c95344d5..5ae895f5 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -50,10 +50,10 @@ impl Application { // Set up a workspace in the current directory. let workspace = create_workspace(&mut view, &preferences.borrow(), args)?; - Ok(Application { + let mut app = Application { current_mode: ModeKey::Normal, mode: Mode::Normal, - modes: create_modes(), + modes: HashMap::new(), workspace, search_query: None, view, @@ -63,7 +63,11 @@ impl Application { preferences, event_channel, events, - }) + }; + + app.create_modes(); + + Ok(app) } pub fn run(&mut self) -> Result<()> { @@ -218,6 +222,20 @@ impl Application { Mode::Exit => None, } } + + fn create_modes(&mut self) { + // Do the easy ones first. + self.modes.insert(ModeKey::Exit, Mode::Exit); + self.modes.insert(ModeKey::Insert, Mode::Insert); + self.modes.insert(ModeKey::Normal, Mode::Normal); + + self.modes.insert( + ModeKey::Command, + Mode::Command(CommandMode::new( + self.preferences.borrow().search_select_config(), + )), + ); + } } fn initialize_preferences() -> Rc> { @@ -298,17 +316,6 @@ fn create_workspace( Ok(workspace) } -fn create_modes() -> HashMap { - let mut modes = HashMap::new(); - - // Do the easy ones first. - modes.insert(ModeKey::Exit, Mode::Exit); - modes.insert(ModeKey::Insert, Mode::Insert); - modes.insert(ModeKey::Normal, Mode::Normal); - - return modes; -} - #[cfg(not(any(test, feature = "bench")))] fn user_syntax_path() -> Result> { Preferences::syntax_path().map(Some) From b85de7a9461ef434c0fdf24e7c46b42bd6bacd2a Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 25 Feb 2024 23:35:36 -0500 Subject: [PATCH 05/37] Add confirm mode --- src/models/application/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 5ae895f5..56f6125b 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -235,6 +235,12 @@ impl Application { self.preferences.borrow().search_select_config(), )), ); + self.modes.insert( + ModeKey::Confirm, + Mode::Confirm(ConfirmMode::new( + commands::application::switch_to_normal_mode, + )), + ); } } From 4b90da591585d88a8b519008900326995e16111d Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 25 Feb 2024 23:41:54 -0500 Subject: [PATCH 06/37] Add jump mode --- src/models/application/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 56f6125b..f43f8c35 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -241,6 +241,8 @@ impl Application { commands::application::switch_to_normal_mode, )), ); + self.modes + .insert(ModeKey::Jump, Mode::Jump(JumpMode::new(0))); } } From 57b49b648b544d6d86f91bbdbbe12eb30a7cbbd4 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Mon, 26 Feb 2024 23:18:40 -0500 Subject: [PATCH 07/37] Add line jump mode --- src/models/application/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index f43f8c35..5c9ad364 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -243,6 +243,8 @@ impl Application { ); self.modes .insert(ModeKey::Jump, Mode::Jump(JumpMode::new(0))); + self.modes + .insert(ModeKey::LineJump, Mode::LineJump(LineJumpMode::new())); } } From 08a3b34e11528572e370b31f394665cd9c0d019c Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 11:58:12 -0500 Subject: [PATCH 08/37] Add open mode --- src/models/application/mod.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 5c9ad364..966647d9 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -65,7 +65,7 @@ impl Application { events, }; - app.create_modes(); + app.create_modes()?; Ok(app) } @@ -223,7 +223,7 @@ impl Application { } } - fn create_modes(&mut self) { + fn create_modes(&mut self) -> Result<()> { // Do the easy ones first. self.modes.insert(ModeKey::Exit, Mode::Exit); self.modes.insert(ModeKey::Insert, Mode::Insert); @@ -245,6 +245,19 @@ impl Application { .insert(ModeKey::Jump, Mode::Jump(JumpMode::new(0))); self.modes .insert(ModeKey::LineJump, Mode::LineJump(LineJumpMode::new())); + self.modes + .insert(ModeKey::LineJump, Mode::LineJump(LineJumpMode::new())); + self.modes.insert( + ModeKey::Open, + Mode::Open(OpenMode::new( + self.workspace.path.clone(), + self.preferences.borrow().open_mode_exclusions()?, + self.event_channel.clone(), + self.preferences.borrow().search_select_config(), + )), + ); + + Ok(()) } } From 02abce59a557ae99260ceb15a739399a7272960d Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 12:12:55 -0500 Subject: [PATCH 09/37] Add path mode --- src/models/application/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 966647d9..e3f20dd6 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -256,6 +256,8 @@ impl Application { self.preferences.borrow().search_select_config(), )), ); + self.modes + .insert(ModeKey::Path, Mode::Path(PathMode::new(String::new()))); Ok(()) } From 15e8543e79f791ca15bc229eafed9a9b11ac0c55 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 12:29:03 -0500 Subject: [PATCH 10/37] Add search mode --- src/models/application/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index e3f20dd6..6f693a19 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -258,6 +258,8 @@ impl Application { ); self.modes .insert(ModeKey::Path, Mode::Path(PathMode::new(String::new()))); + self.modes + .insert(ModeKey::Search, Mode::Search(SearchMode::new(None))); Ok(()) } From 418754fa5bf9d1cee165c376c21bf299b005b8dc Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 12:34:55 -0500 Subject: [PATCH 11/37] Add select mode --- src/models/application/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 6f693a19..b51dd746 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -16,6 +16,7 @@ use crate::errors::*; use crate::presenters; use crate::view::View; use git2::Repository; +use scribe::buffer::Position; use scribe::{Buffer, Workspace}; use std::cell::RefCell; use std::collections::HashMap; @@ -260,6 +261,10 @@ impl Application { .insert(ModeKey::Path, Mode::Path(PathMode::new(String::new()))); self.modes .insert(ModeKey::Search, Mode::Search(SearchMode::new(None))); + self.modes.insert( + ModeKey::Select, + Mode::Select(SelectMode::new(Position::default())), + ); Ok(()) } From de3f11165a50e705557435ad6c449cc97448b0a9 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 12:38:46 -0500 Subject: [PATCH 12/37] Add select line mode --- src/models/application/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index b51dd746..f4b774f4 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -265,6 +265,10 @@ impl Application { ModeKey::Select, Mode::Select(SelectMode::new(Position::default())), ); + self.modes.insert( + ModeKey::SelectLine, + Mode::SelectLine(SelectLineMode::new(0)), + ); Ok(()) } From 9bbbdd839849e146f6f9d31cd76af00c8d80de18 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 12:55:04 -0500 Subject: [PATCH 13/37] Add symbol jump mode --- src/models/application/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index f4b774f4..461ec143 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -16,7 +16,7 @@ use crate::errors::*; use crate::presenters; use crate::view::View; use git2::Repository; -use scribe::buffer::Position; +use scribe::buffer::{Position, TokenSet}; use scribe::{Buffer, Workspace}; use std::cell::RefCell; use std::collections::HashMap; @@ -269,6 +269,17 @@ impl Application { ModeKey::SelectLine, Mode::SelectLine(SelectLineMode::new(0)), ); + self.modes.insert( + ModeKey::SymbolJump, + Mode::SymbolJump(SymbolJumpMode::new( + &TokenSet::new( + String::new(), + &self.workspace.syntax_set.find_syntax_plain_text(), + &self.workspace.syntax_set, + ), + self.preferences.borrow().search_select_config(), + )?), + ); Ok(()) } From afb7a095759dd0743f84b76842b5618105a8b074 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 12:57:33 -0500 Subject: [PATCH 14/37] Add syntax mode --- src/models/application/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 461ec143..11e29500 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -281,6 +281,13 @@ impl Application { )?), ); + self.modes.insert( + ModeKey::Syntax, + Mode::Syntax(SyntaxMode::new( + Vec::new(), + self.preferences.borrow().search_select_config(), + )), + ); Ok(()) } } From 0ada53376269a5142ad45e7e73439364e1a0d730 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 12:58:34 -0500 Subject: [PATCH 15/37] Add theme mode --- src/models/application/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 11e29500..7dc5684e 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -280,7 +280,6 @@ impl Application { self.preferences.borrow().search_select_config(), )?), ); - self.modes.insert( ModeKey::Syntax, Mode::Syntax(SyntaxMode::new( @@ -288,6 +287,14 @@ impl Application { self.preferences.borrow().search_select_config(), )), ); + self.modes.insert( + ModeKey::Theme, + Mode::Theme(ThemeMode::new( + Vec::new(), + self.preferences.borrow().search_select_config(), + )), + ); + Ok(()) } } From 5934e33a053a6d45cb81a6cbe510d90f137b6ffe Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 15:58:40 -0500 Subject: [PATCH 16/37] Implement switch_to method for application type --- src/models/application/mod.rs | 48 ++++++++++++++++++++++++++++- src/models/application/modes/mod.rs | 2 +- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 7dc5684e..2355c5ff 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -21,6 +21,7 @@ use scribe::{Buffer, Workspace}; use std::cell::RefCell; use std::collections::HashMap; use std::env; +use std::mem; use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::mpsc::{self, Receiver, Sender}; @@ -224,6 +225,20 @@ impl Application { } } + pub fn switch_to(&mut self, mode_key: ModeKey) { + // Check out the specified mode. + let mut mode = self.modes.remove(&mode_key).unwrap(); + + // Activate the specified mode. + mem::swap(&mut self.mode, &mut mode); + + // Check in the previous mode. + self.modes.insert(self.current_mode, mode); + + // Track the new active mode. + self.current_mode = mode_key; + } + fn create_modes(&mut self) -> Result<()> { // Do the easy ones first. self.modes.insert(ModeKey::Exit, Mode::Exit); @@ -393,7 +408,7 @@ fn user_syntax_path() -> Result> { #[cfg(test)] mod tests { use super::preferences::Preferences; - use super::Application; + use super::{Application, Mode, ModeKey}; use crate::view::View; use scribe::Buffer; @@ -468,4 +483,35 @@ mod tests { "Rust" ); } + + #[test] + fn switch_to_activates_the_specified_mode() { + let mut app = Application::new(&Vec::new()).unwrap(); + + assert_eq!(app.current_mode, ModeKey::Normal); + assert!(matches!(app.mode, Mode::Normal)); + + app.switch_to(ModeKey::Exit); + + assert_eq!(app.current_mode, ModeKey::Exit); + assert!(matches!(app.mode, Mode::Exit)); + } + + #[test] + fn switch_to_retains_state_from_previous_modes() { + let mut app = Application::new(&Vec::new()).unwrap(); + + app.switch_to(ModeKey::Search); + match app.mode { + Mode::Search(ref mut s) => s.input = Some(String::from("state")), + _ => panic!("switch_to didn't change app mode"), + } + + app.switch_to(ModeKey::Normal); + app.switch_to(ModeKey::Search); + match app.mode { + Mode::Search(ref s) => assert_eq!(s.input, Some(String::from("state"))), + _ => panic!("switch_to didn't change app mode"), + } + } } diff --git a/src/models/application/modes/mod.rs b/src/models/application/modes/mod.rs index 4fbf8f19..7dc4fb4a 100644 --- a/src/models/application/modes/mod.rs +++ b/src/models/application/modes/mod.rs @@ -30,7 +30,7 @@ pub enum Mode { Theme(ThemeMode), } -#[derive(Eq, Hash, PartialEq)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum ModeKey { Command, Confirm, From ac4b42ee84663a550545c4307efa2e9740a29a05 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 16:01:08 -0500 Subject: [PATCH 17/37] Make current_mode/modes private These should be mutated through switch_to. --- src/models/application/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 2355c5ff..bd1e9665 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -27,9 +27,7 @@ use std::rc::Rc; use std::sync::mpsc::{self, Receiver, Sender}; pub struct Application { - pub current_mode: ModeKey, pub mode: Mode, - pub modes: HashMap, pub workspace: Workspace, pub search_query: Option, pub view: View, @@ -39,6 +37,8 @@ pub struct Application { pub preferences: Rc>, pub event_channel: Sender, events: Receiver, + current_mode: ModeKey, + modes: HashMap, } impl Application { From c8e3d56ec8d087169892acd67b846381bcee1e74 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 16:05:47 -0500 Subject: [PATCH 18/37] Update simple mode switch commands to use switch_to --- src/commands/application.rs | 8 ++++---- src/models/application/mod.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index a6a22251..344dbb89 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -2,7 +2,7 @@ use crate::commands::{self, Result}; use crate::errors::*; use crate::input::KeyMap; use crate::models::application::modes::*; -use crate::models::application::{Application, Mode}; +use crate::models::application::{Application, Mode, ModeKey}; use crate::util; use scribe::Buffer; use std::mem; @@ -26,7 +26,7 @@ pub fn handle_input(app: &mut Application) -> Result { pub fn switch_to_normal_mode(app: &mut Application) -> Result { let _ = commands::buffer::end_command_group(app); - app.mode = Mode::Normal; + app.switch_to(ModeKey::Normal); Ok(()) } @@ -34,7 +34,7 @@ pub fn switch_to_normal_mode(app: &mut Application) -> Result { pub fn switch_to_insert_mode(app: &mut Application) -> Result { if app.workspace.current_buffer.is_some() { commands::buffer::start_command_group(app)?; - app.mode = Mode::Insert; + app.switch_to(ModeKey::Insert); commands::view::scroll_to_cursor(app)?; } else { bail!(BUFFER_MISSING); @@ -282,7 +282,7 @@ pub fn suspend(app: &mut Application) -> Result { } pub fn exit(app: &mut Application) -> Result { - app.mode = Mode::Exit; + app.switch_to(ModeKey::Exit); Ok(()) } diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index bd1e9665..b64cc1f1 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -6,7 +6,7 @@ mod preferences; // Published API pub use self::clipboard::ClipboardContent; pub use self::event::Event; -pub use self::modes::Mode; +pub use self::modes::{Mode, ModeKey}; pub use self::preferences::Preferences; use self::clipboard::Clipboard; From ad46b608db9533e42c803020b1b64b6dd38d3494 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 21:59:57 -0500 Subject: [PATCH 19/37] Add the ability to switch to the previous mode --- src/models/application/mod.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index b64cc1f1..7f200771 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -38,6 +38,7 @@ pub struct Application { pub event_channel: Sender, events: Receiver, current_mode: ModeKey, + previous_mode: ModeKey, modes: HashMap, } @@ -54,6 +55,7 @@ impl Application { let mut app = Application { current_mode: ModeKey::Normal, + previous_mode: ModeKey::Normal, mode: Mode::Normal, modes: HashMap::new(), workspace, @@ -235,10 +237,17 @@ impl Application { // Check in the previous mode. self.modes.insert(self.current_mode, mode); + // Track the previous mode. + self.previous_mode = self.current_mode; + // Track the new active mode. self.current_mode = mode_key; } + pub fn switch_to_previous_mode(&mut self) { + self.switch_to(self.previous_mode); + } + fn create_modes(&mut self) -> Result<()> { // Do the easy ones first. self.modes.insert(ModeKey::Exit, Mode::Exit); @@ -514,4 +523,20 @@ mod tests { _ => panic!("switch_to didn't change app mode"), } } + + #[test] + fn switch_to_previous_mode_works() { + let mut app = Application::new(&Vec::new()).unwrap(); + + app.switch_to(ModeKey::Insert); + app.switch_to(ModeKey::Exit); + + assert_eq!(app.current_mode, ModeKey::Exit); + assert!(matches!(app.mode, Mode::Exit)); + + app.switch_to_previous_mode(); + + assert_eq!(app.current_mode, ModeKey::Insert); + assert!(matches!(app.mode, Mode::Insert)); + } } From f18422b871d622d04d95b4bfb186bb9b46476bf2 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 22:03:58 -0500 Subject: [PATCH 20/37] Update switch_to_jump_mode This one is a big win, as jump mode effectively implemented persistent select modes all on its own, which is now solved by the app-wide persistent modes. --- src/commands/application.rs | 36 +++++++----------------- src/commands/jump.rs | 22 +-------------- src/models/application/modes/jump/mod.rs | 23 +++++++-------- 3 files changed, 21 insertions(+), 60 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index 344dbb89..0ca0a3c0 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -5,7 +5,6 @@ use crate::models::application::modes::*; use crate::models::application::{Application, Mode, ModeKey}; use crate::util; use scribe::Buffer; -use std::mem; pub fn handle_input(app: &mut Application) -> Result { // Listen for and respond to user input. @@ -44,34 +43,19 @@ pub fn switch_to_insert_mode(app: &mut Application) -> Result { } pub fn switch_to_jump_mode(app: &mut Application) -> Result { - let buffer = app + let line = app .workspace .current_buffer .as_ref() - .ok_or(BUFFER_MISSING)?; - - // Initialize a new jump mode and swap - // it with the current application mode. - let jump_mode = Mode::Jump(JumpMode::new(buffer.cursor.line)); - let old_mode = mem::replace(&mut app.mode, jump_mode); - - // If we were previously in a select mode, store it - // in the current jump mode so that we can return to - // it after we've jumped to a location. This is how - // we compose select and jump modes. - match old_mode { - Mode::Select(select_mode) => { - if let Mode::Jump(ref mut mode) = app.mode { - mode.select_mode = jump::SelectModeOptions::Select(select_mode); - } - } - Mode::SelectLine(select_mode) => { - if let Mode::Jump(ref mut mode) = app.mode { - mode.select_mode = jump::SelectModeOptions::SelectLine(select_mode); - } - } + .ok_or(BUFFER_MISSING)? + .cursor + .line; + + app.switch_to(ModeKey::Jump); + match app.mode { + Mode::Jump(ref mut mode) => mode.reset(line), _ => (), - }; + } Ok(()) } @@ -81,7 +65,7 @@ pub fn switch_to_second_stage_jump_mode(app: &mut Application) -> Result { if let Mode::Jump(ref mut mode) = app.mode { mode.first_phase = false; } else { - bail!("Failed to switch to jump mode."); + bail!("Cannot enter second stage jump mode from other modes."); }; Ok(()) diff --git a/src/commands/jump.rs b/src/commands/jump.rs index ab4b26d9..4450a7ec 100644 --- a/src/commands/jump.rs +++ b/src/commands/jump.rs @@ -1,11 +1,9 @@ use crate::commands::Result; use crate::errors::*; use crate::input::Key; -use crate::models::application::modes::jump; use crate::models::application::modes::JumpMode; use crate::models::application::{Application, Mode}; use scribe::Workspace; -use std::mem; pub fn match_tag(app: &mut Application) -> Result { let result = if let Mode::Jump(ref mut jump_mode) = app.mode { @@ -23,7 +21,7 @@ pub fn match_tag(app: &mut Application) -> Result { } else { bail!("Can't match jump tags outside of jump mode."); }; - switch_to_previous_mode(app); + app.switch_to_previous_mode(); result } @@ -45,24 +43,6 @@ fn jump_to_tag(jump_mode: &mut JumpMode, workspace: &mut Workspace) -> Result { Ok(()) } -fn switch_to_previous_mode(app: &mut Application) { - let old_mode = mem::replace(&mut app.mode, Mode::Normal); - - // Now that we own the jump mode, switch to - // the previous select mode, if there was one. - if let Mode::Jump(jump_mode) = old_mode { - match jump_mode.select_mode { - jump::SelectModeOptions::None => (), - jump::SelectModeOptions::Select(select_mode) => { - app.mode = Mode::Select(select_mode); - } - jump::SelectModeOptions::SelectLine(select_mode) => { - app.mode = Mode::SelectLine(select_mode); - } - } - } -} - pub fn push_search_char(app: &mut Application) -> Result { if let Some(ref key) = *app.view.last_key() { if let Mode::Jump(ref mut mode) = app.mode { diff --git a/src/models/application/modes/jump/mod.rs b/src/models/application/modes/jump/mod.rs index b1d477ac..ce82421f 100644 --- a/src/models/application/modes/jump/mod.rs +++ b/src/models/application/modes/jump/mod.rs @@ -3,22 +3,12 @@ mod tag_generator; use self::single_character_tag_generator::SingleCharacterTagGenerator; use self::tag_generator::TagGenerator; -use crate::models::application::modes::select::SelectMode; -use crate::models::application::modes::select_line::SelectLineMode; use crate::util::movement_lexer; use crate::view::{LexemeMapper, MappedLexeme}; use luthor::token::Category; use scribe::buffer::{Distance, Position}; use std::collections::HashMap; -/// Used to compose select and jump modes, allowing jump mode -/// to be used for cursor navigation (to select a range of text). -pub enum SelectModeOptions { - None, - Select(SelectMode), - SelectLine(SelectLineMode), -} - enum MappedLexemeValue { Tag((String, Position)), Text((String, Position)), @@ -28,7 +18,6 @@ pub struct JumpMode { pub input: String, pub first_phase: bool, cursor_line: usize, - pub select_mode: SelectModeOptions, tag_positions: HashMap, tag_generator: TagGenerator, single_characters: SingleCharacterTagGenerator, @@ -42,11 +31,10 @@ impl JumpMode { input: String::new(), first_phase: true, cursor_line, - select_mode: SelectModeOptions::None, tag_positions: HashMap::new(), tag_generator: TagGenerator::new(), single_characters: SingleCharacterTagGenerator::new(), - current_position: Position { line: 0, offset: 0 }, + current_position: Position::default(), mapped_lexeme_values: Vec::new(), } } @@ -60,6 +48,15 @@ impl JumpMode { self.tag_generator.reset(); self.single_characters.reset(); } + + pub fn reset(&mut self, cursor_line: usize) { + self.input = String::new(); + self.first_phase = true; + self.current_position = Position::default(); + self.cursor_line = cursor_line; + self.mapped_lexeme_values = Vec::new(); + self.reset_display(); + } } impl LexemeMapper for JumpMode { From dfcca1bb7e934bad7f3a8073d76600ad99e74b11 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 22:17:35 -0500 Subject: [PATCH 21/37] Update switch_to_line_jump_mode --- src/commands/application.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index 0ca0a3c0..992f45b8 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -73,7 +73,11 @@ pub fn switch_to_second_stage_jump_mode(app: &mut Application) -> Result { pub fn switch_to_line_jump_mode(app: &mut Application) -> Result { if app.workspace.current_buffer.is_some() { - app.mode = Mode::LineJump(LineJumpMode::new()); + app.switch_to(ModeKey::LineJump); + match app.mode { + Mode::LineJump(ref mut mode) => mode.input = String::new(), + _ => (), + } } else { bail!(BUFFER_MISSING); } From 3b159a7b58e94b02f2fcc531700f674d31c2dfb4 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 23:29:49 -0500 Subject: [PATCH 22/37] Update switch_to_open_mode --- src/commands/application.rs | 18 ++++++++---- src/models/application/mod.rs | 2 -- src/models/application/modes/open/mod.rs | 36 +++++++++++++++--------- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index 992f45b8..344f7b3f 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -88,12 +88,18 @@ pub fn switch_to_line_jump_mode(app: &mut Application) -> Result { pub fn switch_to_open_mode(app: &mut Application) -> Result { let exclusions = app.preferences.borrow().open_mode_exclusions()?; let config = app.preferences.borrow().search_select_config(); - app.mode = Mode::Open(OpenMode::new( - app.workspace.path.clone(), - exclusions, - app.event_channel.clone(), - config, - )); + + app.switch_to(ModeKey::Open); + match app.mode { + Mode::Open(ref mut mode) => mode.reset( + app.workspace.path.clone(), + exclusions, + app.event_channel.clone(), + config, + ), + _ => (), + } + commands::search_select::search(app)?; Ok(()) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 7f200771..720a8263 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -276,8 +276,6 @@ impl Application { ModeKey::Open, Mode::Open(OpenMode::new( self.workspace.path.clone(), - self.preferences.borrow().open_mode_exclusions()?, - self.event_channel.clone(), self.preferences.borrow().search_select_config(), )), ); diff --git a/src/models/application/modes/open/mod.rs b/src/models/application/modes/open/mod.rs index 841e731b..c596e2b8 100644 --- a/src/models/application/modes/open/mod.rs +++ b/src/models/application/modes/open/mod.rs @@ -28,20 +28,7 @@ pub struct OpenMode { } impl OpenMode { - pub fn new( - path: PathBuf, - exclusions: Option>, - events: Sender, - config: SearchSelectConfig, - ) -> OpenMode { - // Build and populate the index in a separate thread. - let index_path = path.clone(); - thread::spawn(move || { - let mut index = Index::new(index_path); - index.populate(exclusions, false); - let _ = events.send(Event::OpenModeIndexComplete(index)); - }); - + pub fn new(path: PathBuf, config: SearchSelectConfig) -> OpenMode { OpenMode { insert: true, input: String::new(), @@ -54,6 +41,27 @@ impl OpenMode { pub fn set_index(&mut self, index: Index) { self.index = OpenModeIndex::Complete(index) } + + pub fn reset( + &mut self, + path: PathBuf, + exclusions: Option>, + events: Sender, + config: SearchSelectConfig, + ) { + self.insert = true; + self.input = String::new(); + self.config = config; + self.index = OpenModeIndex::Indexing(path.clone()); + self.results = SelectableVec::new(Vec::new()); + + // Build and populate the index in a separate thread. + thread::spawn(move || { + let mut index = Index::new(path); + index.populate(exclusions, false); + let _ = events.send(Event::OpenModeIndexComplete(index)); + }); + } } impl fmt::Display for OpenMode { From f439a10544ec3a10acd35f526ceac6b31573c050 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 3 Mar 2024 23:37:48 -0500 Subject: [PATCH 23/37] Update switch_to_path_mode --- src/commands/application.rs | 7 ++++++- src/models/application/mod.rs | 2 +- src/models/application/modes/path.rs | 11 +++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index 344f7b3f..a39eb902 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -187,7 +187,12 @@ pub fn switch_to_path_mode(app: &mut Application) -> Result { .unwrap_or_else(|| // Default to the workspace directory. format!("{}/", app.workspace.path.to_string_lossy())); - app.mode = Mode::Path(PathMode::new(path)); + + app.switch_to(ModeKey::Path); + match app.mode { + Mode::Path(ref mut mode) => mode.reset(path), + _ => (), + } Ok(()) } diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 720a8263..291128cd 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -280,7 +280,7 @@ impl Application { )), ); self.modes - .insert(ModeKey::Path, Mode::Path(PathMode::new(String::new()))); + .insert(ModeKey::Path, Mode::Path(PathMode::new())); self.modes .insert(ModeKey::Search, Mode::Search(SearchMode::new(None))); self.modes.insert( diff --git a/src/models/application/modes/path.rs b/src/models/application/modes/path.rs index af4378d4..1277c825 100644 --- a/src/models/application/modes/path.rs +++ b/src/models/application/modes/path.rs @@ -6,18 +6,25 @@ pub struct PathMode { } impl PathMode { - pub fn new(initial_path: String) -> PathMode { + pub fn new() -> PathMode { PathMode { - input: initial_path, + input: String::new(), save_on_accept: false, } } + pub fn push_char(&mut self, c: char) { self.input.push(c); } + pub fn pop_char(&mut self) { self.input.pop(); } + + pub fn reset(&mut self, initial_path: String) { + self.input = initial_path; + self.save_on_accept = false; + } } impl fmt::Display for PathMode { From 017898ee696da9febecf3f845b08a0b6952a4fb7 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Mon, 4 Mar 2024 22:11:22 -0500 Subject: [PATCH 24/37] Update switch_to_search_mode --- src/commands/application.rs | 25 ++++++------------------- src/commands/search.rs | 13 +++++-------- src/commands/selection.rs | 5 ++++- src/models/application/mod.rs | 2 -- 4 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index a39eb902..b0b11cc4 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -165,7 +165,12 @@ pub fn switch_to_select_line_mode(app: &mut Application) -> Result { pub fn switch_to_search_mode(app: &mut Application) -> Result { if app.workspace.current_buffer.is_some() { - app.mode = Mode::Search(SearchMode::new(app.search_query.clone())); + app.switch_to(ModeKey::Search); + + match app.mode { + Mode::Search(ref mut mode) => mode.insert = true, + _ => (), + } } else { bail!(BUFFER_MISSING); } @@ -315,24 +320,6 @@ mod tests { assert_eq!(lines.last(), Some("workspace::next_buffer")); } - #[test] - fn switch_to_search_mode_sets_initial_search_query() { - let mut app = Application::new(&Vec::new()).unwrap(); - - // A buffer needs to be open to switch to search mode. - let buffer = Buffer::new(); - app.workspace.add_buffer(buffer); - - app.search_query = Some(String::from("query")); - super::switch_to_search_mode(&mut app).unwrap(); - - let mode_query = match app.mode { - Mode::Search(ref mode) => mode.input.clone(), - _ => None, - }; - assert_eq!(mode_query, Some(String::from("query"))); - } - #[test] fn switch_to_path_mode_inserts_workspace_directory_as_default() { let mut app = Application::new(&Vec::new()).unwrap(); diff --git a/src/commands/search.rs b/src/commands/search.rs index 13f308ec..4ba7e4f3 100644 --- a/src/commands/search.rs +++ b/src/commands/search.rs @@ -70,7 +70,6 @@ pub fn accept_query(app: &mut Application) -> Result { pub fn clear_query(app: &mut Application) -> Result { if let Mode::Search(ref mut mode) = app.mode { mode.input = None; - app.search_query = None; } else { bail!("Can't clear search outside of search mode"); }; @@ -89,7 +88,6 @@ pub fn push_search_char(app: &mut Application) -> Result { if let Mode::Search(ref mut mode) = app.mode { let query = mode.input.get_or_insert(String::new()); query.push(c); - app.search_query = Some(query.clone()); } else { bail!("Can't push search character outside of search mode"); } @@ -105,7 +103,6 @@ pub fn pop_search_char(app: &mut Application) -> Result { let query = mode.input.as_mut().ok_or(SEARCH_QUERY_MISSING)?; query.pop(); - app.search_query = Some(query.clone()); } else { bail!("Can't pop search character outside of search mode"); }; @@ -280,9 +277,12 @@ mod tests { buffer.cursor.move_to(Position { line: 0, offset: 4 }); app.workspace.add_buffer(buffer); - // Add a search query, enter search mode, and accept the query. - app.search_query = Some(String::from("ed")); + // Enter search mode, add a query, and accept the query. commands::application::switch_to_search_mode(&mut app).unwrap(); + match app.mode { + Mode::Search(ref mut mode) => mode.input = Some("ed".into()), + _ => (), + } commands::search::accept_query(&mut app).unwrap(); // Ensure that we've disabled insert sub-mode. @@ -291,9 +291,6 @@ mod tests { _ => false, }); - // Ensure that the search query is properly set. - assert_eq!(app.search_query, Some("ed".to_string())); - // Ensure the buffer cursor is at the expected position. assert_eq!( *app.workspace.current_buffer.as_ref().unwrap().cursor, diff --git a/src/commands/selection.rs b/src/commands/selection.rs index 34094d79..fb0a7216 100644 --- a/src/commands/selection.rs +++ b/src/commands/selection.rs @@ -222,8 +222,11 @@ mod tests { // Now that we've set up the buffer, add it // to the application and call the command. app.workspace.add_buffer(buffer); - app.search_query = Some(String::from("ed")); commands::application::switch_to_search_mode(&mut app).unwrap(); + match app.mode { + Mode::Search(ref mut mode) => mode.input = Some("ed".into()), + _ => (), + } commands::search::accept_query(&mut app).unwrap(); commands::selection::delete(&mut app).unwrap(); diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 291128cd..397c8998 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -29,7 +29,6 @@ use std::sync::mpsc::{self, Receiver, Sender}; pub struct Application { pub mode: Mode, pub workspace: Workspace, - pub search_query: Option, pub view: View, pub clipboard: Clipboard, pub repository: Option, @@ -59,7 +58,6 @@ impl Application { mode: Mode::Normal, modes: HashMap::new(), workspace, - search_query: None, view, clipboard, repository: Repository::discover(env::current_dir()?).ok(), From dc86b104958c0363953347c54d9971daf983c255 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Mon, 4 Mar 2024 22:17:29 -0500 Subject: [PATCH 25/37] Update switch_to_select_mode --- src/commands/application.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index b0b11cc4..49e6c9fb 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -144,10 +144,17 @@ pub fn switch_to_theme_mode(app: &mut Application) -> Result { } pub fn switch_to_select_mode(app: &mut Application) -> Result { - if let Some(buffer) = app.workspace.current_buffer.as_ref() { - app.mode = Mode::Select(SelectMode::new(*buffer.cursor.clone())); - } else { - bail!(BUFFER_MISSING); + let position = *app + .workspace + .current_buffer + .as_ref() + .ok_or(BUFFER_MISSING)? + .cursor; + + app.switch_to(ModeKey::Select); + match app.mode { + Mode::Select(ref mut mode) => mode.anchor = position, + _ => (), } Ok(()) From 01c7036ace0f7675abd15a3eeacd52d33dc3b7c4 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Mon, 4 Mar 2024 22:19:35 -0500 Subject: [PATCH 26/37] Update switch_to_select_line_mode --- src/commands/application.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index 49e6c9fb..da897328 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -161,10 +161,18 @@ pub fn switch_to_select_mode(app: &mut Application) -> Result { } pub fn switch_to_select_line_mode(app: &mut Application) -> Result { - if let Some(buffer) = app.workspace.current_buffer.as_ref() { - app.mode = Mode::SelectLine(SelectLineMode::new(buffer.cursor.line)); - } else { - bail!(BUFFER_MISSING); + let line = app + .workspace + .current_buffer + .as_ref() + .ok_or(BUFFER_MISSING)? + .cursor + .line; + + app.switch_to(ModeKey::SelectLine); + match app.mode { + Mode::SelectLine(ref mut mode) => mode.anchor = line, + _ => (), } Ok(()) From 6961e693dba23233b3b32c685135e232b8b973b6 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Mon, 4 Mar 2024 22:50:01 -0500 Subject: [PATCH 27/37] Update switch_to_symbol_jump_mode --- src/commands/application.rs | 7 ++++++- src/models/application/mod.rs | 7 +------ src/models/application/modes/symbol_jump.rs | 13 +++++++++---- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index da897328..4fc1c69e 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -114,13 +114,18 @@ pub fn switch_to_command_mode(app: &mut Application) -> Result { } pub fn switch_to_symbol_jump_mode(app: &mut Application) -> Result { + app.switch_to(ModeKey::SymbolJump); + let token_set = app .workspace .current_buffer_tokens() .chain_err(|| BUFFER_TOKENS_FAILED)?; let config = app.preferences.borrow().search_select_config(); - app.mode = Mode::SymbolJump(SymbolJumpMode::new(&token_set, config)?); + match app.mode { + Mode::SymbolJump(ref mut mode) => mode.reset(&token_set, config), + _ => Ok(()), + }?; commands::search_select::search(app)?; diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 397c8998..7f780163 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -16,7 +16,7 @@ use crate::errors::*; use crate::presenters; use crate::view::View; use git2::Repository; -use scribe::buffer::{Position, TokenSet}; +use scribe::buffer::Position; use scribe::{Buffer, Workspace}; use std::cell::RefCell; use std::collections::HashMap; @@ -292,11 +292,6 @@ impl Application { self.modes.insert( ModeKey::SymbolJump, Mode::SymbolJump(SymbolJumpMode::new( - &TokenSet::new( - String::new(), - &self.workspace.syntax_set.find_syntax_plain_text(), - &self.workspace.syntax_set, - ), self.preferences.borrow().search_select_config(), )?), ); diff --git a/src/models/application/modes/symbol_jump.rs b/src/models/application/modes/symbol_jump.rs index a421f08f..b9781c38 100644 --- a/src/models/application/modes/symbol_jump.rs +++ b/src/models/application/modes/symbol_jump.rs @@ -52,17 +52,22 @@ impl AsStr for Symbol { } impl SymbolJumpMode { - pub fn new(tokens: &TokenSet, config: SearchSelectConfig) -> Result { - let symbols = symbols(tokens.iter().chain_err(|| BUFFER_PARSE_FAILED)?); - + pub fn new(config: SearchSelectConfig) -> Result { Ok(SymbolJumpMode { insert: true, input: String::new(), - symbols, + symbols: Vec::new(), results: SelectableVec::new(Vec::new()), config, }) } + + pub fn reset(&mut self, tokens: &TokenSet, config: SearchSelectConfig) -> Result<()> { + self.symbols = symbols(tokens.iter().chain_err(|| BUFFER_PARSE_FAILED)?); + self.config = config; + + Ok(()) + } } impl fmt::Display for SymbolJumpMode { From 0eb3728146a24f256398979e0ef3dd2a0718ee13 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Mon, 4 Mar 2024 23:02:08 -0500 Subject: [PATCH 28/37] Update switch_to_syntax_mode --- src/commands/application.rs | 22 +++++++++++++--------- src/models/application/mod.rs | 1 - src/models/application/modes/syntax.rs | 9 +++++++-- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index 4fc1c69e..6d36a394 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -231,16 +231,20 @@ pub fn switch_to_syntax_mode(app: &mut Application) -> Result { .as_ref() .ok_or("Switching syntaxes requires an open buffer")?; + app.switch_to(ModeKey::Syntax); let config = app.preferences.borrow().search_select_config(); - app.mode = Mode::Syntax(SyntaxMode::new( - app.workspace - .syntax_set - .syntaxes() - .iter() - .map(|syntax| syntax.name.clone()) - .collect(), - config, - )); + let syntaxes = app + .workspace + .syntax_set + .syntaxes() + .iter() + .map(|syntax| syntax.name.clone()) + .collect(); + match app.mode { + Mode::Syntax(ref mut mode) => mode.reset(syntaxes, config), + _ => (), + } + commands::search_select::search(app)?; Ok(()) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index 7f780163..c810078c 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -298,7 +298,6 @@ impl Application { self.modes.insert( ModeKey::Syntax, Mode::Syntax(SyntaxMode::new( - Vec::new(), self.preferences.borrow().search_select_config(), )), ); diff --git a/src/models/application/modes/syntax.rs b/src/models/application/modes/syntax.rs index 50b94e5e..e106073c 100644 --- a/src/models/application/modes/syntax.rs +++ b/src/models/application/modes/syntax.rs @@ -13,15 +13,20 @@ pub struct SyntaxMode { } impl SyntaxMode { - pub fn new(syntaxes: Vec, config: SearchSelectConfig) -> SyntaxMode { + pub fn new(config: SearchSelectConfig) -> SyntaxMode { SyntaxMode { insert: true, input: String::new(), - syntaxes, + syntaxes: Vec::new(), results: SelectableVec::new(Vec::new()), config, } } + + pub fn reset(&mut self, syntaxes: Vec, config: SearchSelectConfig) { + self.syntaxes = syntaxes; + self.config = config; + } } impl fmt::Display for SyntaxMode { From 741814d146d42091e9cc9ac3544aa39617a670f6 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Mon, 4 Mar 2024 23:05:33 -0500 Subject: [PATCH 29/37] Update switch_to_theme_mode --- src/commands/application.rs | 23 ++++++++++++++--------- src/models/application/mod.rs | 1 - src/models/application/modes/theme.rs | 9 +++++++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index 6d36a394..6cb15763 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -133,16 +133,21 @@ pub fn switch_to_symbol_jump_mode(app: &mut Application) -> Result { } pub fn switch_to_theme_mode(app: &mut Application) -> Result { + let themes = app + .view + .theme_set + .themes + .keys() + .map(|k| k.to_string()) + .collect(); let config = app.preferences.borrow().search_select_config(); - app.mode = Mode::Theme(ThemeMode::new( - app.view - .theme_set - .themes - .keys() - .map(|k| k.to_string()) - .collect(), - config, - )); + + app.switch_to(ModeKey::Theme); + match app.mode { + Mode::Theme(ref mut mode) => mode.reset(themes, config), + _ => (), + } + commands::search_select::search(app)?; Ok(()) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index c810078c..f7a8f469 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -304,7 +304,6 @@ impl Application { self.modes.insert( ModeKey::Theme, Mode::Theme(ThemeMode::new( - Vec::new(), self.preferences.borrow().search_select_config(), )), ); diff --git a/src/models/application/modes/theme.rs b/src/models/application/modes/theme.rs index d093fd36..c184ef57 100644 --- a/src/models/application/modes/theme.rs +++ b/src/models/application/modes/theme.rs @@ -13,15 +13,20 @@ pub struct ThemeMode { } impl ThemeMode { - pub fn new(themes: Vec, config: SearchSelectConfig) -> ThemeMode { + pub fn new(config: SearchSelectConfig) -> ThemeMode { ThemeMode { insert: true, input: String::new(), - themes, + themes: Vec::new(), results: SelectableVec::new(Vec::new()), config, } } + + pub fn reset(&mut self, themes: Vec, config: SearchSelectConfig) { + self.themes = themes; + self.config = config; + } } impl fmt::Display for ThemeMode { From 4586cf971cc2625f406602c7febd61dfa73ce059 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Mon, 4 Mar 2024 23:08:49 -0500 Subject: [PATCH 30/37] Update switch_to_command_mode --- src/commands/application.rs | 9 +++++++-- src/models/application/modes/command/mod.rs | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index 6cb15763..721e32eb 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -1,7 +1,6 @@ use crate::commands::{self, Result}; use crate::errors::*; use crate::input::KeyMap; -use crate::models::application::modes::*; use crate::models::application::{Application, Mode, ModeKey}; use crate::util; use scribe::Buffer; @@ -107,7 +106,13 @@ pub fn switch_to_open_mode(app: &mut Application) -> Result { pub fn switch_to_command_mode(app: &mut Application) -> Result { let config = app.preferences.borrow().search_select_config(); - app.mode = Mode::Command(CommandMode::new(config)); + + app.switch_to(ModeKey::Command); + match app.mode { + Mode::Command(ref mut mode) => mode.reset(config), + _ => (), + } + commands::search_select::search(app)?; Ok(()) diff --git a/src/models/application/modes/command/mod.rs b/src/models/application/modes/command/mod.rs index 5f68f6b4..d27c3388 100644 --- a/src/models/application/modes/command/mod.rs +++ b/src/models/application/modes/command/mod.rs @@ -27,6 +27,10 @@ impl CommandMode { config, } } + + pub fn reset(&mut self, config: SearchSelectConfig) { + self.config = config; + } } impl fmt::Display for CommandMode { From c73ec148baf9786906151cc9276a7e10f0b4e933 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Tue, 5 Mar 2024 08:50:14 -0500 Subject: [PATCH 31/37] Update switch_to to ignore requests for the current mode --- src/models/application/mod.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/models/application/mod.rs b/src/models/application/mod.rs index f7a8f469..48b5dc96 100644 --- a/src/models/application/mod.rs +++ b/src/models/application/mod.rs @@ -226,6 +226,10 @@ impl Application { } pub fn switch_to(&mut self, mode_key: ModeKey) { + if self.current_mode == mode_key { + return; + } + // Check out the specified mode. let mut mode = self.modes.remove(&mode_key).unwrap(); @@ -528,4 +532,19 @@ mod tests { assert_eq!(app.current_mode, ModeKey::Insert); assert!(matches!(app.mode, Mode::Insert)); } + + #[test] + fn switch_to_handles_switching_to_current_mode() { + let mut app = Application::new(&Vec::new()).unwrap(); + + app.switch_to(ModeKey::Insert); + + assert_eq!(app.current_mode, ModeKey::Insert); + assert!(matches!(app.mode, Mode::Insert)); + + app.switch_to(ModeKey::Insert); + + assert_eq!(app.current_mode, ModeKey::Insert); + assert!(matches!(app.mode, Mode::Insert)); + } } From 391ee9b0cf84c55fff6d8bffbb003c5a5144a728 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Tue, 5 Mar 2024 22:50:34 -0500 Subject: [PATCH 32/37] Migrate manual mode changes to switch_to --- src/commands/buffer.rs | 17 +++++++++++------ src/commands/path.rs | 4 ++-- src/commands/search_select.rs | 11 +++-------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/commands/buffer.rs b/src/commands/buffer.rs index 7f0f5dfd..4b3074eb 100644 --- a/src/commands/buffer.rs +++ b/src/commands/buffer.rs @@ -1,8 +1,7 @@ use crate::commands::{self, Result}; use crate::errors::*; use crate::input::Key; -use crate::models::application::modes::ConfirmMode; -use crate::models::application::{Application, ClipboardContent, Mode}; +use crate::models::application::{Application, ClipboardContent, Mode, ModeKey}; use crate::util; use crate::util::token::{adjacent_token_position, Direction}; use scribe::buffer::{Buffer, Position, Range, Token}; @@ -204,8 +203,11 @@ pub fn close(app: &mut Application) -> Result { app.workspace.close_current_buffer(); } else { // Display a confirmation prompt before closing a modified buffer. - let confirm_mode = ConfirmMode::new(close); - app.mode = Mode::Confirm(confirm_mode); + app.switch_to(ModeKey::Confirm); + match app.mode { + Mode::Confirm(ref mut mode) => mode.command = close, + _ => (), + } } Ok(()) @@ -249,8 +251,11 @@ pub fn close_others(app: &mut Application) -> Result { if modified_buffer { // Display a confirmation prompt before closing a modified buffer. - let confirm_mode = ConfirmMode::new(close_others_confirm); - app.mode = Mode::Confirm(confirm_mode); + app.switch_to(ModeKey::Confirm); + match app.mode { + Mode::Confirm(ref mut mode) => mode.command = close_others_confirm, + _ => (), + } break; } diff --git a/src/commands/path.rs b/src/commands/path.rs index d72cb4c7..0fdc0149 100644 --- a/src/commands/path.rs +++ b/src/commands/path.rs @@ -1,7 +1,7 @@ use crate::commands::{self, Result}; use crate::errors::*; use crate::input::Key; -use crate::models::application::{Application, Mode}; +use crate::models::application::{Application, Mode, ModeKey}; use std::path::PathBuf; pub fn push_char(app: &mut Application) -> Result { @@ -51,7 +51,7 @@ pub fn accept_path(app: &mut Application) -> Result { app.workspace .update_current_syntax() .chain_err(|| BUFFER_SYNTAX_UPDATE_FAILED)?; - app.mode = Mode::Normal; + app.switch_to(ModeKey::Normal); if save_on_accept { commands::buffer::save(app) diff --git a/src/commands/search_select.rs b/src/commands/search_select.rs index 5e6651bf..57e5931d 100644 --- a/src/commands/search_select.rs +++ b/src/commands/search_select.rs @@ -3,16 +3,10 @@ use crate::errors::*; use crate::input::Key; use crate::models::application::modes::open::DisplayablePath; use crate::models::application::modes::SearchSelectMode; -use crate::models::application::{Application, Mode}; -use std::mem; +use crate::models::application::{Application, Mode, ModeKey}; pub fn accept(app: &mut Application) -> Result { - // Consume the application mode. This is necessary because the selection in - // command mode needs to run against the application, but we can't hold the - // reference to the selection and lend the app mutably to it at the time. - let mut app_mode = mem::replace(&mut app.mode, Mode::Normal); - - match app_mode { + match app.mode { Mode::Command(ref mode) => { let selection = mode.selection().ok_or("No command selected")?; @@ -76,6 +70,7 @@ pub fn accept(app: &mut Application) -> Result { _ => bail!("Can't accept selection outside of search select mode."), } + app.switch_to(ModeKey::Normal); commands::view::scroll_cursor_to_center(app).ok(); Ok(()) From e2b398db4a19a38b4a664cafc7d3adb1aad84f13 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 7 Apr 2024 00:10:40 -0400 Subject: [PATCH 33/37] Replace single-pattern match with if let --- src/commands/application.rs | 53 +++++++++++++++---------------------- src/commands/buffer.rs | 11 ++++---- 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index 721e32eb..a2c141e8 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -51,9 +51,8 @@ pub fn switch_to_jump_mode(app: &mut Application) -> Result { .line; app.switch_to(ModeKey::Jump); - match app.mode { - Mode::Jump(ref mut mode) => mode.reset(line), - _ => (), + if let Mode::Jump(ref mut mode) = app.mode { + mode.reset(line) } Ok(()) @@ -73,9 +72,8 @@ pub fn switch_to_second_stage_jump_mode(app: &mut Application) -> Result { pub fn switch_to_line_jump_mode(app: &mut Application) -> Result { if app.workspace.current_buffer.is_some() { app.switch_to(ModeKey::LineJump); - match app.mode { - Mode::LineJump(ref mut mode) => mode.input = String::new(), - _ => (), + if let Mode::LineJump(ref mut mode) = app.mode { + mode.input = String::new() } } else { bail!(BUFFER_MISSING); @@ -89,14 +87,13 @@ pub fn switch_to_open_mode(app: &mut Application) -> Result { let config = app.preferences.borrow().search_select_config(); app.switch_to(ModeKey::Open); - match app.mode { - Mode::Open(ref mut mode) => mode.reset( + if let Mode::Open(ref mut mode) = app.mode { + mode.reset( app.workspace.path.clone(), exclusions, app.event_channel.clone(), config, - ), - _ => (), + ); } commands::search_select::search(app)?; @@ -108,9 +105,8 @@ pub fn switch_to_command_mode(app: &mut Application) -> Result { let config = app.preferences.borrow().search_select_config(); app.switch_to(ModeKey::Command); - match app.mode { - Mode::Command(ref mut mode) => mode.reset(config), - _ => (), + if let Mode::Command(ref mut mode) = app.mode { + mode.reset(config) } commands::search_select::search(app)?; @@ -148,9 +144,8 @@ pub fn switch_to_theme_mode(app: &mut Application) -> Result { let config = app.preferences.borrow().search_select_config(); app.switch_to(ModeKey::Theme); - match app.mode { - Mode::Theme(ref mut mode) => mode.reset(themes, config), - _ => (), + if let Mode::Theme(ref mut mode) = app.mode { + mode.reset(themes, config) } commands::search_select::search(app)?; @@ -167,9 +162,8 @@ pub fn switch_to_select_mode(app: &mut Application) -> Result { .cursor; app.switch_to(ModeKey::Select); - match app.mode { - Mode::Select(ref mut mode) => mode.anchor = position, - _ => (), + if let Mode::Select(ref mut mode) = app.mode { + mode.anchor = position } Ok(()) @@ -185,9 +179,8 @@ pub fn switch_to_select_line_mode(app: &mut Application) -> Result { .line; app.switch_to(ModeKey::SelectLine); - match app.mode { - Mode::SelectLine(ref mut mode) => mode.anchor = line, - _ => (), + if let Mode::SelectLine(ref mut mode) = app.mode { + mode.anchor = line } Ok(()) @@ -196,10 +189,8 @@ pub fn switch_to_select_line_mode(app: &mut Application) -> Result { pub fn switch_to_search_mode(app: &mut Application) -> Result { if app.workspace.current_buffer.is_some() { app.switch_to(ModeKey::Search); - - match app.mode { - Mode::Search(ref mut mode) => mode.insert = true, - _ => (), + if let Mode::Search(ref mut mode) = app.mode { + mode.insert = true } } else { bail!(BUFFER_MISSING); @@ -224,9 +215,8 @@ pub fn switch_to_path_mode(app: &mut Application) -> Result { format!("{}/", app.workspace.path.to_string_lossy())); app.switch_to(ModeKey::Path); - match app.mode { - Mode::Path(ref mut mode) => mode.reset(path), - _ => (), + if let Mode::Path(ref mut mode) = app.mode { + mode.reset(path) } Ok(()) @@ -250,9 +240,8 @@ pub fn switch_to_syntax_mode(app: &mut Application) -> Result { .iter() .map(|syntax| syntax.name.clone()) .collect(); - match app.mode { - Mode::Syntax(ref mut mode) => mode.reset(syntaxes, config), - _ => (), + if let Mode::Syntax(ref mut mode) = app.mode { + mode.reset(syntaxes, config) } commands::search_select::search(app)?; diff --git a/src/commands/buffer.rs b/src/commands/buffer.rs index 4b3074eb..8836dbe7 100644 --- a/src/commands/buffer.rs +++ b/src/commands/buffer.rs @@ -204,9 +204,8 @@ pub fn close(app: &mut Application) -> Result { } else { // Display a confirmation prompt before closing a modified buffer. app.switch_to(ModeKey::Confirm); - match app.mode { - Mode::Confirm(ref mut mode) => mode.command = close, - _ => (), + if let Mode::Confirm(ref mut mode) = app.mode { + mode.command = close } } @@ -252,10 +251,10 @@ pub fn close_others(app: &mut Application) -> Result { if modified_buffer { // Display a confirmation prompt before closing a modified buffer. app.switch_to(ModeKey::Confirm); - match app.mode { - Mode::Confirm(ref mut mode) => mode.command = close_others_confirm, - _ => (), + if let Mode::Confirm(ref mut mode) = app.mode { + mode.command = close_others_confirm } + break; } From 2d4b288c08ada91a87625c57ab547ddc1bd283c0 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 7 Apr 2024 00:23:22 -0400 Subject: [PATCH 34/37] Use Default trait for PathMode constructor --- src/models/application/modes/path.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/models/application/modes/path.rs b/src/models/application/modes/path.rs index 1277c825..758fd146 100644 --- a/src/models/application/modes/path.rs +++ b/src/models/application/modes/path.rs @@ -1,5 +1,6 @@ use std::fmt; +#[derive(Default)] pub struct PathMode { pub input: String, pub save_on_accept: bool, @@ -7,10 +8,7 @@ pub struct PathMode { impl PathMode { pub fn new() -> PathMode { - PathMode { - input: String::new(), - save_on_accept: false, - } + PathMode::default() } pub fn push_char(&mut self, c: char) { From 9f699d073714c89deab154b055c3e912cba87de2 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Sun, 7 Apr 2024 23:43:05 -0400 Subject: [PATCH 35/37] Use reset pattern for all modes --- src/commands/application.rs | 8 ++++---- src/models/application/modes/line_jump.rs | 4 ++++ src/models/application/modes/search.rs | 4 ++++ src/models/application/modes/select.rs | 4 ++++ src/models/application/modes/select_line.rs | 4 ++++ 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index a2c141e8..95384f6e 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -73,7 +73,7 @@ pub fn switch_to_line_jump_mode(app: &mut Application) -> Result { if app.workspace.current_buffer.is_some() { app.switch_to(ModeKey::LineJump); if let Mode::LineJump(ref mut mode) = app.mode { - mode.input = String::new() + mode.reset(); } } else { bail!(BUFFER_MISSING); @@ -163,7 +163,7 @@ pub fn switch_to_select_mode(app: &mut Application) -> Result { app.switch_to(ModeKey::Select); if let Mode::Select(ref mut mode) = app.mode { - mode.anchor = position + mode.reset(position); } Ok(()) @@ -180,7 +180,7 @@ pub fn switch_to_select_line_mode(app: &mut Application) -> Result { app.switch_to(ModeKey::SelectLine); if let Mode::SelectLine(ref mut mode) = app.mode { - mode.anchor = line + mode.reset(line); } Ok(()) @@ -190,7 +190,7 @@ pub fn switch_to_search_mode(app: &mut Application) -> Result { if app.workspace.current_buffer.is_some() { app.switch_to(ModeKey::Search); if let Mode::Search(ref mut mode) = app.mode { - mode.insert = true + mode.reset(); } } else { bail!(BUFFER_MISSING); diff --git a/src/models/application/modes/line_jump.rs b/src/models/application/modes/line_jump.rs index f46c07fd..860daac5 100644 --- a/src/models/application/modes/line_jump.rs +++ b/src/models/application/modes/line_jump.rs @@ -7,4 +7,8 @@ impl LineJumpMode { pub fn new() -> LineJumpMode { LineJumpMode::default() } + + pub fn reset(&mut self) { + self.input = String::new(); + } } diff --git a/src/models/application/modes/search.rs b/src/models/application/modes/search.rs index d21de0e1..864604ca 100644 --- a/src/models/application/modes/search.rs +++ b/src/models/application/modes/search.rs @@ -18,6 +18,10 @@ impl SearchMode { } } + pub fn reset(&mut self) { + self.insert = true; + } + pub fn insert_mode(&self) -> bool { self.insert } diff --git a/src/models/application/modes/select.rs b/src/models/application/modes/select.rs index 604125c0..77314b6d 100644 --- a/src/models/application/modes/select.rs +++ b/src/models/application/modes/select.rs @@ -8,4 +8,8 @@ impl SelectMode { pub fn new(anchor: Position) -> SelectMode { SelectMode { anchor } } + + pub fn reset(&mut self, anchor: Position) { + self.anchor = anchor; + } } diff --git a/src/models/application/modes/select_line.rs b/src/models/application/modes/select_line.rs index bab71a54..428c91bd 100644 --- a/src/models/application/modes/select_line.rs +++ b/src/models/application/modes/select_line.rs @@ -9,6 +9,10 @@ impl SelectLineMode { SelectLineMode { anchor } } + pub fn reset(&mut self, anchor: usize) { + self.anchor = anchor; + } + pub fn to_range(&self, cursor: &Position) -> Range { LineRange::new(self.anchor, cursor.line).to_inclusive_range() } From 9201aca45000ac3ffb9a911f563197d9af53986c Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Tue, 9 Apr 2024 23:59:21 -0400 Subject: [PATCH 36/37] Use default pattern for theme mode reset --- src/models/application/modes/theme.rs | 15 +++++++++------ src/util/selectable_vec.rs | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/models/application/modes/theme.rs b/src/models/application/modes/theme.rs index c184ef57..a01d7b8c 100644 --- a/src/models/application/modes/theme.rs +++ b/src/models/application/modes/theme.rs @@ -4,6 +4,7 @@ use fragment; use std::fmt; use std::slice::Iter; +#[derive(Default)] pub struct ThemeMode { insert: bool, input: String, @@ -15,17 +16,19 @@ pub struct ThemeMode { impl ThemeMode { pub fn new(config: SearchSelectConfig) -> ThemeMode { ThemeMode { - insert: true, - input: String::new(), - themes: Vec::new(), - results: SelectableVec::new(Vec::new()), config, + insert: true, + ..Default::default() } } pub fn reset(&mut self, themes: Vec, config: SearchSelectConfig) { - self.themes = themes; - self.config = config; + *self = ThemeMode { + config, + insert: true, + themes, + ..Default::default() + }; } } diff --git a/src/util/selectable_vec.rs b/src/util/selectable_vec.rs index 0f0855f2..9e8d93d1 100644 --- a/src/util/selectable_vec.rs +++ b/src/util/selectable_vec.rs @@ -3,6 +3,7 @@ use std::ops::Deref; /// A simple decorator around a Vec that allows a single element to be selected. /// The selection can be incremented/decremented in single steps, and the /// selected value wraps when moved beyond either edge of the set. +#[derive(Default)] pub struct SelectableVec { set: Vec, selected_index: usize, From 0d82d9ab176f9d08a45e583dababa52b273747f2 Mon Sep 17 00:00:00 2001 From: Jordan MacDonald Date: Thu, 25 Jul 2024 16:42:10 -0400 Subject: [PATCH 37/37] Fix search mode reset behaviour Resetting this mode should clear its input and results. That said, we don't want to reset automatically when entering this mode, because that breaks jumping to the next result from normal mode. --- src/commands/application.rs | 3 --- src/commands/search.rs | 6 +++--- src/input/key_map/default.yml | 4 ++-- src/models/application/modes/search.rs | 2 ++ 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/commands/application.rs b/src/commands/application.rs index 95384f6e..cc8ebc6a 100644 --- a/src/commands/application.rs +++ b/src/commands/application.rs @@ -189,9 +189,6 @@ pub fn switch_to_select_line_mode(app: &mut Application) -> Result { pub fn switch_to_search_mode(app: &mut Application) -> Result { if app.workspace.current_buffer.is_some() { app.switch_to(ModeKey::Search); - if let Mode::Search(ref mut mode) = app.mode { - mode.reset(); - } } else { bail!(BUFFER_MISSING); } diff --git a/src/commands/search.rs b/src/commands/search.rs index 4ba7e4f3..72d88d8e 100644 --- a/src/commands/search.rs +++ b/src/commands/search.rs @@ -67,11 +67,11 @@ pub fn accept_query(app: &mut Application) -> Result { Ok(()) } -pub fn clear_query(app: &mut Application) -> Result { +pub fn reset(app: &mut Application) -> Result { if let Mode::Search(ref mut mode) = app.mode { - mode.input = None; + mode.reset(); } else { - bail!("Can't clear search outside of search mode"); + bail!("Can't reset search outside of search mode"); }; Ok(()) diff --git a/src/input/key_map/default.yml b/src/input/key_map/default.yml index bf8b39e9..83557a79 100644 --- a/src/input/key_map/default.yml +++ b/src/input/key_map/default.yml @@ -58,7 +58,7 @@ normal: "#": application::switch_to_syntax_mode /: - application::switch_to_search_mode - - search::clear_query + - search::reset ",": view::scroll_up ">": buffer::indent_line "<": buffer::outdent_line @@ -125,7 +125,7 @@ search: - search::run /: - application::switch_to_search_mode - - search::clear_query + - search::reset m: view::scroll_down ",": view::scroll_up n: search::move_to_next_result diff --git a/src/models/application/modes/search.rs b/src/models/application/modes/search.rs index 864604ca..e508aaf6 100644 --- a/src/models/application/modes/search.rs +++ b/src/models/application/modes/search.rs @@ -20,6 +20,8 @@ impl SearchMode { pub fn reset(&mut self) { self.insert = true; + self.input = None; + self.results = None; } pub fn insert_mode(&self) -> bool {