diff options
author | Jesse Luehrs <doy@tozt.net> | 2021-11-17 22:29:05 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2021-11-17 22:29:05 -0500 |
commit | 70f48c3ef7dde34546b6d646818333505d0e4777 (patch) | |
tree | db5d3fd7a2f4cfd168a73e03c8c8272ac375ecc1 /src | |
parent | 96f335c58f9b9b9035a43f106f2dfddbe62777e7 (diff) | |
download | nbsh-70f48c3ef7dde34546b6d646818333505d0e4777.tar.gz nbsh-70f48c3ef7dde34546b6d646818333505d0e4777.zip |
refactor
Diffstat (limited to 'src')
-rw-r--r-- | src/action.rs | 11 | ||||
-rw-r--r-- | src/history.rs | 19 | ||||
-rw-r--r-- | src/main.rs | 29 | ||||
-rw-r--r-- | src/readline.rs | 29 | ||||
-rw-r--r-- | src/state.rs | 88 |
5 files changed, 89 insertions, 87 deletions
diff --git a/src/action.rs b/src/action.rs index c7f437c..22f088e 100644 --- a/src/action.rs +++ b/src/action.rs @@ -4,6 +4,7 @@ pub enum Action { ForceRedraw, Run(String), UpdateFocus(crate::state::Focus), + ToggleFullscreen(usize), Resize((u16, u16)), Quit, } @@ -37,6 +38,7 @@ struct Pending { force_redraw: Option<()>, run: std::collections::VecDeque<String>, focus: Option<crate::state::Focus>, + fullscreen: std::collections::VecDeque<usize>, size: Option<(u16, u16)>, done: bool, } @@ -52,6 +54,7 @@ impl Pending { || self.force_redraw.is_some() || !self.run.is_empty() || self.focus.is_some() + || !self.fullscreen.is_empty() || self.size.is_some() } @@ -65,6 +68,11 @@ impl Pending { if self.focus.is_some() { return Some(Action::UpdateFocus(self.focus.take().unwrap())); } + if !self.fullscreen.is_empty() { + return Some(Action::ToggleFullscreen( + self.fullscreen.pop_front().unwrap(), + )); + } if self.force_redraw.is_some() { self.force_redraw.take(); self.render.take(); @@ -86,6 +94,9 @@ impl Pending { Some(Action::ForceRedraw) => self.force_redraw = Some(()), Some(Action::Run(cmd)) => self.run.push_back(cmd.to_string()), Some(Action::UpdateFocus(focus)) => self.focus = Some(*focus), + Some(Action::ToggleFullscreen(idx)) => { + self.fullscreen.push_back(*idx); + } Some(Action::Resize(size)) => self.size = Some(*size), Some(Action::Quit) | None => self.done = true, } diff --git a/src/history.rs b/src/history.rs index 8549ab7..c55f62c 100644 --- a/src/history.rs +++ b/src/history.rs @@ -7,21 +7,21 @@ use textmode::Textmode as _; pub struct History { size: (u16, u16), entries: Vec<crate::util::Mutex<HistoryEntry>>, - action: async_std::channel::Sender<crate::action::Action>, } impl History { - pub fn new( - action: async_std::channel::Sender<crate::action::Action>, - ) -> Self { + pub fn new() -> Self { Self { size: (24, 80), entries: vec![], - action, } } - pub async fn run(&mut self, cmd: &str) -> anyhow::Result<usize> { + pub async fn run( + &mut self, + cmd: &str, + action_w: async_std::channel::Sender<crate::action::Action>, + ) -> anyhow::Result<usize> { let (exe, args) = crate::parse::cmd(cmd); let mut process = async_std::process::Command::new(&exe); process.args(&args); @@ -37,7 +37,6 @@ impl History { cmd, self.size, input_w, resize_w, )); let task_entry = async_std::sync::Arc::clone(&entry); - let task_action = self.action.clone(); async_std::task::spawn(async move { loop { enum Res { @@ -70,7 +69,7 @@ impl History { Some(ExitInfo::new( child.status().await.unwrap(), )); - task_action + action_w .send(crate::action::Action::UpdateFocus( crate::state::Focus::Readline, )) @@ -79,7 +78,7 @@ impl History { break; } } - task_action + action_w .send(crate::action::Action::Render) .await .unwrap(); @@ -122,7 +121,7 @@ impl History { Ok(self.entries.len() - 1) } - pub async fn handle_key(&mut self, key: textmode::Key, idx: usize) { + pub async fn handle_key(&self, key: textmode::Key, idx: usize) { let entry = self.entries[idx].lock_arc().await; if entry.running() { entry.input.send(key.into_bytes()).await.unwrap(); diff --git a/src/main.rs b/src/main.rs index ba8fa8a..73a05ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,19 @@ mod util; use async_std::stream::StreamExt as _; +async fn resize( + action_w: &async_std::channel::Sender<crate::action::Action>, +) { + let size = terminal_size::terminal_size().map_or( + (24, 80), + |(terminal_size::Width(w), terminal_size::Height(h))| (h, w), + ); + action_w + .send(crate::action::Action::Resize(size)) + .await + .unwrap(); +} + async fn async_main() -> anyhow::Result<()> { let mut input = textmode::Input::new().await?; let mut output = textmode::Output::new().await?; @@ -25,30 +38,34 @@ async fn async_main() -> anyhow::Result<()> { let (action_w, action_r) = async_std::channel::unbounded(); - let mut state = state::State::new(action_w); + let state = state::State::new(); state.render(&mut output, true).await.unwrap(); let state = util::mutex(state); { - let state = async_std::sync::Arc::clone(&state); let mut signals = signal_hook_async_std::Signals::new(&[ signal_hook::consts::signal::SIGWINCH, ])?; + let action_w = action_w.clone(); async_std::task::spawn(async move { while signals.next().await.is_some() { - state.lock_arc().await.resize().await; + resize(&action_w).await; } }); } - state.lock_arc().await.resize().await; + resize(&action_w).await; { let state = async_std::sync::Arc::clone(&state); + let action_w = action_w.clone(); async_std::task::spawn(async move { while let Some(key) = input.read_key().await.unwrap() { - state.lock_arc().await.handle_input(key).await; + let action = state.lock_arc().await.handle_key(key).await; + if let Some(action) = action { + action_w.send(action).await.unwrap(); + } } }); } @@ -58,7 +75,7 @@ async fn async_main() -> anyhow::Result<()> { state .lock_arc() .await - .handle_action(action, &mut output) + .handle_action(action, &mut output, &action_w) .await; } diff --git a/src/readline.rs b/src/readline.rs index 093de3d..529c102 100644 --- a/src/readline.rs +++ b/src/readline.rs @@ -6,23 +6,22 @@ pub struct Readline { prompt: String, input_line: String, pos: usize, - action: async_std::channel::Sender<crate::action::Action>, } impl Readline { - pub fn new( - action: async_std::channel::Sender<crate::action::Action>, - ) -> Self { + pub fn new() -> Self { Self { size: (24, 80), prompt: "$ ".into(), input_line: "".into(), pos: 0, - action, } } - pub async fn handle_key(&mut self, key: textmode::Key) { + pub async fn handle_key( + &mut self, + key: textmode::Key, + ) -> Option<crate::action::Action> { match key { textmode::Key::String(s) => self.add_input(&s), textmode::Key::Char(c) => { @@ -30,20 +29,15 @@ impl Readline { } textmode::Key::Ctrl(b'c') => self.clear_input(), textmode::Key::Ctrl(b'd') => { - self.action.send(crate::action::Action::Quit).await.unwrap(); + return Some(crate::action::Action::Quit); } textmode::Key::Ctrl(b'l') => { - self.action - .send(crate::action::Action::ForceRedraw) - .await - .unwrap(); + return Some(crate::action::Action::ForceRedraw); } textmode::Key::Ctrl(b'm') => { - self.action - .send(crate::action::Action::Run(self.input())) - .await - .unwrap(); + let cmd = self.input(); self.clear_input(); + return Some(crate::action::Action::Run(cmd)); } textmode::Key::Ctrl(b'u') => self.clear_backwards(), textmode::Key::Backspace => self.backspace(), @@ -51,10 +45,7 @@ impl Readline { textmode::Key::Right => self.cursor_right(), _ => {} } - self.action - .send(crate::action::Action::Render) - .await - .unwrap(); + Some(crate::action::Action::Render) } pub fn lines(&self) -> usize { diff --git a/src/state.rs b/src/state.rs index f75b7dc..8271cec 100644 --- a/src/state.rs +++ b/src/state.rs @@ -6,15 +6,12 @@ pub struct State { focus: Focus, escape: bool, hide_readline: bool, - action: async_std::channel::Sender<crate::action::Action>, } impl State { - pub fn new( - action: async_std::channel::Sender<crate::action::Action>, - ) -> Self { - let readline = crate::readline::Readline::new(action.clone()); - let history = crate::history::History::new(action.clone()); + pub fn new() -> Self { + let readline = crate::readline::Readline::new(); + let history = crate::history::History::new(); let focus = Focus::Readline; Self { readline, @@ -22,12 +19,11 @@ impl State { focus, escape: false, hide_readline: false, - action, } } pub async fn render( - &mut self, + &self, out: &mut textmode::Output, hard: bool, ) -> anyhow::Result<()> { @@ -64,6 +60,7 @@ impl State { &mut self, action: crate::action::Action, out: &mut textmode::Output, + action_w: &async_std::channel::Sender<crate::action::Action>, ) { match action { crate::action::Action::Render => { @@ -73,15 +70,21 @@ impl State { self.render(out, true).await.unwrap(); } crate::action::Action::Run(ref cmd) => { - let idx = self.history.run(cmd).await.unwrap(); + let idx = + self.history.run(cmd, action_w.clone()).await.unwrap(); self.focus = Focus::History(idx); self.hide_readline = true; + self.render(out, false).await.unwrap(); } crate::action::Action::UpdateFocus(new_focus) => { self.focus = new_focus; self.hide_readline = false; self.render(out, false).await.unwrap(); } + crate::action::Action::ToggleFullscreen(idx) => { + self.history.toggle_fullscreen(idx).await; + self.render(out, false).await.unwrap(); + } crate::action::Action::Resize(new_size) => { self.readline.resize(new_size).await; self.history.resize(new_size).await; @@ -96,26 +99,25 @@ impl State { } } - pub async fn handle_input(&mut self, key: textmode::Key) { + pub async fn handle_key( + &mut self, + key: textmode::Key, + ) -> Option<crate::action::Action> { if self.escape { + self.escape = false; let mut fallthrough = false; match key { textmode::Key::Ctrl(b'e') => { fallthrough = true; } textmode::Key::Ctrl(b'l') => { - self.action - .send(crate::action::Action::ForceRedraw) - .await - .unwrap(); + return Some(crate::action::Action::ForceRedraw); } textmode::Key::Char('f') => { if let Focus::History(idx) = self.focus { - self.history.toggle_fullscreen(idx).await; - self.action - .send(crate::action::Action::Render) - .await - .unwrap(); + return Some( + crate::action::Action::ToggleFullscreen(idx), + ); } } textmode::Key::Char('j') => { @@ -129,12 +131,9 @@ impl State { } Focus::Readline => Focus::Readline, }; - self.focus = new_focus; - self.hide_readline = false; - self.action - .send(crate::action::Action::Render) - .await - .unwrap(); + return Some(crate::action::Action::UpdateFocus( + new_focus, + )); } textmode::Key::Char('k') => { let new_focus = match self.focus { @@ -149,48 +148,33 @@ impl State { Focus::History(self.history.entry_count() - 1) } }; - self.focus = new_focus; - self.hide_readline = false; - self.action - .send(crate::action::Action::Render) - .await - .unwrap(); + return Some(crate::action::Action::UpdateFocus( + new_focus, + )); } textmode::Key::Char('r') => { - self.focus = Focus::Readline; - self.hide_readline = false; - self.action - .send(crate::action::Action::Render) - .await - .unwrap(); + return Some(crate::action::Action::UpdateFocus( + Focus::Readline, + )); } _ => {} } - self.escape = false; if !fallthrough { - return; + return None; } } else if key == textmode::Key::Ctrl(b'e') { self.escape = true; - return; + return None; } match self.focus { Focus::Readline => self.readline.handle_key(key).await, - Focus::History(idx) => self.history.handle_key(key, idx).await, + Focus::History(idx) => { + self.history.handle_key(key, idx).await; + None + } } } - - pub async fn resize(&mut self) { - let size = terminal_size::terminal_size().map_or( - (24, 80), - |(terminal_size::Width(w), terminal_size::Height(h))| (h, w), - ); - self.action - .send(crate::action::Action::Resize(size)) - .await - .unwrap(); - } } #[derive(Copy, Clone, Debug)] |