diff options
author | Jeff Zhao <jeff.no.zhao@gmail.com> | 2021-10-02 08:21:43 -0400 |
---|---|---|
committer | Jeff Zhao <jeff.no.zhao@gmail.com> | 2021-10-02 08:21:43 -0400 |
commit | 4a22c9a36c2895b3937daa23568b4f1cef599ed9 (patch) | |
tree | 9e919560125b3e9a654238bc01c47bdb3d64c065 /src | |
parent | fdbedc755be268884e111c357c8156561cd10f3d (diff) |
add basic support for command history
- move worker processing into input.rs
- change readline to read_and_execute
Diffstat (limited to 'src')
-rw-r--r-- | src/commands/command_line.rs | 3 | ||||
-rw-r--r-- | src/commands/key_command.rs | 2 | ||||
-rw-r--r-- | src/commands/rename_file.rs | 4 | ||||
-rw-r--r-- | src/context/app_context.rs | 18 | ||||
-rw-r--r-- | src/context/commandline_context.rs | 27 | ||||
-rw-r--r-- | src/context/mod.rs | 2 | ||||
-rw-r--r-- | src/run.rs | 4 | ||||
-rw-r--r-- | src/ui/views/tui_textfield.rs | 38 | ||||
-rw-r--r-- | src/util/input.rs | 4 |
9 files changed, 91 insertions, 11 deletions
diff --git a/src/commands/command_line.rs b/src/commands/command_line.rs index 0c80aa2..b8278b9 100644 --- a/src/commands/command_line.rs +++ b/src/commands/command_line.rs @@ -8,7 +8,7 @@ use crate::ui::TuiBackend; use super::AppExecute; -pub fn readline( +pub fn read_and_execute( context: &mut AppContext, backend: &mut TuiBackend, prefix: &str, @@ -23,6 +23,7 @@ pub fn readline( if let Some(s) = user_input { let trimmed = s.trim_start(); + context.commandline_context_mut().history_mut().add(trimmed); let command = KeyCommand::from_str(trimmed)?; command.execute(context, backend) } else { diff --git a/src/commands/key_command.rs b/src/commands/key_command.rs index b6f9a23..5d414e0 100644 --- a/src/commands/key_command.rs +++ b/src/commands/key_command.rs @@ -397,7 +397,7 @@ impl AppExecute for KeyCommand { Self::NewTab => tab_ops::new_tab(context), Self::CloseTab => tab_ops::close_tab(context), Self::CommandLine(p, s) => { - command_line::readline(context, backend, p.as_str(), s.as_str()) + command_line::read_and_execute(context, backend, p.as_str(), s.as_str()) } Self::CutFiles => file_ops::cut(context), Self::CopyFiles => file_ops::copy(context), diff --git a/src/commands/rename_file.rs b/src/commands/rename_file.rs index 718aef8..c7a6a98 100644 --- a/src/commands/rename_file.rs +++ b/src/commands/rename_file.rs @@ -61,7 +61,7 @@ pub fn _rename_file_append( ), None => (format!("rename {}", file_name), "".to_string()), }; - command_line::readline(context, backend, &prefix, &suffix) + command_line::read_and_execute(context, backend, &prefix, &suffix) } pub fn rename_file_append(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoResult<()> { @@ -86,7 +86,7 @@ pub fn _rename_file_prepend( ) -> JoshutoResult<()> { let prefix = String::from("rename "); let suffix = file_name; - command_line::readline(context, backend, &prefix, &suffix) + command_line::read_and_execute(context, backend, &prefix, &suffix) } pub fn rename_file_prepend( diff --git a/src/context/app_context.rs b/src/context/app_context.rs index df6035e..72b8426 100644 --- a/src/context/app_context.rs +++ b/src/context/app_context.rs @@ -1,7 +1,9 @@ use std::sync::mpsc; use crate::config; -use crate::context::{LocalStateContext, MessageQueue, PreviewContext, TabContext, WorkerContext}; +use crate::context::{ + CommandLineContext, LocalStateContext, MessageQueue, PreviewContext, TabContext, WorkerContext, +}; use crate::event::{AppEvent, Events}; use crate::util::search::SearchPattern; @@ -31,12 +33,17 @@ pub struct AppContext { worker_context: WorkerContext, // context related to previews preview_context: PreviewContext, + // context related to command line + commandline_context: CommandLineContext, } impl AppContext { pub fn new(config: config::AppConfig) -> Self { let events = Events::new(); let event_tx = events.event_tx.clone(); + + let mut commandline_context = CommandLineContext::new(); + commandline_context.history_mut().set_max_len(20); Self { quit: QuitType::DoNot, events, @@ -46,6 +53,7 @@ impl AppContext { message_queue: MessageQueue::new(), worker_context: WorkerContext::new(event_tx), preview_context: PreviewContext::new(), + commandline_context, config, } } @@ -110,4 +118,12 @@ impl AppContext { pub fn worker_context_mut(&mut self) -> &mut WorkerContext { &mut self.worker_context } + + pub fn commandline_context_ref(&self) -> &CommandLineContext { + &self.commandline_context + } + + pub fn commandline_context_mut(&mut self) -> &mut CommandLineContext { + &mut self.commandline_context + } } diff --git a/src/context/commandline_context.rs b/src/context/commandline_context.rs new file mode 100644 index 0000000..6a6142b --- /dev/null +++ b/src/context/commandline_context.rs @@ -0,0 +1,27 @@ +use rustyline::history; + +pub struct CommandLineContext { + history: history::History, +} + +impl std::default::Default for CommandLineContext { + fn default() -> Self { + Self { + history: history::History::new(), + } + } +} + +impl CommandLineContext { + pub fn new() -> Self { + Self::default() + } + + pub fn history_ref(&self) -> &history::History { + &self.history + } + + pub fn history_mut(&mut self) -> &mut history::History { + &mut self.history + } +} diff --git a/src/context/mod.rs b/src/context/mod.rs index d5ba100..884c492 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -1,4 +1,5 @@ mod app_context; +mod commandline_context; mod local_state; mod message_queue; mod preview_context; @@ -6,6 +7,7 @@ mod tab_context; mod worker_context; pub use self::app_context::*; +pub use self::commandline_context::*; pub use self::local_state::*; pub use self::message_queue::*; pub use self::preview_context::*; @@ -29,10 +29,6 @@ pub fn run( while context.quit == QuitType::DoNot { backend.render(TuiView::new(context)); - if !context.worker_context_ref().is_busy() && !context.worker_context_ref().is_empty() { - context.worker_context_mut().start_next_job(); - } - let event = match context.poll_event() { Ok(event) => event, Err(_) => return Ok(()), // TODO diff --git a/src/ui/views/tui_textfield.rs b/src/ui/views/tui_textfield.rs index c86b49f..348c0f4 100644 --- a/src/ui/views/tui_textfield.rs +++ b/src/ui/views/tui_textfield.rs @@ -86,6 +86,8 @@ impl<'a> TuiTextField<'a> { let terminal = backend.terminal_mut(); let _ = terminal.show_cursor(); + let mut curr_history_index = context.commandline_context_ref().history_ref().len(); + loop { terminal .draw(|frame| { @@ -186,8 +188,40 @@ impl<'a> TuiTextField<'a> { line_buffer.move_end(); completion_tracker.take(); } - Key::Up => {} - Key::Down => {} + Key::Up => { + curr_history_index = if curr_history_index > 0 { + curr_history_index - 1 + } else { + 0 + }; + line_buffer.move_home(); + line_buffer.kill_line(); + if let Some(s) = context + .commandline_context_ref() + .history_ref() + .get(curr_history_index) + { + line_buffer.insert_str(0, s); + } + } + Key::Down => { + curr_history_index = if curr_history_index + < context.commandline_context_ref().history_ref().len() + { + curr_history_index + 1 + } else { + curr_history_index + }; + line_buffer.move_home(); + line_buffer.kill_line(); + if let Some(s) = context + .commandline_context_ref() + .history_ref() + .get(curr_history_index) + { + line_buffer.insert_str(0, s); + } + } Key::Esc => { let _ = terminal.hide_cursor(); return None; diff --git a/src/util/input.rs b/src/util/input.rs index f1c2a84..4e831d0 100644 --- a/src/util/input.rs +++ b/src/util/input.rs @@ -102,6 +102,10 @@ pub fn process_finished_worker(context: &mut AppContext, res: std::io::Result<Io context.message_queue_mut().push_error(msg); } } + + if !context.worker_context_ref().is_busy() && !context.worker_context_ref().is_empty() { + context.worker_context_mut().start_next_job(); + } } pub fn process_dir_preview(context: &mut AppContext, dirlist: JoshutoDirList) { |