Fix horizontal scrolling support with replaced buffer ranges
tab character were not properly handled when scrolling horizontally
This commit is contained in:
parent
5b4ef23b9d
commit
e510bf8b96
|
@ -5,6 +5,24 @@
|
||||||
namespace Kakoune
|
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)
|
DisplayLine::iterator DisplayLine::split(iterator it, BufferCoord pos)
|
||||||
{
|
{
|
||||||
kak_assert(it->content.type() == AtomContent::BufferRange);
|
kak_assert(it->content.type() == AtomContent::BufferRange);
|
||||||
|
@ -65,6 +83,37 @@ CharCount DisplayLine::length() const
|
||||||
return len;
|
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()
|
void DisplayBuffer::compute_range()
|
||||||
{
|
{
|
||||||
m_range.first = {INT_MAX,INT_MAX};
|
m_range.first = {INT_MAX,INT_MAX};
|
||||||
|
|
|
@ -97,6 +97,8 @@ public:
|
||||||
|
|
||||||
Type type() const { return m_type; }
|
Type type() const { return m_type; }
|
||||||
|
|
||||||
|
void trim_begin(CharCount count);
|
||||||
|
void trim_end(CharCount count);
|
||||||
private:
|
private:
|
||||||
friend class DisplayLine;
|
friend class DisplayLine;
|
||||||
|
|
||||||
|
@ -152,6 +154,10 @@ public:
|
||||||
iterator insert(iterator it, DisplayAtom atom) { return m_atoms.insert(it, std::move(atom)); }
|
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)); }
|
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();
|
void optimize();
|
||||||
private:
|
private:
|
||||||
LineCount m_buffer_line;
|
LineCount m_buffer_line;
|
||||||
|
|
|
@ -69,17 +69,17 @@ void Window::update_display_buffer()
|
||||||
LineCount buffer_line = m_position.line + line;
|
LineCount buffer_line = m_position.line + line;
|
||||||
if (buffer_line >= buffer().line_count())
|
if (buffer_line >= buffer().line_count())
|
||||||
break;
|
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.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_display_buffer.compute_range();
|
||||||
m_highlighters(*this, m_display_buffer);
|
m_highlighters(*this, m_display_buffer);
|
||||||
m_builtin_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_display_buffer.optimize();
|
||||||
|
|
||||||
m_timestamp = buffer().timestamp();
|
m_timestamp = buffer().timestamp();
|
||||||
|
@ -152,12 +152,12 @@ void Window::scroll_to_keep_cursor_visible_ifn()
|
||||||
if (first_col < m_position.column)
|
if (first_col < m_position.column)
|
||||||
m_position.column = first_col;
|
m_position.column = first_col;
|
||||||
else if (column >= m_position.column + m_dimensions.column)
|
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)
|
if (last_col < m_position.column)
|
||||||
m_position.column = last_col;
|
m_position.column = last_col;
|
||||||
else if (column >= m_position.column + m_dimensions.column)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user