diff options
author | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2020-05-30 14:09:54 +0300 |
---|---|---|
committer | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2020-05-30 14:09:54 +0300 |
commit | 2c45c390480ab9e9326b3cf514460cf9e2807abb (patch) | |
tree | e2dc0010f999c44f2bedbf912ccb0d15f5c8f839 /melib/src/lib.rs | |
parent | 960d660786657bd482b2c3e88bcf55795df781c0 (diff) |
ShellExpandTrait: fix for non-linux targets
Diffstat (limited to 'melib/src/lib.rs')
-rw-r--r-- | melib/src/lib.rs | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/melib/src/lib.rs b/melib/src/lib.rs index 6b87920b..2da14a5b 100644 --- a/melib/src/lib.rs +++ b/melib/src/lib.rs @@ -141,6 +141,9 @@ pub use shellexpand::ShellExpandTrait; pub mod shellexpand { use smallvec::SmallVec; + use std::ffi::OsStr; + use std::os::unix::ffi::OsStrExt; + use std::os::unix::io::AsRawFd; use std::path::{Path, PathBuf}; pub trait ShellExpandTrait { @@ -181,12 +184,10 @@ pub mod shellexpand { ret } + #[cfg(target_os = "linux")] fn complete(&self, force: bool) -> SmallVec<[String; 128]> { use libc::dirent64; use nix::fcntl::OFlag; - use std::ffi::OsStr; - use std::os::unix::ffi::OsStrExt; - use std::os::unix::io::AsRawFd; const BUF_SIZE: ::libc::size_t = 8 << 10; let (prefix, _match) = if self.as_os_str().as_bytes().ends_with(b"/.") { @@ -287,6 +288,70 @@ pub mod shellexpand { } return entries; } + + #[cfg(not(target_os = "linux"))] + fn complete(&self, force: bool) -> SmallVec<[String; 128]> { + let mut entries = SmallVec::new(); + let (prefix, _match) = { + if self.exists() && (!force || self.as_os_str().as_bytes().ends_with(b"/")) { + // println!("{} {:?}", self.display(), self.components().last()); + return entries; + } else { + let last_component = self + .components() + .last() + .map(|c| c.as_os_str()) + .unwrap_or(OsStr::from_bytes(b"")); + let prefix = if let Some(p) = self.parent() { + p + } else { + return entries; + }; + (prefix, last_component) + } + }; + if force && self.is_dir() && !self.as_os_str().as_bytes().ends_with(b"/") { + entries.push("/".to_string()); + } + + if let Ok(iter) = std::fs::read_dir(&prefix) { + for entry in iter { + if let Ok(entry) = entry { + if entry.path().as_os_str().as_bytes() != b"." + && entry.path().as_os_str().as_bytes() != b".." + && entry + .path() + .as_os_str() + .as_bytes() + .starts_with(_match.as_bytes()) + { + if entry.path().is_dir() + && !entry.path().as_os_str().as_bytes().ends_with(b"/") + { + let mut s = unsafe { + String::from_utf8_unchecked( + entry.path().as_os_str().as_bytes() + [_match.as_bytes().len()..] + .to_vec(), + ) + }; + s.push('/'); + entries.push(s); + } else { + entries.push(unsafe { + String::from_utf8_unchecked( + entry.path().as_os_str().as_bytes() + [_match.as_bytes().len()..] + .to_vec(), + ) + }); + } + } + } + } + } + entries + } } #[test] |