diff --git a/Cargo.lock b/Cargo.lock index ee234f273..3458c0b53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,6 +5,7 @@ dependencies = [ "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ctrlc 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "diff 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -52,6 +53,11 @@ name = "bitflags" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cfg-if" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "clap" version = "2.26.2" @@ -80,6 +86,16 @@ name = "crossbeam" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ctrlc" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "custom_derive" version = "0.1.7" @@ -171,6 +187,17 @@ dependencies = [ "libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "nix" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num_cpus" version = "1.7.0" @@ -337,9 +364,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" +"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3451e409013178663435d6f15fdb212f14ee4424a3d74f979d081d0a66b6f1f2" "checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" "checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97" +"checksum ctrlc 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df391ea008fca636e41e40863a0b39a850e2ab26b0cdeed0c3657fd05a66d44c" "checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" "checksum diff 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0a515461b6c8c08419850ced27bc29e86166dcdcde8fbe76f8b1f0589bb49472" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" @@ -352,6 +381,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf0336886480e671965f794bc9b6fce88503563013d1bfb7a502c81fe3ac527" "checksum magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40d014c7011ac470ae28e2f76a02bfea4a8480f73e701353b49ad7a8d75f4699" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" +"checksum nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "47e49f6982987135c5e9620ab317623e723bd06738fd85377e8d55f57c8b6487" "checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" "checksum rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "eb250fd207a4729c976794d03db689c9be1d634ab5a1c9da9492a13d8fecbcdf" "checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" diff --git a/Cargo.toml b/Cargo.toml index e89068a15..463ec418a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,8 @@ lazy_static = "0.2.9" num_cpus = "1.6.2" regex = "0.2" regex-syntax = "0.4" +ctrlc = "3.0" +shell-escape = "0.1.3" [target.'cfg(all(unix, not(target_os = "redox")))'.dependencies] libc = "0.2" diff --git a/src/output.rs b/src/output.rs index fd54c82cd..f3cbfcb84 100644 --- a/src/output.rs +++ b/src/output.rs @@ -13,16 +13,18 @@ use std::{fs, process}; use std::io::{self, Write}; use std::ops::Deref; use std::path::{self, Path, PathBuf, Component}; +use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; #[cfg(any(unix, target_os = "redox"))] use std::os::unix::fs::PermissionsExt; use ansi_term; -pub fn print_entry(entry: &PathBuf, config: &FdOptions) { +pub fn print_entry(entry: &PathBuf, config: &FdOptions, wants_to_quit: &Arc) { let path = entry.strip_prefix(".").unwrap_or(entry); let r = if let Some(ref ls_colors) = config.ls_colors { - print_entry_colorized(path, config, ls_colors) + print_entry_colorized(path, config, ls_colors, &wants_to_quit) } else { print_entry_uncolorized(path, config) }; @@ -33,7 +35,12 @@ pub fn print_entry(entry: &PathBuf, config: &FdOptions) { } } -fn print_entry_colorized(path: &Path, config: &FdOptions, ls_colors: &LsColors) -> io::Result<()> { +fn print_entry_colorized( + path: &Path, + config: &FdOptions, + ls_colors: &LsColors, + wants_to_quit: &Arc, +) -> io::Result<()> { let default_style = ansi_term::Style::default(); let stdout = io::stdout(); @@ -63,6 +70,11 @@ fn print_entry_colorized(path: &Path, config: &FdOptions, ls_colors: &LsColors) // Everything else uses a separator that is painted the same way as the component. _ => style.paint(path::MAIN_SEPARATOR.to_string()).to_string(), }; + + if wants_to_quit.load(Ordering::Relaxed) { + write!(handle, "\n")?; + process::exit(0); + } } if config.null_separator { diff --git a/src/walk.rs b/src/walk.rs index 0dcbc87c1..874d41b80 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -6,6 +6,8 @@ // notice may not be copied, modified, or distributed except // according to those terms. +extern crate ctrlc; + use exec; use fshelper; use internal::{error, FdOptions}; @@ -13,6 +15,7 @@ use output; use std::path::Path; use std::sync::{Arc, Mutex}; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::channel; use std::thread; use std::time; @@ -74,6 +77,12 @@ pub fn scan(root: &Path, pattern: Arc, config: Arc) { .threads(threads) .build_parallel(); + let wants_to_quit = Arc::new(AtomicBool::new(false)); + + if let Some(_) = config.ls_colors { + let wq = Arc::clone(&wants_to_quit); + ctrlc::set_handler(move || { wq.store(true, Ordering::Relaxed); }).unwrap(); + } // Spawn the thread that receives all results through the channel. let rx_config = Arc::clone(&config); let receiver_thread = thread::spawn(move || { @@ -129,7 +138,7 @@ pub fn scan(root: &Path, pattern: Arc, config: Arc) { if time::Instant::now() - start > max_buffer_time { // Flush the buffer for v in &buffer { - output::print_entry(v, &rx_config); + output::print_entry(&v, &rx_config, &wants_to_quit); } buffer.clear(); @@ -138,7 +147,7 @@ pub fn scan(root: &Path, pattern: Arc, config: Arc) { } } ReceiverMode::Streaming => { - output::print_entry(&value, &rx_config); + output::print_entry(&value, &rx_config, &wants_to_quit); } } } @@ -148,7 +157,7 @@ pub fn scan(root: &Path, pattern: Arc, config: Arc) { if !buffer.is_empty() { buffer.sort(); for value in buffer { - output::print_entry(&value, &rx_config); + output::print_entry(&value, &rx_config, &wants_to_quit); } } }