summaryrefslogtreecommitdiffstats
path: root/src/state.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-12-07 14:27:37 -0500
committerJesse Luehrs <doy@tozt.net>2021-12-07 14:27:37 -0500
commit5c224804ce75c88b78aee49fdc13a7452b1cd198 (patch)
tree68a0ccc00ec19c53d96674898228ae0dbb424067 /src/state.rs
parent08246280e5707cc6a3153efc9648e33d2e122054 (diff)
downloadnbsh-5c224804ce75c88b78aee49fdc13a7452b1cd198.tar.gz
nbsh-5c224804ce75c88b78aee49fdc13a7452b1cd198.zip
improve how history scrolling works
Diffstat (limited to 'src/state.rs')
-rw-r--r--src/state.rs117
1 files changed, 108 insertions, 9 deletions
diff --git a/src/state.rs b/src/state.rs
index a312d91..2cc24c5 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -51,12 +51,21 @@ impl State {
let new_focus = match self.focus {
Focus::History(idx) => {
if idx >= self.history.entry_count() - 1 {
- Focus::Readline
+ Focus::Scrolling(None)
} else {
- Focus::History(idx + 1)
+ Focus::Scrolling(Some(idx + 1))
}
}
- Focus::Readline => Focus::Readline,
+ Focus::Readline => Focus::Scrolling(None),
+ Focus::Scrolling(idx) => {
+ idx.map_or(Focus::Scrolling(None), |idx| {
+ if idx >= self.history.entry_count() - 1 {
+ Focus::Scrolling(None)
+ } else {
+ Focus::Scrolling(Some(idx + 1))
+ }
+ })
+ }
};
return Some(crate::action::Action::UpdateFocus(
new_focus,
@@ -66,14 +75,26 @@ impl State {
let new_focus = match self.focus {
Focus::History(idx) => {
if idx == 0 {
- Focus::History(0)
+ Focus::Scrolling(Some(0))
} else {
- Focus::History(idx - 1)
+ Focus::Scrolling(Some(idx - 1))
}
}
- Focus::Readline => {
- Focus::History(self.history.entry_count() - 1)
- }
+ Focus::Readline => Focus::Scrolling(Some(
+ self.history.entry_count() - 1,
+ )),
+ Focus::Scrolling(idx) => idx.map_or(
+ Focus::Scrolling(Some(
+ self.history.entry_count() - 1,
+ )),
+ |idx| {
+ if idx == 0 {
+ Focus::Scrolling(Some(0))
+ } else {
+ Focus::Scrolling(Some(idx - 1))
+ }
+ },
+ ),
};
return Some(crate::action::Action::UpdateFocus(
new_focus,
@@ -100,6 +121,74 @@ impl State {
self.history.handle_key(key, idx).await;
None
}
+ Focus::Scrolling(idx) => match key {
+ textmode::Key::Ctrl(b'm') => {
+ let focus = if let Some(idx) = idx {
+ self.history.running(idx).await
+ } else {
+ true
+ };
+ if focus {
+ Some(crate::action::Action::UpdateFocus(
+ idx.map_or(Focus::Readline, |idx| {
+ Focus::History(idx)
+ }),
+ ))
+ } else {
+ None
+ }
+ }
+ textmode::Key::Char('j') => {
+ let new_focus = match self.focus {
+ Focus::History(idx) => {
+ if idx >= self.history.entry_count() - 1 {
+ Focus::Scrolling(None)
+ } else {
+ Focus::Scrolling(Some(idx + 1))
+ }
+ }
+ Focus::Readline => Focus::Scrolling(None),
+ Focus::Scrolling(idx) => {
+ idx.map_or(Focus::Scrolling(None), |idx| {
+ if idx >= self.history.entry_count() - 1 {
+ Focus::Scrolling(None)
+ } else {
+ Focus::Scrolling(Some(idx + 1))
+ }
+ })
+ }
+ };
+ Some(crate::action::Action::UpdateFocus(new_focus))
+ }
+ textmode::Key::Char('k') => {
+ let new_focus = match self.focus {
+ Focus::History(idx) => {
+ if idx == 0 {
+ Focus::Scrolling(Some(0))
+ } else {
+ Focus::Scrolling(Some(idx - 1))
+ }
+ }
+ Focus::Readline => Focus::Scrolling(Some(
+ self.history.entry_count() - 1,
+ )),
+ Focus::Scrolling(idx) => idx.map_or(
+ Focus::Scrolling(Some(
+ self.history.entry_count() - 1,
+ )),
+ |idx| {
+ if idx == 0 {
+ Focus::Scrolling(Some(0))
+ } else {
+ Focus::Scrolling(Some(idx - 1))
+ }
+ },
+ ),
+ };
+ Some(crate::action::Action::UpdateFocus(new_focus))
+ }
+ _ => None,
+ },
}
}
@@ -136,6 +225,15 @@ impl State {
out.move_to(pos.0, pos.1);
}
}
+ Focus::Scrolling(idx) => {
+ self.history
+ .render(out, self.readline.lines(), idx, self.offset)
+ .await?;
+ self.readline
+ .render(out, idx.is_none(), self.offset)
+ .await?;
+ out.write(b"\x1b[?25l");
+ }
},
Scene::Fullscreen => {
if let Focus::History(idx) = self.focus {
@@ -198,7 +296,7 @@ impl State {
async fn default_scene(&self, focus: Focus) -> Scene {
match focus {
- Focus::Readline => Scene::Readline,
+ Focus::Readline | Focus::Scrolling(_) => Scene::Readline,
Focus::History(idx) => {
if self.history.should_fullscreen(idx).await {
Scene::Fullscreen
@@ -214,6 +312,7 @@ impl State {
pub enum Focus {
Readline,
History(usize),
+ Scrolling(Option<usize>),
}
#[derive(Copy, Clone, Debug)]