summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-11-17 22:29:05 -0500
committerJesse Luehrs <doy@tozt.net>2021-11-17 22:29:05 -0500
commit70f48c3ef7dde34546b6d646818333505d0e4777 (patch)
treedb5d3fd7a2f4cfd168a73e03c8c8272ac375ecc1 /src
parent96f335c58f9b9b9035a43f106f2dfddbe62777e7 (diff)
downloadnbsh-70f48c3ef7dde34546b6d646818333505d0e4777.tar.gz
nbsh-70f48c3ef7dde34546b6d646818333505d0e4777.zip
refactor
Diffstat (limited to 'src')
-rw-r--r--src/action.rs11
-rw-r--r--src/history.rs19
-rw-r--r--src/main.rs29
-rw-r--r--src/readline.rs29
-rw-r--r--src/state.rs88
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)]