diff options
author | Jeff Zhao <jeff.no.zhao@gmail.com> | 2021-05-14 17:59:34 -0400 |
---|---|---|
committer | Jeff Zhao <jeff.no.zhao@gmail.com> | 2021-05-14 18:04:16 -0400 |
commit | 1456b65de3d9b16ed4292af925928ec4da826a6a (patch) | |
tree | d6de9e8f87edc6e258adf5a74d12cd3c0163eb51 /src | |
parent | 216ca0938f36476e221276f2f63d68bf8b9d770c (diff) |
fix set_mode not working
Diffstat (limited to 'src')
-rw-r--r-- | src/commands/set_mode.rs | 44 | ||||
-rw-r--r-- | src/commands/shell.rs | 2 | ||||
-rw-r--r-- | src/config/theme/style.rs | 2 | ||||
-rw-r--r-- | src/fs/dirlist.rs | 12 | ||||
-rw-r--r-- | src/util/unix.rs | 12 |
5 files changed, 43 insertions, 29 deletions
diff --git a/src/commands/set_mode.rs b/src/commands/set_mode.rs index 62da2d1..4838fe0 100644 --- a/src/commands/set_mode.rs +++ b/src/commands/set_mode.rs @@ -1,3 +1,5 @@ +use std::fs; + use crate::context::AppContext; use crate::error::JoshutoResult; use crate::ui::views::TuiTextField; @@ -9,6 +11,7 @@ use super::cursor_move; #[derive(Clone, Debug)] pub struct SetMode; +#[cfg(unix)] const LIBC_PERMISSION_VALS: [(libc::mode_t, char); 9] = [ (libc::S_IRUSR, 'r'), (libc::S_IWUSR, 'w'), @@ -23,7 +26,7 @@ const LIBC_PERMISSION_VALS: [(libc::mode_t, char); 9] = [ pub fn str_to_mode(s: &str) -> u32 { let mut mode: u32 = 0; - for (i, ch) in s.chars().enumerate() { + for (i, ch) in s.chars().enumerate().take(LIBC_PERMISSION_VALS.len()) { if ch == LIBC_PERMISSION_VALS[i].1 { let val: u32 = LIBC_PERMISSION_VALS[i].0 as u32; mode |= val; @@ -33,6 +36,7 @@ pub fn str_to_mode(s: &str) -> u32 { } pub fn set_mode(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoResult<()> { + #[cfg(unix)] use std::os::unix::fs::PermissionsExt; const PREFIX: &str = "set_mode "; @@ -44,9 +48,12 @@ pub fn set_mode(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoRe let user_input = match entry { Some(entry) => { - context.flush_event(); let mode = entry.metadata.permissions_ref().mode(); + eprintln!("{:o}", mode); let mode_string = unix::mode_to_string(mode); + eprintln!("{}", mode_string); + + context.flush_event(); TuiTextField::default() .prompt(":") .prefix(PREFIX) @@ -58,19 +65,30 @@ pub fn set_mode(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoRe if let Some(s) = user_input { if let Some(stripped) = s.strip_prefix(PREFIX) { - let s = stripped; - let mode = str_to_mode(s); + let mode = str_to_mode(stripped); + if let Some(curr_list) = context.tab_context_mut().curr_tab_mut().curr_list_mut() { + if curr_list.any_selected() { + for entry in curr_list.iter_selected_mut() { + let mut permissions = entry.metadata.permissions_ref().clone(); + let file_mode = (permissions.mode() >> 12) << 12 | mode; + permissions.set_mode(file_mode); + + fs::set_permissions(entry.file_path(), permissions)?; + entry.metadata.permissions_mut().set_mode(file_mode); + } + } else { + if let Some(entry) = curr_list.curr_entry_mut() { + let mut permissions = entry.metadata.permissions_ref().clone(); + let file_mode = (permissions.mode() >> 12) << 12 | mode; + permissions.set_mode(file_mode); - let entry = context - .tab_context_mut() - .curr_tab_mut() - .curr_list_mut() - .and_then(|x| x.curr_entry_mut()) - .unwrap(); + fs::set_permissions(entry.file_path(), permissions)?; + entry.metadata.permissions_mut().set_mode(file_mode); - unix::set_mode(entry.file_path(), mode); - entry.metadata.permissions_mut().set_mode(mode); - cursor_move::down(context, 1)?; + cursor_move::down(context, 1)?; + } + } + } } } Ok(()) diff --git a/src/commands/shell.rs b/src/commands/shell.rs index 598b64d..7823d91 100644 --- a/src/commands/shell.rs +++ b/src/commands/shell.rs @@ -13,7 +13,7 @@ pub fn shell_command(context: &mut AppContext, words: &[String]) -> std::io::Res "%s" => { if let Some(curr_list) = context.tab_context_ref().curr_tab_ref().curr_list_ref() { let mut i = 0; - for entry in curr_list.selected_entries().map(|e| e.file_name()) { + for entry in curr_list.iter_selected().map(|e| e.file_name()) { command.arg(entry); i += 1; } diff --git a/src/config/theme/style.rs b/src/config/theme/style.rs index bee41ed..e63b988 100644 --- a/src/config/theme/style.rs +++ b/src/config/theme/style.rs @@ -60,7 +60,7 @@ impl RawAppStyle { "light_cyan" => style::Color::LightCyan, "white" => style::Color::White, "reset" => style::Color::Reset, - s if s.len() == 0 => style::Color::Reset, + s if s.is_empty() => style::Color::Reset, s => match s.parse::<Rgb>() { Ok(rgb) => { let r = rgb.get_red() as u8; diff --git a/src/fs/dirlist.rs b/src/fs/dirlist.rs index adc848a..b80e05b 100644 --- a/src/fs/dirlist.rs +++ b/src/fs/dirlist.rs @@ -108,13 +108,21 @@ impl JoshutoDirList { Ok(()) } - pub fn selected_entries(&self) -> impl Iterator<Item = &JoshutoDirEntry> { + pub fn any_selected(&self) -> bool { + self.contents.iter().any(|e| e.is_selected()) + } + + pub fn iter_selected(&self) -> impl Iterator<Item = &JoshutoDirEntry> { self.contents.iter().filter(|entry| entry.is_selected()) } + pub fn iter_selected_mut(&mut self) -> impl Iterator<Item = &mut JoshutoDirEntry> { + self.contents.iter_mut().filter(|entry| entry.is_selected()) + } + pub fn get_selected_paths(&self) -> Vec<path::PathBuf> { let vec: Vec<path::PathBuf> = self - .selected_entries() + .iter_selected() .map(|e| e.file_path().to_path_buf()) .collect(); if !vec.is_empty() { diff --git a/src/util/unix.rs b/src/util/unix.rs index c211f6f..5114a69 100644 --- a/src/util/unix.rs +++ b/src/util/unix.rs @@ -1,5 +1,3 @@ -use std::path::Path; - pub fn is_executable(mode: u32) -> bool { const LIBC_PERMISSION_VALS: [libc::mode_t; 3] = [libc::S_IXUSR, libc::S_IXGRP, libc::S_IXOTH]; @@ -51,13 +49,3 @@ pub fn mode_to_string(mode: u32) -> String { } mode_str } - -pub fn set_mode(path: &Path, mode: u32) { - let os_path = path.as_os_str(); - if let Some(s) = os_path.to_str() { - let svec: Vec<libc::c_char> = s.bytes().map(|ch| ch as libc::c_char).collect(); - unsafe { - libc::chmod(svec.as_ptr(), mode as libc::mode_t); - } - } -} |