From db84eaac5ceaa0105422c3185e08a7637e8d97e0 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Mon, 28 Feb 2022 13:51:18 -0500 Subject: convert to std::sync::Mutex and remove a lot of unnecessary async --- src/shell/event.rs | 14 +- src/shell/history/entry.rs | 8 +- src/shell/history/mod.rs | 102 +++++++------ src/shell/history/pty.rs | 8 +- src/shell/mod.rs | 353 ++++++++++++++++++++++----------------------- src/shell/readline.rs | 4 +- 6 files changed, 246 insertions(+), 243 deletions(-) diff --git a/src/shell/event.rs b/src/shell/event.rs index b159a95..e80cdef 100644 --- a/src/shell/event.rs +++ b/src/shell/event.rs @@ -43,9 +43,9 @@ impl Reader { let inner = inner.clone(); tokio::task::spawn(async move { while let Some(event) = input.recv().await { - inner.new_event(Some(event)).await; + inner.new_event(Some(event)); } - inner.new_event(None).await; + inner.new_event(None); }); } Self(inner) @@ -57,29 +57,29 @@ impl Reader { } struct InnerReader { - pending: tokio::sync::Mutex, + pending: std::sync::Mutex, cvar: tokio::sync::Notify, } impl InnerReader { fn new() -> Self { Self { - pending: tokio::sync::Mutex::new(Pending::new()), + pending: std::sync::Mutex::new(Pending::new()), cvar: tokio::sync::Notify::new(), } } async fn recv(&self) -> Option { loop { - if let Some(event) = self.pending.lock().await.get_event() { + if let Some(event) = self.pending.lock().unwrap().get_event() { return event; } self.cvar.notified().await; } } - async fn new_event(&self, event: Option) { - self.pending.lock().await.new_event(event); + fn new_event(&self, event: Option) { + self.pending.lock().unwrap().new_event(event); self.cvar.notify_one(); } } diff --git a/src/shell/history/entry.rs b/src/shell/history/entry.rs index ac3a279..3b4717b 100644 --- a/src/shell/history/entry.rs +++ b/src/shell/history/entry.rs @@ -227,13 +227,13 @@ impl Entry { out.reset_attributes(); } - pub async fn send_input(&self, bytes: Vec) { + pub fn send_input(&self, bytes: Vec) { if self.running() { self.input.send(bytes).unwrap(); } } - pub async fn resize(&mut self, size: (u16, u16)) { + pub fn resize(&mut self, size: (u16, u16)) { if self.running() { self.resize.send(size).unwrap(); self.vt.set_size(size.0, size.1); @@ -338,10 +338,10 @@ impl Entry { } } - pub async fn finish( + pub fn finish( &mut self, env: Env, - event_w: crate::shell::event::Writer, + event_w: &crate::shell::event::Writer, ) { self.state = State::Exited(ExitInfo::new(env.latest_status())); self.env = env; diff --git a/src/shell/history/mod.rs b/src/shell/history/mod.rs index 18231af..5bcc820 100644 --- a/src/shell/history/mod.rs +++ b/src/shell/history/mod.rs @@ -6,7 +6,7 @@ mod pty; pub struct History { size: (u16, u16), - entries: Vec>>, + entries: Vec>>, scroll_pos: usize, } @@ -19,18 +19,18 @@ impl History { } } - pub async fn render( + pub fn render( &self, out: &mut impl textmode::Textmode, repl_lines: usize, focus: Option, scrolling: bool, offset: time::UtcOffset, - ) -> Result<()> { + ) { let mut used_lines = repl_lines; let mut cursor = None; for (idx, mut entry) in - self.visible(repl_lines, focus, scrolling).await.rev() + self.visible(repl_lines, focus, scrolling).rev() { let focused = focus.map_or(false, |focus| idx == focus); used_lines += @@ -59,39 +59,45 @@ impl History { out.move_to(pos.0, pos.1); out.hide_cursor(hide); } - Ok(()) } - pub async fn render_fullscreen( + pub fn render_fullscreen( &self, out: &mut impl textmode::Textmode, idx: usize, ) { - let mut entry = self.entries[idx].clone().lock_owned().await; - entry.render_fullscreen(out); + self.with_entry_mut(idx, |entry| entry.render_fullscreen(out)); + } + + pub fn send_input(&mut self, idx: usize, input: Vec) { + self.with_entry(idx, |entry| entry.send_input(input)); } - pub async fn send_input(&mut self, idx: usize, input: Vec) { - self.entry(idx).await.send_input(input).await; + pub fn should_fullscreen(&self, idx: usize) -> bool { + self.with_entry(idx, Entry::should_fullscreen) } - pub async fn resize(&mut self, size: (u16, u16)) { + pub fn running(&self, idx: usize) -> bool { + self.with_entry(idx, Entry::running) + } + + pub fn resize(&mut self, size: (u16, u16)) { self.size = size; for entry in &self.entries { - entry.clone().lock_owned().await.resize(size).await; + entry.lock().unwrap().resize(size); } } - pub async fn run( + pub fn run( &mut self, cmdline: &str, env: &Env, event_w: crate::shell::event::Writer, - ) -> Result { + ) -> usize { let (input_w, input_r) = tokio::sync::mpsc::unbounded_channel(); let (resize_w, resize_r) = tokio::sync::mpsc::unbounded_channel(); - let entry = std::sync::Arc::new(tokio::sync::Mutex::new(Entry::new( + let entry = std::sync::Arc::new(std::sync::Mutex::new(Entry::new( cmdline.to_string(), env.clone(), self.size, @@ -108,21 +114,32 @@ impl History { ); self.entries.push(entry); - Ok(self.entries.len() - 1) + self.entries.len() - 1 + } + + pub fn with_entry( + &self, + idx: usize, + f: impl FnOnce(&Entry) -> T, + ) -> T { + let entry = self.entries[idx].lock().unwrap(); + f(&*entry) } - pub async fn entry( + pub fn with_entry_mut( &self, idx: usize, - ) -> tokio::sync::OwnedMutexGuard { - self.entries[idx].clone().lock_owned().await + f: impl FnOnce(&mut Entry) -> T, + ) -> T { + let mut entry = self.entries[idx].lock().unwrap(); + f(&mut *entry) } pub fn entry_count(&self) -> usize { self.entries.len() } - pub async fn make_focus_visible( + pub fn make_focus_visible( &mut self, repl_lines: usize, focus: Option, @@ -137,7 +154,6 @@ impl History { while focus < self .visible(repl_lines, Some(focus), scrolling) - .await .map(|(idx, _)| idx) .next() .unwrap() @@ -152,7 +168,6 @@ impl History { while focus > self .visible(repl_lines, Some(focus), scrolling) - .await .map(|(idx, _)| idx) .last() .unwrap() @@ -161,7 +176,7 @@ impl History { } } - async fn visible( + fn visible( &self, repl_lines: usize, focus: Option, @@ -176,7 +191,7 @@ impl History { for (idx, entry) in self.entries.iter().enumerate().rev().skip(self.scroll_pos) { - let entry = entry.clone().lock_owned().await; + let entry = entry.lock().unwrap(); let focused = focus.map_or(false, |focus| idx == focus); used_lines += entry.lines(self.entry_count(), focused && !scrolling); @@ -189,39 +204,33 @@ impl History { } } -struct VisibleEntries { - entries: std::collections::VecDeque<( - usize, - tokio::sync::OwnedMutexGuard, - )>, +struct VisibleEntries<'a> { + entries: + std::collections::VecDeque<(usize, std::sync::MutexGuard<'a, Entry>)>, } -impl VisibleEntries { +impl<'a> VisibleEntries<'a> { fn new() -> Self { Self { entries: std::collections::VecDeque::new(), } } - fn add( - &mut self, - idx: usize, - entry: tokio::sync::OwnedMutexGuard, - ) { + fn add(&mut self, idx: usize, entry: std::sync::MutexGuard<'a, Entry>) { // push_front because we are adding them in reverse order self.entries.push_front((idx, entry)); } } -impl std::iter::Iterator for VisibleEntries { - type Item = (usize, tokio::sync::OwnedMutexGuard); +impl<'a> std::iter::Iterator for VisibleEntries<'a> { + type Item = (usize, std::sync::MutexGuard<'a, Entry>); fn next(&mut self) -> Option { self.entries.pop_front() } } -impl std::iter::DoubleEndedIterator for VisibleEntries { +impl<'a> std::iter::DoubleEndedIterator for VisibleEntries<'a> { fn next_back(&mut self) -> Option { self.entries.pop_back() } @@ -229,15 +238,16 @@ impl std::iter::DoubleEndedIterator for VisibleEntries { fn run_commands( cmdline: String, - entry: std::sync::Arc>, + entry: std::sync::Arc>, mut env: Env, input_r: tokio::sync::mpsc::UnboundedReceiver>, resize_r: tokio::sync::mpsc::UnboundedReceiver<(u16, u16)>, event_w: crate::shell::event::Writer, ) { tokio::task::spawn(async move { + let size = entry.lock().unwrap().size(); let pty = match pty::Pty::new( - entry.clone().lock_owned().await.size(), + size, &entry, input_r, resize_r, @@ -245,13 +255,13 @@ fn run_commands( ) { Ok(pty) => pty, Err(e) => { - let mut entry = entry.clone().lock_owned().await; + let mut entry = entry.lock().unwrap(); entry.process( format!("nbsh: failed to allocate pty: {}\r\n", e) .as_bytes(), ); env.set_status(std::process::ExitStatus::from_raw(1 << 8)); - entry.finish(env, event_w).await; + entry.finish(env, &event_w); return; } }; @@ -262,7 +272,7 @@ fn run_commands( { Ok(status) => status, Err(e) => { - let mut entry = entry.clone().lock_owned().await; + let mut entry = entry.lock().unwrap(); entry.process( format!( "nbsh: failed to spawn {}: {}\r\n", @@ -273,14 +283,14 @@ fn run_commands( env.set_status(std::process::ExitStatus::from_raw( 1 << 8, )); - entry.finish(env, event_w).await; + entry.finish(env, &event_w); return; } }; env.set_status(status); - entry.clone().lock_owned().await.finish(env, event_w).await; - pty.close().await; + entry.lock().unwrap().finish(env, &event_w); + pty.close(); }); } diff --git a/src/shell/history/pty.rs b/src/shell/history/pty.rs index 499ccc6..2a33e40 100644 --- a/src/shell/history/pty.rs +++ b/src/shell/history/pty.rs @@ -8,7 +8,7 @@ pub struct Pty { impl Pty { pub fn new( size: (u16, u16), - entry: &std::sync::Arc>, + entry: &std::sync::Arc>, input_r: tokio::sync::mpsc::UnboundedReceiver>, resize_r: tokio::sync::mpsc::UnboundedReceiver<(u16, u16)>, event_w: crate::shell::event::Writer, @@ -39,7 +39,7 @@ impl Pty { Ok(cmd.spawn(&*self.pts)?) } - pub async fn close(&self) { + pub fn close(&self) { self.close_w.send(()).unwrap(); } } @@ -49,7 +49,7 @@ async fn pty_task( // take the pts here just to ensure that we don't close it before this // task finishes, otherwise the read call can return EIO _pts: std::sync::Arc, - entry: std::sync::Arc>, + entry: std::sync::Arc>, input_r: tokio::sync::mpsc::UnboundedReceiver>, resize_r: tokio::sync::mpsc::UnboundedReceiver<(u16, u16)>, close_r: tokio::sync::mpsc::UnboundedReceiver<()>, @@ -83,7 +83,7 @@ async fn pty_task( match res { Res::Read(res) => match res { Ok(bytes) => { - entry.clone().lock_owned().await.process(&bytes); + entry.lock().unwrap().process(&bytes); event_w.send(Event::PtyOutput); } Err(e) => { diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 68025f0..ab01161 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -150,18 +150,18 @@ pub async fn main() -> Result { prev_dir = dir.to_path_buf(); git_w.send(dir.to_path_buf()).unwrap(); } - match shell.handle_event(event, &event_w).await { + match shell.handle_event(event, &event_w) { Some(Action::Refresh) => { - shell.render(&mut output).await?; + shell.render(&mut output)?; output.refresh().await?; } Some(Action::HardRefresh) => { - shell.render(&mut output).await?; + shell.render(&mut output)?; output.hard_refresh().await?; } Some(Action::Resize(rows, cols)) => { output.set_size(rows, cols); - shell.render(&mut output).await?; + shell.render(&mut output)?; output.hard_refresh().await?; } Some(Action::Quit) => break, @@ -222,87 +222,76 @@ impl Shell { }) } - pub async fn render( - &self, - out: &mut impl textmode::Textmode, - ) -> Result<()> { + pub fn render(&self, out: &mut impl textmode::Textmode) -> Result<()> { out.clear(); out.write(&vt100::Parser::default().screen().input_mode_formatted()); match self.scene { Scene::Readline => match self.focus { Focus::Readline => { - self.history - .render( + self.history.render( + out, + self.readline.lines(), + None, + false, + self.offset, + ); + self.readline.render( + out, + &self.env, + self.git.as_ref(), + true, + self.offset, + )?; + } + Focus::History(idx) => { + if self.hide_readline { + self.history.render( + out, + 0, + Some(idx), + false, + self.offset, + ); + } else { + self.history.render( out, self.readline.lines(), - None, + Some(idx), false, self.offset, - ) - .await?; - self.readline - .render( + ); + let pos = out.screen().cursor_position(); + self.readline.render( out, &self.env, self.git.as_ref(), - true, + false, self.offset, - ) - .await?; - } - Focus::History(idx) => { - if self.hide_readline { - self.history - .render(out, 0, Some(idx), false, self.offset) - .await?; - } else { - self.history - .render( - out, - self.readline.lines(), - Some(idx), - false, - self.offset, - ) - .await?; - let pos = out.screen().cursor_position(); - self.readline - .render( - out, - &self.env, - self.git.as_ref(), - false, - self.offset, - ) - .await?; + )?; out.move_to(pos.0, pos.1); } } Focus::Scrolling(idx) => { - self.history - .render( - out, - self.readline.lines(), - idx, - true, - self.offset, - ) - .await?; - self.readline - .render( - out, - &self.env, - self.git.as_ref(), - idx.is_none(), - self.offset, - ) - .await?; + self.history.render( + out, + self.readline.lines(), + idx, + true, + self.offset, + ); + self.readline.render( + out, + &self.env, + self.git.as_ref(), + idx.is_none(), + self.offset, + )?; out.hide_cursor(true); } }, Scene::Fullscreen => { if let Focus::History(idx) = self.focus { - self.history.render_fullscreen(out, idx).await; + self.history.render_fullscreen(out, idx); } else { unreachable!(); } @@ -311,7 +300,7 @@ impl Shell { Ok(()) } - pub async fn handle_event( + pub fn handle_event( &mut self, event: Event, event_w: &crate::shell::event::Writer, @@ -320,50 +309,60 @@ impl Shell { Event::Key(key) => { return if self.escape { self.escape = false; - self.handle_key_escape(key, event_w.clone()).await + self.handle_key_escape(&key, event_w.clone()) } else if key == textmode::Key::Ctrl(b'e') { self.escape = true; None } else { match self.focus { Focus::Readline => { - self.handle_key_readline(key, event_w.clone()) - .await + self.handle_key_readline(&key, event_w.clone()) } Focus::History(idx) => { - self.handle_key_history(key, idx).await; + self.handle_key_history(key, idx); None } Focus::Scrolling(_) => { - self.handle_key_escape(key, event_w.clone()).await + self.handle_key_escape(&key, event_w.clone()) } } }; } Event::Resize(new_size) => { - self.readline.resize(new_size).await; - self.history.resize(new_size).await; + self.readline.resize(new_size); + self.history.resize(new_size); return Some(Action::Resize(new_size.0, new_size.1)); } Event::PtyOutput => { + let idx = self.focus_idx(); // the number of visible lines may have changed, so make sure // the focus is still visible - self.history - .make_focus_visible( - self.readline.lines(), - self.focus_idx(), - matches!(self.focus, Focus::Scrolling(_)), - ) - .await; - self.scene = self.default_scene(self.focus, None).await; + self.history.make_focus_visible( + self.readline.lines(), + idx, + matches!(self.focus, Focus::Scrolling(_)), + ); + self.scene = Self::default_scene( + self.focus, + idx.map_or(false, |idx| { + self.history.should_fullscreen(idx) + }), + ); } Event::PtyClose => { if let Some(idx) = self.focus_idx() { - let entry = self.history.entry(idx).await; - if !entry.running() { + let (running, env, fullscreen) = + self.history.with_entry(idx, |entry| { + ( + entry.running(), + entry.env().clone(), + entry.should_fullscreen(), + ) + }); + if !running { if self.hide_readline { let idx = self.env.idx(); - self.env = entry.env().clone(); + self.env = env; self.env.set_idx(idx); } self.set_focus( @@ -372,18 +371,17 @@ impl Shell { } else { Focus::Scrolling(Some(idx)) }, - Some(entry), - ) - .await; + fullscreen, + ); } } } - Event::ChildRunPipeline(idx, span) => { - self.history.entry(idx).await.set_span(span); - } + Event::ChildRunPipeline(idx, span) => self + .history + .with_entry_mut(idx, |entry| entry.set_span(span)), Event::ChildSuspend(idx) => { if self.focus_idx() == Some(idx) { - self.set_focus(Focus::Readline, None).await; + self.set_focus(Focus::Readline, false); } } Event::GitInfo(info) => { @@ -394,9 +392,9 @@ impl Shell { Some(Action::Refresh) } - async fn handle_key_escape( + fn handle_key_escape( &mut self, - key: textmode::Key, + key: &textmode::Key, event_w: crate::shell::event::Writer, ) -> Option { match key { @@ -404,8 +402,7 @@ impl Shell { return Some(Action::Quit); } textmode::Key::Ctrl(b'e') => { - self.set_focus(Focus::Scrolling(self.focus_idx()), None) - .await; + self.set_focus(Focus::Scrolling(self.focus_idx()), false); } textmode::Key::Ctrl(b'l') => { return Some(Action::HardRefresh); @@ -413,88 +410,101 @@ impl Shell { textmode::Key::Ctrl(b'm') => { if let Some(idx) = self.focus_idx() { self.readline.clear_input(); - let entry = self.history.entry(idx).await; - let input = entry.cmd(); - let idx = self - .history - .run(input, &self.env, event_w.clone()) - .await - .unwrap(); - self.set_focus(Focus::History(idx), Some(entry)).await; + let (input, fullscreen) = + self.history.with_entry(idx, |entry| { + ( + entry.cmd().to_string(), + entry.should_fullscreen(), + ) + }); + let idx = self.history.run(&input, &self.env, event_w); + self.set_focus(Focus::History(idx), fullscreen); self.hide_readline = true; self.env.set_idx(idx + 1); } else { - self.set_focus(Focus::Readline, None).await; + self.set_focus(Focus::Readline, false); } } textmode::Key::Char(' ') => { let idx = self.focus_idx(); - let (focus, entry) = if let Some(idx) = idx { - let entry = self.history.entry(idx).await; - (entry.running(), Some(entry)) + if let Some(idx) = idx { + let (running, fullscreen) = + self.history.with_entry(idx, |entry| { + (entry.running(), entry.should_fullscreen()) + }); + if running { + self.set_focus(Focus::History(idx), fullscreen); + } } else { - (true, None) - }; - if focus { - self.set_focus( - idx.map_or(Focus::Readline, |idx| { - Focus::History(idx) - }), - entry, - ) - .await; + self.set_focus(Focus::Readline, false); } } textmode::Key::Char('e') => { if let Focus::History(idx) = self.focus { - self.handle_key_history(textmode::Key::Ctrl(b'e'), idx) - .await; + self.handle_key_history(textmode::Key::Ctrl(b'e'), idx); } } textmode::Key::Char('f') => { if let Some(idx) = self.focus_idx() { - let mut entry = self.history.entry(idx).await; let mut focus = Focus::History(idx); - if let Focus::Scrolling(_) = self.focus { - entry.set_fullscreen(true); - } else { - entry.toggle_fullscreen(); - if !entry.should_fullscreen() && !entry.running() { - focus = Focus::Scrolling(Some(idx)); - } - } - self.set_focus(focus, Some(entry)).await; + let fullscreen = + self.history.with_entry_mut(idx, |entry| { + if let Focus::Scrolling(_) = self.focus { + entry.set_fullscreen(true); + } else { + entry.toggle_fullscreen(); + if !entry.should_fullscreen() + && !entry.running() + { + focus = Focus::Scrolling(Some(idx)); + } + } + entry.should_fullscreen() + }); + self.set_focus(focus, fullscreen); } } textmode::Key::Char('i') => { if let Some(idx) = self.focus_idx() { - let entry = self.history.entry(idx).await; - self.readline.set_input(entry.cmd()); - self.set_focus(Focus::Readline, Some(entry)).await; + let input = self + .history + .with_entry(idx, |entry| entry.cmd().to_string()); + self.readline.set_input(&input); + self.set_focus(Focus::Readline, false); } } textmode::Key::Char('j') | textmode::Key::Down => { self.set_focus( Focus::Scrolling(self.scroll_down(self.focus_idx())), - None, - ) - .await; + false, + ); } textmode::Key::Char('k') | textmode::Key::Up => { self.set_focus( Focus::Scrolling(self.scroll_up(self.focus_idx())), - None, - ) - .await; + false, + ); } textmode::Key::Char('n') => { - self.set_focus(self.next_running().await, None).await; + let focus = self.next_running(); + let fullscreen = if let Focus::History(idx) = focus { + self.history.should_fullscreen(idx) + } else { + false + }; + self.set_focus(focus, fullscreen); } textmode::Key::Char('p') => { - self.set_focus(self.prev_running().await, None).await; + let focus = self.prev_running(); + let fullscreen = if let Focus::History(idx) = focus { + self.history.should_fullscreen(idx) + } else { + false + }; + self.set_focus(focus, fullscreen); } textmode::Key::Char('r') => { - self.set_focus(Focus::Readline, None).await; + self.set_focus(Focus::Readline, false); } _ => { return None; @@ -503,9 +513,9 @@ impl Shell { Some(Action::Refresh) } - async fn handle_key_readline( + fn handle_key_readline( &mut self, - key: textmode::Key, + key: &textmode::Key, event_w: crate::shell::event::Writer, ) -> Option { match key { @@ -522,12 +532,11 @@ impl Shell { textmode::Key::Ctrl(b'm') => { let input = self.readline.input(); if !input.is_empty() { - let idx = self - .history - .run(input, &self.env, event_w.clone()) - .await - .unwrap(); - self.set_focus(Focus::History(idx), None).await; + let idx = self.history.run(input, &self.env, event_w); + self.set_focus( + Focus::History(idx), + self.history.should_fullscreen(idx), + ); self.hide_readline = true; self.env.set_idx(idx + 1); self.readline.clear_input(); @@ -542,9 +551,8 @@ impl Shell { if entry_count > 0 { self.set_focus( Focus::Scrolling(Some(entry_count - 1)), - None, - ) - .await; + false, + ); } } _ => return None, @@ -552,23 +560,14 @@ impl Shell { Some(Action::Refresh) } - async fn handle_key_history(&mut self, key: textmode::Key, idx: usize) { - self.history.send_input(idx, key.into_bytes()).await; + fn handle_key_history(&mut self, key: textmode::Key, idx: usize) { + self.history.send_input(idx, key.into_bytes()); } - async fn default_scene( - &self, - focus: Focus, - entry: Option>, - ) -> Scene { + fn default_scene(focus: Focus, fullscreen: bool) -> Scene { match focus { Focus::Readline | Focus::Scrolling(_) => Scene::Readline, - Focus::History(idx) => { - let fullscreen = if let Some(entry) = entry { - entry.should_fullscreen() - } else { - self.history.entry(idx).await.should_fullscreen() - }; + Focus::History(_) => { if fullscreen { Scene::Fullscreen } else { @@ -578,25 +577,19 @@ impl Shell { } } - async fn set_focus( - &mut self, - new_focus: Focus, - entry: Option>, - ) { + fn set_focus(&mut self, new_focus: Focus, fullscreen: bool) { self.focus = new_focus; self.hide_readline = false; - self.scene = self.default_scene(new_focus, entry).await; + self.scene = Self::default_scene(new_focus, fullscreen); // passing entry into default_scene above consumes it, which means // that the mutex lock will be dropped before we call into // make_focus_visible, which is important because otherwise we might // get a deadlock depending on what is visible - self.history - .make_focus_visible( - self.readline.lines(), - self.focus_idx(), - matches!(self.focus, Focus::Scrolling(_)), - ) - .await; + self.history.make_focus_visible( + self.readline.lines(), + self.focus_idx(), + matches!(self.focus, Focus::Scrolling(_)), + ); } fn env(&self) -> &Env { @@ -635,22 +628,22 @@ impl Shell { }) } - async fn next_running(&self) -> Focus { + fn next_running(&self) -> Focus { let count = self.history.entry_count(); let cur = self.focus_idx().unwrap_or(count); for idx in ((cur + 1)..count).chain(0..cur) { - if self.history.entry(idx).await.running() { + if self.history.running(idx) { return Focus::History(idx); } } self.focus_idx().map_or(Focus::Readline, Focus::History) } - async fn prev_running(&self) -> Focus { + fn prev_running(&self) -> Focus { let count = self.history.entry_count(); let cur = self.focus_idx().unwrap_or(count); for idx in ((cur + 1)..count).chain(0..cur).rev() { - if self.history.entry(idx).await.running() { + if self.history.running(idx) { return Focus::History(idx); } } diff --git a/src/shell/readline.rs b/src/shell/readline.rs index 463a7f0..49a3ab6 100644 --- a/src/shell/readline.rs +++ b/src/shell/readline.rs @@ -19,7 +19,7 @@ impl Readline { } } - pub async fn render( + pub fn render( &self, out: &mut impl textmode::Textmode, env: &Env, @@ -83,7 +83,7 @@ impl Readline { Ok(()) } - pub async fn resize(&mut self, size: (u16, u16)) { + pub fn resize(&mut self, size: (u16, u16)) { self.size = size; } -- cgit v1.2.3-54-g00ecf