diff --git a/src/buffer.cc b/src/buffer.cc index 08c27796..fb0d0e82 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -218,9 +218,6 @@ void Buffer::apply_modification(const Modification& modification) void Buffer::modify(Modification&& modification) { - for (auto filter : m_filters) - filter.second(*this, modification); - apply_modification(modification); m_current_undo_group.push_back(std::move(modification)); } @@ -271,22 +268,4 @@ void Buffer::unregister_modification_listener(ModificationListener* listener) m_modification_listeners.erase(it); } -void Buffer::add_filter(FilterAndId&& filter) -{ - if (m_filters.contains(filter.first)) - throw filter_id_not_unique(filter.first); - m_filters.append(filter); -} - -void Buffer::remove_filter(const std::string& id) -{ - m_filters.remove(id); -} - -CandidateList Buffer::complete_filterid(const std::string& prefix, - size_t cursor_pos) -{ - return m_filters.complete_id(prefix, cursor_pos); -} - } diff --git a/src/buffer.hh b/src/buffer.hh index eb4c5c67..dfa34c2d 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -7,10 +7,6 @@ #include #include "line_and_column.hh" -#include "filter.hh" -#include "exception.hh" -#include "completion.hh" -#include "idvaluemap.hh" namespace Kakoune { @@ -154,18 +150,6 @@ public: void register_modification_listener(ModificationListener* listener); void unregister_modification_listener(ModificationListener* listener); - struct filter_id_not_unique : public runtime_error - { - filter_id_not_unique(const std::string& id) - : runtime_error("filter id not unique: " + id) {} - }; - - void add_filter(FilterAndId&& filter); - void remove_filter(const std::string& id); - - CandidateList complete_filterid(const std::string& prefix, - size_t cursor_pos = std::string::npos); - // returns an iterator pointing to the first character of the line // iterator is on BufferIterator iterator_at_line_begin(const BufferIterator& iterator) const; @@ -205,8 +189,6 @@ private: size_t m_last_save_undo_index; std::vector m_modification_listeners; - - idvaluemap m_filters; }; inline Modification Modification::make_erase(BufferIterator begin, diff --git a/src/filter_registry.cc b/src/filter_registry.cc index c931b567..45e565f5 100644 --- a/src/filter_registry.cc +++ b/src/filter_registry.cc @@ -1,7 +1,7 @@ #include "filter_registry.hh" #include "exception.hh" -#include "buffer.hh" +#include "window.hh" namespace Kakoune { @@ -19,7 +19,7 @@ void FilterRegistry::register_factory(const std::string& name, m_factories.append(std::make_pair(name, factory)); } -void FilterRegistry::add_filter_to_buffer(Buffer& buffer, +void FilterRegistry::add_filter_to_window(Window& window, const std::string& name, const FilterParameters& parameters) { @@ -27,7 +27,7 @@ void FilterRegistry::add_filter_to_buffer(Buffer& buffer, if (it == m_factories.end()) throw factory_not_found(name); - buffer.add_filter(it->second(buffer, parameters)); + window.add_filter(it->second(window, parameters)); } CandidateList FilterRegistry::complete_filter(const std::string& prefix, diff --git a/src/filter_registry.hh b/src/filter_registry.hh index 4fbb8df7..b00cc19c 100644 --- a/src/filter_registry.hh +++ b/src/filter_registry.hh @@ -16,7 +16,7 @@ class Window; typedef std::vector FilterParameters; -typedef std::function FilterFactory; class FilterRegistry : public Singleton @@ -25,7 +25,7 @@ public: void register_factory(const std::string& name, const FilterFactory& factory); - void add_filter_to_buffer(Buffer& window, + void add_filter_to_window(Window& window, const std::string& factory_name, const FilterParameters& parameters); diff --git a/src/filters.cc b/src/filters.cc index 947725cb..42fa50c7 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -49,7 +49,7 @@ class SimpleFilterFactory public: SimpleFilterFactory(const std::string& id) : m_id(id) {} - FilterAndId operator()(Buffer& buffer, + FilterAndId operator()(Window& window, const FilterParameters& params) const { return FilterAndId(m_id, FilterFunc(filter_func)); diff --git a/src/kakrc b/src/kakrc index a8e9a766..cd65ca56 100644 --- a/src/kakrc +++ b/src/kakrc @@ -1,3 +1,3 @@ hook WinCreate .*\.(c|cc|cpp|cxx|C|h|hh|hpp|hxx|H) addhl hlcpp -hook BufCreate .*\.(c|cc|cpp|cxx|C|h|hh|hpp|hxx|H) addfilter preserve_indent +hook WinCreate .*\.(c|cc|cpp|cxx|C|h|hh|hpp|hxx|H) addfilter preserve_indent hook WinCreate .* addhl regex \h+(?=\n) default red diff --git a/src/main.cc b/src/main.cc index 8737db1e..415d9ffb 100644 --- a/src/main.cc +++ b/src/main.cc @@ -499,7 +499,7 @@ void add_filter(const CommandParameters& params, const Context& context) { FilterRegistry& registry = FilterRegistry::instance(); FilterParameters filter_params(params.begin()+1, params.end()); - registry.add_filter_to_buffer(*context.buffer, params[0], + registry.add_filter_to_window(*context.window, params[0], filter_params); } catch (runtime_error& err) @@ -513,7 +513,7 @@ void rm_filter(const CommandParameters& params, const Context& context) if (params.size() != 1) throw wrong_argument_count(); - context.buffer->remove_filter(params[0]); + context.window->remove_filter(params[0]); } void add_hook(const CommandParameters& params, const Context& context) @@ -770,7 +770,7 @@ int main(int argc, char* argv[]) command_manager.register_command(std::vector{ "rf", "rmfilter" }, rm_filter, PerArgumentCommandCompleter { [&](const std::string& prefix, size_t cursor_pos) - { return main_context.buffer->complete_filterid(prefix, cursor_pos); } + { return main_context.window->complete_filterid(prefix, cursor_pos); } }); command_manager.register_command(std::vector{ "hook" }, add_hook); diff --git a/src/window.cc b/src/window.cc index 0cf0fbef..fc1a6e41 100644 --- a/src/window.cc +++ b/src/window.cc @@ -353,7 +353,7 @@ std::string Window::status_line() const void Window::add_highlighter(HighlighterAndId&& highlighter) { if (m_highlighters.contains(highlighter.first)) - throw highlighter_id_not_unique(highlighter.first); + throw id_not_unique(highlighter.first); m_highlighters.append(highlighter); } @@ -368,6 +368,24 @@ CandidateList Window::complete_highlighterid(const std::string& prefix, return m_highlighters.complete_id(prefix, cursor_pos); } +void Window::add_filter(FilterAndId&& filter) +{ + if (m_filters.contains(filter.first)) + throw id_not_unique(filter.first); + m_filters.append(filter); +} + +void Window::remove_filter(const std::string& id) +{ + m_filters.remove(id); +} + +CandidateList Window::complete_filterid(const std::string& prefix, + size_t cursor_pos) +{ + return m_filters.complete_id(prefix, cursor_pos); +} + IncrementalInserter::IncrementalInserter(Window& window, Mode mode) : m_window(window) @@ -394,14 +412,14 @@ IncrementalInserter::IncrementalInserter(Window& window, Mode mode) case Mode::AppendAtLineEnd: pos = m_window.m_buffer.iterator_at_line_end(sel.end() - 1) - 1; if (mode == Mode::OpenLineBelow) - window.m_buffer.modify(Modification::make_insert(pos, "\n")); + apply(Modification::make_insert(pos, "\n")); break; case Mode::OpenLineAbove: case Mode::InsertAtLineBegin: pos = m_window.m_buffer.iterator_at_line_begin(sel.begin()); if (mode == Mode::OpenLineAbove) - window.m_buffer.modify(Modification::make_insert(--pos, "\n")); + apply(Modification::make_insert(--pos, "\n")); break; } sel = Selection(pos, pos, sel.captures()); @@ -417,9 +435,18 @@ IncrementalInserter::~IncrementalInserter() m_window.m_buffer.end_undo_group(); } +void IncrementalInserter::apply(Modification&& modification) const +{ + for (auto filter : m_window.m_filters) + filter.second(m_window.buffer(), modification); + m_window.buffer().modify(std::move(modification)); +} + + void IncrementalInserter::insert(const Window::String& string) { - m_window.insert_noundo(string); + for (auto& sel : m_window.m_selections) + apply(Modification::make_insert(sel.begin(), string)); } void IncrementalInserter::insert_capture(size_t index) @@ -433,8 +460,11 @@ void IncrementalInserter::insert_capture(size_t index) void IncrementalInserter::erase() { for (auto& sel : m_window.m_selections) + { sel = Selection(sel.first() - 1, sel.last() - 1); - m_window.erase_noundo(); + apply(Modification::make_erase(sel.begin(), sel.end())); + } + m_window.scroll_to_keep_cursor_visible_ifn(); } diff --git a/src/window.hh b/src/window.hh index fa64d59b..0513daa0 100644 --- a/src/window.hh +++ b/src/window.hh @@ -8,6 +8,7 @@ #include "display_buffer.hh" #include "completion.hh" #include "highlighter.hh" +#include "filter.hh" #include "idvaluemap.hh" namespace Kakoune @@ -88,10 +89,10 @@ public: std::string status_line() const; - struct highlighter_id_not_unique : public runtime_error + struct id_not_unique : public runtime_error { - highlighter_id_not_unique(const std::string& id) - : runtime_error("highlighter id not unique: " + id) {} + id_not_unique(const std::string& id) + : runtime_error("id not unique: " + id) {} }; void add_highlighter(HighlighterAndId&& highlighter); @@ -100,6 +101,13 @@ public: CandidateList complete_highlighterid(const std::string& prefix, size_t cursor_pos = std::string::npos); + void add_filter(FilterAndId&& filter); + void remove_filter(const std::string& id); + + CandidateList complete_filterid(const std::string& prefix, + size_t cursor_pos = std::string::npos); + + private: friend class Buffer; @@ -123,6 +131,7 @@ private: DisplayBuffer m_display_buffer; idvaluemap m_highlighters; + idvaluemap m_filters; }; class IncrementalInserter @@ -148,7 +157,9 @@ public: void move_cursor(const DisplayCoord& offset); private: - Window& m_window; + void apply(Modification&& modification) const; + + Window& m_window; }; }