Try to improve file completion
diff --git a/src/completion.rs b/src/completion.rs
index 61c6dc5..57489d8 100644
--- a/src/completion.rs
+++ b/src/completion.rs
@@ -112,6 +112,8 @@
     double_quotes_special_chars: &'static [u8],
 }
 
+static DOUBLE_QUOTES_ESCAPE_CHAR: Option<char> = Some('\\');
+
 // rl_basic_word_break_characters, rl_completer_word_break_characters
 #[cfg(unix)]
 static DEFAULT_BREAK_CHARS: [u8; 18] = [
@@ -131,7 +133,17 @@
 
 // In double quotes, not all break_chars need to be escaped
 // https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html
+#[cfg(unix)]
 static DOUBLE_QUOTES_SPECIAL_CHARS: [u8; 4] = [b'"', b'$', b'\\', b'`'];
+#[cfg(windows)]
+static DOUBLE_QUOTES_SPECIAL_CHARS: [u8; 1] = [b'"']; // TODO Validate
+
+#[derive(Clone, Copy, PartialEq)]
+pub enum Quote {
+    Double,
+    Single,
+    None,
+}
 
 impl FilenameCompleter {
     pub fn new() -> FilenameCompleter {
@@ -152,25 +164,32 @@
     type Candidate = Pair;
 
     fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<Pair>)> {
-        let (start, path, esc_char, break_chars) =
+        let (start, path, esc_char, break_chars, quote) =
             if let Some((idx, double_quote)) = find_unclosed_quote(&line[..pos]) {
                 let start = idx + 1;
                 if double_quote {
                     (
                         start,
-                        unescape(&line[start..pos], ESCAPE_CHAR),
-                        ESCAPE_CHAR,
+                        unescape(&line[start..pos], DOUBLE_QUOTES_ESCAPE_CHAR),
+                        DOUBLE_QUOTES_ESCAPE_CHAR,
                         &self.double_quotes_special_chars,
+                        Quote::Double,
                     )
                 } else {
-                    (start, Borrowed(&line[start..pos]), None, &self.break_chars)
+                    (
+                        start,
+                        Borrowed(&line[start..pos]),
+                        None,
+                        &self.break_chars,
+                        Quote::Single,
+                    )
                 }
             } else {
                 let (start, path) = extract_word(line, pos, ESCAPE_CHAR, &self.break_chars);
                 let path = unescape(path, ESCAPE_CHAR);
-                (start, path, ESCAPE_CHAR, &self.break_chars)
+                (start, path, ESCAPE_CHAR, &self.break_chars, Quote::None)
             };
-        let matches = try!(filename_complete(&path, esc_char, break_chars));
+        let matches = try!(filename_complete(&path, esc_char, break_chars, quote));
         Ok((start, matches))
     }
 }
@@ -202,18 +221,30 @@
 /// Escape any `break_chars` in `input` string with `esc_char`.
 /// For example, '/User Information' becomes '/User\ Information'
 /// when space is a breaking char and '\\' the escape char.
-pub fn escape(input: String, esc_char: Option<char>, break_chars: &[u8]) -> String {
-    if esc_char.is_none() {
-        return input;
+pub fn escape(
+    mut input: String,
+    esc_char: Option<char>,
+    break_chars: &[u8],
+    quote: Quote,
+) -> String {
+    if quote == Quote::Single {
+        return input; // no escape in single quotes
     }
-    let esc_char = esc_char.unwrap();
     let n = input
         .bytes()
         .filter(|b| memchr(*b, break_chars).is_some())
         .count();
     if n == 0 {
+        return input; // no need to escape
+    }
+    if esc_char.is_none() {
+        if cfg!(windows) && quote == Quote::None {
+            input.insert(0, '"'); // force double quote
+            return input;
+        }
         return input;
     }
+    let esc_char = esc_char.unwrap();
     let mut result = String::with_capacity(input.len() + n);
 
     for c in input.chars() {
@@ -225,7 +256,12 @@
     result
 }
 
-fn filename_complete(path: &str, esc_char: Option<char>, break_chars: &[u8]) -> Result<Vec<Pair>> {
+fn filename_complete(
+    path: &str,
+    esc_char: Option<char>,
+    break_chars: &[u8],
+    quote: Quote,
+) -> Result<Vec<Pair>> {
     use dirs::home_dir;
     use std::env::current_dir;
 
@@ -269,7 +305,7 @@
                     }
                     entries.push(Pair {
                         display: String::from(s),
-                        replacement: escape(path, esc_char, break_chars),
+                        replacement: escape(path, esc_char, break_chars, quote),
                     });
                 } // else ignore PermissionDenied
             }
@@ -435,11 +471,14 @@
         let input = String::from("/usr/local/b");
         assert_eq!(
             input.clone(),
-            super::escape(input, Some('\\'), &break_chars)
+            super::escape(input, Some('\\'), &break_chars, super::Quote::None)
         );
         let input = String::from("/User Information");
         let result = String::from("/User\\ Information");
-        assert_eq!(result, super::escape(input, Some('\\'), &break_chars));
+        assert_eq!(
+            result,
+            super::escape(input, Some('\\'), &break_chars, super::Quote::None)
+        );
     }
 
     #[test]