diff options
author | qkzk <qu3nt1n@gmail.com> | 2022-09-26 13:57:47 +0200 |
---|---|---|
committer | qkzk <qu3nt1n@gmail.com> | 2022-09-26 13:57:47 +0200 |
commit | 6f35e3dfaa94aa5f210f5a1f1b6492b4aa43c994 (patch) | |
tree | 6e4de85cf71891daf719fd36e3e3dac3e2e1ad6b | |
parent | edf49c60f51648f6e077311789ac15268d067f5b (diff) |
jump to a flagged fileregex-search
-rw-r--r-- | config.yaml | 1 | ||||
-rw-r--r-- | readme.md | 2 | ||||
-rw-r--r-- | src/config.rs | 9 | ||||
-rw-r--r-- | src/main.rs | 63 |
4 files changed, 73 insertions, 2 deletions
diff --git a/config.yaml b/config.yaml index e131b9df..1cef51f1 100644 --- a/config.yaml +++ b/config.yaml @@ -36,3 +36,4 @@ keybindings: flag_all: '*' reverse_flags: v regex_match: w + jump: j @@ -46,6 +46,7 @@ - [x] regex - [x] search - [x] mark multiple files +- [x] jump pour next flagged file ## TODO @@ -57,7 +58,6 @@ - [ ] installed config file, user config file - [ ] completion in goto mode, exec mode, searchmode (???) - [ ] confirmation for cut/paste, copy/paste, delete -- [ ] jump pour next flagged file ## BUGS diff --git a/src/config.rs b/src/config.rs index 0a18cfab..71a60e53 100644 --- a/src/config.rs +++ b/src/config.rs @@ -78,6 +78,7 @@ pub struct Keybindings { pub flag_all: char, pub reverse_flags: char, pub regex_match: char, + pub jump: char, } impl Keybindings { @@ -222,6 +223,13 @@ impl Keybindings { .chars() .next() .unwrap_or('w'); + let jump = yaml["jump"] + .as_str() + .map(|s| s.to_string()) + .unwrap_or_else(|| "j".to_string()) + .chars() + .next() + .unwrap_or('j'); Self { toggle_hidden, copy_paste, @@ -243,6 +251,7 @@ impl Keybindings { flag_all, reverse_flags, regex_match, + jump, } } } diff --git a/src/main.rs b/src/main.rs index fabcd7df..eb6a1f2f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,6 +70,7 @@ o: xdg-open this file r: RENAME g: GOTO w: REGEXMATCH + j: JUMP Enter: Execute mode then NORMAL Esc: NORMAL "; @@ -158,6 +159,7 @@ enum Mode { Search, Goto, RegexMatch, + Jump, } impl fmt::Debug for Mode { @@ -173,6 +175,7 @@ impl fmt::Debug for Mode { Mode::Search => write!(f, "Search: "), Mode::Goto => write!(f, "Goto : "), Mode::RegexMatch => write!(f, "Regex : "), + Mode::Jump => write!(f, "Jump : "), } } } @@ -201,6 +204,7 @@ struct Status { terminal: String, opener: String, keybindings: Keybindings, + jump_index: usize, } impl Status { @@ -229,6 +233,7 @@ impl Status { let input_string = "".to_string(); let col = 0; let keybindings = Keybindings::new(&config_file["keybindings"]); + let jump_index = 0; Self { mode, file_index, @@ -244,6 +249,7 @@ impl Status { terminal, opener, keybindings, + jump_index, } } @@ -262,6 +268,10 @@ impl Status { } self.path_content.select_prev(); self.window.scroll_up_one(self.file_index); + } else if let Mode::Jump = self.mode { + if self.jump_index > 0 { + self.jump_index -= 1; + } } } @@ -272,6 +282,10 @@ impl Status { } self.path_content.select_next(); self.window.scroll_down_one(self.file_index); + } else if let Mode::Jump = self.mode { + if self.jump_index < self.flagged.len() { + self.jump_index += 1; + } } } @@ -402,6 +416,8 @@ impl Status { self.event_flag_all(); } else if c == self.keybindings.reverse_flags { self.event_reverse_flags(); + } else if c == self.keybindings.jump { + self.event_jump(); } } Mode::Help => { @@ -411,6 +427,7 @@ impl Status { std::process::exit(0); } } + Mode::Jump => (), } } @@ -577,6 +594,12 @@ impl Status { } } + fn event_jump(&mut self) { + if !self.flagged.is_empty() { + self.mode = Mode::Jump + } + } + fn event_enter(&mut self) { match self.mode { Mode::Rename => self.exec_rename(), @@ -587,6 +610,7 @@ impl Status { Mode::Search => self.exec_search(), Mode::Goto => self.exec_goto(), Mode::RegexMatch => self.exec_regex(), + Mode::Jump => self.exec_jump(), Mode::Normal | Mode::Help => (), } @@ -689,15 +713,35 @@ impl Status { fn exec_goto(&mut self) { let target_string = self.input_string.clone(); + self.input_string.clear(); let expanded_cow_path = shellexpand::tilde(&target_string); let expanded_target: &str = expanded_cow_path.borrow(); - self.input_string.clear(); if let Ok(path) = std::fs::canonicalize(expanded_target) { self.path_content = PathContent::new(path, self.args.hidden); self.window.reset(self.path_content.files.len()); } } + fn exec_jump(&mut self) { + self.input_string.clear(); + let jump_list: Vec<&path::PathBuf> = self.flagged.iter().collect(); + let jump_target = jump_list[self.jump_index].clone(); + let target_dir = match jump_target.parent() { + Some(parent) => parent.to_path_buf(), + None => jump_target.clone(), + }; + self.path_content = PathContent::new(target_dir, self.args.hidden); + self.file_index = self + .path_content + .files + .iter() + .position(|file| file.path == jump_target.clone()) + .unwrap_or(0); + self.path_content.select_index(self.file_index); + self.window.reset(self.path_content.files.len()); + self.window.scroll_to(self.file_index); + } + fn exec_regex(&mut self) { let re = Regex::new(&self.input_string).unwrap(); if !self.input_string.is_empty() { @@ -779,6 +823,22 @@ impl Display { } } } + + fn jump_list(&mut self, status: &Status) { + if let Mode::Jump = status.mode { + let _ = self.term.clear(); + let _ = self.term.print(0, 0, "Jump to..."); + for (row, path) in status.flagged.iter().enumerate() { + let mut attr = Attr::default(); + if row == status.jump_index { + attr.effect |= Effect::REVERSE; + } + let _ = self + .term + .print_with_attr(row + 1, 4, path.to_str().unwrap(), attr); + } + } + } } fn read_args() -> Args { @@ -830,6 +890,7 @@ fn main() { display.first_line(&status); display.files(&status); display.help_or_cursor(&status); + display.jump_list(&status); let _ = display.term.present(); } |