diff --git a/src/display_buffer.cc b/src/display_buffer.cc index c656410c..7e42c2b0 100644 --- a/src/display_buffer.cc +++ b/src/display_buffer.cc @@ -5,6 +5,24 @@ namespace Kakoune { +void AtomContent::trim_begin(CharCount count) +{ + if (m_type == BufferRange) + m_begin = utf8::advance(m_buffer->iterator_at(m_begin), + m_buffer->iterator_at(m_end), count).coord(); + else + m_text = m_text.substr(count); +} + +void AtomContent::trim_end(CharCount count) +{ + if (m_type == BufferRange) + m_end = utf8::advance(m_buffer->iterator_at(m_end), + m_buffer->iterator_at(m_begin), -count).coord(); + else + m_text = m_text.substr(0, m_text.char_length() - count); +} + DisplayLine::iterator DisplayLine::split(iterator it, BufferCoord pos) { kak_assert(it->content.type() == AtomContent::BufferRange); @@ -65,6 +83,37 @@ CharCount DisplayLine::length() const return len; } +void DisplayLine::trim(CharCount first_char, CharCount char_count) +{ + for (auto it = begin(); first_char > 0 and it != end(); ) + { + if (not it->content.has_buffer_range()) + { + ++it; + continue; + } + + auto len = it->content.length(); + if (len <= first_char) + { + m_atoms.erase(it); + first_char -= len; + } + else + { + it->content.trim_begin(first_char); + first_char = 0; + } + } + auto it = begin(); + for (; it != end() and char_count > 0; ++it) + char_count -= it->content.length(); + + if (char_count < 0) + (it-1)->content.trim_end(-char_count); + m_atoms.erase(it, end()); +} + void DisplayBuffer::compute_range() { m_range.first = {INT_MAX,INT_MAX}; diff --git a/src/display_buffer.hh b/src/display_buffer.hh index be83fe11..16fe2758 100644 --- a/src/display_buffer.hh +++ b/src/display_buffer.hh @@ -97,6 +97,8 @@ public: Type type() const { return m_type; } + void trim_begin(CharCount count); + void trim_end(CharCount count); private: friend class DisplayLine; @@ -152,6 +154,10 @@ public: 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)); } + // remove first_char from the begining of the line, and make sure + // the line is less that char_count character + void trim(CharCount first_char, CharCount char_count); + void optimize(); private: LineCount m_buffer_line; diff --git a/src/window.cc b/src/window.cc index dcdc42e3..6072c142 100644 --- a/src/window.cc +++ b/src/window.cc @@ -69,17 +69,17 @@ void Window::update_display_buffer() LineCount buffer_line = m_position.line + line; if (buffer_line >= buffer().line_count()) break; - const String& content = buffer()[buffer_line]; - BufferCoord begin{buffer_line, content.byte_count_to(m_position.column)}; - BufferCoord end = buffer().advance(buffer_line, content.byte_count_to(m_position.column + m_dimensions.column)); - lines.push_back(DisplayLine(buffer_line)); - lines.back().push_back(DisplayAtom(AtomContent(buffer(), begin, end))); + lines.back().push_back(DisplayAtom(AtomContent(buffer(), buffer_line, buffer_line+1))); } m_display_buffer.compute_range(); m_highlighters(*this, m_display_buffer); m_builtin_highlighters(*this, m_display_buffer); + + // cut the start of the line before m_position.column + for (auto& line : lines) + line.trim(m_position.column, m_dimensions.column); m_display_buffer.optimize(); m_timestamp = buffer().timestamp(); @@ -152,12 +152,12 @@ void Window::scroll_to_keep_cursor_visible_ifn() if (first_col < m_position.column) m_position.column = first_col; else if (column >= m_position.column + m_dimensions.column) - m_position.column = column - (m_dimensions.column - 1); + m_position.column = column - m_dimensions.column; if (last_col < m_position.column) m_position.column = last_col; else if (column >= m_position.column + m_dimensions.column) - m_position.column = column - (m_dimensions.column - 1); + m_position.column = column - m_dimensions.column; return; }