mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-14 00:47:30 +00:00
Make completion request flags an enum_set
This commit is contained in:
parent
acd33cbabb
commit
63bdc949ab
5 changed files with 63 additions and 62 deletions
|
@ -329,8 +329,7 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
recursion_level++;
|
||||
|
||||
std::vector<completion_t> comp;
|
||||
complete(do_complete_param, &comp,
|
||||
COMPLETION_REQUEST_DEFAULT | COMPLETION_REQUEST_FUZZY_MATCH, parser.vars());
|
||||
complete(do_complete_param, &comp, completion_request_t::fuzzy_match, parser.vars());
|
||||
|
||||
for (size_t i = 0; i < comp.size(); i++) {
|
||||
const completion_t &next = comp.at(i);
|
||||
|
|
|
@ -287,7 +287,7 @@ void completions_sort_and_prioritize(std::vector<completion_t> *comps,
|
|||
|
||||
// Lastly, if this is for an autosuggestion, prefer to avoid completions that duplicate
|
||||
// arguments.
|
||||
if (flags & COMPLETION_REQUEST_AUTOSUGGESTION)
|
||||
if (flags & completion_request_t::autosuggestion)
|
||||
stable_sort(comps->begin(), comps->end(), compare_completions_by_duplicate_arguments);
|
||||
}
|
||||
|
||||
|
@ -313,18 +313,17 @@ class completer_t {
|
|||
enum complete_type_t { COMPLETE_DEFAULT, COMPLETE_AUTOSUGGEST };
|
||||
|
||||
complete_type_t type() const {
|
||||
return flags & COMPLETION_REQUEST_AUTOSUGGESTION ? COMPLETE_AUTOSUGGEST : COMPLETE_DEFAULT;
|
||||
return (flags & completion_request_t::autosuggestion) ? COMPLETE_AUTOSUGGEST
|
||||
: COMPLETE_DEFAULT;
|
||||
}
|
||||
|
||||
bool wants_descriptions() const {
|
||||
return static_cast<bool>(flags & COMPLETION_REQUEST_DESCRIPTIONS);
|
||||
}
|
||||
bool wants_descriptions() const { return flags & completion_request_t::descriptions; }
|
||||
|
||||
bool fuzzy() const { return static_cast<bool>(flags & COMPLETION_REQUEST_FUZZY_MATCH); }
|
||||
bool fuzzy() const { return flags & completion_request_t::fuzzy_match; }
|
||||
|
||||
fuzzy_match_type_t max_fuzzy_match_type() const {
|
||||
// If we are doing fuzzy matching, request all types; if not request only prefix matching.
|
||||
if (flags & COMPLETION_REQUEST_FUZZY_MATCH) return fuzzy_match_none;
|
||||
if (fuzzy()) return fuzzy_match_none;
|
||||
return fuzzy_match_prefix_case_insensitive;
|
||||
}
|
||||
|
||||
|
@ -1226,7 +1225,7 @@ bool completer_t::try_complete_variable(const wcstring &str) {
|
|||
|
||||
// Now complete if we have a variable start. Note the variable text may be empty; in that case
|
||||
// don't generate an autosuggestion, but do allow tab completion.
|
||||
bool allow_empty = !(this->flags & COMPLETION_REQUEST_AUTOSUGGESTION);
|
||||
bool allow_empty = !(this->flags & completion_request_t::autosuggestion);
|
||||
bool text_is_empty = (variable_start == len);
|
||||
bool result = false;
|
||||
if (variable_start != wcstring::npos && (allow_empty || !text_is_empty)) {
|
||||
|
@ -1414,7 +1413,7 @@ void completer_t::perform() {
|
|||
// first of the sequence of nodes without source locations at the very end of the parse
|
||||
// tree).
|
||||
bool do_file = true;
|
||||
if (flags & COMPLETION_REQUEST_AUTOSUGGESTION) {
|
||||
if (flags & completion_request_t::autosuggestion) {
|
||||
if (position_in_statement < pos) {
|
||||
do_file = false;
|
||||
} else if (pos > 0) {
|
||||
|
@ -1551,7 +1550,7 @@ void completer_t::perform() {
|
|||
// buitin_commandline will refer to the wrapped command. But not if
|
||||
// we're doing autosuggestions.
|
||||
std::unique_ptr<builtin_commandline_scoped_transient_t> bcst;
|
||||
if (depth > 0 && !(flags & COMPLETION_REQUEST_AUTOSUGGESTION)) {
|
||||
if (depth > 0 && !(flags & completion_request_t::autosuggestion)) {
|
||||
bcst = make_unique<builtin_commandline_scoped_transient_t>(cmdline);
|
||||
}
|
||||
// Now invoke any custom completions for this command.
|
||||
|
@ -1567,7 +1566,7 @@ void completer_t::perform() {
|
|||
handle_as_special_cd = (current_command_unescape == L"cd");
|
||||
|
||||
// And if we're autosuggesting, and the token is empty, don't do file suggestions.
|
||||
if ((flags & COMPLETION_REQUEST_AUTOSUGGESTION) &&
|
||||
if ((flags & completion_request_t::autosuggestion) &&
|
||||
current_argument_unescape.empty()) {
|
||||
do_file = false;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#include "enum_set.h"
|
||||
|
||||
struct completion_mode_t {
|
||||
/// If set, skip file completions.
|
||||
bool no_files{false};
|
||||
|
@ -99,14 +101,19 @@ class completion_t {
|
|||
void prepend_token_prefix(const wcstring &prefix);
|
||||
};
|
||||
|
||||
enum {
|
||||
COMPLETION_REQUEST_DEFAULT = 0,
|
||||
COMPLETION_REQUEST_AUTOSUGGESTION = 1
|
||||
<< 0, // indicates the completion is for an autosuggestion
|
||||
COMPLETION_REQUEST_DESCRIPTIONS = 1 << 1, // indicates that we want descriptions
|
||||
COMPLETION_REQUEST_FUZZY_MATCH = 1 << 2 // indicates that we don't require a prefix match
|
||||
enum class completion_request_t {
|
||||
autosuggestion, // indicates the completion is for an autosuggestion
|
||||
descriptions, // indicates that we want descriptions
|
||||
fuzzy_match, // indicates that we don't require a prefix match
|
||||
COUNT
|
||||
};
|
||||
typedef uint32_t completion_request_flags_t;
|
||||
|
||||
template <>
|
||||
struct enum_info_t<completion_request_t> {
|
||||
static constexpr auto count = completion_request_t::COUNT;
|
||||
};
|
||||
|
||||
using completion_request_flags_t = enum_set_t<completion_request_t>;
|
||||
|
||||
enum complete_option_type_t {
|
||||
option_type_args_only, // no option
|
||||
|
@ -118,7 +125,7 @@ enum complete_option_type_t {
|
|||
/// 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,
|
||||
completion_request_flags_t flags = COMPLETION_REQUEST_DEFAULT);
|
||||
completion_request_flags_t flags = {});
|
||||
|
||||
/// Add a completion.
|
||||
///
|
||||
|
|
|
@ -2493,7 +2493,7 @@ static void test_complete() {
|
|||
test_complete_vars_t vars;
|
||||
|
||||
completion_list_t completions;
|
||||
complete(L"$", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"$", &completions, {}, vars);
|
||||
completions_sort_and_prioritize(&completions);
|
||||
do_test(completions.size() == 6);
|
||||
do_test(completions.at(0).completion == L"Bar1");
|
||||
|
@ -2504,7 +2504,7 @@ static void test_complete() {
|
|||
do_test(completions.at(5).completion == L"Foo3");
|
||||
|
||||
completions.clear();
|
||||
complete(L"$F", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"$F", &completions, {}, vars);
|
||||
completions_sort_and_prioritize(&completions);
|
||||
do_test(completions.size() == 3);
|
||||
do_test(completions.at(0).completion == L"oo1");
|
||||
|
@ -2512,13 +2512,12 @@ static void test_complete() {
|
|||
do_test(completions.at(2).completion == L"oo3");
|
||||
|
||||
completions.clear();
|
||||
complete(L"$1", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"$1", &completions, {}, vars);
|
||||
completions_sort_and_prioritize(&completions);
|
||||
do_test(completions.empty());
|
||||
|
||||
completions.clear();
|
||||
complete(L"$1", &completions, COMPLETION_REQUEST_DEFAULT | COMPLETION_REQUEST_FUZZY_MATCH,
|
||||
vars);
|
||||
complete(L"$1", &completions, completion_request_t::fuzzy_match, vars);
|
||||
completions_sort_and_prioritize(&completions);
|
||||
do_test(completions.size() == 2);
|
||||
do_test(completions.at(0).completion == L"$Bar1");
|
||||
|
@ -2530,25 +2529,23 @@ static void test_complete() {
|
|||
if (system("chmod 700 'test/complete_test/testfile'")) err(L"chmod failed");
|
||||
|
||||
completions.clear();
|
||||
complete(L"echo (test/complete_test/testfil", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"echo (test/complete_test/testfil", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"e");
|
||||
|
||||
completions.clear();
|
||||
complete(L"echo (ls test/complete_test/testfil", &completions, COMPLETION_REQUEST_DEFAULT,
|
||||
vars);
|
||||
complete(L"echo (ls test/complete_test/testfil", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"e");
|
||||
|
||||
completions.clear();
|
||||
complete(L"echo (command ls test/complete_test/testfil", &completions,
|
||||
COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"echo (command ls test/complete_test/testfil", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"e");
|
||||
|
||||
// Completing after spaces - see #2447
|
||||
completions.clear();
|
||||
complete(L"echo (ls test/complete_test/has\\ ", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"echo (ls test/complete_test/has\\ ", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"space");
|
||||
|
||||
|
@ -2561,23 +2558,23 @@ static void test_complete() {
|
|||
|
||||
// Complete a function name.
|
||||
completions.clear();
|
||||
complete(L"echo (scuttlebut", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"echo (scuttlebut", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"t");
|
||||
|
||||
// But not with the command prefix.
|
||||
completions.clear();
|
||||
complete(L"echo (command scuttlebut", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"echo (command scuttlebut", &completions, {}, vars);
|
||||
do_test(completions.size() == 0);
|
||||
|
||||
// Not with the builtin prefix.
|
||||
completions.clear();
|
||||
complete(L"echo (builtin scuttlebut", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"echo (builtin scuttlebut", &completions, {}, vars);
|
||||
do_test(completions.size() == 0);
|
||||
|
||||
// Not after a redirection.
|
||||
completions.clear();
|
||||
complete(L"echo hi > scuttlebut", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"echo hi > scuttlebut", &completions, {}, vars);
|
||||
do_test(completions.size() == 0);
|
||||
|
||||
// Trailing spaces (#1261).
|
||||
|
@ -2586,81 +2583,81 @@ static void test_complete() {
|
|||
complete_add(L"foobarbaz", false, wcstring(), option_type_args_only, no_files, NULL, L"qux",
|
||||
NULL, COMPLETE_AUTO_SPACE);
|
||||
completions.clear();
|
||||
complete(L"foobarbaz ", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"foobarbaz ", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"qux");
|
||||
|
||||
// Don't complete variable names in single quotes (#1023).
|
||||
completions.clear();
|
||||
complete(L"echo '$Foo", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"echo '$Foo", &completions, {}, vars);
|
||||
do_test(completions.empty());
|
||||
completions.clear();
|
||||
complete(L"echo \\$Foo", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"echo \\$Foo", &completions, {}, vars);
|
||||
do_test(completions.empty());
|
||||
|
||||
// File completions.
|
||||
completions.clear();
|
||||
complete(L"cat test/complete_test/te", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"cat test/complete_test/te", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"stfile");
|
||||
completions.clear();
|
||||
complete(L"echo sup > test/complete_test/te", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"echo sup > test/complete_test/te", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"stfile");
|
||||
completions.clear();
|
||||
complete(L"echo sup > test/complete_test/te", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"echo sup > test/complete_test/te", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"stfile");
|
||||
|
||||
if (!pushd("test/complete_test")) return;
|
||||
complete(L"cat te", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"cat te", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"stfile");
|
||||
do_test(!(completions.at(0).flags & COMPLETE_REPLACES_TOKEN));
|
||||
do_test(!(completions.at(0).flags & COMPLETE_DUPLICATES_ARGUMENT));
|
||||
completions.clear();
|
||||
complete(L"cat testfile te", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"cat testfile te", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"stfile");
|
||||
do_test(completions.at(0).flags & COMPLETE_DUPLICATES_ARGUMENT);
|
||||
completions.clear();
|
||||
complete(L"cat testfile TE", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"cat testfile TE", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"testfile");
|
||||
do_test(completions.at(0).flags & COMPLETE_REPLACES_TOKEN);
|
||||
do_test(completions.at(0).flags & COMPLETE_DUPLICATES_ARGUMENT);
|
||||
completions.clear();
|
||||
complete(L"something --abc=te", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"something --abc=te", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"stfile");
|
||||
completions.clear();
|
||||
complete(L"something -abc=te", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"something -abc=te", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"stfile");
|
||||
completions.clear();
|
||||
complete(L"something abc=te", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"something abc=te", &completions, {}, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"stfile");
|
||||
completions.clear();
|
||||
complete(L"something abc=stfile", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"something abc=stfile", &completions, {}, vars);
|
||||
do_test(completions.size() == 0);
|
||||
completions.clear();
|
||||
complete(L"something abc=stfile", &completions, COMPLETION_REQUEST_FUZZY_MATCH, vars);
|
||||
complete(L"something abc=stfile", &completions, completion_request_t::fuzzy_match, vars);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"abc=testfile");
|
||||
|
||||
// Zero escapes can cause problems. See issue #1631.
|
||||
completions.clear();
|
||||
complete(L"cat foo\\0", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"cat foo\\0", &completions, {}, vars);
|
||||
do_test(completions.empty());
|
||||
completions.clear();
|
||||
complete(L"cat foo\\0bar", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"cat foo\\0bar", &completions, {}, vars);
|
||||
do_test(completions.empty());
|
||||
completions.clear();
|
||||
complete(L"cat \\0", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"cat \\0", &completions, {}, vars);
|
||||
do_test(completions.empty());
|
||||
completions.clear();
|
||||
complete(L"cat te\\0", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(L"cat te\\0", &completions, {}, vars);
|
||||
do_test(completions.empty());
|
||||
|
||||
popd();
|
||||
|
@ -2672,7 +2669,7 @@ static void test_complete() {
|
|||
fd.name = L"testabbrsonetwothreefour";
|
||||
function_add(fd, parser_t::principal_parser());
|
||||
int ret = pvars.set_one(L"_fish_abbr_testabbrsonetwothreezero", ENV_LOCAL, L"expansion");
|
||||
complete(L"testabbrsonetwothree", &completions, COMPLETION_REQUEST_DEFAULT, pvars);
|
||||
complete(L"testabbrsonetwothree", &completions, {}, pvars);
|
||||
do_test(ret == 0);
|
||||
do_test(completions.size() == 2);
|
||||
do_test(completions.at(0).completion == L"four");
|
||||
|
@ -2752,7 +2749,7 @@ static void test_completion_insertions() {
|
|||
static void perform_one_autosuggestion_cd_test(const wcstring &command, const wcstring &expected,
|
||||
const environment_t &vars, long line) {
|
||||
std::vector<completion_t> comps;
|
||||
complete(command, &comps, COMPLETION_REQUEST_AUTOSUGGESTION, vars);
|
||||
complete(command, &comps, completion_request_t::autosuggestion, vars);
|
||||
|
||||
bool expects_error = (expected == L"<error>");
|
||||
|
||||
|
@ -2788,7 +2785,7 @@ static void perform_one_autosuggestion_cd_test(const wcstring &command, const wc
|
|||
static void perform_one_completion_cd_test(const wcstring &command, const wcstring &expected,
|
||||
const environment_t &vars, long line) {
|
||||
std::vector<completion_t> comps;
|
||||
complete(command, &comps, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
complete(command, &comps, {}, vars);
|
||||
|
||||
bool expects_error = (expected == L"<error>");
|
||||
|
||||
|
@ -2928,7 +2925,7 @@ static void test_autosuggest_suggest_special() {
|
|||
|
||||
static void perform_one_autosuggestion_should_ignore_test(const wcstring &command, long line) {
|
||||
completion_list_t comps;
|
||||
complete(command, &comps, COMPLETION_REQUEST_AUTOSUGGESTION, null_environment_t{});
|
||||
complete(command, &comps, completion_request_t::autosuggestion, null_environment_t{});
|
||||
do_test(comps.empty());
|
||||
if (!comps.empty()) {
|
||||
const wcstring &suggestion = comps.front().completion;
|
||||
|
|
|
@ -1325,7 +1325,7 @@ static std::function<autosuggestion_result_t(void)> get_autosuggestion_performer
|
|||
if (std::wcschr(L"'\"", last_char) && cursor_at_end) return nothing;
|
||||
|
||||
// Try normal completions.
|
||||
completion_request_flags_t complete_flags = COMPLETION_REQUEST_AUTOSUGGESTION;
|
||||
completion_request_flags_t complete_flags = completion_request_t::autosuggestion;
|
||||
std::vector<completion_t> completions;
|
||||
complete(search_string, &completions, complete_flags, *vars);
|
||||
completions_sort_and_prioritize(&completions, complete_flags);
|
||||
|
@ -2583,9 +2583,8 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
|
|||
const wcstring buffcpy = wcstring(cmdsub_begin, token_end);
|
||||
|
||||
// std::fwprintf(stderr, L"Complete (%ls)\n", buffcpy.c_str());
|
||||
complete_flags_t complete_flags = COMPLETION_REQUEST_DEFAULT |
|
||||
COMPLETION_REQUEST_DESCRIPTIONS |
|
||||
COMPLETION_REQUEST_FUZZY_MATCH;
|
||||
completion_request_flags_t complete_flags = {completion_request_t::descriptions,
|
||||
completion_request_t::fuzzy_match};
|
||||
complete_func(buffcpy, &rls.comp, complete_flags, vars);
|
||||
|
||||
// Munge our completions.
|
||||
|
|
Loading…
Reference in a new issue