Complete to take a pointer to output completions, not a mutable ref

This commit is contained in:
ridiculousfish 2016-02-06 19:17:43 -08:00
parent 31bc88d16f
commit c39b94949b
7 changed files with 64 additions and 36 deletions

View file

@ -456,7 +456,7 @@ static int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **a
recursion_level++;
std::vector<completion_t> comp;
complete(do_complete_param, comp, COMPLETION_REQUEST_DEFAULT);
complete(do_complete_param, &comp, COMPLETION_REQUEST_DEFAULT);
for (size_t i=0; i< comp.size() ; i++)
{

View file

@ -1631,7 +1631,7 @@ bool completer_t::try_complete_user(const wcstring &str)
return res;
}
void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> &comps, completion_request_flags_t flags)
void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_comps, completion_request_flags_t flags)
{
/* Determine the innermost subcommand */
const wchar_t *cmdsubst_begin, *cmdsubst_end;
@ -1872,7 +1872,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> &comps
}
}
comps = completer.get_completions();
*out_comps = completer.get_completions();
}

View file

@ -219,7 +219,7 @@ void complete_remove_all(const wcstring &cmd, bool cmd_is_path);
/** Find all completions of the command cmd, insert them into out.
*/
void complete(const wcstring &cmd,
std::vector<completion_t> &comp,
std::vector<completion_t> *out_comps,
completion_request_flags_t flags);
/**

View file

@ -2094,18 +2094,18 @@ static void test_complete(void)
complete_set_variable_names(&names);
std::vector<completion_t> completions;
complete(L"$F", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"$F", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 3);
do_test(completions.at(0).completion == L"oo1");
do_test(completions.at(1).completion == L"oo2");
do_test(completions.at(2).completion == L"oo3");
completions.clear();
complete(L"$1", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"$1", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.empty());
completions.clear();
complete(L"$1", completions, COMPLETION_REQUEST_DEFAULT | COMPLETION_REQUEST_FUZZY_MATCH);
complete(L"$1", &completions, COMPLETION_REQUEST_DEFAULT | COMPLETION_REQUEST_FUZZY_MATCH);
do_test(completions.size() == 2);
do_test(completions.at(0).completion == L"$Foo1");
do_test(completions.at(1).completion == L"$Bar1");
@ -2115,17 +2115,17 @@ static void test_complete(void)
if (system("chmod 700 '/tmp/complete_test/testfile'")) err(L"chmod failed");
completions.clear();
complete(L"echo (/tmp/complete_test/testfil", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"echo (/tmp/complete_test/testfil", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 1);
do_test(completions.at(0).completion == L"e");
completions.clear();
complete(L"echo (ls /tmp/complete_test/testfil", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"echo (ls /tmp/complete_test/testfil", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 1);
do_test(completions.at(0).completion == L"e");
completions.clear();
complete(L"echo (command ls /tmp/complete_test/testfil", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"echo (command ls /tmp/complete_test/testfil", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 1);
do_test(completions.at(0).completion == L"e");
@ -2137,38 +2137,38 @@ static void test_complete(void)
/* Complete a function name */
completions.clear();
complete(L"echo (scuttlebut", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"echo (scuttlebut", &completions, COMPLETION_REQUEST_DEFAULT);
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);
complete(L"echo (command scuttlebut", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 0);
/* Not with the builtin prefix */
completions.clear();
complete(L"echo (builtin scuttlebut", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"echo (builtin scuttlebut", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 0);
/* Not after a redirection */
completions.clear();
complete(L"echo hi > scuttlebut", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"echo hi > scuttlebut", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 0);
/* Trailing spaces (#1261) */
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);
complete(L"foobarbaz ", &completions, COMPLETION_REQUEST_DEFAULT);
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);
complete(L"echo '$Foo", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.empty());
completions.clear();
complete(L"echo \\$Foo", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"echo \\$Foo", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.empty());
/* File completions */
@ -2179,54 +2179,54 @@ static void test_complete(void)
exit(-1);
}
if (chdir("/tmp/complete_test/")) err(L"chdir failed");
complete(L"cat te", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"cat te", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 1);
do_test(completions.at(0).completion == L"stfile");
completions.clear();
complete(L"something --abc=te", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"something --abc=te", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 1);
do_test(completions.at(0).completion == L"stfile");
completions.clear();
complete(L"something -abc=te", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"something -abc=te", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 1);
do_test(completions.at(0).completion == L"stfile");
completions.clear();
complete(L"something abc=te", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"something abc=te", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 1);
do_test(completions.at(0).completion == L"stfile");
completions.clear();
complete(L"something abc=stfile", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"something abc=stfile", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 0);
completions.clear();
complete(L"something abc=stfile", completions, COMPLETION_REQUEST_FUZZY_MATCH);
complete(L"something abc=stfile", &completions, COMPLETION_REQUEST_FUZZY_MATCH);
do_test(completions.size() == 1);
do_test(completions.at(0).completion == L"abc=testfile");
completions.clear();
complete(L"cat /tmp/complete_test/te", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"cat /tmp/complete_test/te", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 1);
do_test(completions.at(0).completion == L"stfile");
completions.clear();
complete(L"echo sup > /tmp/complete_test/te", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"echo sup > /tmp/complete_test/te", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 1);
do_test(completions.at(0).completion == L"stfile");
completions.clear();
complete(L"echo sup > /tmp/complete_test/te", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"echo sup > /tmp/complete_test/te", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.size() == 1);
do_test(completions.at(0).completion == L"stfile");
completions.clear();
// Zero escapes can cause problems. See #1631
complete(L"cat foo\\0", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"cat foo\\0", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.empty());
completions.clear();
complete(L"cat foo\\0bar", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"cat foo\\0bar", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.empty());
completions.clear();
complete(L"cat \\0", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"cat \\0", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.empty());
completions.clear();
complete(L"cat te\\0", completions, COMPLETION_REQUEST_DEFAULT);
complete(L"cat te\\0", &completions, COMPLETION_REQUEST_DEFAULT);
do_test(completions.empty());
completions.clear();
@ -2404,7 +2404,7 @@ static void test_autosuggest_suggest_special()
static void perform_one_autosuggestion_should_ignore_test(const wcstring &command, const wcstring &wd, long line)
{
completion_list_t comps;
complete(command, comps, COMPLETION_REQUEST_AUTOSUGGESTION);
complete(command, &comps, COMPLETION_REQUEST_AUTOSUGGESTION);
do_test(comps.empty());
if (! comps.empty())
{
@ -2473,7 +2473,7 @@ void perf_complete()
str[0]=c;
reader_set_buffer(str, 0);
complete(str, out, COMPLETION_REQUEST_DEFAULT);
complete(str, &out, COMPLETION_REQUEST_DEFAULT);
matches += out.size();
out.clear();
@ -2493,7 +2493,7 @@ void perf_complete()
reader_set_buffer(str, 0);
complete(str, out, COMPLETION_REQUEST_DEFAULT);
complete(str, &out, COMPLETION_REQUEST_DEFAULT);
matches += out.size();
out.clear();

View file

@ -26,6 +26,7 @@
#include "env.h"
#include "expand.h"
#include "common.h"
#include "complete.h"
#include "output.h"
#include "wildcard.h"
#include "path.h"
@ -496,6 +497,33 @@ bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_di
bool result = false;
if (parsed_command == L"cd" && last_arg_node.type == symbol_argument && last_arg_node.has_source())
{
/* We always return true because we recognized the command. This prevents us from falling back to dumber algorithms; for example we won't suggest a non-directory for the cd command. */
result = true;
#if 0
std::vector<completion_t> comps;
complete(str, &comps, COMPLETION_REQUEST_AUTOSUGGESTION);
if (! comps.empty())
{
*out_suggestion = comps.at(0);
}
// Hackish to make tests pass
if (!(out_suggestion->flags & COMPLETE_REPLACES_TOKEN))
{
out_suggestion->completion.insert(0, str);
out_suggestion->flags |= COMPLETE_REPLACES_TOKEN;
wcstring escaped_dir = last_arg_node.get_source(str);
wchar_t quote = L'\0';
parse_util_get_parameter_info(escaped_dir, 0, &quote, NULL, NULL);
if (quote != L'\0') out_suggestion->completion.push_back(quote);
}
return result;
#endif
/* We can possibly handle this specially */
const wcstring escaped_dir = last_arg_node.get_source(str);
wcstring suggested_path;

View file

@ -1506,7 +1506,7 @@ struct autosuggestion_context_t
/* Try normal completions */
std::vector<completion_t> completions;
complete(search_string, completions, COMPLETION_REQUEST_AUTOSUGGESTION);
complete(search_string, &completions, COMPLETION_REQUEST_AUTOSUGGESTION);
completions_sort_and_prioritize(&completions);
if (! completions.empty())
{
@ -3324,7 +3324,7 @@ const wchar_t *reader_readline(int nchars)
const wcstring buffcpy = wcstring(cmdsub_begin, token_end);
//fprintf(stderr, "Complete (%ls)\n", buffcpy.c_str());
data->complete_func(buffcpy, comp, COMPLETION_REQUEST_DEFAULT | COMPLETION_REQUEST_DESCRIPTIONS | COMPLETION_REQUEST_FUZZY_MATCH);
data->complete_func(buffcpy, &comp, COMPLETION_REQUEST_DEFAULT | COMPLETION_REQUEST_DESCRIPTIONS | COMPLETION_REQUEST_FUZZY_MATCH);
/* Munge our completions */
completions_sort_and_prioritize(&comp);

View file

@ -223,7 +223,7 @@ void reader_pop();
- The command to be completed as a null terminated array of wchar_t
- An array_list_t in which completions will be inserted.
*/
typedef void (*complete_function_t)(const wcstring &, std::vector<completion_t> &, completion_request_flags_t);
typedef void (*complete_function_t)(const wcstring &, std::vector<completion_t> *, completion_request_flags_t);
void reader_set_complete_function(complete_function_t);
/**