From 670f8192c8d68c33e42b95847edd0678f87ca39b Mon Sep 17 00:00:00 2001 From: Justin Frank Date: Thu, 7 Mar 2019 22:31:04 -0800 Subject: Set up command boilerplate for provide-module and require-module --- src/commands.cc | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src') diff --git a/src/commands.cc b/src/commands.cc index ef597f6f..3c50accb 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -2405,6 +2405,36 @@ const CommandDesc enter_user_mode_cmd = { } }; +const CommandDesc provide_module_cmd = { + "provide-module", + nullptr, + "provide-module [] : declares a module provided by ", + ParameterDesc{ + { { "override", { false, "allow overriding an existing module" } } }, + ParameterDesc::Flags::None, + 2, 2 + }, + CommandFlags::None, + CommandHelper{}, + CommandCompleter{}, + [](const ParametersParser& parse, Context& context, const ShellContext&) + { + } +}; + +const CommandDesc require_module_cmd = { + "require-module", + nullptr, + "require-module : ensures that module has been loaded", + ParameterDesc{ {}, ParameterDesc::Flags::None, 1, 1 }, + CommandFlags::None, + CommandHelper{}, + CommandCompleter{}, + [](const ParametersParser& parser, Context& context, const ShellContext&) + { + } +}; + } void register_commands() @@ -2470,6 +2500,8 @@ void register_commands() register_command(fail_cmd); register_command(declare_user_mode_cmd); register_command(enter_user_mode_cmd); + register_command(provide_module_cmd); + register_command(require_module_cmd); } } -- cgit v1.2.3 From 6092852640096c777f700cf669666504b10e2a58 Mon Sep 17 00:00:00 2001 From: Justin Frank Date: Tue, 12 Mar 2019 10:34:30 -0700 Subject: Added 'provide-module' and 'require-module' commands --- src/command_manager.cc | 27 +++++++++++++++++++++++++++ src/command_manager.hh | 14 ++++++++++++++ src/commands.cc | 12 +++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/command_manager.cc b/src/command_manager.cc index 5e8c8196..91c41bd3 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -40,6 +40,33 @@ void CommandManager::register_command(String command_name, std::move(completer) }; } +bool CommandManager::module_defined(StringView module_name) const +{ + return m_modules.find(module_name) != m_modules.end(); +} + +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) + throw runtime_error{format("module already loaded: '{}'", module_name)}; + + m_modules[module_name] = { false, std::move(commands) }; +} + +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; + + module->value.loaded = true; + execute(module->value.commands, context); + module->value.commands.clear(); +} + struct parse_error : runtime_error { parse_error(StringView error) diff --git a/src/command_manager.hh b/src/command_manager.hh index 0468a1fc..329c24f2 100644 --- a/src/command_manager.hh +++ b/src/command_manager.hh @@ -123,6 +123,12 @@ public: void clear_last_complete_command() { m_last_complete_command = String{}; } + bool module_defined(StringView module_name) const; + + void register_module(String module_name, String commands); + + void load_module(StringView module_name, Context& context); + private: void execute_single_command(CommandParameters params, Context& context, @@ -143,6 +149,14 @@ private: String m_last_complete_command; int m_command_depth = 0; + struct Module + { + bool loaded; + String commands; + }; + using ModuleMap = HashMap; + ModuleMap m_modules; + CommandMap::const_iterator find_command(const Context& context, StringView name) const; }; diff --git a/src/commands.cc b/src/commands.cc index 3c50accb..264ad46c 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -2417,8 +2417,17 @@ const CommandDesc provide_module_cmd = { CommandFlags::None, CommandHelper{}, CommandCompleter{}, - [](const ParametersParser& parse, Context& context, const ShellContext&) + [](const ParametersParser& parser, Context& context, const ShellContext&) { + const String& module_name = parser[0]; + auto& cm = CommandManager::instance(); + + if (not all_of(module_name, is_identifier)) + throw runtime_error(format("invalid module name: '{}'", module_name)); + + if (cm.module_defined(module_name) and not parser.get_switch("override")) + throw runtime_error(format("module '{}' already defined", module_name)); + cm.register_module(module_name, parser[1]); } }; @@ -2432,6 +2441,7 @@ const CommandDesc require_module_cmd = { CommandCompleter{}, [](const ParametersParser& parser, Context& context, const ShellContext&) { + CommandManager::instance().load_module(parser[0], context); } }; -- cgit v1.2.3 From 7866d88131837f7c514e73c57773185ba33beb7b Mon Sep 17 00:00:00 2001 From: Justin Frank Date: Wed, 13 Mar 2019 12:46:53 -0700 Subject: Added ModuleLoad hook that uses the module name as the parameter --- src/command_manager.cc | 2 ++ src/hook_manager.hh | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/command_manager.cc b/src/command_manager.cc index 91c41bd3..aff9e3fd 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -65,6 +65,8 @@ void CommandManager::load_module(StringView module_name, Context& context) module->value.loaded = true; execute(module->value.commands, context); module->value.commands.clear(); + + context.hooks().run_hook(Hook::ModuleLoad, module_name, context); } struct parse_error : runtime_error diff --git a/src/hook_manager.hh b/src/hook_manager.hh index 1653791c..38d1c611 100644 --- a/src/hook_manager.hh +++ b/src/hook_manager.hh @@ -57,12 +57,13 @@ enum class Hook WinCreate, WinDisplay, WinResize, - WinSetOption + WinSetOption, + ModuleLoad }; constexpr auto enum_desc(Meta::Type) { - return make_array, 41>({ + return make_array, 42>({ {Hook::BufCreate, "BufCreate"}, {Hook::BufNewFile, "BufNewFile"}, {Hook::BufOpenFile, "BufOpenFile"}, @@ -104,6 +105,7 @@ constexpr auto enum_desc(Meta::Type) {Hook::WinDisplay, "WinDisplay"}, {Hook::WinResize, "WinResize"}, {Hook::WinSetOption, "WinSetOption"}, + {Hook::ModuleLoad, "ModuleLoad"} }); } -- cgit v1.2.3 From c40bb6fc009bd0933290b61717605c0d5bf68aee Mon Sep 17 00:00:00 2001 From: Justin Frank Date: Sat, 16 Mar 2019 01:38:32 -0700 Subject: Evaluate modules in an empty context --- src/command_manager.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/command_manager.cc b/src/command_manager.cc index aff9e3fd..1fdfa34d 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -63,7 +63,8 @@ void CommandManager::load_module(StringView module_name, Context& context) return; module->value.loaded = true; - execute(module->value.commands, context); + Context empty_context{Context::EmptyContextFlag{}}; + execute(module->value.commands, empty_context); module->value.commands.clear(); context.hooks().run_hook(Hook::ModuleLoad, module_name, context); -- cgit v1.2.3