From 11bc24f992244b01859ce1dc532d983d96fbb328 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 29 Apr 2013 14:20:42 +0200 Subject: [PATCH] FlagLines: use a shared updaters for options previously, having two windows showing the same buffer with the same line flags would have updated the options twice, resulting in wrong lines in option. Now line flags options are updated only once by a shared object along all FlagLines highlighter using the same option. --- src/highlighters.cc | 104 +++++++++++++++++++++++++++--------------- src/option_manager.hh | 2 +- 2 files changed, 67 insertions(+), 39 deletions(-) diff --git a/src/highlighters.cc b/src/highlighters.cc index fefee345..aef857c5 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -332,22 +332,22 @@ void expand_unprintable(DisplayBuffer& display_buffer) } } -class FlagLines : public BufferChangeListener_AutoRegister, - public OptionManagerWatcher_AutoRegister +class FlagLines : public OptionManagerWatcher_AutoRegister { public: FlagLines(Color bg, String option_name, Window& window) - : BufferChangeListener_AutoRegister(window.buffer()), - OptionManagerWatcher_AutoRegister(window.options()), + : OptionManagerWatcher_AutoRegister(window.options()), m_bg(bg), m_option_name(std::move(option_name)), m_window(window) { // trigger an exception if option is not of right type. m_window.options()[m_option_name].get>(); + update_shared_option_updater(); } void operator()(DisplayBuffer& display_buffer) { + update_shared_option_updater(); auto& lines = m_window.options()[m_option_name].get>(); CharCount width = 0; @@ -366,54 +366,82 @@ public: } } - void on_option_changed(const Option& option) +private: + void on_option_changed(const Option& option) override { if (option.name() == m_option_name) m_window.forget_timestamp(); } - void on_insert(const BufferIterator& begin, const BufferIterator& end) override + struct OptionUpdater : BufferChangeListener_AutoRegister { - LineCount new_lines = end.line() - begin.line(); - if (new_lines == 0) - return; - - const Option& opt = m_window.options()[m_option_name]; - if (&opt.manager() == &GlobalOptions::instance()) - return; - auto lines = opt.get>(); - for (auto& line : lines) + OptionUpdater(Buffer& buffer, Option& option) + : BufferChangeListener_AutoRegister(buffer), m_option(&option) { - if (std::get<0>(line) > begin.line()) - std::get<0>(line) += new_lines; + // sanity checks + kak_assert(&m_option->manager() != &GlobalOptions::instance()); + m_option->get>(); } - opt.manager().get_local_option(m_option_name).set(lines); + + void on_insert(const BufferIterator& begin, const BufferIterator& end) override + { + LineCount new_lines = end.line() - begin.line(); + if (new_lines == 0) + return; + + auto lines = m_option->get>(); + for (auto& line : lines) + { + if (std::get<0>(line) > begin.line()) + std::get<0>(line) += new_lines; + } + m_option->set(lines); + } + + void on_erase(const BufferIterator& begin, const BufferIterator& end) override + { + LineCount removed_lines = end.line() - begin.line(); + if (removed_lines == 0) + return; + + auto lines = m_option->get>(); + for (auto& line : lines) + { + if (std::get<0>(line) > begin.line()) + std::get<0>(line) -= removed_lines; + } + m_option->set(lines); + } + + const Option& option() const { return *m_option; } + private: + safe_ptr