diff --git a/src/main.cc b/src/main.cc index ba6eaccc..39fdc25f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -440,6 +440,10 @@ int main(int argc, char* argv[]) shell_manager.register_env_var("opt_.+", [](const String& name, const Context& context) { return context.option_manager()[name.substr(4)].as_string(); }); + + register_manager.register_dynamic_register('%', [&]() { return std::vector(1, main_context.buffer().name()); }); + register_manager.register_dynamic_register('.', [&]() { return main_context.window().selections_content(); }); + register_commands(); register_highlighters(); register_filters(); diff --git a/src/register.cc b/src/register.cc deleted file mode 100644 index af0852ea..00000000 --- a/src/register.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include "register.hh" - -namespace Kakoune -{ - -const String Register::ms_empty; - -Register& Register::operator=(const memoryview& values) -{ - m_content = std::vector(values.begin(), values.end()); - return *this; -} - -const String& Register::operator[](size_t index) const -{ - if (m_content.size() > index) - return m_content[index]; - else - return ms_empty; -} - -} diff --git a/src/register.hh b/src/register.hh index fc50e44f..c90b7233 100644 --- a/src/register.hh +++ b/src/register.hh @@ -1,8 +1,6 @@ #ifndef register_hh_INCLUDED #define register_hh_INCLUDED -#include - #include "string.hh" #include "memoryview.hh" @@ -12,16 +10,12 @@ namespace Kakoune class Register { public: - Register& operator=(const memoryview& values); + virtual ~Register() {} + virtual Register& operator=(const memoryview& values) = 0; - const String& operator[](size_t index) const; + virtual const String& operator[](size_t index) = 0; - operator memoryview() const - { return memoryview(m_content); } -private: - std::vector m_content; - - static const String ms_empty; + virtual operator memoryview() = 0; }; } diff --git a/src/register_manager.cc b/src/register_manager.cc new file mode 100644 index 00000000..857f7324 --- /dev/null +++ b/src/register_manager.cc @@ -0,0 +1,84 @@ +#include "register_manager.hh" + +#include "utils.hh" +#include "assert.hh" + +namespace Kakoune +{ + +// static value register, which can be modified +// using operator=, so should be user modifiable +class StaticRegister : public Register +{ +public: + Register& operator=(const memoryview& values) + { + m_content = std::vector(values.begin(), values.end()); + return *this; + } + + const String& operator[](size_t index) + { + if (m_content.size() > index) + return m_content[index]; + else + return ms_empty; + } + + operator memoryview() + { + return memoryview(m_content); + } +protected: + std::vector m_content; + + static const String ms_empty; +}; + +const String StaticRegister::ms_empty; + +// Dynamic value register, use it's RegisterRetriever +// to get it's value when needed. +class DynamicRegister : public StaticRegister +{ +public: + DynamicRegister(RegisterRetriever function) + : m_function(std::move(function)) {} + + Register& operator=(const memoryview& values) + { + throw runtime_error("this register is not assignable"); + } + + const String& operator[](size_t index) + { + m_content = m_function(); + return StaticRegister::operator[](index); + } + + operator memoryview() + { + m_content = m_function(); + return StaticRegister::operator memoryview(); + } + +private: + RegisterRetriever m_function; +}; + +Register& RegisterManager::operator[](char reg) +{ + auto& reg_ptr = m_registers[reg]; + if (not reg_ptr) + reg_ptr.reset(new StaticRegister()); + return *reg_ptr; +} + +void RegisterManager::register_dynamic_register(char reg, RegisterRetriever function) +{ + auto& reg_ptr = m_registers[reg]; + assert(not reg_ptr); + reg_ptr.reset(new DynamicRegister(std::move(function))); +} + +} diff --git a/src/register_manager.hh b/src/register_manager.hh index d37ed2dd..9f125b9f 100644 --- a/src/register_manager.hh +++ b/src/register_manager.hh @@ -2,20 +2,26 @@ #define register_manager_hh_INCLUDED #include "register.hh" + #include "utils.hh" #include +#include +#include namespace Kakoune { +typedef std::function ()> RegisterRetriever; + class RegisterManager : public Singleton { public: - Register& operator[](char reg) { return m_registers[reg]; } + Register& operator[](char reg); + void register_dynamic_register(char reg, RegisterRetriever function); protected: - std::unordered_map m_registers; + std::unordered_map> m_registers; }; }