mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-23 07:23:34 +08:00
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.
This commit is contained in:
parent
9f8cec7f9e
commit
73f344f41b
|
@ -1565,7 +1565,7 @@ static int builtin_functions(parser_t &parser, wchar_t **argv)
|
|||
{
|
||||
int i;
|
||||
for (i=woptind; i<argc; i++)
|
||||
function_remove_ignore_autoload(argv[i]);
|
||||
function_remove(argv[i]);
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
else if (desc)
|
||||
|
|
39
function.cpp
39
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)
|
||||
|
|
|
@ -105,9 +105,6 @@ void function_init();
|
|||
/** Add a function. definition_line_offset is the line number of the function's definition within its source file */
|
||||
void function_add(const function_data_t &data, const parser_t &parser, int definition_line_offset = 0);
|
||||
|
||||
/** Removes a function from our internal table, returning true if it was found and false if not */
|
||||
bool function_remove_ignore_autoload(const wcstring &name);
|
||||
|
||||
/**
|
||||
Remove the function with the specified name.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user