Refactor filter and highlighter registry into a common template

This commit is contained in:
Maxime Coste 2012-11-23 13:40:20 +01:00
parent 11e885e5a5
commit d2f811a8d5
14 changed files with 95 additions and 190 deletions

View File

@ -9,8 +9,8 @@
#include "file.hh" #include "file.hh"
#include "input_handler.hh" #include "input_handler.hh"
#include "string.hh" #include "string.hh"
#include "highlighter_registry.hh" #include "highlighter.hh"
#include "filter_registry.hh" #include "filter.hh"
#include "register_manager.hh" #include "register_manager.hh"
#include "completion.hh" #include "completion.hh"
#include "shell_manager.hh" #include "shell_manager.hh"
@ -453,8 +453,8 @@ void add_highlighter(const CommandParameters& params, Context& context)
window.highlighters().get_group(parser.option_value("group")) window.highlighters().get_group(parser.option_value("group"))
: window.highlighters(); : window.highlighters();
registry.add_highlighter_to_group(window, group, name, auto& factory = registry[name];
highlighter_params); group.append(factory(window, highlighter_params));
} }
void rm_highlighter(const CommandParameters& params, Context& context) void rm_highlighter(const CommandParameters& params, Context& context)
@ -490,7 +490,8 @@ void add_filter(const CommandParameters& params, Context& context)
editor.filters().get_group(parser.option_value("group")) editor.filters().get_group(parser.option_value("group"))
: editor.filters(); : editor.filters();
registry.add_filter_to_group(group, name, filter_params); auto& factory = registry[name];
group.append(factory(filter_params));
} }
void rm_filter(const CommandParameters& params, Context& context) void rm_filter(const CommandParameters& params, Context& context)
@ -809,7 +810,7 @@ void register_commands()
if (token_to_complete == 1 and params[0] == "-group") if (token_to_complete == 1 and params[0] == "-group")
return w.highlighters().complete_group_id(arg, pos_in_token); return w.highlighters().complete_group_id(arg, pos_in_token);
else if (token_to_complete == 0 or (token_to_complete == 2 and params[0] == "-group")) else if (token_to_complete == 0 or (token_to_complete == 2 and params[0] == "-group"))
return HighlighterRegistry::instance().complete_highlighter(arg, pos_in_token); return HighlighterRegistry::instance().complete_name(arg, pos_in_token);
else else
return CandidateList(); return CandidateList();
}); });
@ -837,7 +838,7 @@ void register_commands()
if (token_to_complete == 1 and params[0] == "-group") if (token_to_complete == 1 and params[0] == "-group")
return w.filters().complete_group_id(arg, pos_in_token); return w.filters().complete_group_id(arg, pos_in_token);
else if (token_to_complete == 0 or (token_to_complete == 2 and params[0] == "-group")) else if (token_to_complete == 0 or (token_to_complete == 2 and params[0] == "-group"))
return FilterRegistry::instance().complete_filter(arg, pos_in_token); return FilterRegistry::instance().complete_name(arg, pos_in_token);
else else
return CandidateList(); return CandidateList();
}); });

View File

@ -1,10 +1,14 @@
#ifndef filter_hh_INCLUDED #ifndef filter_hh_INCLUDED
#define filter_hh_INCLUDED #define filter_hh_INCLUDED
#include "string.hh"
#include "selection.hh"
#include <functional> #include <functional>
#include "string.hh"
#include "utils.hh"
#include "memoryview.hh"
#include "selection.hh"
#include "function_registry.hh"
namespace Kakoune namespace Kakoune
{ {
@ -18,6 +22,13 @@ class BufferIterator;
using FilterFunc = std::function<void (Buffer& buffer, Selection& selection, String& content)>; using FilterFunc = std::function<void (Buffer& buffer, Selection& selection, String& content)>;
using FilterAndId = std::pair<String, FilterFunc>; using FilterAndId = std::pair<String, FilterFunc>;
using FilterParameters = memoryview<String>;
using FilterFactory = std::function<FilterAndId (const FilterParameters& params)>;
struct FilterRegistry : FunctionRegistry<FilterFactory>,
Singleton<FilterRegistry>
{};
} }
#endif // filter_hh_INCLUDED #endif // filter_hh_INCLUDED

View File

@ -1,39 +0,0 @@
#include "filter_registry.hh"
#include "exception.hh"
#include "filter_group.hh"
namespace Kakoune
{
struct factory_not_found : public runtime_error
{
factory_not_found(const String& name)
: runtime_error("filter factory not found '" + name + "'") {}
};
void FilterRegistry::register_factory(const String& name,
const FilterFactory& factory)
{
assert(not m_factories.contains(name));
m_factories.append(std::make_pair(name, factory));
}
void FilterRegistry::add_filter_to_group(FilterGroup& group,
const String& name,
const FilterParameters& parameters)
{
auto it = m_factories.find(name);
if (it == m_factories.end())
throw factory_not_found(name);
group.append(it->second(parameters));
}
CandidateList FilterRegistry::complete_filter(const String& prefix,
ByteCount cursor_pos)
{
return m_factories.complete_id(prefix, cursor_pos);
}
}

View File

@ -1,42 +0,0 @@
#ifndef filter_registry_h_INCLUDED
#define filter_registry_h_INCLUDED
#include <unordered_map>
#include "string.hh"
#include "filter.hh"
#include "utils.hh"
#include "completion.hh"
#include "memoryview.hh"
#include "idvaluemap.hh"
namespace Kakoune
{
class FilterGroup;
typedef memoryview<String> FilterParameters;
typedef std::function<FilterAndId (const FilterParameters& params)> FilterFactory;
class FilterRegistry : public Singleton<FilterRegistry>
{
public:
void register_factory(const String& name,
const FilterFactory& factory);
void add_filter_to_group(FilterGroup& group,
const String& factory_name,
const FilterParameters& parameters);
CandidateList complete_filter(const String& prefix,
ByteCount cursor_pos);
private:
idvaluemap<String, FilterFactory> m_factories;
};
}
#endif // filter_registry_h_INCLUDED

View File

@ -1,5 +1,4 @@
#include "filters.hh" #include "filters.hh"
#include "filter_registry.hh"
#include "buffer.hh" #include "buffer.hh"
#include "filter_group.hh" #include "filter_group.hh"
@ -136,11 +135,11 @@ void register_filters()
{ {
FilterRegistry& registry = FilterRegistry::instance(); FilterRegistry& registry = FilterRegistry::instance();
registry.register_factory("preserve_indent", SimpleFilterFactory<preserve_indent>("preserve_indent")); registry.register_func("preserve_indent", SimpleFilterFactory<preserve_indent>("preserve_indent"));
registry.register_factory("cleanup_whitespaces", SimpleFilterFactory<cleanup_whitespaces>("cleanup_whitespaces")); registry.register_func("cleanup_whitespaces", SimpleFilterFactory<cleanup_whitespaces>("cleanup_whitespaces"));
registry.register_factory("expand_tabulations", SimpleFilterFactory<expand_tabulations>("expand_tabulations")); registry.register_func("expand_tabulations", SimpleFilterFactory<expand_tabulations>("expand_tabulations"));
registry.register_factory("regex", regex_filter_factory); registry.register_func("regex", regex_filter_factory);
registry.register_factory("group", filter_group_factory); registry.register_func("group", filter_group_factory);
} }
} }

View File

@ -1,6 +1,8 @@
#ifndef filters_hh_INCLUDED #ifndef filters_hh_INCLUDED
#define filters_hh_INCLUDED #define filters_hh_INCLUDED
#include "filter.hh"
namespace Kakoune namespace Kakoune
{ {

46
src/function_registry.hh Normal file
View File

@ -0,0 +1,46 @@
#ifndef function_registry_h_INCLUDED
#define function_registry_h_INCLUDED
#include "string.hh"
#include "completion.hh"
#include "idvaluemap.hh"
namespace Kakoune
{
struct function_not_found : runtime_error
{
function_not_found(const String& name)
: runtime_error("'" + name + "' not found") {}
};
template<typename FunctionType>
class FunctionRegistry
{
public:
void register_func(const String& name, const FunctionType& function)
{
assert(not m_functions.contains(name));
m_functions.append(std::make_pair(name, function));
}
const FunctionType& operator[](const String& name) const
{
auto it = m_functions.find(name);
if (it == m_functions.end())
throw function_not_found(name);
return it->second;
}
CandidateList complete_name(const String& prefix, ByteCount cursor_pos)
{
return m_functions.complete_id(prefix, cursor_pos);
}
private:
idvaluemap<String, FunctionType> m_functions;
};
}
#endif // function_registry_h_INCLUDED

View File

@ -1,14 +1,18 @@
#ifndef highlighter_hh_INCLUDED #ifndef highlighter_hh_INCLUDED
#define highlighter_hh_INCLUDED #define highlighter_hh_INCLUDED
#include "string.hh"
#include <functional> #include <functional>
#include "string.hh"
#include "utils.hh"
#include "memoryview.hh" #include "memoryview.hh"
#include "function_registry.hh"
namespace Kakoune namespace Kakoune
{ {
class DisplayBuffer; class DisplayBuffer;
class Window;
// An Highlighter is a function which mutates a DisplayBuffer in order to // An Highlighter is a function which mutates a DisplayBuffer in order to
// change the visual representation of a file. It could be changing text // change the visual representation of a file. It could be changing text
@ -19,6 +23,12 @@ typedef std::function<void (DisplayBuffer& display_buffer)> HighlighterFunc;
typedef std::pair<String, HighlighterFunc> HighlighterAndId; typedef std::pair<String, HighlighterFunc> HighlighterAndId;
typedef memoryview<String> HighlighterParameters; typedef memoryview<String> HighlighterParameters;
using HighlighterFactory = std::function<HighlighterAndId (Window& window,
const HighlighterParameters& params)>;
struct HighlighterRegistry : FunctionRegistry<HighlighterFactory>,
Singleton<HighlighterRegistry>
{};
} }

View File

@ -1,41 +0,0 @@
#include "highlighter_registry.hh"
#include "exception.hh"
#include "window.hh"
#include "highlighters.hh"
namespace Kakoune
{
struct factory_not_found : public runtime_error
{
factory_not_found(const String& name)
: runtime_error("highlighter factory not found '" + name + "'") {}
};
void HighlighterRegistry::register_factory(const String& name,
const HighlighterFactory& factory)
{
assert(not m_factories.contains(name));
m_factories.append(std::make_pair(name, factory));
}
void HighlighterRegistry::add_highlighter_to_group(Window& window,
HighlighterGroup& group,
const String& name,
const HighlighterParameters& parameters)
{
auto it = m_factories.find(name);
if (it == m_factories.end())
throw factory_not_found(name);
group.append(it->second(window, parameters));
}
CandidateList HighlighterRegistry::complete_highlighter(const String& prefix,
ByteCount cursor_pos)
{
return m_factories.complete_id(prefix, cursor_pos);
}
}

View File

@ -1,41 +0,0 @@
#ifndef highlighter_registry_h_INCLUDED
#define highlighter_registry_h_INCLUDED
#include "string.hh"
#include <unordered_map>
#include "highlighter.hh"
#include "utils.hh"
#include "completion.hh"
#include "idvaluemap.hh"
namespace Kakoune
{
class Window;
class HighlighterGroup;
typedef std::function<HighlighterAndId (Window& window,
const HighlighterParameters& params)> HighlighterFactory;
class HighlighterRegistry : public Singleton<HighlighterRegistry>
{
public:
void register_factory(const String& name,
const HighlighterFactory& factory);
void add_highlighter_to_group(Window& window,
HighlighterGroup& group,
const String& factory_name,
const HighlighterParameters& parameters);
CandidateList complete_highlighter(const String& prefix,
ByteCount cursor_pos);
private:
idvaluemap<String, HighlighterFactory> m_factories;
};
}
#endif // highlighter_registry_h_INCLUDED

View File

@ -1,7 +1,6 @@
#include "highlighters.hh" #include "highlighters.hh"
#include "assert.hh" #include "assert.hh"
#include "window.hh" #include "window.hh"
#include "highlighter_registry.hh"
#include "color_registry.hh" #include "color_registry.hh"
#include "highlighter_group.hh" #include "highlighter_group.hh"
#include "string.hh" #include "string.hh"
@ -272,11 +271,11 @@ void register_highlighters()
{ {
HighlighterRegistry& registry = HighlighterRegistry::instance(); HighlighterRegistry& registry = HighlighterRegistry::instance();
registry.register_factory("highlight_selections", WindowHighlighterFactory<highlight_selections>("highlight_selections")); registry.register_func("highlight_selections", WindowHighlighterFactory<highlight_selections>("highlight_selections"));
registry.register_factory("expand_tabs", WindowHighlighterFactory<expand_tabulations>("expand_tabs")); registry.register_func("expand_tabs", WindowHighlighterFactory<expand_tabulations>("expand_tabs"));
registry.register_factory("number_lines", WindowHighlighterFactory<show_line_numbers>("number_lines")); registry.register_func("number_lines", WindowHighlighterFactory<show_line_numbers>("number_lines"));
registry.register_factory("regex", colorize_regex_factory); registry.register_func("regex", colorize_regex_factory);
registry.register_factory("group", highlighter_group_factory); registry.register_func("group", highlighter_group_factory);
} }
} }

View File

@ -1,6 +1,8 @@
#ifndef highlighters_hh_INCLUDED #ifndef highlighters_hh_INCLUDED
#define highlighters_hh_INCLUDED #define highlighters_hh_INCLUDED
#include "highlighter.hh"
namespace Kakoune namespace Kakoune
{ {

View File

@ -9,9 +9,7 @@
#include "assert.hh" #include "assert.hh"
#include "debug.hh" #include "debug.hh"
#include "highlighters.hh" #include "highlighters.hh"
#include "highlighter_registry.hh"
#include "filters.hh" #include "filters.hh"
#include "filter_registry.hh"
#include "hook_manager.hh" #include "hook_manager.hh"
#include "option_manager.hh" #include "option_manager.hh"
#include "event_manager.hh" #include "event_manager.hh"

View File

@ -1,7 +1,7 @@
#include "window.hh" #include "window.hh"
#include "assert.hh" #include "assert.hh"
#include "highlighter_registry.hh" #include "highlighter.hh"
#include "hook_manager.hh" #include "hook_manager.hh"
#include "context.hh" #include "context.hh"
@ -21,8 +21,8 @@ Window::Window(Buffer& buffer)
m_hooks.run_hook("WinCreate", buffer.name(), Context(*this)); m_hooks.run_hook("WinCreate", buffer.name(), Context(*this));
m_options.register_watcher(*this); m_options.register_watcher(*this);
registry.add_highlighter_to_group(*this, m_highlighters, "expand_tabs", HighlighterParameters()); m_highlighters.append(registry["expand_tabs"](*this, {}));
registry.add_highlighter_to_group(*this, m_highlighters, "highlight_selections", HighlighterParameters()); m_highlighters.append(registry["highlight_selections"](*this, {}));
for (auto& option : m_options.flatten_options()) for (auto& option : m_options.flatten_options())
on_option_changed(option.first, option.second); on_option_changed(option.first, option.second);