Filters: refactoring

This commit is contained in:
Maxime Coste 2011-11-09 23:56:22 +00:00
parent 5aeee719dd
commit f12929abad
6 changed files with 99 additions and 84 deletions

View File

@ -1,6 +1,7 @@
#include "filter_registry.hh" #include "filter_registry.hh"
#include "exception.hh" #include "exception.hh"
#include "window.hh"
namespace Kakoune namespace Kakoune
{ {
@ -17,14 +18,15 @@ void FilterRegistry::register_factory(const std::string& name,
m_factories[name] = factory; m_factories[name] = factory;
} }
FilterAndId FilterRegistry::get_filter(const std::string& name, void FilterRegistry::add_filter_to_window(Window& window,
const FilterParameters& parameters) const std::string& name,
const FilterParameters& parameters)
{ {
auto it = m_factories.find(name); auto it = m_factories.find(name);
if (it == m_factories.end()) if (it == m_factories.end())
throw factory_not_found(); throw factory_not_found();
return it->second(parameters); window.add_filter(it->second(window, parameters));
} }
} }

View File

@ -10,9 +10,12 @@
namespace Kakoune namespace Kakoune
{ {
class Window;
typedef std::vector<std::string> FilterParameters; typedef std::vector<std::string> FilterParameters;
typedef std::function<FilterAndId (const FilterParameters& params)> FilterFactory; typedef std::function<FilterAndId (Window& window,
const FilterParameters& params)> FilterFactory;
class FilterRegistry : public Singleton<FilterRegistry> class FilterRegistry : public Singleton<FilterRegistry>
{ {
@ -20,8 +23,9 @@ public:
void register_factory(const std::string& name, void register_factory(const std::string& name,
const FilterFactory& factory); const FilterFactory& factory);
FilterAndId get_filter(const std::string& factory_name, void add_filter_to_window(Window& window,
const FilterParameters& parameters); const std::string& factory_name,
const FilterParameters& parameters);
private: private:
std::unordered_map<std::string, FilterFactory> m_factories; std::unordered_map<std::string, FilterFactory> m_factories;

View File

@ -1,5 +1,6 @@
#include "filters.hh" #include "filters.hh"
#include "window.hh"
#include "display_buffer.hh" #include "display_buffer.hh"
#include "filter_registry.hh" #include "filter_registry.hh"
#include <boost/regex.hpp> #include <boost/regex.hpp>
@ -139,7 +140,8 @@ class SimpleFilterFactory
public: public:
SimpleFilterFactory(const std::string& id) : m_id(id) {} SimpleFilterFactory(const std::string& id) : m_id(id) {}
FilterAndId operator()(const FilterParameters& params) const FilterAndId operator()(Window& window,
const FilterParameters& params) const
{ {
return FilterAndId(m_id, FilterFunc(filter_func)); return FilterAndId(m_id, FilterFunc(filter_func));
} }
@ -147,12 +149,89 @@ private:
std::string m_id; std::string m_id;
}; };
class SelectionsHighlighter
{
public:
SelectionsHighlighter(Window& window)
: m_window(window)
{
}
void operator()(DisplayBuffer& display_buffer)
{
SelectionList sorted_selections = m_window.selections();
std::sort(sorted_selections.begin(), sorted_selections.end(),
[](const Selection& lhs, const Selection& rhs) { return lhs.begin() < rhs.begin(); });
auto atom_it = display_buffer.begin();
auto sel_it = sorted_selections.begin();
while (atom_it != display_buffer.end()
and sel_it != sorted_selections.end())
{
Selection& sel = *sel_it;
DisplayAtom& atom = *atom_it;
// [###------]
if (atom.begin() >= sel.begin() and atom.begin() < sel.end() and atom.end() > sel.end())
{
atom_it = display_buffer.split(atom_it, sel.end());
atom_it->attribute() |= Attributes::Underline;
++atom_it;
++sel_it;
}
// [---###---]
else if (atom.begin() < sel.begin() and atom.end() > sel.end())
{
atom_it = display_buffer.split(atom_it, sel.begin());
atom_it = display_buffer.split(++atom_it, sel.end());
atom_it->attribute() |= Attributes::Underline;
++atom_it;
++sel_it;
}
// [------###]
else if (atom.begin() < sel.begin() and atom.end() > sel.begin())
{
atom_it = ++display_buffer.split(atom_it, sel.begin());
atom_it->attribute() |= Attributes::Underline;
++atom_it;
}
// [#########]
else if (atom.begin() >= sel.begin() and atom.end() <= sel.end())
{
atom_it->attribute() |= Attributes::Underline;
++atom_it;
}
// [---------]
else if (atom.begin() >= sel.end())
++sel_it;
// [---------]
else if (atom.end() <= sel.begin())
++atom_it;
else
assert(false);
}
}
static FilterAndId create(Window& window,
const FilterParameters& params)
{
return FilterAndId("highlight_selections",
SelectionsHighlighter(window));
}
private:
const Window& m_window;
};
void register_filters() void register_filters()
{ {
FilterRegistry& registry = FilterRegistry::instance(); FilterRegistry& registry = FilterRegistry::instance();
registry.register_factory("highlight_selections", SelectionsHighlighter::create);
registry.register_factory("expand_tabs", SimpleFilterFactory<expand_tabulations>("expand_tabs")); registry.register_factory("expand_tabs", SimpleFilterFactory<expand_tabulations>("expand_tabs"));
registry.register_factory("line_numbers", SimpleFilterFactory<show_line_numbers>("line_numbers")); registry.register_factory("number_lines", SimpleFilterFactory<show_line_numbers>("number_lines"));
registry.register_factory("hlcpp", SimpleFilterFactory<colorize_cplusplus>("hlcpp")); registry.register_factory("hlcpp", SimpleFilterFactory<colorize_cplusplus>("hlcpp"));
} }

View File

@ -441,8 +441,8 @@ void add_filter(const CommandParameters& params)
{ {
FilterRegistry& registry = FilterRegistry::instance(); FilterRegistry& registry = FilterRegistry::instance();
FilterParameters filter_params(params.begin()+1, params.end()); FilterParameters filter_params(params.begin()+1, params.end());
FilterAndId filter_and_id = registry.get_filter(params[0], filter_params); registry.add_filter_to_window(*current_window, params[0],
current_window->add_filter(std::move(filter_and_id)); filter_params);
} }
catch (runtime_error& err) catch (runtime_error& err)
{ {

View File

@ -38,75 +38,6 @@ private:
Buffer& m_buffer; Buffer& m_buffer;
}; };
class HighlightSelections
{
public:
HighlightSelections(Window& window)
: m_window(window)
{
}
void operator()(DisplayBuffer& display_buffer)
{
SelectionList sorted_selections = m_window.m_selections;
std::sort(sorted_selections.begin(), sorted_selections.end(),
[](const Selection& lhs, const Selection& rhs) { return lhs.begin() < rhs.begin(); });
auto atom_it = display_buffer.begin();
auto sel_it = sorted_selections.begin();
while (atom_it != display_buffer.end()
and sel_it != sorted_selections.end())
{
Selection& sel = *sel_it;
DisplayAtom& atom = *atom_it;
// [###------]
if (atom.begin() >= sel.begin() and atom.begin() < sel.end() and atom.end() > sel.end())
{
atom_it = display_buffer.split(atom_it, sel.end());
atom_it->attribute() |= Attributes::Underline;
++atom_it;
++sel_it;
}
// [---###---]
else if (atom.begin() < sel.begin() and atom.end() > sel.end())
{
atom_it = display_buffer.split(atom_it, sel.begin());
atom_it = display_buffer.split(++atom_it, sel.end());
atom_it->attribute() |= Attributes::Underline;
++atom_it;
++sel_it;
}
// [------###]
else if (atom.begin() < sel.begin() and atom.end() > sel.begin())
{
atom_it = ++display_buffer.split(atom_it, sel.begin());
atom_it->attribute() |= Attributes::Underline;
++atom_it;
}
// [#########]
else if (atom.begin() >= sel.begin() and atom.end() <= sel.end())
{
atom_it->attribute() |= Attributes::Underline;
++atom_it;
}
// [---------]
else if (atom.begin() >= sel.end())
++sel_it;
// [---------]
else if (atom.end() <= sel.begin())
++atom_it;
else
assert(false);
}
}
private:
const Window& m_window;
};
Window::Window(Buffer& buffer) Window::Window(Buffer& buffer)
: m_buffer(buffer), : m_buffer(buffer),
m_position(0, 0), m_position(0, 0),
@ -116,9 +47,9 @@ Window::Window(Buffer& buffer)
m_selections.push_back(Selection(buffer.begin(), buffer.begin())); m_selections.push_back(Selection(buffer.begin(), buffer.begin()));
FilterRegistry& registry = FilterRegistry::instance(); FilterRegistry& registry = FilterRegistry::instance();
add_filter(registry.get_filter("expand_tabs", FilterParameters())); registry.add_filter_to_window(*this, "expand_tabs", FilterParameters());
add_filter(FilterAndId("show_selections", HighlightSelections(*this))); registry.add_filter_to_window(*this, "highlight_selections", FilterParameters());
add_filter(registry.get_filter("hlcpp", FilterParameters())); registry.add_filter_to_window(*this, "hlcpp", FilterParameters());
} }
void Window::check_invariant() const void Window::check_invariant() const

View File

@ -58,6 +58,7 @@ public:
void clear_selections(); void clear_selections();
void select(const Selector& selector, bool append = false); void select(const Selector& selector, bool append = false);
BufferString selection_content() const; BufferString selection_content() const;
const SelectionList selections() const { return m_selections; }
void set_dimensions(const DisplayCoord& dimensions); void set_dimensions(const DisplayCoord& dimensions);
@ -95,8 +96,6 @@ private:
friend class IncrementalInserter; friend class IncrementalInserter;
IncrementalInserter* m_current_inserter; IncrementalInserter* m_current_inserter;
friend class HighlightSelections;
Buffer& m_buffer; Buffer& m_buffer;
BufferCoord m_position; BufferCoord m_position;
DisplayCoord m_dimensions; DisplayCoord m_dimensions;