From c39b94949be30dfbc1c3e271b37ca04cff303b16 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 6 Feb 2016 19:17:43 -0800 Subject: [PATCH] Complete to take a pointer to output completions, not a mutable ref --- src/builtin_complete.cpp | 2 +- src/complete.cpp | 4 +-- src/complete.h | 2 +- src/fish_tests.cpp | 58 ++++++++++++++++++++-------------------- src/highlight.cpp | 28 +++++++++++++++++++ src/reader.cpp | 4 +-- src/reader.h | 2 +- 7 files changed, 64 insertions(+), 36 deletions(-) diff --git a/src/builtin_complete.cpp b/src/builtin_complete.cpp index ee7f235ad..1101f4a5a 100644 --- a/src/builtin_complete.cpp +++ b/src/builtin_complete.cpp @@ -456,7 +456,7 @@ static int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **a recursion_level++; std::vector 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++) { diff --git a/src/complete.cpp b/src/complete.cpp index 5da53aebf..266451c4d 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -1631,7 +1631,7 @@ bool completer_t::try_complete_user(const wcstring &str) return res; } -void complete(const wcstring &cmd_with_subcmds, std::vector &comps, completion_request_flags_t flags) +void complete(const wcstring &cmd_with_subcmds, std::vector *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 &comps } } - comps = completer.get_completions(); + *out_comps = completer.get_completions(); } diff --git a/src/complete.h b/src/complete.h index 0784bc48c..999b3c2ba 100644 --- a/src/complete.h +++ b/src/complete.h @@ -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 &comp, + std::vector *out_comps, completion_request_flags_t flags); /** diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 2f627244d..67e5dfa09 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -2094,18 +2094,18 @@ static void test_complete(void) complete_set_variable_names(&names); std::vector 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(); diff --git a/src/highlight.cpp b/src/highlight.cpp index 4e5dc3f34..595631b78 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -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 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, "e, 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; diff --git a/src/reader.cpp b/src/reader.cpp index 900479b2f..39bfc0bb4 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -1506,7 +1506,7 @@ struct autosuggestion_context_t /* Try normal completions */ std::vector 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); diff --git a/src/reader.h b/src/reader.h index b4a159be1..73c19c2f8 100644 --- a/src/reader.h +++ b/src/reader.h @@ -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_request_flags_t); +typedef void (*complete_function_t)(const wcstring &, std::vector *, completion_request_flags_t); void reader_set_complete_function(complete_function_t); /**