From 263f919bebf2e5be3a95c7445034fab70fed9fab Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Fri, 29 Nov 2013 23:44:26 -0800 Subject: [PATCH] Replace autosuggestions "completions to load" mechanism with moderately less hackish and far simpler "perform on main thread" mechanism --- complete.cpp | 40 ++++++++++++++++------------------------ complete.h | 7 ++----- fish_tests.cpp | 4 ++-- reader.cpp | 28 +++------------------------- reader.h | 2 +- 5 files changed, 24 insertions(+), 57 deletions(-) diff --git a/complete.cpp b/complete.cpp index 2b7423b5a..ed0fc102d 100644 --- a/complete.cpp +++ b/complete.cpp @@ -44,6 +44,7 @@ #include "parser_keywords.h" #include "wutil.h" #include "path.h" +#include "iothread.h" /* Completion description strings, mostly for different types of files, such as sockets, block devices, etc. @@ -341,7 +342,6 @@ class completer_t const completion_request_flags_t flags; const wcstring initial_cmd; std::vector completions; - wcstring_list_t commands_to_load; /** Table of completions conditions that have already been tested and the corresponding test results */ typedef std::map condition_cache_t; @@ -438,18 +438,6 @@ public: return result; } - - void get_commands_to_load(wcstring_list_t *lst) - { - if (lst) - lst->insert(lst->end(), commands_to_load.begin(), commands_to_load.end()); - } - - bool has_commands_to_load() const - { - return ! commands_to_load.empty(); - } - }; /* Autoloader for completions */ @@ -1350,6 +1338,15 @@ void complete_load(const wcstring &name, bool reload) completion_autoloader.load(name, reload); } +// Performed on main thread, from background thread. Return type is ignored. +static int complete_load_no_reload(wcstring *name) +{ + assert(name != NULL); + ASSERT_IS_MAIN_THREAD(); + complete_load(*name, false); + return 0; +} + /** Find completion for the argument str of command cmd_orig with previous option popt. Insert results into comp_out. Return 0 if file @@ -1372,14 +1369,15 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop if (this->type() == COMPLETE_DEFAULT) { + ASSERT_IS_MAIN_THREAD(); complete_load(cmd, true); } else if (this->type() == COMPLETE_AUTOSUGGEST) { - /* Maybe indicate we should try loading this on the main thread */ - if (! list_contains_string(this->commands_to_load, cmd) && ! completion_autoloader.has_tried_loading(cmd)) + /* Maybe load this command (on the main thread) */ + if (! completion_autoloader.has_tried_loading(cmd)) { - this->commands_to_load.push_back(cmd); + iothread_perform_on_main(complete_load_no_reload, &cmd); } } @@ -1790,7 +1788,7 @@ bool completer_t::try_complete_user(const wcstring &str) return res; } -void complete(const wcstring &cmd, std::vector &comps, completion_request_flags_t flags, wcstring_list_t *commands_to_load) +void complete(const wcstring &cmd, std::vector &comps, completion_request_flags_t flags) { /* Make our completer */ completer_t completer(cmd, flags); @@ -1999,12 +1997,7 @@ void complete(const wcstring &cmd, std::vector &comps, completion_ if (completer.empty()) do_file = true; - /* But if we are planning on loading commands, don't do file completions. - See https://github.com/fish-shell/fish-shell/issues/378 */ - if (commands_to_load != NULL && completer.has_commands_to_load()) - do_file = false; - - /* And if we're autosuggesting, and the token is empty, don't do file suggestions */ + /* If we're autosuggesting, and the token is empty, don't do file suggestions */ if ((flags & COMPLETION_REQUEST_AUTOSUGGESTION) && current_token_unescape.empty()) do_file = false; @@ -2016,7 +2009,6 @@ void complete(const wcstring &cmd, std::vector &comps, completion_ } comps = completer.get_completions(); - completer.get_commands_to_load(commands_to_load); } diff --git a/complete.h b/complete.h index 72d5a7214..cd4f22a16 100644 --- a/complete.h +++ b/complete.h @@ -216,14 +216,11 @@ void complete_remove(const wchar_t *cmd, const wchar_t *long_opt); -/** Find all completions of the command cmd, insert them into out. If to_load is - * not NULL, append all commands that we would autoload, but did not (presumably - * because this is not the main thread) +/** Find all completions of the command cmd, insert them into out. */ void complete(const wcstring &cmd, std::vector &comp, - completion_request_flags_t flags, - wcstring_list_t *to_load = NULL); + completion_request_flags_t flags); /** Print a list of all current completions into the string. diff --git a/fish_tests.cpp b/fish_tests.cpp index d00c7da29..e7047c4bc 100644 --- a/fish_tests.cpp +++ b/fish_tests.cpp @@ -1358,7 +1358,7 @@ void perf_complete() str[0]=c; reader_set_buffer(str, 0); - complete(str, out, COMPLETION_REQUEST_DEFAULT, NULL); + complete(str, out, COMPLETION_REQUEST_DEFAULT); matches += out.size(); out.clear(); @@ -1378,7 +1378,7 @@ void perf_complete() reader_set_buffer(str, 0); - complete(str, out, COMPLETION_REQUEST_DEFAULT, NULL); + complete(str, out, COMPLETION_REQUEST_DEFAULT); matches += out.size(); out.clear(); diff --git a/reader.cpp b/reader.cpp index 5b2a5e0a2..5660ff268 100644 --- a/reader.cpp +++ b/reader.cpp @@ -1410,12 +1410,8 @@ struct autosuggestion_context_t file_detection_context_t detector; const wcstring working_directory; const env_vars_snapshot_t vars; - wcstring_list_t commands_to_load; const unsigned int generation_count; - // don't reload more than once - bool has_tried_reloading; - autosuggestion_context_t(history_t *history, const wcstring &term, size_t pos) : search_string(term), cursor_pos(pos), @@ -1423,8 +1419,7 @@ struct autosuggestion_context_t detector(history, term), working_directory(env_get_pwd_slash()), vars(env_vars_snapshot_t::highlighting_keys), - generation_count(s_generation_count), - has_tried_reloading(false) + generation_count(s_generation_count) { } @@ -1494,7 +1489,7 @@ struct autosuggestion_context_t /* Try normal completions */ std::vector completions; - complete(search_string, completions, COMPLETION_REQUEST_AUTOSUGGESTION, &this->commands_to_load); + complete(search_string, completions, COMPLETION_REQUEST_AUTOSUGGESTION); if (! completions.empty()) { const completion_t &comp = completions.at(0); @@ -1523,23 +1518,6 @@ static bool can_autosuggest(void) static void autosuggest_completed(autosuggestion_context_t *ctx, int result) { - - /* Extract the commands to load */ - wcstring_list_t commands_to_load; - ctx->commands_to_load.swap(commands_to_load); - - /* If we have autosuggestions to load, load them and try again */ - if (! result && ! commands_to_load.empty() && ! ctx->has_tried_reloading) - { - ctx->has_tried_reloading = true; - for (wcstring_list_t::const_iterator iter = commands_to_load.begin(); iter != commands_to_load.end(); ++iter) - { - complete_load(*iter, false); - } - iothread_perform(threaded_autosuggest, autosuggest_completed, ctx); - return; - } - if (result && can_autosuggest() && ctx->search_string == data->command_line && @@ -3271,7 +3249,7 @@ const wchar_t *reader_readline(void) 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, NULL); + data->complete_func(buffcpy, comp, COMPLETION_REQUEST_DEFAULT | COMPLETION_REQUEST_DESCRIPTIONS | COMPLETION_REQUEST_FUZZY_MATCH); /* Munge our completions */ sort_and_make_unique(comp); diff --git a/reader.h b/reader.h index 0d7a58f17..b954c1bea 100644 --- a/reader.h +++ b/reader.h @@ -166,7 +166,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, wcstring_list_t * lst); +typedef void (*complete_function_t)(const wcstring &, std::vector &, completion_request_flags_t); void reader_set_complete_function(complete_function_t); /**