Skip to content

Commit

Permalink
feat: backward/forward
Browse files Browse the repository at this point in the history
  • Loading branch information
ndtoan96 authored and sxyazi committed Oct 1, 2023
1 parent b2d3e39 commit 38299ab
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 19 deletions.
4 changes: 2 additions & 2 deletions app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ impl App {
let manager = &mut self.cx.manager;
let tasks = &mut self.cx.tasks;
match event {
Event::Cd(url) => {
Event::Cd(url, backstack_push) => {
futures::executor::block_on(async {
manager.active_mut().cd(expand_url(url)).await;
manager.active_mut().cd(expand_url(url), backstack_push).await;
});
}
Event::Refresh => {
Expand Down
2 changes: 1 addition & 1 deletion app/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl Executor {
if exec.named.contains_key("interactive") {
cx.manager.active_mut().cd_interactive(url)
} else {
emit!(Cd(url));
emit!(Cd(url, true));
false
}
}
Expand Down
6 changes: 3 additions & 3 deletions core/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub enum Event {
Call(Vec<Exec>, KeymapLayer),

// Manager
Cd(Url),
Cd(Url, bool),
Refresh,
Files(FilesOp),
Pages(usize),
Expand Down Expand Up @@ -71,8 +71,8 @@ macro_rules! emit {
$crate::Event::Call($exec, $layer).emit();
};

(Cd($url:expr)) => {
$crate::Event::Cd($url).emit();
(Cd($url:expr, $backstack_push:expr)) => {
$crate::Event::Cd($url, $backstack_push).emit();
};
(Files($op:expr)) => {
$crate::Event::Files($op).emit();
Expand Down
2 changes: 1 addition & 1 deletion core/src/external/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,5 @@ pub async fn clipboard_set(s: impl AsRef<std::ffi::OsStr>) -> Result<()> {
let result =
tokio::task::spawn_blocking(move || set_clipboard(formats::Unicode, s.to_string_lossy()));

Ok(result.await?.map_err(|_| anyhow!("failed to set clipboard"))?)
result.await?.map_err(|_| anyhow!("failed to set clipboard"))
}
69 changes: 69 additions & 0 deletions core/src/manager/backstack.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
pub struct BackStack<T> {
current: usize,
stack: Vec<T>,
}

impl<T> BackStack<T> {
pub fn new(item: T) -> Self { Self { current: 0, stack: vec![item] } }

pub fn shift_backward(&mut self) -> Option<&T> {
if self.current > 0 {
self.current -= 1;
Some(&self.stack[self.current])
} else {
None
}
}

pub fn shift_forward(&mut self) -> Option<&T> {
if self.current + 1 == self.stack.len() {
None
} else {
self.current += 1;
Some(&self.stack[self.current])
}
}

pub fn push(&mut self, item: T) {
self.current += 1;
if self.current == self.stack.len() {
self.stack.push(item);
} else {
self.stack[self.current] = item;
self.stack.truncate(self.current + 1);
}
}
}

#[cfg(test)]
mod tests {
use super::*;

fn get_current<T>(backstack: &BackStack<T>) -> &T { &backstack.stack[backstack.current] }

#[test]
fn test_backstack() {
let mut backstack = BackStack::<i32>::new(1);
assert_eq!(get_current(&backstack), &1);

backstack.push(2);
backstack.push(3);
assert_eq!(get_current(&backstack), &3);

assert_eq!(backstack.shift_backward(), Some(&2));
assert_eq!(backstack.shift_backward(), Some(&1));
assert_eq!(backstack.shift_backward(), None);
assert_eq!(backstack.shift_backward(), None);
assert_eq!(get_current(&backstack), &1);
assert_eq!(backstack.shift_forward(), Some(&2));
assert_eq!(backstack.shift_forward(), Some(&3));
assert_eq!(backstack.shift_forward(), None);

backstack.shift_backward();
backstack.push(4);

assert_eq!(get_current(&backstack), &4);
assert_eq!(backstack.shift_forward(), None);
assert_eq!(backstack.shift_backward(), Some(&2));
}
}
1 change: 1 addition & 0 deletions core/src/manager/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod backstack;
mod finder;
mod folder;
mod manager;
Expand Down
42 changes: 30 additions & 12 deletions core/src/manager/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ use shared::{Debounce, Defer, InputError, Url};
use tokio::{pin, task::JoinHandle};
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};

use super::{Finder, Folder, Mode, Preview, PreviewLock};
use super::{backstack::BackStack, Finder, Folder, Mode, Preview, PreviewLock};
use crate::{emit, external::{self, FzfOpt, ZoxideOpt}, files::{File, FilesOp, FilesSorter}, input::InputOpt, Event, Step, BLOCKER};

pub struct Tab {
pub(super) mode: Mode,
pub(super) current: Folder,
pub(super) parent: Option<Folder>,

pub(super) history: BTreeMap<Url, Folder>,
pub(super) preview: Preview,
pub(super) backstack: BackStack<Url>,
pub(super) history: BTreeMap<Url, Folder>,
pub(super) preview: Preview,

finder: Option<Finder>,
search: Option<JoinHandle<Result<()>>>,
Expand All @@ -29,9 +30,10 @@ impl From<Url> for Tab {

Self {
mode: Default::default(),
current: Folder::from(url),
current: Folder::from(url.clone()),
parent,

backstack: BackStack::new(url),
history: Default::default(),
preview: Default::default(),

Expand Down Expand Up @@ -87,7 +89,7 @@ impl Tab {
true
}

pub async fn cd(&mut self, mut target: Url) -> bool {
pub async fn cd(&mut self, mut target: Url, backstack_push: bool) -> bool {
let Ok(file) = File::from(target.clone()).await else {
return false;
};
Expand All @@ -109,6 +111,10 @@ impl Tab {
self.history.insert(rep.cwd.clone(), rep);
}

if backstack_push {
self.backstack.push(target.clone());
}

let rep = self.history_new(&target);
let rep = mem::replace(&mut self.current, rep);
if rep.cwd.is_regular() {
Expand All @@ -132,7 +138,7 @@ impl Tab {
emit!(Input(InputOpt::top("Change directory:").with_value(target.to_string_lossy())));

if let Some(Ok(s)) = result.recv().await {
emit!(Cd(Url::from(s)));
emit!(Cd(Url::from(s), true));
}
});
false
Expand All @@ -157,6 +163,8 @@ impl Tab {
}
self.parent = Some(self.history_new(&hovered.parent().unwrap()));

self.backstack.push(self.current.cwd.clone());

emit!(Refresh);
true
}
Expand Down Expand Up @@ -187,15 +195,25 @@ impl Tab {
self.history.insert(rep.cwd.clone(), rep);
}

self.backstack.push(self.current.cwd.clone());

emit!(Refresh);
true
}

// TODO
pub fn back(&mut self) -> bool { false }
pub fn back(&mut self) -> bool {
if let Some(url) = self.backstack.shift_backward() {
emit!(Cd(url.clone(), false));
}
false
}

// TODO
pub fn forward(&mut self) -> bool { false }
pub fn forward(&mut self) -> bool {
if let Some(url) = self.backstack.shift_forward() {
emit!(Cd(url.clone(), false));
}
false
}

pub fn select(&mut self, state: Option<bool>) -> bool {
if let Some(ref hovered) = self.current.hovered {
Expand Down Expand Up @@ -309,7 +327,7 @@ impl Tab {
let mut first = true;
while let Some(chunk) = rx.next().await {
if first {
emit!(Cd(cwd.clone()));
emit!(Cd(cwd.clone(), true));
first = false;
}
emit!(Files(FilesOp::Part(cwd.clone(), ticket, chunk)));
Expand Down Expand Up @@ -345,7 +363,7 @@ impl Tab {
if global { external::fzf(FzfOpt { cwd }) } else { external::zoxide(ZoxideOpt { cwd }) }?;

if let Ok(target) = rx.await? {
emit!(Cd(target));
emit!(Cd(target, true));
}
Ok::<(), Error>(())
});
Expand Down

0 comments on commit 38299ab

Please sign in to comment.