diff options
author | Sanne Wouda <sanne.wouda@gmail.com> | 2015-03-11 14:14:56 +0100 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2015-04-06 00:10:55 -0700 |
commit | 73f344f41bd20c005a0f5b810dc20229392f2bf8 (patch) | |
tree | eadc9615a1f35dae8201e3d5232b60f40ff7d999 /function.cpp | |
parent | 9f8cec7f9e13f6a0cbf8e5e986c3dfbffac0be99 (diff) |
Revert 1349d12 and properly fix #213
As suggested by @ridiculousfish, when removing autoloaded functions, add them
to a tombstones set. These functions will never be autoloaded again in the
current shell, not even when the timestamp changes.
Tested as per comment 1 of #1033. `~/.config/fish/functions/ls.fish` contains
the function definition. `function -e ls` removes the redefined `ls` (and
reverts back to the built-in command). `touch .../ls.fish` does not cause the
function to be reloaded.
Diffstat (limited to 'function.cpp')
-rw-r--r-- | function.cpp | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/function.cpp b/function.cpp index 11c23114..adb16479 100644 --- a/function.cpp +++ b/function.cpp @@ -43,6 +43,11 @@ typedef std::map<wcstring, function_info_t> function_map_t; static function_map_t loaded_functions; +/** + Functions that shouldn't be autoloaded (anymore). +*/ +static std::set<wcstring> function_tombstones; + /* Lock for functions */ static pthread_mutex_t functions_lock; @@ -61,6 +66,8 @@ function_autoload_t::function_autoload_t() : autoload_t(L"fish_function_path", N { } +static bool function_remove_ignore_autoload(const wcstring &name); + /** Callback when an autoloaded function is removed */ void function_autoload_t::command_removed(const wcstring &cmd) { @@ -84,6 +91,11 @@ static int load(const wcstring &name) scoped_lock lock(functions_lock); bool was_autoload = is_autoload; int res; + + bool no_more_autoload = function_tombstones.count(name) == 1; + if (no_more_autoload) + return 0; + function_map_t::iterator iter = loaded_functions.find(name); if (iter != loaded_functions.end() && !iter->second.is_autoload) { @@ -225,19 +237,28 @@ int function_exists_no_autoload(const wcstring &cmd, const env_vars_snapshot_t & return loaded_functions.find(cmd) != loaded_functions.end() || function_autoloader.can_load(cmd, vars); } -bool function_remove_ignore_autoload(const wcstring &name) +static bool function_remove_ignore_autoload(const wcstring &name) { scoped_lock lock(functions_lock); - bool erased = (loaded_functions.erase(name) > 0); - if (erased) - { - event_t ev(EVENT_ANY); - ev.function_name=name; - event_remove(ev); - } - return erased; + function_map_t::iterator iter = loaded_functions.find(name); + + // not found. not erasing. + if (iter == loaded_functions.end()) + return false; + + // removing an auto-loaded function. prevent it from being + // auto-reloaded. + if (iter->second.is_autoload) + function_tombstones.insert(name); + + loaded_functions.erase(iter); + + event_t ev(EVENT_ANY); + ev.function_name=name; + event_remove(ev); + return true; } void function_remove(const wcstring &name) |