support static and dynamic registers, add '%' (filename) and '.' (selection) registers

This commit is contained in:
Maxime Coste 2012-06-29 18:37:17 +02:00
parent 5b2ef1da6a
commit dfbda951d3
5 changed files with 100 additions and 34 deletions

View File

@ -440,6 +440,10 @@ int main(int argc, char* argv[])
shell_manager.register_env_var("opt_.+", shell_manager.register_env_var("opt_.+",
[](const String& name, const Context& context) [](const String& name, const Context& context)
{ return context.option_manager()[name.substr(4)].as_string(); }); { return context.option_manager()[name.substr(4)].as_string(); });
register_manager.register_dynamic_register('%', [&]() { return std::vector<String>(1, main_context.buffer().name()); });
register_manager.register_dynamic_register('.', [&]() { return main_context.window().selections_content(); });
register_commands(); register_commands();
register_highlighters(); register_highlighters();
register_filters(); register_filters();

View File

@ -1,22 +0,0 @@
#include "register.hh"
namespace Kakoune
{
const String Register::ms_empty;
Register& Register::operator=(const memoryview<String>& values)
{
m_content = std::vector<String>(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;
}
}

View File

@ -1,8 +1,6 @@
#ifndef register_hh_INCLUDED #ifndef register_hh_INCLUDED
#define register_hh_INCLUDED #define register_hh_INCLUDED
#include <vector>
#include "string.hh" #include "string.hh"
#include "memoryview.hh" #include "memoryview.hh"
@ -12,16 +10,12 @@ namespace Kakoune
class Register class Register
{ {
public: public:
Register& operator=(const memoryview<String>& values); virtual ~Register() {}
virtual Register& operator=(const memoryview<String>& values) = 0;
const String& operator[](size_t index) const; virtual const String& operator[](size_t index) = 0;
operator memoryview<String>() const virtual operator memoryview<String>() = 0;
{ return memoryview<String>(m_content); }
private:
std::vector<String> m_content;
static const String ms_empty;
}; };
} }

84
src/register_manager.cc Normal file
View File

@ -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<String>& values)
{
m_content = std::vector<String>(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<String>()
{
return memoryview<String>(m_content);
}
protected:
std::vector<String> 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<String>& 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<String>()
{
m_content = m_function();
return StaticRegister::operator memoryview<String>();
}
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)));
}
}

View File

@ -2,20 +2,26 @@
#define register_manager_hh_INCLUDED #define register_manager_hh_INCLUDED
#include "register.hh" #include "register.hh"
#include "utils.hh" #include "utils.hh"
#include <unordered_map> #include <unordered_map>
#include <vector>
#include <functional>
namespace Kakoune namespace Kakoune
{ {
typedef std::function<std::vector<String> ()> RegisterRetriever;
class RegisterManager : public Singleton<RegisterManager> class RegisterManager : public Singleton<RegisterManager>
{ {
public: public:
Register& operator[](char reg) { return m_registers[reg]; } Register& operator[](char reg);
void register_dynamic_register(char reg, RegisterRetriever function);
protected: protected:
std::unordered_map<char, Register> m_registers; std::unordered_map<char, std::unique_ptr<Register>> m_registers;
}; };
} }