mirror of https://github.com/sharkdp/fd.git
Fix --exec
This commit is contained in:
parent
87ba4e3bb0
commit
6b232a82ee
|
@ -12,6 +12,7 @@ dependencies = [
|
|||
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"windows 0.0.0",
|
||||
]
|
||||
|
@ -225,6 +226,11 @@ dependencies = [
|
|||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shell-escape"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.6.0"
|
||||
|
@ -360,6 +366,7 @@ dependencies = [
|
|||
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
|
||||
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
|
||||
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
|
||||
"checksum shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5cc96481d54583947bfe88bf30c23d53f883c6cd0145368b69989d97b84ef8"
|
||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||
"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
|
||||
"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
|
||||
|
|
|
@ -39,6 +39,7 @@ lazy_static = "0.2.9"
|
|||
num_cpus = "1.6.2"
|
||||
regex = "0.2"
|
||||
regex-syntax = "0.4"
|
||||
shell-escape = "0.1"
|
||||
|
||||
[target.'cfg(all(unix, not(target_os = "redox")))'.dependencies]
|
||||
libc = "0.2"
|
||||
|
|
|
@ -9,11 +9,7 @@
|
|||
use std::path::MAIN_SEPARATOR;
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[cfg(windows)]
|
||||
const ESCAPE: char = '^';
|
||||
|
||||
#[cfg(not(windows))]
|
||||
const ESCAPE: char = '\\';
|
||||
use shell_escape::escape;
|
||||
|
||||
/// A builder for efficiently generating input strings.
|
||||
///
|
||||
|
@ -88,61 +84,12 @@ impl<'a> Input<'a> {
|
|||
}
|
||||
|
||||
pub fn get(&'a self) -> Cow<'a, str> {
|
||||
fn char_is_quotable(x: char) -> bool {
|
||||
[
|
||||
' ',
|
||||
'(',
|
||||
')',
|
||||
'[',
|
||||
']',
|
||||
'&',
|
||||
'$',
|
||||
'@',
|
||||
'{',
|
||||
'}',
|
||||
'<',
|
||||
'>',
|
||||
'|',
|
||||
';',
|
||||
'"',
|
||||
'\'',
|
||||
'#',
|
||||
'*',
|
||||
'%',
|
||||
'?',
|
||||
'`',
|
||||
].contains(&x)
|
||||
};
|
||||
escape(Cow::Borrowed(self.data))
|
||||
}
|
||||
|
||||
// If a quotable character is found, we will use that position for allocating.
|
||||
let pos = match self.data.find(char_is_quotable) {
|
||||
Some(pos) => pos,
|
||||
// Otherwise, we will return the contents of `data` without allocating.
|
||||
None => return Cow::Borrowed(self.data),
|
||||
};
|
||||
|
||||
// When building the input string, we will start by adding the characters that
|
||||
// we've already verified to be free of special characters.
|
||||
let mut owned = String::with_capacity(self.data.len());
|
||||
owned.push_str(&self.data[..pos]);
|
||||
owned.push(ESCAPE);
|
||||
|
||||
// This slice contains the data that is left to be scanned for special characters.
|
||||
// If multiple characters are found, this slice will be sliced and updated multiple times.
|
||||
let mut slice = &self.data[pos..];
|
||||
|
||||
// Repeatedly search for special characters until all special characters have been found,
|
||||
// appending and inserting the escape character each time, as well as updating our
|
||||
// starting position.
|
||||
while let Some(pos) = slice[1..].find(char_is_quotable) {
|
||||
owned.push_str(&slice[..pos + 1]);
|
||||
owned.push(ESCAPE);
|
||||
slice = &slice[pos + 1..];
|
||||
}
|
||||
|
||||
// Finally, we return our newly-allocated input string.
|
||||
owned.push_str(slice);
|
||||
Cow::Owned(owned)
|
||||
#[cfg(test)]
|
||||
fn get_private(&'a self) -> Cow<'a, str> {
|
||||
Cow::Borrowed(self.data)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,101 +105,101 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn path_remove_ext_simple() {
|
||||
assert_eq!(&Input::new("foo.txt").remove_extension().get(), "foo");
|
||||
assert_eq!(
|
||||
&Input::new("foo.txt").remove_extension().get_private(),
|
||||
"foo"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_remove_ext_dir() {
|
||||
assert_eq!(
|
||||
&Input::new(&correct("dir/foo.txt")).remove_extension().get(),
|
||||
&Input::new(&correct("dir/foo.txt"))
|
||||
.remove_extension()
|
||||
.get_private(),
|
||||
&correct("dir/foo")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_hidden() {
|
||||
assert_eq!(&Input::new(".foo").remove_extension().get(), ".foo")
|
||||
assert_eq!(&Input::new(".foo").remove_extension().get_private(), ".foo")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_remove_ext_utf8() {
|
||||
assert_eq!(&Input::new("💖.txt").remove_extension().get(), "💖");
|
||||
assert_eq!(
|
||||
&Input::new("💖.txt").remove_extension().get_private(),
|
||||
"💖"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_remove_ext_empty() {
|
||||
assert_eq!(&Input::new("").remove_extension().get(), "");
|
||||
assert_eq!(&Input::new("").remove_extension().get_private(), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_basename_simple() {
|
||||
assert_eq!(&Input::new("foo.txt").basename().get(), "foo.txt");
|
||||
assert_eq!(&Input::new("foo.txt").basename().get_private(), "foo.txt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_basename_dir() {
|
||||
assert_eq!(
|
||||
&Input::new(&correct("dir/foo.txt")).basename().get(),
|
||||
&Input::new(&correct("dir/foo.txt")).basename().get_private(),
|
||||
"foo.txt"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_basename_empty() {
|
||||
assert_eq!(&Input::new("").basename().get(), "");
|
||||
assert_eq!(&Input::new("").basename().get_private(), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_basename_utf8() {
|
||||
assert_eq!(
|
||||
&Input::new(&correct("💖/foo.txt")).basename().get(),
|
||||
&Input::new(&correct("💖/foo.txt"))
|
||||
.basename()
|
||||
.get_private(),
|
||||
"foo.txt"
|
||||
);
|
||||
assert_eq!(
|
||||
&Input::new(&correct("dir/💖.txt")).basename().get(),
|
||||
&Input::new(&correct("dir/💖.txt"))
|
||||
.basename()
|
||||
.get_private(),
|
||||
"💖.txt"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_dirname_simple() {
|
||||
assert_eq!(&Input::new("foo.txt").dirname().get(), ".");
|
||||
assert_eq!(&Input::new("foo.txt").dirname().get_private(), ".");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_dirname_dir() {
|
||||
assert_eq!(&Input::new(&correct("dir/foo.txt")).dirname().get(), "dir");
|
||||
assert_eq!(
|
||||
&Input::new(&correct("dir/foo.txt")).dirname().get_private(),
|
||||
"dir"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_dirname_utf8() {
|
||||
assert_eq!(
|
||||
&Input::new(&correct("💖/foo.txt")).dirname().get(),
|
||||
&Input::new(&correct("💖/foo.txt")).dirname().get_private(),
|
||||
"💖"
|
||||
);
|
||||
assert_eq!(&Input::new(&correct("dir/💖.txt")).dirname().get(), "dir");
|
||||
assert_eq!(
|
||||
&Input::new(&correct("dir/💖.txt")).dirname().get_private(),
|
||||
"dir"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_dirname_empty() {
|
||||
assert_eq!(&Input::new("").dirname().get(), ".");
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[test]
|
||||
fn path_special_chars() {
|
||||
assert_eq!(
|
||||
&Input::new("A Directory\\And A File").get(),
|
||||
"A^ Directory\\And^ A^ File"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[test]
|
||||
fn path_special_chars() {
|
||||
assert_eq!(
|
||||
&Input::new("A Directory/And A File").get(),
|
||||
"A\\ Directory/And\\ A\\ File"
|
||||
);
|
||||
assert_eq!(&Input::new("").dirname().get_private(), ".");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ extern crate libc;
|
|||
extern crate num_cpus;
|
||||
extern crate regex;
|
||||
extern crate regex_syntax;
|
||||
extern crate shell_escape;
|
||||
#[cfg(windows)]
|
||||
extern crate windows;
|
||||
|
||||
|
|
Loading…
Reference in New Issue