diff --git a/src/filter_registry.cc b/src/filter_registry.cc index 208adaa35..c9f9149ae 100644 --- a/src/filter_registry.cc +++ b/src/filter_registry.cc @@ -1,6 +1,7 @@ #include "filter_registry.hh" #include "exception.hh" +#include "window.hh" namespace Kakoune { @@ -17,14 +18,15 @@ void FilterRegistry::register_factory(const std::string& name, m_factories[name] = factory; } -FilterAndId FilterRegistry::get_filter(const std::string& name, - const FilterParameters& parameters) +void FilterRegistry::add_filter_to_window(Window& window, + const std::string& name, + const FilterParameters& parameters) { auto it = m_factories.find(name); if (it == m_factories.end()) throw factory_not_found(); - return it->second(parameters); + window.add_filter(it->second(window, parameters)); } } diff --git a/src/filter_registry.hh b/src/filter_registry.hh index 09b1fec2a..fef04822c 100644 --- a/src/filter_registry.hh +++ b/src/filter_registry.hh @@ -10,9 +10,12 @@ namespace Kakoune { +class Window; + typedef std::vector FilterParameters; -typedef std::function FilterFactory; +typedef std::function FilterFactory; class FilterRegistry : public Singleton { @@ -20,8 +23,9 @@ public: void register_factory(const std::string& name, const FilterFactory& factory); - FilterAndId get_filter(const std::string& factory_name, - const FilterParameters& parameters); + void add_filter_to_window(Window& window, + const std::string& factory_name, + const FilterParameters& parameters); private: std::unordered_map m_factories; diff --git a/src/filters.cc b/src/filters.cc index 6d9e99fbe..130a9066a 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -1,5 +1,6 @@ #include "filters.hh" +#include "window.hh" #include "display_buffer.hh" #include "filter_registry.hh" #include @@ -139,7 +140,8 @@ class SimpleFilterFactory public: 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)); } @@ -147,12 +149,89 @@ private: 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() { FilterRegistry& registry = FilterRegistry::instance(); + registry.register_factory("highlight_selections", SelectionsHighlighter::create); registry.register_factory("expand_tabs", SimpleFilterFactory("expand_tabs")); - registry.register_factory("line_numbers", SimpleFilterFactory("line_numbers")); + registry.register_factory("number_lines", SimpleFilterFactory("number_lines")); registry.register_factory("hlcpp", SimpleFilterFactory("hlcpp")); } diff --git a/src/main.cc b/src/main.cc index 81442cd45..5b6c4351d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -441,8 +441,8 @@ void add_filter(const CommandParameters& params) { FilterRegistry& registry = FilterRegistry::instance(); FilterParameters filter_params(params.begin()+1, params.end()); - FilterAndId filter_and_id = registry.get_filter(params[0], filter_params); - current_window->add_filter(std::move(filter_and_id)); + registry.add_filter_to_window(*current_window, params[0], + filter_params); } catch (runtime_error& err) { diff --git a/src/window.cc b/src/window.cc index 4b0fdd5f6..c0ecdc28e 100644 --- a/src/window.cc +++ b/src/window.cc @@ -38,75 +38,6 @@ private: 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) : m_buffer(buffer), m_position(0, 0), @@ -116,9 +47,9 @@ Window::Window(Buffer& buffer) m_selections.push_back(Selection(buffer.begin(), buffer.begin())); FilterRegistry& registry = FilterRegistry::instance(); - add_filter(registry.get_filter("expand_tabs", FilterParameters())); - add_filter(FilterAndId("show_selections", HighlightSelections(*this))); - add_filter(registry.get_filter("hlcpp", FilterParameters())); + registry.add_filter_to_window(*this, "expand_tabs", FilterParameters()); + registry.add_filter_to_window(*this, "highlight_selections", FilterParameters()); + registry.add_filter_to_window(*this, "hlcpp", FilterParameters()); } void Window::check_invariant() const diff --git a/src/window.hh b/src/window.hh index 12003c6aa..9d0de6099 100644 --- a/src/window.hh +++ b/src/window.hh @@ -58,6 +58,7 @@ public: void clear_selections(); void select(const Selector& selector, bool append = false); BufferString selection_content() const; + const SelectionList selections() const { return m_selections; } void set_dimensions(const DisplayCoord& dimensions); @@ -95,8 +96,6 @@ private: friend class IncrementalInserter; IncrementalInserter* m_current_inserter; - friend class HighlightSelections; - Buffer& m_buffer; BufferCoord m_position; DisplayCoord m_dimensions;