1
0
mirror of https://github.com/bobwen-dev/hunter synced 2025-04-12 00:55:41 +02:00

multi-file selection

This commit is contained in:
rabite 2019-02-07 16:32:27 +01:00
parent 626ba13239
commit ea9d6d4d92
4 changed files with 66 additions and 17 deletions

View File

@ -170,6 +170,10 @@ impl Files {
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.files.len() 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)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@ -210,6 +214,7 @@ pub struct File {
pub mode: u32, pub mode: u32,
pub user: u32, pub user: u32,
pub group: u32, pub group: u32,
pub selected: bool
// flags: Option<String>, // flags: Option<String>,
} }
@ -234,10 +239,8 @@ impl File {
color: color, color: color,
mode: mode, mode: mode,
user: user, user: user,
group: group group: group,
// owner: None, selected: false
// group: None,
// flags: None,
} }
} }
@ -320,6 +323,14 @@ impl File {
self.path.clone() 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 { pub fn pretty_print_permissions(&self) -> String {
let perms: usize = format!("{:o}", self.mode).parse().unwrap(); let perms: usize = format!("{:o}", self.mode).parse().unwrap();
let perms: usize = perms % 800; let perms: usize = perms % 800;

View File

@ -20,8 +20,6 @@ where
selection: usize, selection: usize,
offset: usize, offset: usize,
buffer: Vec<String>, buffer: Vec<String>,
// dimensions: (u16, u16),
// position: (u16, u16),
coordinates: Coordinates, coordinates: Coordinates,
seeking: bool, seeking: bool,
} }
@ -94,6 +92,12 @@ where
let name = &file.name; let name = &file.name;
let (size, unit) = file.calculate_size(); 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 xsize = self.get_size().xsize();
let sized_string = term::sized_string(&name, xsize); let sized_string = term::sized_string(&name, xsize);
let size_pos = xsize - (size.to_string().len() as u16 let size_pos = xsize - (size.to_string().len() as u16
@ -105,13 +109,17 @@ where
"{}{}{}{}{}{}{}", "{}{}{}{}{}{}{}",
termion::cursor::Save, termion::cursor::Save,
match &file.color { match &file.color {
Some(color) => format!("{}{:padding$}", Some(color) => format!("{}{}{:padding$}{}",
term::from_lscolor(color), term::from_lscolor(color),
selection_color,
&sized_string, &sized_string,
term::normal_color(),
padding = padding as usize), padding = padding as usize),
_ => format!("{}{:padding$}", _ => format!("{}{}{:padding$}{}",
term::normal_color(), term::normal_color(),
selection_color,
&sized_string, &sized_string,
term::normal_color(),
padding = padding as usize), padding = padding as usize),
} , } ,
termion::cursor::Restore, termion::cursor::Restore,
@ -135,6 +143,12 @@ where
file 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 { pub fn clone_selected_file(&self) -> File {
let selection = self.selection; let selection = self.selection;
let file = self.content[selection].clone(); let file = self.content[selection].clone();
@ -247,9 +261,9 @@ where
} }
let file = self.clone_selected_file(); let file = self.clone_selected_file();
// self.content.dirs_first = dir_settings; self.content.dirs_first = dir_settings;
// self.content.sort = sort_settings; self.content.sort = sort_settings;
// self.content.sort(); self.content.sort();
self.select_file(&file); self.select_file(&file);
self.seeking = true; self.seeking = true;
@ -273,21 +287,44 @@ where
self.show_status(&format!("Direcories first: {}", self.content.dirs_first)); 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) { 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) => { Some(cmd) => {
self.show_status(&format!("Running: \"{}\"", &cmd)); self.show_status(&format!("Running: \"{}\"", &cmd));
let filename = self.selected_file().name.clone(); 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") let status = std::process::Command::new("sh")
.arg("-c") .arg("-c")
.arg(&cmd) .arg(&cmd)
.status(); .status();
match status { match status {
Ok(status) => self.show_status(&format!("\"{}\" exited with {}", cmd, status)), Ok(status) => self.show_status(&format!("\"{}\" exited with {}",
Err(err) => self.show_status(&format!("Can't run this \"{}\": {}", cmd, err)), cmd, status)),
Err(err) => self.show_status(&format!("Can't run this \"{}\": {}",
cmd, err)),
} }
} }
None => self.show_status(""), None => self.show_status(""),
@ -380,6 +417,7 @@ impl Widget for ListView<Files> {
} }
Key::Left => self.goto_grand_parent(), Key::Left => self.goto_grand_parent(),
Key::Right => self.goto_selected(), Key::Right => self.goto_selected(),
Key::Char(' ') => self.multi_select_file(),
Key::Char('h') => self.toggle_hidden(), Key::Char('h') => self.toggle_hidden(),
Key::Char('r') => self.reverse_sort(), Key::Char('r') => self.reverse_sort(),
Key::Char('s') => self.cycle_sort(), Key::Char('s') => self.cycle_sort(),

View File

@ -17,7 +17,6 @@ lazy_static! {
fn kill_procs() { fn kill_procs() {
let mut pids = PIDS.lock().unwrap(); let mut pids = PIDS.lock().unwrap();
for pid in &*pids { for pid in &*pids {
let msg = format!("KILLING PROC: {}", pid);
unsafe { libc::kill(*pid, 9); } unsafe { libc::kill(*pid, 9); }
} }
pids.clear(); pids.clear();

View File

@ -148,11 +148,12 @@ pub fn minibuffer(query: &str) -> Option<String> {
return Some(buffer); return Some(buffer);
} }
} }
Key::Char('\t') => buffer += "$s",
Key::Backspace => { Key::Backspace => {
buffer.pop(); buffer.pop();
} }
Key::Char(key) => { Key::Char(key) => {
buffer = buffer + &format!("{}", key); buffer += &format!("{}", key);
} }
_ => {} _ => {}
}, },