implemented options to dedup/rotate stack

This commit is contained in:
2025-07-06 21:20:59 +02:00
parent 7dcdce624f
commit 71658df5fe
4 changed files with 54 additions and 7 deletions
+2 -2
View File
@@ -60,8 +60,8 @@ Style settings accept styles and one color in the following formats:
- [x] `show-bookmarks-on-book` - [x] `show-bookmarks-on-book`
- [x] setting for separator string when displaying stack/bookmarks - [x] setting for separator string when displaying stack/bookmarks
- [x] color option for punctuation (mostly '/') - [x] color option for punctuation (mostly '/')
- [ ] option to dedup stack entries - [x] option to dedup stack entries
- [ ] option for behaviour when jumping to stack entry via `push =<n>` - [x] option for behaviour when jumping to stack entry via `push =<n>`
- [x] bookmarks - [x] bookmarks
- [x] do not resolve links in bookmarks - [x] do not resolve links in bookmarks
- [x] option to show invalid paths - [x] option to show invalid paths
+8
View File
@@ -25,6 +25,14 @@ pub struct Config {
#[derive(Debug, Clone, Default, ConfigParser)] #[derive(Debug, Clone, Default, ConfigParser)]
pub struct GeneralSettings { pub struct GeneralSettings {
/// (bool) delete all older occurences of paths in the stack
#[default_value(false)]
pub dedup_stack: bool,
/// (bool) rotate stack to chosen path when jumping to stack entry
#[default_value(false)]
pub rotate_stack_on_jump_to_entry: bool,
/// (bool) show stack when pushing a path to the stack /// (bool) show stack when pushing a path to the stack
#[default_value(false)] #[default_value(false)]
pub show_stack_on_push: bool, pub show_stack_on_push: bool,
+7 -2
View File
@@ -58,7 +58,7 @@ fn main() -> Result<()> {
return Ok(()); return Ok(());
} }
}; };
let mut stack = match Stack::new(args.pid) { let mut stack = match Stack::new(&config, args.pid) {
Ok(stack) => stack, Ok(stack) => stack,
Err(_) => { Err(_) => {
output.push_error(&"-- failed to build stack".to_string()); output.push_error(&"-- failed to build stack".to_string());
@@ -104,7 +104,12 @@ fn handle_push(args: &PushArgs, config: &Config, stack: &mut Stack, output: &mut
Ok(value) => value, Ok(value) => value,
Err(_) => return Err(Error::other("-- push : failed to convert path argument to number")), Err(_) => return Err(Error::other("-- push : failed to convert path argument to number")),
}; };
stack.get_entry_by_number(number)?.to_path_buf() let path = stack.get_entry_by_number(number)?.to_path_buf();
if config.general.rotate_stack_on_jump_to_entry {
stack.rotate_stack(number)?;
}
_ = stack.pop_entry(None);
path
} else { } else {
match PathBuf::from_str(&path_string) { match PathBuf::from_str(&path_string) {
Ok(value) => value, Ok(value) => value,
+37 -3
View File
@@ -21,13 +21,13 @@ pub struct Stack {
impl Stack { impl Stack {
const STACK_FILE_DIRECTORY: &str = "/tmp/navigate/"; const STACK_FILE_DIRECTORY: &str = "/tmp/navigate/";
pub fn new(process_id: u32) -> Result<Self> { pub fn new(config: &Config, process_id: u32) -> Result<Self> {
let mut stack: Stack = Stack { let mut stack: Stack = Stack {
pid: process_id, pid: process_id,
path: PathBuf::new(), path: PathBuf::new(),
stack: Vec::<PathBuf>::new(), stack: Vec::<PathBuf>::new(),
}; };
stack.build_stack()?; stack.build_stack(config)?;
Ok(stack) Ok(stack)
} }
@@ -138,8 +138,25 @@ impl Stack {
} }
} }
/// rotate stack so that the <entry_number> is the latest
/// entry (first to be popped)
pub fn rotate_stack(&mut self, entry_number: usize) -> Result<()> {
if 0 == entry_number {
return Ok(());
} else if self.stack.len() <= entry_number {
return Err(Error::other("-- number to rotate is greater than the stacks length"));
}
let mut rotated_stack: Vec<PathBuf> = self.stack.drain(self.stack.len() - entry_number..).collect();
rotated_stack.extend(self.stack.drain(..));
self.stack = rotated_stack;
Ok(())
}
/// clean up dead stack files, parse and build stack /// clean up dead stack files, parse and build stack
fn build_stack(&mut self) -> Result<()> { fn build_stack(&mut self, config: &Config) -> Result<()> {
let stack_dir: PathBuf = match PathBuf::from_str(Self::STACK_FILE_DIRECTORY) { let stack_dir: PathBuf = match PathBuf::from_str(Self::STACK_FILE_DIRECTORY) {
Ok(value) => value, Ok(value) => value,
Err(_) => { Err(_) => {
@@ -187,6 +204,10 @@ impl Stack {
} }
self.cleanup_stack(); self.cleanup_stack();
if config.general.dedup_stack {
self.dedup_stack();
}
Ok(()) Ok(())
} }
@@ -208,6 +229,19 @@ impl Stack {
} }
} }
/// keep only the newest occurence of a path
fn dedup_stack(&mut self) {
let mut deduped_stack: Vec<PathBuf> = Vec::new();
while !self.stack.is_empty() {
let entry: PathBuf = self.stack.remove(0);
if !self.stack.contains(&entry) {
deduped_stack.push(entry);
}
}
self.stack = deduped_stack;
}
/// write stack current stack to file to save it for next execution /// write stack current stack to file to save it for next execution
fn write_stack_file(&mut self) -> Result<()> { fn write_stack_file(&mut self) -> Result<()> {
let mut output = Vec::<&str>::new(); let mut output = Vec::<&str>::new();