diff --git a/src/display_buffer.cc b/src/display_buffer.cc index 7e42c2b0..7aec9848 100644 --- a/src/display_buffer.cc +++ b/src/display_buffer.cc @@ -23,6 +23,12 @@ void AtomContent::trim_end(CharCount count) m_text = m_text.substr(0, m_text.char_length() - count); } +DisplayLine::DisplayLine(AtomList atoms) + : m_atoms(std::move(atoms)) +{ + compute_range(); +} + DisplayLine::iterator DisplayLine::split(iterator it, BufferCoord pos) { kak_assert(it->content.type() == AtomContent::BufferRange); @@ -35,6 +41,26 @@ DisplayLine::iterator DisplayLine::split(iterator it, BufferCoord pos) return m_atoms.insert(it, std::move(atom)); } +DisplayLine::iterator DisplayLine::insert(iterator it, DisplayAtom atom) +{ + if (atom.content.has_buffer_range()) + { + m_range.first = std::min(m_range.first, atom.content.begin()); + m_range.second = std::max(m_range.second, atom.content.end()); + } + return m_atoms.insert(it, std::move(atom)); +} + +void DisplayLine::push_back(DisplayAtom atom) +{ + if (atom.content.has_buffer_range()) + { + m_range.first = std::min(m_range.first, atom.content.begin()); + m_range.second = std::max(m_range.second, atom.content.end()); + } + m_atoms.push_back(std::move(atom)); +} + void DisplayLine::optimize() { if (m_atoms.empty()) @@ -112,6 +138,20 @@ void DisplayLine::trim(CharCount first_char, CharCount char_count) if (char_count < 0) (it-1)->content.trim_end(-char_count); m_atoms.erase(it, end()); + + compute_range(); +} + +void DisplayLine::compute_range() +{ + m_range = { {INT_MAX, INT_MAX}, {INT_MIN, INT_MIN} }; + for (auto& atom : m_atoms) + { + if (not atom.content.has_buffer_range()) + continue; + m_range.first = std::min(m_range.first, atom.content.begin()); + m_range.second = std::max(m_range.second, atom.content.end()); + } } void DisplayBuffer::compute_range() @@ -120,17 +160,8 @@ void DisplayBuffer::compute_range() m_range.second = {0,0}; for (auto& line : m_lines) { - for (auto& atom : line) - { - if (not atom.content.has_buffer_range()) - continue; - - if (m_range.first > atom.content.begin()) - m_range.first = atom.content.begin(); - - if (m_range.second < atom.content.end()) - m_range.second = atom.content.end(); - } + m_range.first = std::min(line.range().first, m_range.first); + m_range.second = std::max(line.range().second, m_range.second); } kak_assert(m_range.first <= m_range.second); } diff --git a/src/display_buffer.hh b/src/display_buffer.hh index 16fe2758..27fa9a08 100644 --- a/src/display_buffer.hh +++ b/src/display_buffer.hh @@ -29,8 +29,6 @@ enum Attributes Bold = 8 }; -class DisplayLine; - struct AtomContent { public: @@ -123,6 +121,8 @@ struct DisplayAtom {} }; +using BufferRange = std::pair; + class DisplayLine { public: @@ -130,13 +130,10 @@ public: using iterator = AtomList::iterator; using const_iterator = AtomList::const_iterator; - explicit DisplayLine(LineCount buffer_line) : m_buffer_line(buffer_line) {} - DisplayLine(LineCount buffer_line, AtomList atoms) - : m_buffer_line(buffer_line), m_atoms(std::move(atoms)) {} + DisplayLine() = default; + DisplayLine(AtomList atoms); DisplayLine(String str, ColorPair color) - : m_buffer_line(-1), m_atoms{ { std::move(str), color } } {} - - LineCount buffer_line() const { return m_buffer_line; } + { push_back({ std::move(str), color }); } iterator begin() { return m_atoms.begin(); } iterator end() { return m_atoms.end(); } @@ -147,12 +144,13 @@ public: const AtomList& atoms() const { return m_atoms; } CharCount length() const; + const BufferRange& range() const { return m_range; } // Split atom pointed by it at pos, returns an iterator to the first atom iterator split(iterator it, BufferCoord pos); - iterator insert(iterator it, DisplayAtom atom) { return m_atoms.insert(it, std::move(atom)); } - void push_back(DisplayAtom atom) { m_atoms.push_back(std::move(atom)); } + iterator insert(iterator it, DisplayAtom atom); + void push_back(DisplayAtom atom); // remove first_char from the begining of the line, and make sure // the line is less that char_count character @@ -160,12 +158,11 @@ public: void optimize(); private: - LineCount m_buffer_line; + void compute_range(); + BufferRange m_range = { { INT_MAX, INT_MAX }, { INT_MIN, INT_MIN } }; AtomList m_atoms; }; -using BufferRange = std::pair; - class DisplayBuffer { public: diff --git a/src/highlighters.cc b/src/highlighters.cc index 0bdd81eb..e58e5110 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -31,7 +31,8 @@ void highlight_range(DisplayBuffer& display_buffer, for (auto& line : display_buffer.lines()) { - if (line.buffer_line() < begin.line or end.line < line.buffer_line()) + auto& range = line.range(); + if (range.second <= begin or end < range.first) continue; for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it) @@ -235,7 +236,7 @@ void expand_tabulations(const Window& window, DisplayBuffer& display_buffer) atom_it = line.split(atom_it, (it+1).coord()); int column = 0; - for (auto line_it = buffer.iterator_at(line.buffer_line()); + for (auto line_it = buffer.iterator_at(it.coord().line); line_it != it; ++line_it) { kak_assert(*line_it != '\n'); @@ -270,7 +271,7 @@ void show_line_numbers(const Window& window, DisplayBuffer& display_buffer) for (auto& line : display_buffer.lines()) { char buffer[10]; - snprintf(buffer, 10, format, (int)line.buffer_line() + 1); + snprintf(buffer, 10, format, (int)line.range().first.line + 1); DisplayAtom atom = DisplayAtom(AtomContent(buffer)); atom.colors = colors; line.insert(line.begin(), std::move(atom)); @@ -358,7 +359,7 @@ public: const String empty{' ', width}; for (auto& line : display_buffer.lines()) { - int line_num = (int)line.buffer_line() + 1; + int line_num = (int)line.range().first.line + 1; auto it = find_if(lines, [&](const LineAndFlag& l) { return std::get<0>(l) == line_num; }); String content = it != lines.end() ? std::get<2>(*it) : empty; content += String(' ', width - content.char_length()); diff --git a/src/input_handler.cc b/src/input_handler.cc index 9e8610c5..bdee3b2b 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -146,12 +146,12 @@ public: { kak_assert(m_cursor_pos <= m_line.char_length()); if (m_cursor_pos == m_line.char_length()) - return DisplayLine{-1, { {m_line, get_color("StatusLine")}, - {" "_str, get_color("StatusCursor")} }}; + return DisplayLine{{ {m_line, get_color("StatusLine")}, + {" "_str, get_color("StatusCursor")} }}; else - return DisplayLine(-1, { DisplayAtom{ m_line.substr(0, m_cursor_pos), get_color("StatusLine") }, - DisplayAtom{ m_line.substr(m_cursor_pos, 1), get_color("StatusCursor") }, - DisplayAtom{ m_line.substr(m_cursor_pos+1), get_color("StatusLine") } }); + return DisplayLine({ { m_line.substr(0, m_cursor_pos), get_color("StatusLine") }, + { m_line.substr(m_cursor_pos, 1), get_color("StatusCursor") }, + { m_line.substr(m_cursor_pos+1), get_color("StatusLine") } }); } private: CharCount m_cursor_pos = 0; @@ -181,7 +181,7 @@ public: if (key == Key(Key::Modifiers::Control, 'm')) { context().ui().menu_hide(); - context().ui().print_status(DisplayLine{ -1 }); + context().ui().print_status(DisplayLine{}); reset_normal_mode(); int selected = m_selected - m_choices.begin(); m_callback(selected, MenuEvent::Validate, context()); @@ -194,7 +194,7 @@ public: m_edit_filter = false; m_filter = boost::regex(".*"); m_filter_editor.reset(""); - context().ui().print_status(DisplayLine{ -1 }); + context().ui().print_status(DisplayLine{}); } else { @@ -319,7 +319,7 @@ public: history.erase(it); history.push_back(line); } - context().ui().print_status(DisplayLine{ -1 }); + context().ui().print_status(DisplayLine{}); context().ui().menu_hide(); reset_normal_mode(); // call callback after reset_normal_mode so that callback @@ -329,7 +329,7 @@ public: } else if (key == Key::Escape or key == Key { Key::Modifiers::Control, 'c' }) { - context().ui().print_status(DisplayLine{ -1 }); + context().ui().print_status(DisplayLine{}); context().ui().menu_hide(); reset_normal_mode(); m_callback(line, PromptEvent::Abort, context()); diff --git a/src/ncurses.cc b/src/ncurses.cc index c4e2ffd7..21175d19 100644 --- a/src/ncurses.cc +++ b/src/ncurses.cc @@ -142,8 +142,7 @@ void on_sigint(int) } NCursesUI::NCursesUI() - : m_stdin_watcher{0, [this](FDWatcher&){ if (m_input_callback) m_input_callback(); }}, - m_status_line{-1} + : m_stdin_watcher{0, [this](FDWatcher&){ if (m_input_callback) m_input_callback(); }} { initscr(); cbreak(); diff --git a/src/remote.cc b/src/remote.cc index d25ace62..a015e143 100644 --- a/src/remote.cc +++ b/src/remote.cc @@ -194,7 +194,7 @@ DisplayAtom read(int socket) template<> DisplayLine read(int socket) { - return DisplayLine(0, read_vector(socket)); + return DisplayLine(read_vector(socket)); } template<> diff --git a/src/window.cc b/src/window.cc index 6c73e11f..b23b7deb 100644 --- a/src/window.cc +++ b/src/window.cc @@ -69,7 +69,7 @@ void Window::update_display_buffer() LineCount buffer_line = m_position.line + line; if (buffer_line >= buffer().line_count()) break; - lines.push_back(DisplayLine(buffer_line)); + lines.emplace_back(); lines.back().push_back(DisplayAtom(AtomContent(buffer(), buffer_line, buffer_line+1))); } @@ -125,7 +125,7 @@ void Window::scroll_to_keep_cursor_visible_ifn() // highlight only the line containing the cursor DisplayBuffer display_buffer; DisplayBuffer::LineList& lines = display_buffer.lines(); - lines.push_back(DisplayLine(last.line)); + lines.emplace_back(); lines.back().push_back(DisplayAtom(AtomContent(buffer(), last.line, last.line+1))); @@ -172,7 +172,6 @@ namespace CharCount find_display_column(const DisplayLine& line, const Buffer& buffer, const BufferCoord& coord) { - kak_assert(coord.line == line.buffer_line()); CharCount column = 0; for (auto& atom : line) { @@ -193,7 +192,7 @@ CharCount find_display_column(const DisplayLine& line, const Buffer& buffer, BufferCoord find_buffer_coord(const DisplayLine& line, const Buffer& buffer, CharCount column) { - LineCount l = line.buffer_line(); + auto& range = line.range(); for (auto& atom : line) { auto& content = atom.content; @@ -201,13 +200,13 @@ BufferCoord find_buffer_coord(const DisplayLine& line, const Buffer& buffer, if (content.has_buffer_range() and column < len) { if (content.type() == AtomContent::BufferRange) - return utf8::advance(buffer.iterator_at(content.begin()), buffer.iterator_at(l+1), + return utf8::advance(buffer.iterator_at(content.begin()), buffer.iterator_at(range.second), std::max(0_char, column)).coord(); return content.begin(); } column -= len; } - return buffer.clamp({l, buffer[l].length()}); + return buffer.clamp(buffer.prev(range.second)); } } @@ -216,7 +215,8 @@ DisplayCoord Window::display_position(const BufferCoord& coord) LineCount l = 0; for (auto& line : m_display_buffer.lines()) { - if (line.buffer_line() == coord.line) + auto& range = line.range(); + if (range.first <= coord and coord < range.second) return {l, find_display_column(line, buffer(), coord)}; ++l; } @@ -229,9 +229,9 @@ BufferCoord Window::offset_coord(const BufferCoord& coord, LineCount offset) DisplayBuffer display_buffer; DisplayBuffer::LineList& lines = display_buffer.lines(); { - lines.emplace_back(coord.line); + lines.emplace_back(); lines.back().push_back({AtomContent(buffer(), coord.line, coord.line+1)}); - lines.emplace_back(line); + lines.emplace_back(); lines.back().push_back({AtomContent(buffer(), line, line+1)}); } display_buffer.compute_range();