diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2016-02-06 15:06:33 -0800 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2016-02-18 17:00:26 -0800 |
commit | 31bc88d16f7396865bbf2c7ae5d3afc80b44e254 (patch) | |
tree | c4a82c9c33f19260f044fe181ce460b376be25fb | |
parent | 5dbf40ca750a1413c5000c6921bff04e17ccd55a (diff) |
Migrate sort_and_prioritize to complete.cpp
-rw-r--r-- | src/complete.cpp | 38 | ||||
-rw-r--r-- | src/complete.h | 3 | ||||
-rw-r--r-- | src/reader.cpp | 47 |
3 files changed, 43 insertions, 45 deletions
diff --git a/src/complete.cpp b/src/complete.cpp index 790971f8..5da53aeb 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -299,6 +299,44 @@ void completion_t::prepend_token_prefix(const wcstring &prefix) } } + +static bool compare_completions_by_match_type(const completion_t &a, const completion_t &b) +{ + return a.match.type < b.match.type; +} + +void completions_sort_and_prioritize(std::vector<completion_t> *comps) +{ + /* Find the best match type */ + fuzzy_match_type_t best_type = fuzzy_match_none; + for (size_t i=0; i < comps->size(); i++) + { + best_type = std::min(best_type, comps->at(i).match.type); + } + /* If the best type is an exact match, reduce it to prefix match. Otherwise a tab completion will only show one match if it matches a file exactly. (see issue #959) */ + if (best_type == fuzzy_match_exact) + { + best_type = fuzzy_match_prefix; + } + + /* Throw out completions whose match types are less suitable than the best. */ + size_t i = comps->size(); + while (i--) + { + if (comps->at(i).match.type > best_type) + { + comps->erase(comps->begin() + i); + } + } + + /* Remove duplicates */ + sort(comps->begin(), comps->end(), completion_t::is_naturally_less_than); + comps->erase(std::unique(comps->begin(), comps->end(), completion_t::is_alphabetically_equal_to), comps->end()); + + /* Sort the remainder by match type. They're already sorted alphabetically */ + stable_sort(comps->begin(), comps->end(), compare_completions_by_match_type); +} + /** Class representing an attempt to compute completions */ class completer_t { diff --git a/src/complete.h b/src/complete.h index 4972981f..0784bc48 100644 --- a/src/complete.h +++ b/src/complete.h @@ -125,6 +125,9 @@ public: void prepend_token_prefix(const wcstring &prefix); }; +/** Sorts and remove any duplicate completions in the completion list, then puts them in priority order. */ +void completions_sort_and_prioritize(std::vector<completion_t> *comps); + enum { COMPLETION_REQUEST_DEFAULT = 0, diff --git a/src/reader.cpp b/src/reader.cpp index d6eea53a..900479b2 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -165,8 +165,6 @@ static pthread_key_t generation_count_key; static void set_command_line_and_position(editable_line_t *el, const wcstring &new_str, size_t pos); -static void sort_and_prioritize(std::vector<completion_t> *comps); - void editable_line_t::insert_string(const wcstring &str, size_t start, size_t len) { // Clamp the range to something valid @@ -1509,7 +1507,7 @@ struct autosuggestion_context_t /* Try normal completions */ std::vector<completion_t> completions; complete(search_string, completions, COMPLETION_REQUEST_AUTOSUGGESTION); - sort_and_prioritize(&completions); + completions_sort_and_prioritize(&completions); if (! completions.empty()) { const completion_t &comp = completions.at(0); @@ -1683,23 +1681,6 @@ static bool reader_can_replace(const wcstring &in, int flags) return true; } -/* Compare two completions, ordering completions with better match types first */ -bool compare_completions_by_match_type(const completion_t &a, const completion_t &b) -{ - /* Compare match types, unless both completions are prefix (#923) in which case we always want to compare them alphabetically */ - if (a.match.type != fuzzy_match_prefix || b.match.type != fuzzy_match_prefix) - { - int match_compare = a.match.compare(b.match); - if (match_compare != 0) - { - return match_compare < 0; - } - } - - /* Compare using file comparison */ - return wcsfilecmp(a.completion.c_str(), b.completion.c_str()) < 0; -} - /* Determine the best match type for a set of completions */ static fuzzy_match_type_t get_best_match_type(const std::vector<completion_t> &comp) { @@ -1716,30 +1697,6 @@ static fuzzy_match_type_t get_best_match_type(const std::vector<completion_t> &c return best_type; } - -/** Sorts and remove any duplicate completions in the completion list, then puts them in priority order. */ -static void sort_and_prioritize(std::vector<completion_t> *comps) -{ - fuzzy_match_type_t best_type = get_best_match_type(*comps); - - /* Throw out completions whose match types are less suitable than the best. */ - size_t i = comps->size(); - while (i--) - { - if (comps->at(i).match.type > best_type) - { - comps->erase(comps->begin() + i); - } - } - - /* Remove duplicates */ - sort(comps->begin(), comps->end(), completion_t::is_naturally_less_than); - comps->erase(std::unique(comps->begin(), comps->end(), completion_t::is_alphabetically_equal_to), comps->end()); - - /* Sort the remainder by match type. They're already sorted alphabetically */ - stable_sort(comps->begin(), comps->end(), compare_completions_by_match_type); -} - /** Handle the list of completions. This means the following: @@ -3370,7 +3327,7 @@ const wchar_t *reader_readline(int nchars) data->complete_func(buffcpy, comp, COMPLETION_REQUEST_DEFAULT | COMPLETION_REQUEST_DESCRIPTIONS | COMPLETION_REQUEST_FUZZY_MATCH); /* Munge our completions */ - sort_and_prioritize(&comp); + completions_sort_and_prioritize(&comp); /* Record our cycle_command_line */ data->cycle_command_line = el->text; |