diff options
Diffstat (limited to 'wildcard.cpp')
-rw-r--r-- | wildcard.cpp | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/wildcard.cpp b/wildcard.cpp index 7814a53f..1aa930fc 100644 --- a/wildcard.cpp +++ b/wildcard.cpp @@ -306,7 +306,15 @@ static bool wildcard_complete_internal(const wcstring &orig, } /* Note: out_completion may be empty if the completion really is empty, e.g. tab-completing 'foo' when a file 'foo' exists. */ - append_completion(out, out_completion, out_desc, flags, fuzzy_match); + if ((expand_flags & EXPAND_NO_SANITIZE_FLAGLIKE_FILES) == 0 && string_prefixes_string(L"-", out_completion)) + { + append_completion(out, L"./" + out_completion, out_desc, flags, fuzzy_match); + } + else + { + append_completion(out, out_completion, out_desc, flags, fuzzy_match); + } + return true; } @@ -629,7 +637,7 @@ static void wildcard_completion_allocate(std::vector<completion_t> &list, wcstring sb; wcstring munged_completion; - int flags = 0; + complete_flags_t complete_flags = 0; int stat_res, lstat_res; int stat_errno=0; @@ -683,7 +691,7 @@ static void wildcard_completion_allocate(std::vector<completion_t> &list, if (sz >= 0 && S_ISDIR(buf.st_mode)) { - flags |= COMPLETE_NO_SPACE; + complete_flags |= COMPLETE_NO_SPACE; munged_completion = completion; munged_completion.push_back(L'/'); if (wants_desc) @@ -702,8 +710,14 @@ static void wildcard_completion_allocate(std::vector<completion_t> &list, } } + /* Hackish. If the fullname is longer than the completion, it means we have a prefix. An example is completing "./foo" where the fullname is "./foo" and the completion might be "foo". In that case, we will pass "foo" to wildcard_complete, and it may choose to sanitize the file by appending a ./ to the front (since it doesn't know it already has one). Avoid that by cleaing the sanitize flag. */ + if (completion.size() < fullname.size()) + { + expand_flags |= EXPAND_NO_SANITIZE_FLAGLIKE_FILES; + } + const wcstring &completion_to_use = munged_completion.empty() ? completion : munged_completion; - wildcard_complete(completion_to_use, wc, sb.c_str(), NULL, list, expand_flags, flags); + wildcard_complete(completion_to_use, wc, sb.c_str(), NULL, list, expand_flags, complete_flags); } /** @@ -711,8 +725,9 @@ static void wildcard_completion_allocate(std::vector<completion_t> &list, expansion flags specified. flags can be a combination of EXECUTABLES_ONLY and DIRECTORIES_ONLY. */ -static bool test_flags(const wchar_t *filename, expand_flags_t flags) +static bool test_flags(const wcstring &filename_str, expand_flags_t flags) { + const wchar_t * const filename = filename_str.c_str(); if (flags & DIRECTORIES_ONLY) { struct stat buf; @@ -747,11 +762,22 @@ static bool test_flags(const wchar_t *filename, expand_flags_t flags) return true; } -/** Appends a completion to the completion list, if the string is missing from the set. */ -static void insert_completion_if_missing(const wcstring &str, std::vector<completion_t> &out, std::set<wcstring> &completion_set) +/** Appends a completion to the completion list, if the string is missing from the set. Sanitizing means that if the file looks like a flag (has a leading -), we prepend a ./ */ +static void insert_and_sanitize_completion_if_missing(const wcstring &str, std::vector<completion_t> &out, expand_flags_t flags, std::set<wcstring> &completion_set) { if (completion_set.insert(str).second) - append_completion(out, str); + { + if ((flags & EXPAND_NO_SANITIZE_FLAGLIKE_FILES) == 0 && string_prefixes_string(L"-", str)) + { + // sanitized + append_completion(out, L"./" + str); + } + else + { + // not sanitized + append_completion(out, str); + } + } } /** @@ -857,11 +883,11 @@ static int wildcard_expand_internal(const wchar_t *wc, wcstring next; while (wreaddir(dir, next)) { - if (next[0] != L'.') + if (! next.empty() && next.at(0) != L'.') { wcstring long_name = make_path(base_dir, next); - if (test_flags(long_name.c_str(), flags)) + if (test_flags(long_name, flags)) { wildcard_completion_allocate(out, long_name, next, L"", flags); } @@ -871,7 +897,7 @@ static int wildcard_expand_internal(const wchar_t *wc, else { res = 1; - insert_completion_if_missing(base_dir, out, completion_set); + insert_and_sanitize_completion_if_missing(base_dir, out, flags, completion_set); } } else @@ -889,7 +915,7 @@ static int wildcard_expand_internal(const wchar_t *wc, std::vector<completion_t> test; if (wildcard_complete(name_str, wc, L"", NULL, test, flags & EXPAND_FUZZY_MATCH, 0)) { - if (test_flags(long_name.c_str(), flags)) + if (test_flags(long_name, flags)) { wildcard_completion_allocate(out, long_name, name_str, wc, flags); @@ -907,7 +933,7 @@ static int wildcard_expand_internal(const wchar_t *wc, { /* In recursive mode, we are only - interested in adding files -directories + interested in adding files. Directories will be added in the next pass. */ struct stat buf; @@ -918,7 +944,7 @@ static int wildcard_expand_internal(const wchar_t *wc, } if (! skip) { - insert_completion_if_missing(long_name, out, completion_set); + insert_and_sanitize_completion_if_missing(long_name, out, flags, completion_set); } res = 1; } @@ -1060,10 +1086,7 @@ static int wildcard_expand_internal(const wchar_t *wc, } -int wildcard_expand(const wchar_t *wc, - const wchar_t *base_dir, - expand_flags_t flags, - std::vector<completion_t> &out) +static int wildcard_expand(const wchar_t *wc, const wchar_t *base_dir, expand_flags_t flags, std::vector<completion_t> &out) { size_t c = out.size(); |