mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-28 12:13:55 +08:00
Reimplement completion autoloading via autoloader_t
This switches the completion autoloading machinery to autoloader_t.
This commit is contained in:
parent
960266fe24
commit
68a28106b2
|
@ -151,12 +151,24 @@ maybe_t<autoloadable_file_t> autoload_file_cache_t::check(const wcstring &cmd, b
|
||||||
autoloader_t::autoloader_t(wcstring env_var_name)
|
autoloader_t::autoloader_t(wcstring env_var_name)
|
||||||
: env_var_name_(std::move(env_var_name)), cache_(make_unique<autoload_file_cache_t>()) {}
|
: env_var_name_(std::move(env_var_name)), cache_(make_unique<autoload_file_cache_t>()) {}
|
||||||
|
|
||||||
|
autoloader_t::autoloader_t(autoloader_t &&) = default;
|
||||||
autoloader_t::~autoloader_t() = default;
|
autoloader_t::~autoloader_t() = default;
|
||||||
|
|
||||||
bool autoloader_t::can_autoload(const wcstring &cmd) {
|
bool autoloader_t::can_autoload(const wcstring &cmd) {
|
||||||
return cache_->check(cmd, true /* allow stale */).has_value();
|
return cache_->check(cmd, true /* allow stale */).has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wcstring_list_t autoloader_t::get_autoloaded_commands() const {
|
||||||
|
wcstring_list_t result;
|
||||||
|
result.reserve(autoloaded_files_.size());
|
||||||
|
for (const auto &kv : autoloaded_files_) {
|
||||||
|
result.push_back(kv.first);
|
||||||
|
}
|
||||||
|
// Sort the output to make it easier to test.
|
||||||
|
std::sort(result.begin(), result.end());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
maybe_t<wcstring> autoloader_t::resolve_command(const wcstring &cmd, const environment_t &env) {
|
maybe_t<wcstring> autoloader_t::resolve_command(const wcstring &cmd, const environment_t &env) {
|
||||||
// Are we currently in the process of autoloading this?
|
// Are we currently in the process of autoloading this?
|
||||||
if (current_autoloading_.count(cmd) > 0) return none();
|
if (current_autoloading_.count(cmd) > 0) return none();
|
||||||
|
|
|
@ -42,6 +42,7 @@ class autoloader_t {
|
||||||
/// Construct an autoloader that loads from the paths given by \p env_var_name.
|
/// Construct an autoloader that loads from the paths given by \p env_var_name.
|
||||||
explicit autoloader_t(wcstring env_var_name);
|
explicit autoloader_t(wcstring env_var_name);
|
||||||
|
|
||||||
|
autoloader_t(autoloader_t &&);
|
||||||
~autoloader_t();
|
~autoloader_t();
|
||||||
|
|
||||||
/// Given a command, get a path to autoload.
|
/// Given a command, get a path to autoload.
|
||||||
|
@ -75,6 +76,9 @@ class autoloader_t {
|
||||||
/// This does not actually mark the command as being autoloaded.
|
/// This does not actually mark the command as being autoloaded.
|
||||||
bool can_autoload(const wcstring &cmd);
|
bool can_autoload(const wcstring &cmd);
|
||||||
|
|
||||||
|
/// \return the names of all commands that have been autoloaded.
|
||||||
|
wcstring_list_t get_autoloaded_commands() const;
|
||||||
|
|
||||||
/// Mark that all autoloaded files have been forgotten.
|
/// Mark that all autoloaded files have been forgotten.
|
||||||
/// Future calls to path_to_autoload() will return previously-returned paths.
|
/// Future calls to path_to_autoload() will return previously-returned paths.
|
||||||
void clear() {
|
void clear() {
|
||||||
|
|
|
@ -380,8 +380,8 @@ class completer_t {
|
||||||
std::vector<completion_t> acquire_completions() { return std::move(completions); }
|
std::vector<completion_t> acquire_completions() { return std::move(completions); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Autoloader for completions
|
// Autoloader for completions.
|
||||||
static autoload_t completion_autoloader(L"fish_complete_path");
|
static owning_lock<autoloader_t> completion_autoloader{autoloader_t(L"fish_complete_path")};
|
||||||
|
|
||||||
/// Create a new completion entry.
|
/// Create a new completion entry.
|
||||||
void append_completion(std::vector<completion_t> *completions, wcstring comp, wcstring desc,
|
void append_completion(std::vector<completion_t> *completions, wcstring comp, wcstring desc,
|
||||||
|
@ -860,7 +860,16 @@ static void complete_load(const wcstring &name, bool reload) {
|
||||||
// We have to load this as a function, since it may define a --wraps or signature.
|
// We have to load this as a function, since it may define a --wraps or signature.
|
||||||
// See issue #2466.
|
// See issue #2466.
|
||||||
function_load(name);
|
function_load(name);
|
||||||
completion_autoloader.load(name, reload);
|
|
||||||
|
// It's important to NOT hold the lock around completion loading.
|
||||||
|
// We need to take the lock to decide what to load, drop it to perform the load, then reacquire
|
||||||
|
// it.
|
||||||
|
const environment_t &vars = parser_t::principal_parser().vars();
|
||||||
|
maybe_t<wcstring> path_to_load = completion_autoloader.acquire()->resolve_command(name, vars);
|
||||||
|
if (path_to_load) {
|
||||||
|
autoloader_t::perform_autoload(*path_to_load);
|
||||||
|
completion_autoloader.acquire()->mark_autoload_finished(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// complete_param: Given a command, find completions for the argument str of command cmd_orig with
|
/// complete_param: Given a command, find completions for the argument str of command cmd_orig with
|
||||||
|
@ -1659,7 +1668,15 @@ wcstring complete_print() {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void complete_invalidate_path() { completion_autoloader.invalidate(); }
|
void complete_invalidate_path() {
|
||||||
|
// TODO: here we unload all completions for commands that are loaded by the autoloader. We also
|
||||||
|
// unload any completions that the user may specified on the command line. We should in
|
||||||
|
// principle track those completions loaded by the autoloader alone.
|
||||||
|
wcstring_list_t cmds = completion_autoloader.acquire()->get_autoloaded_commands();
|
||||||
|
for (const wcstring &cmd : cmds) {
|
||||||
|
complete_remove_all(cmd, false /* not a path */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a new target that wraps a command. Example: __fish_XYZ (function) wraps XYZ (target).
|
/// Add a new target that wraps a command. Example: __fish_XYZ (function) wraps XYZ (target).
|
||||||
bool complete_add_wrapper(const wcstring &command, const wcstring &new_target) {
|
bool complete_add_wrapper(const wcstring &command, const wcstring &new_target) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user