summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2020-06-15 19:37:46 +1000
committerMaxime Coste <mawww@kakoune.org>2020-06-16 19:08:10 +1000
commitd4487d3bfcced1a41425afc1b2d3142d6177ddd3 (patch)
tree8ea3990d41fb05c0a640f700cfb005df8f77b094
parent2544f97c892b350fd74dca713dec2729991def0d (diff)
A module is not loaded after failing during load
distinguish the loading from loaded state, detect recursive loading.
-rw-r--r--src/command_manager.cc26
-rw-r--r--src/command_manager.hh8
2 files changed, 25 insertions, 9 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc
index 3a8ffaea..c6e52992 100644
--- a/src/command_manager.cc
+++ b/src/command_manager.cc
@@ -49,10 +49,10 @@ bool CommandManager::module_defined(StringView module_name) const
void CommandManager::register_module(String module_name, String commands)
{
auto module = m_modules.find(module_name);
- if (module != m_modules.end() and module->value.loaded)
+ if (module != m_modules.end() and module->value.state != Module::State::Registered)
throw runtime_error{format("module already loaded: '{}'", module_name)};
- m_modules[module_name] = { false, std::move(commands) };
+ m_modules[module_name] = { Module::State::Registered, std::move(commands) };
}
void CommandManager::load_module(StringView module_name, Context& context)
@@ -60,13 +60,23 @@ void CommandManager::load_module(StringView module_name, Context& context)
auto module = m_modules.find(module_name);
if (module == m_modules.end())
throw runtime_error{format("no such module: '{}'", module_name)};
- if (module->value.loaded)
- return;
+ switch (module->value.state)
+ {
+ case Module::State::Loading:
+ throw runtime_error(format("module '{}' loaded recursively", module_name));
+ case Module::State::Loaded: return;
+ case Module::State::Registered: default: break;
+ }
- module->value.loaded = true;
- Context empty_context{Context::EmptyContextFlag{}};
- execute(module->value.commands, empty_context);
+ {
+ module->value.state = Module::State::Loading;
+ auto restore_state = on_scope_end([&] { module->value.state = Module::State::Registered; });
+
+ Context empty_context{Context::EmptyContextFlag{}};
+ execute(module->value.commands, empty_context);
+ }
module->value.commands.clear();
+ module->value.state = Module::State::Loaded;
context.hooks().run_hook(Hook::ModuleLoaded, module_name, context);
}
@@ -630,7 +640,7 @@ Completions CommandManager::complete_command_name(const Context& context, String
Completions CommandManager::complete_module_name(StringView query) const
{
return {0, query.length(),
- Kakoune::complete(query, query.length(), m_modules | filter([](auto&& item) { return not item.value.loaded; })
+ Kakoune::complete(query, query.length(), m_modules | filter([](auto&& item) { return item.value.state == Module::State::Registered; })
| transform(&ModuleMap::Item::key))};
}
diff --git a/src/command_manager.hh b/src/command_manager.hh
index 35d73ba1..a8b3b146 100644
--- a/src/command_manager.hh
+++ b/src/command_manager.hh
@@ -155,7 +155,13 @@ private:
struct Module
{
- bool loaded;
+ enum class State
+ {
+ Registered,
+ Loading,
+ Loaded
+ };
+ State state = State::Registered;
String commands;
};
using ModuleMap = HashMap<String, Module, MemoryDomain::Commands>;