summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2022-09-26 13:57:47 +0200
committerqkzk <qu3nt1n@gmail.com>2022-09-26 13:57:47 +0200
commit6f35e3dfaa94aa5f210f5a1f1b6492b4aa43c994 (patch)
tree6e4de85cf71891daf719fd36e3e3dac3e2e1ad6b
parentedf49c60f51648f6e077311789ac15268d067f5b (diff)
jump to a flagged fileregex-search
-rw-r--r--config.yaml1
-rw-r--r--readme.md2
-rw-r--r--src/config.rs9
-rw-r--r--src/main.rs63
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
diff --git a/readme.md b/readme.md
index 3bbde1f6..a4dc169f 100644
--- a/readme.md
+++ b/readme.md
@@ -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();
}