From 5cbded8221b5be8b1842de6841ce161b0b7bf4a8 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 3 Jul 2012 23:23:07 +0200 Subject: [PATCH] make display buffers and highlighters handle better longer than display lines still work in progress, I think the whole display system will in fact need a rewrite. --- src/display_buffer.cc | 22 ++++++++++++++++++---- src/display_buffer.hh | 42 +++++++++++++++++++++--------------------- src/highlighters.cc | 23 ++++++++++++----------- src/window.cc | 22 +++++++++++++++------- 4 files changed, 66 insertions(+), 43 deletions(-) diff --git a/src/display_buffer.cc b/src/display_buffer.cc index 11913e76..6aaa0843 100644 --- a/src/display_buffer.cc +++ b/src/display_buffer.cc @@ -95,10 +95,20 @@ DisplayBuffer::DisplayBuffer() { } -DisplayBuffer::iterator DisplayBuffer::insert(iterator where, const DisplayAtom& atom) +DisplayBuffer::iterator DisplayBuffer::append(BufferIterator begin, BufferIterator end) { - iterator res = m_atoms.insert(where, atom); - // check_invariant(); + DisplayCoord coord; + if (not m_atoms.empty()) + coord = m_atoms.back().end_coord(); + m_atoms.push_back(DisplayAtom(std::move(coord), std::move(begin), std::move(end))); + return --(this->end()); +} + +DisplayBuffer::iterator DisplayBuffer::insert_empty_atom_before(iterator where) +{ + assert(where != end()); + iterator res = m_atoms.insert( + where, DisplayAtom(where->coord(), where->begin(), where->begin())); return res; } @@ -124,6 +134,7 @@ DisplayBuffer::iterator DisplayBuffer::atom_containing(const BufferIterator& whe DisplayBuffer::iterator DisplayBuffer::split(iterator atom, const BufferIterator& pos) { + assert(atom->splitable()); assert(pos > atom->begin()); assert(pos < atom->end()); @@ -136,7 +147,7 @@ DisplayBuffer::iterator DisplayBuffer::split(iterator atom, const BufferIterator iterator insert_pos = atom; ++insert_pos; m_atoms.insert(insert_pos, std::move(new_atom)); - // check_invariant(); + check_invariant(); return atom; } @@ -147,7 +158,10 @@ void DisplayBuffer::check_invariant() const { assert(it->end() >= it->begin()); if (it != begin()) + { assert(prev_it->end() == it->begin()); + assert(prev_it->end_coord() == it->coord()); + } prev_it = it; } } diff --git a/src/display_buffer.hh b/src/display_buffer.hh index 89561bde..deb31f04 100644 --- a/src/display_buffer.hh +++ b/src/display_buffer.hh @@ -52,19 +52,6 @@ enum class Color // text stored in the replacement_string field. struct DisplayAtom { - DisplayAtom(const DisplayCoord& coord, - const BufferIterator& begin, const BufferIterator& end, - Color fg_color = Color::Default, - Color bg_color = Color::Default, - Attribute attribute = Attributes::Normal) - : m_content_mode(BufferText), - m_coord(coord), - m_begin(begin), m_end(end), - m_fg_color(fg_color), - m_bg_color(bg_color), - m_attribute(attribute) - {} - const DisplayCoord& coord() const { return m_coord; } const BufferIterator& begin() const { return m_begin; } const BufferIterator& end() const { return m_end; } @@ -72,6 +59,12 @@ struct DisplayAtom const Color& bg_color() const { return m_bg_color; } const Attribute& attribute() const { return m_attribute; } + enum ContentMode + { + BufferText, + ReplacementText + }; + ContentMode content_mode() const { return m_content_mode; } Color& fg_color() { return m_fg_color; } Color& bg_color() { return m_bg_color; } @@ -82,16 +75,23 @@ struct DisplayAtom BufferIterator iterator_at(const DisplayCoord& coord) const; DisplayCoord line_and_column_at(const BufferIterator& iterator) const; - bool splitable() const { return m_replacement_text.empty(); } + bool splitable() const { return m_content_mode != ReplacementText; } private: friend class DisplayBuffer; + DisplayAtom(DisplayCoord coord, + BufferIterator begin, BufferIterator end, + Color fg_color = Color::Default, + Color bg_color = Color::Default, + Attribute attribute = Attributes::Normal) + : m_content_mode(BufferText), + m_coord(std::move(coord)), + m_begin(std::move(begin)), m_end(std::move(end)), + m_fg_color(fg_color), + m_bg_color(bg_color), + m_attribute(attribute) + {} - enum ContentMode - { - BufferText, - ReplacementText - }; ContentMode m_content_mode; DisplayCoord m_coord; @@ -117,8 +117,8 @@ public: DisplayBuffer(); void clear() { m_atoms.clear(); } - void append(const DisplayAtom& atom) { m_atoms.push_back(atom); } - iterator insert(iterator where, const DisplayAtom& atom); + iterator append(BufferIterator begin, BufferIterator end); + iterator insert_empty_atom_before(iterator where); iterator split(iterator atom, const BufferIterator& pos); void replace_atom_content(iterator atom, const String& replacement); diff --git a/src/highlighters.cc b/src/highlighters.cc index 72c633bd..e59315ef 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -43,15 +43,18 @@ void colorize_regex_range(DisplayBuffer& display_buffer, auto begin_atom_it = display_buffer.atom_containing(begin, atom_it); assert(begin_atom_it != display_buffer.end()); if (begin_atom_it->begin() != begin) - begin_atom_it = ++display_buffer.split(begin_atom_it, begin); + { + if (begin_atom_it->splitable()) + begin_atom_it = ++display_buffer.split(begin_atom_it, begin); + else + ++begin_atom_it; + } auto end_atom_it = display_buffer.atom_containing(end, begin_atom_it); if (end_atom_it != display_buffer.end() and - end_atom_it->begin() != end) + end_atom_it->begin() != end and end_atom_it->splitable()) end_atom_it = ++display_buffer.split(end_atom_it, end); - assert(begin_atom_it != end_atom_it); - for (auto it = begin_atom_it; it != end_atom_it; ++it) { if (it->attribute() & Attributes::Final) @@ -169,12 +172,10 @@ void show_line_numbers(DisplayBuffer& display_buffer) atom_it = ++display_buffer.split(atom_it, line_start); } - atom_it = display_buffer.insert( - atom_it, - DisplayAtom(atom_it->coord(), - atom_it->begin(), atom_it->begin(), - Color::Black, Color::White, - Attributes::Final)); + atom_it = display_buffer.insert_empty_atom_before(atom_it); + atom_it->fg_color() = Color::Black; + atom_it->bg_color() = Color::White; + atom_it->attribute() = Attributes::Final; char buffer[10]; snprintf(buffer, 10, format, coord.line + 1); @@ -257,7 +258,7 @@ void highlight_selections(Window& window, DisplayBuffer& display_buffer) const BufferIterator& last = sel.last(); DisplayBuffer::iterator atom_it = display_buffer.atom_containing(last); - if (atom_it == display_buffer.end()) + if (atom_it == display_buffer.end() or not atom_it->splitable()) continue; if (atom_it->begin() < last) diff --git a/src/window.cc b/src/window.cc index e6fffa28..e242d508 100644 --- a/src/window.cc +++ b/src/window.cc @@ -83,13 +83,22 @@ void Window::update_display_buffer() m_display_buffer.clear(); - BufferIterator begin = buffer().iterator_at(m_position); - BufferIterator end = buffer().iterator_at(m_position + - BufferCoord(m_dimensions.line, m_dimensions.column))+2; - if (begin == end) - return; + for (auto line = 0; line < m_dimensions.line; ++line) + { + auto buffer_line = m_position.line + line; + if (buffer_line >= buffer().line_count()) + break; + BufferIterator pos = buffer().iterator_at({ buffer_line, m_position.column }); + BufferIterator line_begin = buffer().iterator_at_line_begin(pos); + BufferIterator line_end = buffer().iterator_at_line_end(pos); - m_display_buffer.append(DisplayAtom(DisplayCoord(0,0), begin, end)); + if (line_begin != pos) + { + auto atom_it = m_display_buffer.append(line_begin, pos); + m_display_buffer.replace_atom_content(atom_it, ""); + } + m_display_buffer.append(pos, line_end); + } m_highlighters(m_display_buffer); m_display_buffer.check_invariant(); @@ -141,5 +150,4 @@ void Window::on_option_changed(const String& name, const Option& option) m_hook_manager.run_hook("WinSetOption", desc, Context(*this)); } - }