mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Thread the parser into complete()
Eliminates uses of principal_parser
This commit is contained in:
parent
63bdc949ab
commit
923a7ca0f0
8 changed files with 68 additions and 54 deletions
|
@ -329,7 +329,8 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||||
recursion_level++;
|
recursion_level++;
|
||||||
|
|
||||||
std::vector<completion_t> comp;
|
std::vector<completion_t> comp;
|
||||||
complete(do_complete_param, &comp, completion_request_t::fuzzy_match, parser.vars());
|
complete(do_complete_param, &comp, completion_request_t::fuzzy_match, parser.vars(),
|
||||||
|
parser.shared());
|
||||||
|
|
||||||
for (size_t i = 0; i < comp.size(); i++) {
|
for (size_t i = 0; i < comp.size(); i++) {
|
||||||
const completion_t &next = comp.at(i);
|
const completion_t &next = comp.at(i);
|
||||||
|
|
|
@ -296,13 +296,17 @@ class completer_t {
|
||||||
/// Environment inside which we are completing.
|
/// Environment inside which we are completing.
|
||||||
const environment_t &vars;
|
const environment_t &vars;
|
||||||
|
|
||||||
|
/// The parser used for condition testing and subshell expansion.
|
||||||
|
/// If null, these features are disabled.
|
||||||
|
std::shared_ptr<parser_t> parser;
|
||||||
|
|
||||||
/// The command to complete.
|
/// The command to complete.
|
||||||
const wcstring cmd;
|
const wcstring cmd;
|
||||||
|
|
||||||
/// Flags associated with the completion request.
|
/// Flags associated with the completion request.
|
||||||
const completion_request_flags_t flags;
|
const completion_request_flags_t flags;
|
||||||
|
|
||||||
/// The output cmopletions.
|
/// The output completions.
|
||||||
std::vector<completion_t> completions;
|
std::vector<completion_t> completions;
|
||||||
|
|
||||||
/// Table of completions conditions that have already been tested and the corresponding test
|
/// Table of completions conditions that have already been tested and the corresponding test
|
||||||
|
@ -371,8 +375,9 @@ class completer_t {
|
||||||
void mark_completions_duplicating_arguments(const wcstring &prefix, const arg_list_t &args);
|
void mark_completions_duplicating_arguments(const wcstring &prefix, const arg_list_t &args);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
completer_t(const environment_t &vars, wcstring c, completion_request_flags_t f)
|
completer_t(const environment_t &vars, const std::shared_ptr<parser_t> &parser, wcstring c,
|
||||||
: vars(vars), cmd(std::move(c)), flags(f) {}
|
completion_request_flags_t f)
|
||||||
|
: vars(vars), parser(parser), cmd(std::move(c)), flags(f) {}
|
||||||
|
|
||||||
void perform();
|
void perform();
|
||||||
|
|
||||||
|
@ -398,21 +403,16 @@ bool completer_t::condition_test(const wcstring &condition) {
|
||||||
// std::fwprintf( stderr, L"No condition specified\n" );
|
// std::fwprintf( stderr, L"No condition specified\n" );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (!parser) {
|
||||||
if (this->type() == COMPLETE_AUTOSUGGEST) {
|
|
||||||
// Autosuggestion can't support conditions.
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_IS_MAIN_THREAD();
|
ASSERT_IS_MAIN_THREAD();
|
||||||
|
|
||||||
bool test_res;
|
bool test_res;
|
||||||
condition_cache_t::iterator cached_entry = condition_cache.find(condition);
|
condition_cache_t::iterator cached_entry = condition_cache.find(condition);
|
||||||
if (cached_entry == condition_cache.end()) {
|
if (cached_entry == condition_cache.end()) {
|
||||||
// Compute new value and reinsert it.
|
// Compute new value and reinsert it.
|
||||||
// TODO: rationalize this principal_parser.
|
test_res = (0 == exec_subshell(condition, *parser, false /* don't apply exit status */));
|
||||||
test_res = (0 == exec_subshell(condition, parser_t::principal_parser(),
|
|
||||||
false /* don't apply exit status */));
|
|
||||||
condition_cache[condition] = test_res;
|
condition_cache[condition] = test_res;
|
||||||
} else {
|
} else {
|
||||||
// Use the old value.
|
// Use the old value.
|
||||||
|
@ -559,6 +559,7 @@ void completer_t::complete_strings(const wcstring &wc_escaped, const description
|
||||||
/// for the executable.
|
/// for the executable.
|
||||||
void completer_t::complete_cmd_desc(const wcstring &str) {
|
void completer_t::complete_cmd_desc(const wcstring &str) {
|
||||||
ASSERT_IS_MAIN_THREAD();
|
ASSERT_IS_MAIN_THREAD();
|
||||||
|
if (!parser) return;
|
||||||
|
|
||||||
wcstring cmd;
|
wcstring cmd;
|
||||||
size_t pos = str.find_last_of(L'/');
|
size_t pos = str.find_last_of(L'/');
|
||||||
|
@ -596,9 +597,7 @@ void completer_t::complete_cmd_desc(const wcstring &str) {
|
||||||
// search if we know the location of the whatis database. This can take some time on slower
|
// search if we know the location of the whatis database. This can take some time on slower
|
||||||
// systems with a large set of manuals, but it should be ok since apropos is only called once.
|
// systems with a large set of manuals, but it should be ok since apropos is only called once.
|
||||||
wcstring_list_t list;
|
wcstring_list_t list;
|
||||||
// TODO: justify this use of parser_t::principal_parser.
|
if (exec_subshell(lookup_cmd, *parser, list, false /* don't apply exit status */) != -1) {
|
||||||
if (exec_subshell(lookup_cmd, parser_t::principal_parser(), list,
|
|
||||||
false /* don't apply exit status */) != -1) {
|
|
||||||
std::unordered_map<wcstring, wcstring> lookup;
|
std::unordered_map<wcstring, wcstring> lookup;
|
||||||
lookup.reserve(list.size());
|
lookup.reserve(list.size());
|
||||||
|
|
||||||
|
@ -1582,14 +1581,15 @@ void completer_t::perform() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_comps,
|
void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_comps,
|
||||||
completion_request_flags_t flags, const environment_t &vars) {
|
completion_request_flags_t flags, const environment_t &vars,
|
||||||
|
const std::shared_ptr<parser_t> &parser) {
|
||||||
// Determine the innermost subcommand.
|
// Determine the innermost subcommand.
|
||||||
const wchar_t *cmdsubst_begin, *cmdsubst_end;
|
const wchar_t *cmdsubst_begin, *cmdsubst_end;
|
||||||
parse_util_cmdsubst_extent(cmd_with_subcmds.c_str(), cmd_with_subcmds.size(), &cmdsubst_begin,
|
parse_util_cmdsubst_extent(cmd_with_subcmds.c_str(), cmd_with_subcmds.size(), &cmdsubst_begin,
|
||||||
&cmdsubst_end);
|
&cmdsubst_end);
|
||||||
assert(cmdsubst_begin != NULL && cmdsubst_end != NULL && cmdsubst_end >= cmdsubst_begin);
|
assert(cmdsubst_begin != NULL && cmdsubst_end != NULL && cmdsubst_end >= cmdsubst_begin);
|
||||||
wcstring cmd = wcstring(cmdsubst_begin, cmdsubst_end - cmdsubst_begin);
|
wcstring cmd = wcstring(cmdsubst_begin, cmdsubst_end - cmdsubst_begin);
|
||||||
completer_t completer(vars, std::move(cmd), flags);
|
completer_t completer(vars, parser, std::move(cmd), flags);
|
||||||
completer.perform();
|
completer.perform();
|
||||||
*out_comps = completer.acquire_completions();
|
*out_comps = completer.acquire_completions();
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,8 +170,10 @@ void complete_remove(const wcstring &cmd, bool cmd_is_path, const wcstring &opti
|
||||||
void complete_remove_all(const wcstring &cmd, bool cmd_is_path);
|
void complete_remove_all(const wcstring &cmd, bool cmd_is_path);
|
||||||
|
|
||||||
/// Find all completions of the command cmd, insert them into out.
|
/// Find all completions of the command cmd, insert them into out.
|
||||||
|
class parser_t;
|
||||||
void complete(const wcstring &cmd, std::vector<completion_t> *out_comps,
|
void complete(const wcstring &cmd, std::vector<completion_t> *out_comps,
|
||||||
completion_request_flags_t flags, const environment_t &vars);
|
completion_request_flags_t flags, const environment_t &vars,
|
||||||
|
const std::shared_ptr<parser_t> &parser);
|
||||||
|
|
||||||
/// Return a list of all current completions.
|
/// Return a list of all current completions.
|
||||||
wcstring complete_print();
|
wcstring complete_print();
|
||||||
|
|
|
@ -2492,8 +2492,10 @@ static void test_complete() {
|
||||||
};
|
};
|
||||||
test_complete_vars_t vars;
|
test_complete_vars_t vars;
|
||||||
|
|
||||||
|
auto parser = parser_t::principal_parser().shared();
|
||||||
|
|
||||||
completion_list_t completions;
|
completion_list_t completions;
|
||||||
complete(L"$", &completions, {}, vars);
|
complete(L"$", &completions, {}, vars, parser);
|
||||||
completions_sort_and_prioritize(&completions);
|
completions_sort_and_prioritize(&completions);
|
||||||
do_test(completions.size() == 6);
|
do_test(completions.size() == 6);
|
||||||
do_test(completions.at(0).completion == L"Bar1");
|
do_test(completions.at(0).completion == L"Bar1");
|
||||||
|
@ -2504,7 +2506,7 @@ static void test_complete() {
|
||||||
do_test(completions.at(5).completion == L"Foo3");
|
do_test(completions.at(5).completion == L"Foo3");
|
||||||
|
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"$F", &completions, {}, vars);
|
complete(L"$F", &completions, {}, vars, parser);
|
||||||
completions_sort_and_prioritize(&completions);
|
completions_sort_and_prioritize(&completions);
|
||||||
do_test(completions.size() == 3);
|
do_test(completions.size() == 3);
|
||||||
do_test(completions.at(0).completion == L"oo1");
|
do_test(completions.at(0).completion == L"oo1");
|
||||||
|
@ -2512,12 +2514,12 @@ static void test_complete() {
|
||||||
do_test(completions.at(2).completion == L"oo3");
|
do_test(completions.at(2).completion == L"oo3");
|
||||||
|
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"$1", &completions, {}, vars);
|
complete(L"$1", &completions, {}, vars, parser);
|
||||||
completions_sort_and_prioritize(&completions);
|
completions_sort_and_prioritize(&completions);
|
||||||
do_test(completions.empty());
|
do_test(completions.empty());
|
||||||
|
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"$1", &completions, completion_request_t::fuzzy_match, vars);
|
complete(L"$1", &completions, completion_request_t::fuzzy_match, vars, parser);
|
||||||
completions_sort_and_prioritize(&completions);
|
completions_sort_and_prioritize(&completions);
|
||||||
do_test(completions.size() == 2);
|
do_test(completions.size() == 2);
|
||||||
do_test(completions.at(0).completion == L"$Bar1");
|
do_test(completions.at(0).completion == L"$Bar1");
|
||||||
|
@ -2529,23 +2531,23 @@ static void test_complete() {
|
||||||
if (system("chmod 700 'test/complete_test/testfile'")) err(L"chmod failed");
|
if (system("chmod 700 'test/complete_test/testfile'")) err(L"chmod failed");
|
||||||
|
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo (test/complete_test/testfil", &completions, {}, vars);
|
complete(L"echo (test/complete_test/testfil", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"e");
|
do_test(completions.at(0).completion == L"e");
|
||||||
|
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo (ls test/complete_test/testfil", &completions, {}, vars);
|
complete(L"echo (ls test/complete_test/testfil", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"e");
|
do_test(completions.at(0).completion == L"e");
|
||||||
|
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo (command ls test/complete_test/testfil", &completions, {}, vars);
|
complete(L"echo (command ls test/complete_test/testfil", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"e");
|
do_test(completions.at(0).completion == L"e");
|
||||||
|
|
||||||
// Completing after spaces - see #2447
|
// Completing after spaces - see #2447
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo (ls test/complete_test/has\\ ", &completions, {}, vars);
|
complete(L"echo (ls test/complete_test/has\\ ", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"space");
|
do_test(completions.at(0).completion == L"space");
|
||||||
|
|
||||||
|
@ -2558,23 +2560,23 @@ static void test_complete() {
|
||||||
|
|
||||||
// Complete a function name.
|
// Complete a function name.
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo (scuttlebut", &completions, {}, vars);
|
complete(L"echo (scuttlebut", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"t");
|
do_test(completions.at(0).completion == L"t");
|
||||||
|
|
||||||
// But not with the command prefix.
|
// But not with the command prefix.
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo (command scuttlebut", &completions, {}, vars);
|
complete(L"echo (command scuttlebut", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 0);
|
do_test(completions.size() == 0);
|
||||||
|
|
||||||
// Not with the builtin prefix.
|
// Not with the builtin prefix.
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo (builtin scuttlebut", &completions, {}, vars);
|
complete(L"echo (builtin scuttlebut", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 0);
|
do_test(completions.size() == 0);
|
||||||
|
|
||||||
// Not after a redirection.
|
// Not after a redirection.
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo hi > scuttlebut", &completions, {}, vars);
|
complete(L"echo hi > scuttlebut", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 0);
|
do_test(completions.size() == 0);
|
||||||
|
|
||||||
// Trailing spaces (#1261).
|
// Trailing spaces (#1261).
|
||||||
|
@ -2583,81 +2585,82 @@ static void test_complete() {
|
||||||
complete_add(L"foobarbaz", false, wcstring(), option_type_args_only, no_files, NULL, L"qux",
|
complete_add(L"foobarbaz", false, wcstring(), option_type_args_only, no_files, NULL, L"qux",
|
||||||
NULL, COMPLETE_AUTO_SPACE);
|
NULL, COMPLETE_AUTO_SPACE);
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"foobarbaz ", &completions, {}, vars);
|
complete(L"foobarbaz ", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"qux");
|
do_test(completions.at(0).completion == L"qux");
|
||||||
|
|
||||||
// Don't complete variable names in single quotes (#1023).
|
// Don't complete variable names in single quotes (#1023).
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo '$Foo", &completions, {}, vars);
|
complete(L"echo '$Foo", &completions, {}, vars, parser);
|
||||||
do_test(completions.empty());
|
do_test(completions.empty());
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo \\$Foo", &completions, {}, vars);
|
complete(L"echo \\$Foo", &completions, {}, vars, parser);
|
||||||
do_test(completions.empty());
|
do_test(completions.empty());
|
||||||
|
|
||||||
// File completions.
|
// File completions.
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"cat test/complete_test/te", &completions, {}, vars);
|
complete(L"cat test/complete_test/te", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"stfile");
|
do_test(completions.at(0).completion == L"stfile");
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo sup > test/complete_test/te", &completions, {}, vars);
|
complete(L"echo sup > test/complete_test/te", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"stfile");
|
do_test(completions.at(0).completion == L"stfile");
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"echo sup > test/complete_test/te", &completions, {}, vars);
|
complete(L"echo sup > test/complete_test/te", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"stfile");
|
do_test(completions.at(0).completion == L"stfile");
|
||||||
|
|
||||||
if (!pushd("test/complete_test")) return;
|
if (!pushd("test/complete_test")) return;
|
||||||
complete(L"cat te", &completions, {}, vars);
|
complete(L"cat te", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"stfile");
|
do_test(completions.at(0).completion == L"stfile");
|
||||||
do_test(!(completions.at(0).flags & COMPLETE_REPLACES_TOKEN));
|
do_test(!(completions.at(0).flags & COMPLETE_REPLACES_TOKEN));
|
||||||
do_test(!(completions.at(0).flags & COMPLETE_DUPLICATES_ARGUMENT));
|
do_test(!(completions.at(0).flags & COMPLETE_DUPLICATES_ARGUMENT));
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"cat testfile te", &completions, {}, vars);
|
complete(L"cat testfile te", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"stfile");
|
do_test(completions.at(0).completion == L"stfile");
|
||||||
do_test(completions.at(0).flags & COMPLETE_DUPLICATES_ARGUMENT);
|
do_test(completions.at(0).flags & COMPLETE_DUPLICATES_ARGUMENT);
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"cat testfile TE", &completions, {}, vars);
|
complete(L"cat testfile TE", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"testfile");
|
do_test(completions.at(0).completion == L"testfile");
|
||||||
do_test(completions.at(0).flags & COMPLETE_REPLACES_TOKEN);
|
do_test(completions.at(0).flags & COMPLETE_REPLACES_TOKEN);
|
||||||
do_test(completions.at(0).flags & COMPLETE_DUPLICATES_ARGUMENT);
|
do_test(completions.at(0).flags & COMPLETE_DUPLICATES_ARGUMENT);
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"something --abc=te", &completions, {}, vars);
|
complete(L"something --abc=te", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"stfile");
|
do_test(completions.at(0).completion == L"stfile");
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"something -abc=te", &completions, {}, vars);
|
complete(L"something -abc=te", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"stfile");
|
do_test(completions.at(0).completion == L"stfile");
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"something abc=te", &completions, {}, vars);
|
complete(L"something abc=te", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"stfile");
|
do_test(completions.at(0).completion == L"stfile");
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"something abc=stfile", &completions, {}, vars);
|
complete(L"something abc=stfile", &completions, {}, vars, parser);
|
||||||
do_test(completions.size() == 0);
|
do_test(completions.size() == 0);
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"something abc=stfile", &completions, completion_request_t::fuzzy_match, vars);
|
complete(L"something abc=stfile", &completions, completion_request_t::fuzzy_match, vars,
|
||||||
|
parser);
|
||||||
do_test(completions.size() == 1);
|
do_test(completions.size() == 1);
|
||||||
do_test(completions.at(0).completion == L"abc=testfile");
|
do_test(completions.at(0).completion == L"abc=testfile");
|
||||||
|
|
||||||
// Zero escapes can cause problems. See issue #1631.
|
// Zero escapes can cause problems. See issue #1631.
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"cat foo\\0", &completions, {}, vars);
|
complete(L"cat foo\\0", &completions, {}, vars, parser);
|
||||||
do_test(completions.empty());
|
do_test(completions.empty());
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"cat foo\\0bar", &completions, {}, vars);
|
complete(L"cat foo\\0bar", &completions, {}, vars, parser);
|
||||||
do_test(completions.empty());
|
do_test(completions.empty());
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"cat \\0", &completions, {}, vars);
|
complete(L"cat \\0", &completions, {}, vars, parser);
|
||||||
do_test(completions.empty());
|
do_test(completions.empty());
|
||||||
completions.clear();
|
completions.clear();
|
||||||
complete(L"cat te\\0", &completions, {}, vars);
|
complete(L"cat te\\0", &completions, {}, vars, parser);
|
||||||
do_test(completions.empty());
|
do_test(completions.empty());
|
||||||
|
|
||||||
popd();
|
popd();
|
||||||
|
@ -2669,7 +2672,7 @@ static void test_complete() {
|
||||||
fd.name = L"testabbrsonetwothreefour";
|
fd.name = L"testabbrsonetwothreefour";
|
||||||
function_add(fd, parser_t::principal_parser());
|
function_add(fd, parser_t::principal_parser());
|
||||||
int ret = pvars.set_one(L"_fish_abbr_testabbrsonetwothreezero", ENV_LOCAL, L"expansion");
|
int ret = pvars.set_one(L"_fish_abbr_testabbrsonetwothreezero", ENV_LOCAL, L"expansion");
|
||||||
complete(L"testabbrsonetwothree", &completions, {}, pvars);
|
complete(L"testabbrsonetwothree", &completions, {}, pvars, parser);
|
||||||
do_test(ret == 0);
|
do_test(ret == 0);
|
||||||
do_test(completions.size() == 2);
|
do_test(completions.size() == 2);
|
||||||
do_test(completions.at(0).completion == L"four");
|
do_test(completions.at(0).completion == L"four");
|
||||||
|
@ -2749,7 +2752,7 @@ static void test_completion_insertions() {
|
||||||
static void perform_one_autosuggestion_cd_test(const wcstring &command, const wcstring &expected,
|
static void perform_one_autosuggestion_cd_test(const wcstring &command, const wcstring &expected,
|
||||||
const environment_t &vars, long line) {
|
const environment_t &vars, long line) {
|
||||||
std::vector<completion_t> comps;
|
std::vector<completion_t> comps;
|
||||||
complete(command, &comps, completion_request_t::autosuggestion, vars);
|
complete(command, &comps, completion_request_t::autosuggestion, vars, nullptr);
|
||||||
|
|
||||||
bool expects_error = (expected == L"<error>");
|
bool expects_error = (expected == L"<error>");
|
||||||
|
|
||||||
|
@ -2785,7 +2788,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,
|
static void perform_one_completion_cd_test(const wcstring &command, const wcstring &expected,
|
||||||
const environment_t &vars, long line) {
|
const environment_t &vars, long line) {
|
||||||
std::vector<completion_t> comps;
|
std::vector<completion_t> comps;
|
||||||
complete(command, &comps, {}, vars);
|
complete(command, &comps, {}, vars, nullptr);
|
||||||
|
|
||||||
bool expects_error = (expected == L"<error>");
|
bool expects_error = (expected == L"<error>");
|
||||||
|
|
||||||
|
@ -2925,7 +2928,7 @@ static void test_autosuggest_suggest_special() {
|
||||||
|
|
||||||
static void perform_one_autosuggestion_should_ignore_test(const wcstring &command, long line) {
|
static void perform_one_autosuggestion_should_ignore_test(const wcstring &command, long line) {
|
||||||
completion_list_t comps;
|
completion_list_t comps;
|
||||||
complete(command, &comps, completion_request_t::autosuggestion, null_environment_t{});
|
complete(command, &comps, completion_request_t::autosuggestion, null_environment_t{}, nullptr);
|
||||||
do_test(comps.empty());
|
do_test(comps.empty());
|
||||||
if (!comps.empty()) {
|
if (!comps.empty()) {
|
||||||
const wcstring &suggestion = comps.front().completion;
|
const wcstring &suggestion = comps.front().completion;
|
||||||
|
|
|
@ -344,6 +344,8 @@ wcstring parser_t::stack_trace() const {
|
||||||
return trace;
|
return trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<parser_t> parser_t::shared() { return shared_from_this(); }
|
||||||
|
|
||||||
void parser_t::stack_trace_internal(size_t block_idx, wcstring *buff) const {
|
void parser_t::stack_trace_internal(size_t block_idx, wcstring *buff) const {
|
||||||
// Check if we should end the recursion.
|
// Check if we should end the recursion.
|
||||||
if (block_idx >= this->block_count()) return;
|
if (block_idx >= this->block_count()) return;
|
||||||
|
|
|
@ -328,6 +328,9 @@ class parser_t : public std::enable_shared_from_this<parser_t> {
|
||||||
/// Return a string representing the current stack trace.
|
/// Return a string representing the current stack trace.
|
||||||
wcstring stack_trace() const;
|
wcstring stack_trace() const;
|
||||||
|
|
||||||
|
/// \return a shared pointer reference to this parser.
|
||||||
|
std::shared_ptr<parser_t> shared();
|
||||||
|
|
||||||
~parser_t();
|
~parser_t();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1327,7 +1327,7 @@ static std::function<autosuggestion_result_t(void)> get_autosuggestion_performer
|
||||||
// Try normal completions.
|
// Try normal completions.
|
||||||
completion_request_flags_t complete_flags = completion_request_t::autosuggestion;
|
completion_request_flags_t complete_flags = completion_request_t::autosuggestion;
|
||||||
std::vector<completion_t> completions;
|
std::vector<completion_t> completions;
|
||||||
complete(search_string, &completions, complete_flags, *vars);
|
complete(search_string, &completions, complete_flags, *vars, nullptr);
|
||||||
completions_sort_and_prioritize(&completions, complete_flags);
|
completions_sort_and_prioritize(&completions, complete_flags);
|
||||||
if (!completions.empty()) {
|
if (!completions.empty()) {
|
||||||
const completion_t &comp = completions.at(0);
|
const completion_t &comp = completions.at(0);
|
||||||
|
@ -2585,7 +2585,9 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
|
||||||
// std::fwprintf(stderr, L"Complete (%ls)\n", buffcpy.c_str());
|
// std::fwprintf(stderr, L"Complete (%ls)\n", buffcpy.c_str());
|
||||||
completion_request_flags_t complete_flags = {completion_request_t::descriptions,
|
completion_request_flags_t complete_flags = {completion_request_t::descriptions,
|
||||||
completion_request_t::fuzzy_match};
|
completion_request_t::fuzzy_match};
|
||||||
complete_func(buffcpy, &rls.comp, complete_flags, vars);
|
// TODO: eliminate this principal_parser.
|
||||||
|
complete_func(buffcpy, &rls.comp, complete_flags, vars,
|
||||||
|
parser_t::principal_parser().shared());
|
||||||
|
|
||||||
// Munge our completions.
|
// Munge our completions.
|
||||||
completions_sort_and_prioritize(&rls.comp);
|
completions_sort_and_prioritize(&rls.comp);
|
||||||
|
|
|
@ -157,7 +157,8 @@ void reader_pop();
|
||||||
|
|
||||||
/// Specify function to use for finding possible tab completions.
|
/// Specify function to use for finding possible tab completions.
|
||||||
typedef void (*complete_function_t)(const wcstring &, std::vector<completion_t> *,
|
typedef void (*complete_function_t)(const wcstring &, std::vector<completion_t> *,
|
||||||
completion_request_flags_t, const environment_t &);
|
completion_request_flags_t, const environment_t &,
|
||||||
|
const std::shared_ptr<parser_t> &parser);
|
||||||
void reader_set_complete_function(complete_function_t);
|
void reader_set_complete_function(complete_function_t);
|
||||||
|
|
||||||
/// The type of a highlight function.
|
/// The type of a highlight function.
|
||||||
|
|
Loading…
Reference in a new issue