summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-02-07 16:32:27 +0100
committerrabite <rabite@posteo.de>2019-02-07 16:32:27 +0100
commitea9d6d4d92a620a52efec96cd3310ecd690e7c40 (patch)
tree122f28c0beec203b54ccb58721f46ba6cf36f360
parent626ba13239108d926a0b256f711f7981f93ac3c3 (diff)
multi-file selection
-rw-r--r--src/files.rs19
-rw-r--r--src/listview.rs60
-rw-r--r--src/preview.rs1
-rw-r--r--src/window.rs3
4 files changed, 66 insertions, 17 deletions
diff --git a/src/files.rs b/src/files.rs
index 728fb71..6cb3611 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -170,6 +170,10 @@ impl Files {
pub fn len(&self) -> usize {
self.files.len()
}
+
+ pub fn get_selected(&self) -> Vec<&File> {
+ self.files.iter().filter(|f| f.is_selected()).collect()
+ }
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -210,6 +214,7 @@ pub struct File {
pub mode: u32,
pub user: u32,
pub group: u32,
+ pub selected: bool
// flags: Option<String>,
}
@@ -234,10 +239,8 @@ impl File {
color: color,
mode: mode,
user: user,
- group: group
- // owner: None,
- // group: None,
- // flags: None,
+ group: group,
+ selected: false
}
}
@@ -320,6 +323,14 @@ impl File {
self.path.clone()
}
+ pub fn toggle_selection(&mut self) {
+ self.selected = !self.selected
+ }
+
+ pub fn is_selected(&self) -> bool {
+ self.selected
+ }
+
pub fn pretty_print_permissions(&self) -> String {
let perms: usize = format!("{:o}", self.mode).parse().unwrap();
let perms: usize = perms % 800;
diff --git a/src/listview.rs b/src/listview.rs
index 4fbcc8e..5b102f3 100644
--- a/src/listview.rs
+++ b/src/listview.rs
@@ -20,8 +20,6 @@ where
selection: usize,
offset: usize,
buffer: Vec<String>,
- // dimensions: (u16, u16),
- // position: (u16, u16),
coordinates: Coordinates,
seeking: bool,
}
@@ -94,6 +92,12 @@ where
let name = &file.name;
let (size, unit) = file.calculate_size();
+ let selection_gap = " ".to_string();
+ let (name, selection_color) = if file.is_selected() {
+ (selection_gap + name, crate::term::color_yellow())
+ } else { (name.clone(), "".to_string()) };
+
+
let xsize = self.get_size().xsize();
let sized_string = term::sized_string(&name, xsize);
let size_pos = xsize - (size.to_string().len() as u16
@@ -105,13 +109,17 @@ where
"{}{}{}{}{}{}{}",
termion::cursor::Save,
match &file.color {
- Some(color) => format!("{}{:padding$}",
+ Some(color) => format!("{}{}{:padding$}{}",
term::from_lscolor(color),
+ selection_color,
&sized_string,
+ term::normal_color(),
padding = padding as usize),
- _ => format!("{}{:padding$}",
+ _ => format!("{}{}{:padding$}{}",
term::normal_color(),
+ selection_color,
&sized_string,
+ term::normal_color(),
padding = padding as usize),
} ,
termion::cursor::Restore,
@@ -135,6 +143,12 @@ where
file
}
+ pub fn selected_file_mut(&mut self) -> &mut File {
+ let selection = self.selection;
+ let file = &mut self.content.files[selection];
+ file
+ }
+
pub fn clone_selected_file(&self) -> File {
let selection = self.selection;
let file = self.content[selection].clone();
@@ -247,9 +261,9 @@ where
}
let file = self.clone_selected_file();
- // self.content.dirs_first = dir_settings;
- // self.content.sort = sort_settings;
- // self.content.sort();
+ self.content.dirs_first = dir_settings;
+ self.content.sort = sort_settings;
+ self.content.sort();
self.select_file(&file);
self.seeking = true;
@@ -273,21 +287,44 @@ where
self.show_status(&format!("Direcories first: {}", self.content.dirs_first));
}
+ fn multi_select_file(&mut self) {
+ let file = self.selected_file_mut();
+ file.toggle_selection();
+ self.move_down();
+ self.refresh();
+ }
+
fn exec_cmd(&mut self) {
- match self.minibuffer("exec ($s for selected files)") {
+ let selected_files = self.content.get_selected();
+ let file_names
+ = selected_files.iter().map(|f| f.name.clone()).collect::<Vec<String>>();
+
+ match self.minibuffer("exec ($s for selected file(s))") {
Some(cmd) => {
self.show_status(&format!("Running: \"{}\"", &cmd));
let filename = self.selected_file().name.clone();
- let cmd = cmd.replace("$s", &format!("{}", &filename));
+
+ let cmd = if file_names.len() == 0 {
+ cmd.replace("$s", &format!("{}", &filename))
+ } else {
+ let args = file_names.iter().map(|f| {
+ format!(" \"{}\" ", f)
+ }).collect::<String>();
+ let clean_cmd = cmd.replace("$s", "");
+
+ clean_cmd + &args
+ };
let status = std::process::Command::new("sh")
.arg("-c")
.arg(&cmd)
.status();
match status {
- Ok(status) => self.show_status(&format!("\"{}\" exited with {}", cmd, status)),
- Err(err) => self.show_status(&format!("Can't run this \"{}\": {}", cmd, err)),
+ Ok(status) => self.show_status(&format!("\"{}\" exited with {}",
+ cmd, status)),
+ Err(err) => self.show_status(&format!("Can't run this \"{}\": {}",
+ cmd, err)),
}
}
None => self.show_status(""),
@@ -380,6 +417,7 @@ impl Widget for ListView<Files> {
}
Key::Left => self.goto_grand_parent(),
Key::Right => self.goto_selected(),
+ Key::Char(' ') => self.multi_select_file(),
Key::Char('h') => self.toggle_hidden(),
Key::Char('r') => self.reverse_sort(),
Key::Char('s') => self.cycle_sort(),
diff --git a/src/preview.rs b/src/preview.rs
index 59fa675..15638aa 100644
--- a/src/preview.rs
+++ b/src/preview.rs
@@ -17,7 +17,6 @@ lazy_static! {
fn kill_procs() {
let mut pids = PIDS.lock().unwrap();
for pid in &*pids {
- let msg = format!("KILLING PROC: {}", pid);
unsafe { libc::kill(*pid, 9); }
}
pids.clear();
diff --git a/src/window.rs b/src/window.rs
index 6033c71..2903662 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -148,11 +148,12 @@ pub fn minibuffer(query: &str) -> Option<String> {
return Some(buffer);
}
}
+ Key::Char('\t') => buffer += "$s",
Key::Backspace => {
buffer.pop();
}
Key::Char(key) => {
- buffer = buffer + &format!("{}", key);
+ buffer += &format!("{}", key);
}
_ => {}
},