diff --git a/README.asciidoc b/README.asciidoc index eea1e6baf..70afe7dd3 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -976,6 +976,8 @@ Some parameters provide a way to change the context of execution: on all buffers. * `-no-hooks`: disable hook execution while executing the keys/commands * `-with-maps`: use user key mapping in `:exec` instead of built in keys. + * `-save-regs `: regs is a string of registers to be restored after + execution. The execution stops when the last key/command is reached, or an error is raised. diff --git a/src/commands.cc b/src/commands.cc index f85ce7f3d..ddaee769d 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -1198,7 +1198,8 @@ const ParameterDesc context_wrap_params = { { "draft", { false, "run in a disposable context" } }, { "no-hooks", { false, "disable hooks" } }, { "with-maps", { false, "use user defined key mapping when executing keys" } }, - { "itersel", { false, "run once for each selection with that selection as the only one" } } }, + { "itersel", { false, "run once for each selection with that selection as the only one" } }, + { "save-regs", { true, "restore all given registers after execution" } } }, ParameterDesc::Flags::SwitchesOnlyAtStart, 1 }; @@ -1216,6 +1217,41 @@ private: T m_prev_value; }; +class RegisterRestorer +{ +public: + RegisterRestorer(char name, const Context& context) + : m_name(name) + { + ConstArrayView save = RegisterManager::instance()[name].values(context); + m_save = Vector(save.begin(), save.end()); + } + + RegisterRestorer(RegisterRestorer&& other) noexcept + : m_save(std::move(other.m_save)), m_name(other.m_name) + { + other.m_name = 0; + } + + RegisterRestorer& operator=(RegisterRestorer&& other) noexcept + { + m_save = std::move(other.m_save); + m_name = other.m_name; + other.m_name = 0; + return *this; + } + + ~RegisterRestorer() + { + if (m_name != 0) + RegisterManager::instance()[m_name] = m_save; + } + +private: + Vector m_save; + char m_name; +}; + template void context_wrap(const ParametersParser& parser, Context& context, Func func) { @@ -1229,6 +1265,13 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func) context.user_hooks_disabled(); const bool disable_keymaps = not parser.get_switch("with-maps"); + Vector saved_registers; + if (auto regs = parser.get_switch("save-regs")) + { + for (auto& r : *regs) + saved_registers.emplace_back(r, context); + } + ClientManager& cm = ClientManager::instance(); if (auto bufnames = parser.get_switch("buffer")) { @@ -1652,24 +1695,6 @@ const CommandDesc change_working_directory_cmd = { } }; -class RegisterRestorer -{ -public: - RegisterRestorer(char name, const Context& context) - : m_name(name) - { - ConstArrayView save = RegisterManager::instance()[name].values(context); - m_save = Vector(save.begin(), save.end()); - } - - ~RegisterRestorer() - { RegisterManager::instance()[m_name] = m_save; } - -private: - Vector m_save; - char m_name; -}; - } void exec_keys(ConstArrayView keys, Context& context)