Repository: cristianoliveira/funzzy (language: rust)

Issue:
No working with VScode
Hi, I'm not sure if this is out of scope. 
Is working fine with `vim` or the default visual editor on the os but not working with editor like `vscode`, `pulsar editor` or `sublime text`
also not working with `nano`
the output is just 
`Funzzy: Watching...`
I'm using `Linux mint` as OS

Here the yml file:

```yml
- name: run my test
  run: [
    'ls -a',
    'echo helooooo'
  ]
  change: "**"
```

also i want to point out that `inotifywait` is working fine:

```bash
while inotifywait -e close_write **; \
do clear && \
    date +"%T"
    ls -la
done
```

Any idea? Thank you



Discussion / hints:
Hello @Mgldvd it isn't out of scope! The watcher must work on any regular terminal, even when running within an IDE. 
Could you help me understand the issue by:

 - Let me know which version you are using
 - Checking if it works with a more specific rule like:
```js
- name: run my test
  run: [
    'ls -a',
    'echo helooooo'
  ]
  change: "./src/**"
```

- Could you paste here the verbose output? Enable it with `-V` (capitalized v)
Ok, after some tests, I think I figured! Thanks again for reporting 😄 

Today the watcher only listen`Create` which, when editing with VIM, is always triggered. ([here](https://github.com/cristianoliveira/funzzy/blob/master/src/cli/watch.rs#L62)). The reason is to avoid triggering multiple times the same task.

It seems the VScode only triggers `Write` and `NoticeWrite` events when saving a file. I think I know how to fix that by checking more events and only picking the first one, to avoid running the task multiple times

Here is the output for when VIM saves a buffer into a file: 
```
-----------------------------
Funzzy: Watching...
-----------------------------
Funzzy verbose: event NoticeRemove("/Users/cristianoliveira/other/funzzy.nvim/lua/funzzy/4913") 
-----------------------------
-----------------------------
Funzzy verbose: event NoticeRemove("/Users/cristianoliveira/other/funzzy.nvim/lua/funzzy/init.lua") 
-----------------------------
-----------------------------
Funzzy verbose: event NoticeRemove("/Users/cristianoliveira/other/funzzy.nvim/lua/funzzy/init.lua~") 
-----------------------------
-----------------------------
Funzzy verbose: event Remove("/Users/cristianoliveira/other/funzzy.nvim/lua/funzzy/4913") 
-----------------------------
-----------------------------
Funzzy verbose: event Create("/Users/cristianoliveira/other/funzzy.nvim/lua/funzzy/init.lua") 
-----------------------------
-----------------------------
Funzzy verbose: Triggered by change in: /Users/cristianoliveira/other/funzzy.nvim/lua/funzzy/init.lua 
-----------------------------
Funzzy:  task make test 

```
Here is for VScode:

```
-----------------------------
Funzzy verbose: watches Watches { rules: [Rules { name: "run my test", commands: ["make test"], watch_patterns: ["lua/**"], ignore_patterns: [], run_on_init: false }] } 
-----------------------------
-----------------------------
Funzzy verbose: Verbose mode enabled. 
-----------------------------
Funzzy: Watching...
-----------------------------
Funzzy verbose: event NoticeWrite("/Users/cristianoliveira/other/funzzy.nvim/lua/funzzy/init.lua") 
-----------------------------
-----------------------------
Funzzy verbose: event Write("/Users/cristianoliveira/other/funzzy.nvim/lua/funzzy/init.lua") 
-----------------------------
```


Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index ecc8fca..ff9d133 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -13,9 +13,9 @@ dependencies = [
 
 [[package]]
 name = "bitflags"
-version = "1.0.4"
+version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "cfg-if"
@@ -23,6 +23,31 @@ version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
 
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
+dependencies = [
+ "cfg-if 1.0.0",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
 [[package]]
 name = "docopt"
 version = "1.1.0"
@@ -37,13 +62,14 @@ dependencies = [
 
 [[package]]
 name = "filetime"
-version = "0.2.5"
+version = "0.2.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f8c63033fcba1f51ef744505b3cad42510432b904c062afa67ad7ece008429d"
+checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
  "redox_syscall",
+ "windows-sys 0.48.0",
 ]
 
 [[package]]
@@ -53,7 +79,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
 dependencies = [
  "bitflags",
- "fsevent-sys",
+ "fsevent-sys 2.0.1",
 ]
 
 [[package]]
@@ -65,6 +91,15 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "fsevent-sys"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "fuchsia-zircon"
 version = "0.3.3"
@@ -87,7 +122,8 @@ version = "1.0.0"
 dependencies = [
  "docopt",
  "glob",
- "notify",
+ "notify 4.0.11",
+ "notify-debouncer-mini",
  "serde",
  "serde_derive",
  "yaml-rust",
@@ -110,6 +146,17 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "inotify"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
+dependencies = [
+ "bitflags",
+ "inotify-sys",
+ "libc",
+]
+
 [[package]]
 name = "inotify-sys"
 version = "0.1.3"
@@ -139,6 +186,26 @@ dependencies = [
  "winapi-build",
 ]
 
+[[package]]
+name = "kqueue"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98"
+dependencies = [
+ "kqueue-sys",
+ "libc",
+]
+
+[[package]]
+name = "kqueue-sys"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587"
+dependencies = [
+ "bitflags",
+ "libc",
+]
+
 [[package]]
 name = "lazy_static"
 version = "1.3.0"
@@ -153,9 +220,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 
 [[package]]
 name = "libc"
-version = "0.2.54"
+version = "0.2.146"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6"
+checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
 
 [[package]]
 name = "linked-hash-map"
@@ -165,12 +232,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
 
 [[package]]
 name = "log"
-version = "0.4.6"
+version = "0.4.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
-dependencies = [
- "cfg-if",
-]
+checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
 
 [[package]]
 name = "memchr"
@@ -197,6 +261,18 @@ dependencies = [
  "winapi 0.2.8",
 ]
 
+[[package]]
+name = "mio"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys 0.48.0",
+]
+
 [[package]]
 name = "mio-extras"
 version = "2.0.5"
@@ -205,7 +281,7 @@ checksum = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
 dependencies = [
  "lazycell",
  "log",
- "mio",
+ "mio 0.6.16",
  "slab",
 ]
 
@@ -227,7 +303,7 @@ version = "0.2.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631"
 dependencies = [
- "cfg-if",
+ "cfg-if 0.1.7",
  "libc",
  "winapi 0.3.7",
 ]
@@ -241,16 +317,44 @@ dependencies = [
  "bitflags",
  "filetime",
  "fsevent",
- "fsevent-sys",
- "inotify",
+ "fsevent-sys 2.0.1",
+ "inotify 0.6.1",
  "kernel32-sys",
  "libc",
- "mio",
+ "mio 0.6.16",
  "mio-extras",
  "walkdir",
  "winapi 0.3.7",
 ]
 
+[[package]]
+name = "notify"
+version = "6.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d9ba6c734de18ca27c8cef5cd7058aa4ac9f63596131e4c7e41e579319032a2"
+dependencies = [
+ "bitflags",
+ "crossbeam-channel",
+ "filetime",
+ "fsevent-sys 4.1.0",
+ "inotify 0.9.6",
+ "kqueue",
+ "libc",
+ "mio 0.8.8",
+ "walkdir",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "notify-debouncer-mini"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e55ee272914f4563a2f8b8553eb6811f3c0caea81c756346bad15b7e3ef969f0"
+dependencies = [
+ "crossbeam-channel",
+ "notify 6.0.0",
+]
+
 [[package]]
 name = "proc-macro2"
 version = "0.4.30"
@@ -271,9 +375,12 @@ dependencies = [
 
 [[package]]
 name = "redox_syscall"
-version = "0.1.54"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+dependencies = [
+ "bitflags",
+]
 
 [[package]]
 name = "regex"
@@ -361,6 +468,12 @@ dependencies = [
  "winapi-util",
 ]
 
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
 [[package]]
 name = "winapi"
 version = "0.2.8"
@@ -404,6 +517,138 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.0",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.0",
+ "windows_aarch64_msvc 0.48.0",
+ "windows_i686_gnu 0.48.0",
+ "windows_i686_msvc 0.48.0",
+ "windows_x86_64_gnu 0.48.0",
+ "windows_x86_64_gnullvm 0.48.0",
+ "windows_x86_64_msvc 0.48.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+
 [[package]]
 name = "ws2_32-sys"
 version = "0.2.1"
diff --git a/Cargo.toml b/Cargo.toml
index a76fecd..6c715c8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "funzzy"
-version = "1.0.0"
+version = "1.0.1"
 authors = ["Cristian Oliveira <me@cristianoliveira.com>"]
 description = "Yet another fancy watcher inspired by entr."
 license = "MIT"
@@ -13,4 +13,5 @@ serde_derive = "1.0" # if you're using `derive(Deserialize)`
 notify = "4.0.0"
 yaml-rust = "0.4.1"
 glob="0.2.11"
+notify-debouncer-mini = "0.3.0"
 #clippy = "*"
diff --git a/examples/long-task.yaml b/examples/long-task.yaml
index 5cdee03..bcd24da 100644
--- a/examples/long-task.yaml
+++ b/examples/long-task.yaml
@@ -1,22 +1,32 @@
 - name: run long task 2
   run: "bash examples/longtask.sh long 2"
   change: ["src/**", "tests/integration/workdir/**"]
+  # Ignoring VIM backup files
+  ignore: ["**/*~", "**/*.sw?"]
 
 - name: run long task 3
   run: "bash examples/longtask.sh short 3"
   change: ["src/**", "tests/integration/workdir/**"]
+  # Ignoring VIM backup files
+  ignore: ["**/*~", "**/*.sw?"]
 
 - name: run long task 4
   run: "bash examples/longtask.sh short 4"
   change: ["src/**", "tests/integration/workdir/**"]
+  # Ignoring VIM backup files
+  ignore: ["**/*~", "**/*.sw?"]
   run_on_init: true
 
 - name: run long task 5
   run: "bash examples/longtask.sh short 5"
   change: ["src/**", "tests/integration/workdir/**"]
+  # Ignoring VIM backup files
+  ignore: ["**/*~", "**/*.sw?"]
   run_on_init: true
 
 - name: run long task 6
   run: ["bash examples/longtask.sh list 3", "bash examples/longtask.sh list 4"]
   change: ["src/**", "tests/integration/workdir/**"]
+  # Ignoring VIM backup files
+  ignore: ["**/*~", "**/*.sw?"]
   run_on_init: true
diff --git a/linux-install.sh b/linux-install.sh
index 814ab3f..bd4db82 100644
--- a/linux-install.sh
+++ b/linux-install.sh
@@ -1,4 +1,4 @@
-VERSION="v1.0.0"
+VERSION="v1.0.1"
 
 cd /tmp
 
diff --git a/src/cli/watch.rs b/src/cli/watch.rs
index 667dc0d..ffc2de0 100644
--- a/src/cli/watch.rs
+++ b/src/cli/watch.rs
@@ -1,14 +1,8 @@
-extern crate notify;
-
-use std::sync::mpsc::channel;
-
-use self::notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher};
-use std::time::Duration;
-
 use cli::Command;
 use cmd;
 use rules;
 use stdout;
+use watcher;
 use watches::Watches;
 
 pub const DEFAULT_FILENAME: &str = ".watch.yaml";
@@ -35,14 +29,6 @@ impl Command for WatchCommand {
     fn execute(&self) -> Result<(), String> {
         stdout::verbose("Verbose mode enabled.", self.verbose);
 
-        let (tx, rx) = channel();
-        let mut watcher: RecommendedWatcher =
-            Watcher::new(tx, Duration::from_millis(200)).expect("Unable to create watcher");
-
-        if let Err(err) = watcher.watch(".", RecursiveMode::Recursive) {
-            return Err(format!("Unable to watch current directory {:?}", err));
-        }
-
         if let Some(rules) = self.watches.run_on_init() {
             stdout::info("Running on init commands.");
 
@@ -57,29 +43,28 @@ impl Command for WatchCommand {
             stdout::present_results(results);
         }
 
-        stdout::info("Watching...");
-        while let Ok(event) = rx.recv() {
-            stdout::verbose(&format!("Event {:?}", event), self.verbose);
-            if let DebouncedEvent::Create(path) = event {
-                let path_str = path.into_os_string().into_string().unwrap();
-                if let Some(rules) = self.watches.watch(&path_str) {
+        watcher::events(
+            |file_changed| {
+                if let Some(rules) = self.watches.watch(file_changed) {
                     stdout::verbose(
-                        &format!("Triggered by change in: {}", path_str),
+                        &format!("Triggered by change in: {}", file_changed),
                         self.verbose,
                     );
 
-                    let results = rules::template(rules::commands(rules), path_str.as_str())
+                    stdout::verbose(&format!("Rules: {:?}", rules), self.verbose);
+
+                    let results = rules::template(rules::commands(rules), file_changed)
                         .iter()
                         .map(|task| {
                             stdout::info(&format!(" task {} \n", String::from(task)));
                             cmd::execute(task)
                         })
                         .collect::<Vec<Result<(), String>>>();
-
                     stdout::present_results(results);
                 }
-            }
-        }
+            },
+            self.verbose,
+        );
         Ok(())
     }
 }
diff --git a/src/cli/watch_non_block.rs b/src/cli/watch_non_block.rs
index 2b53952..e5b42cd 100644
--- a/src/cli/watch_non_block.rs
+++ b/src/cli/watch_non_block.rs
@@ -1,13 +1,8 @@
 extern crate notify;
 
-use std::sync::mpsc::channel;
-use std::sync::mpsc::TryRecvError;
-
-use self::notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher};
-use std::time::Duration;
-
 use cli::Command;
 use stdout;
+use watcher;
 use watches::Watches;
 use workers;
 
@@ -34,14 +29,6 @@ impl Command for WatchNonBlockCommand {
     fn execute(&self) -> Result<(), String> {
         stdout::verbose("Verbose mode enabled.", self.verbose);
 
-        let (tx, rx) = channel();
-        let mut watcher: RecommendedWatcher =
-            Watcher::new(tx, Duration::from_millis(200)).expect("Unable to create watcher");
-
-        if let Err(err) = watcher.watch(".", RecursiveMode::Recursive) {
-            return Err(format!("Unable to watch current directory {:?}", err));
-        }
-
         let worker = workers::Worker::new(self.verbose);
 
         if let Some(rules) = self.watches.run_on_init() {
@@ -51,46 +38,29 @@ impl Command for WatchNonBlockCommand {
             }
         }
 
-        stdout::info("Watching...");
-        loop {
-            match rx.try_recv() {
-                Ok(event) => {
-                    stdout::verbose(&format!("Event {:?}", event), self.verbose);
-                    if let DebouncedEvent::Create(path) = event {
-                        let path_str = path.into_os_string().into_string().unwrap();
-
-                        stdout::verbose(&format!("Changed file: {}", path_str), self.verbose);
-
-                        if let Some(rules) = self.watches.watch(&path_str) {
-                            stdout::verbose(
-                                &format!("Triggered by change in: {}", path_str),
-                                self.verbose,
-                            );
-
-                            if let Err(err) = worker.cancel_running_tasks() {
-                                stdout::error(&format!(
-                                    "failed to cancel current running tasks: {:?}",
-                                    err
-                                ));
-                            }
-
-                            if let Err(err) = worker.schedule(rules.clone(), path_str.as_str()) {
-                                stdout::error(&format!("failed to initiate next run: {:?}", err));
-                            }
-                        }
+        watcher::events(
+            |file_changed| {
+                if let Some(rules) = self.watches.watch(file_changed) {
+                    stdout::verbose(
+                        &format!("Triggered by change in: {}", file_changed),
+                        self.verbose,
+                    );
+
+                    if let Err(err) = worker.cancel_running_tasks() {
+                        stdout::error(&format!(
+                            "failed to cancel current running tasks: {:?}",
+                            err
+                        ));
                     }
-                }
 
-                Err(err) => {
-                    if err != TryRecvError::Empty {
-                        stdout::error(&format!("failed to receive event: {:?}", err));
-                        break;
+                    if let Err(err) = worker.schedule(rules, file_changed) {
+                        stdout::error(&format!("failed to initiate next run: {:?}", err));
                     }
                 }
-            }
-
-            std::thread::sleep(std::time::Duration::from_millis(200));
-        }
+            },
+            self.verbose,
+        );
+        stdout::info("Watching...");
 
         Ok(())
     }
diff --git a/src/lib.rs b/src/lib.rs
index c5ece20..c5bcc90 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -4,6 +4,7 @@ pub mod cli;
 pub mod cmd;
 pub mod rules;
 pub mod stdout;
+pub mod watcher;
 pub mod watches;
 pub mod workers;
 pub mod yaml;
diff --git a/src/main.rs b/src/main.rs
index 5639363..a4fbc87 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,6 +8,7 @@ mod cli;
 mod cmd;
 mod rules;
 mod stdout;
+mod watcher;
 mod watches;
 mod workers;
 mod yaml;
diff --git a/src/watcher.rs b/src/watcher.rs
new file mode 100644
index 0000000..66987f2
--- /dev/null
+++ b/src/watcher.rs
@@ -0,0 +1,50 @@
+extern crate notify;
+extern crate notify_debouncer_mini;
+use self::notify_debouncer_mini::{new_debouncer, notify::RecursiveMode};
+
+use std::path::Path;
+use std::sync::mpsc::channel;
+use std::sync::mpsc::TryRecvError;
+use std::time::Duration;
+use stdout;
+
+pub fn events(handler: impl Fn(&str), verbose: bool) {
+    let (tx, rx) = channel();
+    let mut debouncer =
+        new_debouncer(Duration::from_millis(200), None, tx).expect("Unable to create watcher");
+    let watcher = debouncer.watcher();
+
+    if let Err(err) = watcher.watch(Path::new("."), RecursiveMode::Recursive) {
+        println!("Unable to watch current directory {:?}", err);
+    }
+
+    stdout::info("Watching...");
+    loop {
+        match rx.try_recv() {
+            Ok(debounced_evts) => {
+                stdout::verbose(&format!("Events {:?}", debounced_evts), verbose);
+                if let Ok(file_change_event) = debounced_evts {
+                    file_change_event.iter().for_each(|event| {
+                        if let Some(path_string) = event.path.to_str() {
+                            handler(path_string);
+                        } else {
+                            stdout::error(&format!(
+                                "failed to convert path {:?} to string",
+                                event.path
+                            ));
+                        }
+                    });
+                }
+            }
+
+            Err(err) => {
+                if err != TryRecvError::Empty {
+                    stdout::error(&format!("failed to receive event: {:?}", err));
+                    break;
+                }
+            }
+        }
+
+        std::thread::sleep(std::time::Duration::from_millis(200));
+    }
+}


Test patch:
diff --git a/tests/integration/specs/ignoring-folders-tests.sh b/tests/integration/specs/ignoring-folders-tests.sh
index d6ec377..30c6301 100644
--- a/tests/integration/specs/ignoring-folders-tests.sh
+++ b/tests/integration/specs/ignoring-folders-tests.sh
@@ -14,7 +14,13 @@ echo "
   change: '$WORKDIR/**'
   ignore: [
     '$WORKDIR/ignored/**',
-    '$WORKDIR/file-to-ignore.txt'
+    '$WORKDIR/output.txt',
+    '$WORKDIR/file-to-ignore.txt',
+
+    # Vim backup files
+    '$WORKDIR/file-to-ignore.txt~',
+    '$WORKDIR/.file-to-ignore.txt.swp',
+    '$WORKDIR/.file-to-ignore.txt.swx'
   ]
 
 - name: run not ignored
diff --git a/tests/integration/specs/watch-command-test.sh b/tests/integration/specs/watch-command-test.sh
index 4b590d3..80b33bb 100644
--- a/tests/integration/specs/watch-command-test.sh
+++ b/tests/integration/specs/watch-command-test.sh
@@ -13,17 +13,27 @@ echo "
 - name: run simple command
   run: echo 'test1'
   change: \"$WORKDIR/**\"
-" > $WORKDIR/.onwatch.yaml
 
-touch $WORKDIR/test.txt
-touch $WORKDIR/output.txt
+- name: run different command
+  run: echo '__placeholder__' | sed s/placeholder/second_commmand/g
+  change: \"$WORKDIR/**\"
+" > "$WORKDIR"/.onwatch.yaml
+
+touch "$WORKDIR"/test.txt
+touch "$WORKDIR"/output.txt
 # $TEST_DIR/funzzy --config $WORKDIR/.onwatch.yaml &
-$TEST_DIR/funzzy watch --config $WORKDIR/.onwatch.yaml >> $WORKDIR/output.txt &
+"$TEST_DIR"/funzzy watch \
+  --config "$WORKDIR"/.onwatch.yaml >> "$WORKDIR"/output.txt &
 FUNZZY_PID=$!
 
-echo "test" >> $WORKDIR/test.txt
 wait_for_file "$WORKDIR/output.txt"
-sh -c "vi +%s/test/foo/g +wq $WORKDIR/test.txt -u NONE"
-assert_file_contains "$WORKDIR/output.txt" "echo 'test1'"
+
+echo "some content" > "$WORKDIR"/test.txt
+
+touch "$WORKDIR"/test.txt
+assert_file_occurrencies "$WORKDIR/output.txt" "__second_commmand__" 1
+
+touch "$WORKDIR"/test.txt
+assert_file_occurrencies "$WORKDIR/output.txt" "__second_commmand__" 2
 
 cleanup