Fix splitting of display atoms accross multi-columns codepoint
Honor the split request by inserting an empty atom to make sure client code can assume splitting does replace one atom with two Fixes #4753
This commit is contained in:
parent
360a6847be
commit
287217b987
|
@ -108,6 +108,10 @@ DisplayLine::iterator DisplayLine::split(iterator it, ColumnCount count)
|
||||||
auto pos = utf8::advance(get_iterator(it->buffer(), it->begin()),
|
auto pos = utf8::advance(get_iterator(it->buffer(), it->begin()),
|
||||||
get_iterator(it->buffer(), it->end()),
|
get_iterator(it->buffer(), it->end()),
|
||||||
count).coord();
|
count).coord();
|
||||||
|
if (pos == it->begin()) // Can happen if we try to split in the middle of a multi-column codepoint
|
||||||
|
return m_atoms.insert(it, {it->buffer(), {pos, pos}, it->face});
|
||||||
|
if (pos == it->end())
|
||||||
|
return std::prev(m_atoms.insert(std::next(it), {it->buffer(), {pos, pos}, it->face}));
|
||||||
return split(it, pos);
|
return split(it, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,11 @@ struct DisplayAtom : public UseMemoryDomain<MemoryDomain::Display>
|
||||||
public:
|
public:
|
||||||
enum Type { Range, ReplacedRange, Text };
|
enum Type { Range, ReplacedRange, Text };
|
||||||
|
|
||||||
DisplayAtom(const Buffer& buffer, BufferCoord begin, BufferCoord end, Face face = {})
|
DisplayAtom(const Buffer& buffer, BufferRange range, Face face = {})
|
||||||
: face(face), m_type(Range), m_buffer(&buffer), m_range{begin, end} {}
|
: face(face), m_type(Range), m_buffer(&buffer), m_range{range} {}
|
||||||
|
|
||||||
DisplayAtom(const Buffer& buffer, BufferCoord begin, BufferCoord end, String str, Face face = {})
|
DisplayAtom(const Buffer& buffer, BufferRange range, String str, Face face = {})
|
||||||
: face(face), m_type(ReplacedRange), m_buffer(&buffer), m_range{begin, end}, m_text{std::move(str)} {}
|
: face(face), m_type(ReplacedRange), m_buffer(&buffer), m_range{range}, m_text{std::move(str)} {}
|
||||||
|
|
||||||
DisplayAtom(String str, Face face)
|
DisplayAtom(String str, Face face)
|
||||||
: face(face), m_type(Text), m_text(std::move(str)) {}
|
: face(face), m_type(Text), m_text(std::move(str)) {}
|
||||||
|
|
|
@ -747,7 +747,7 @@ struct WrapHighlighter : Highlighter
|
||||||
new_line.insert(new_line.begin(), {m_marker, face_marker});
|
new_line.insert(new_line.begin(), {m_marker, face_marker});
|
||||||
if (indent > marker_len)
|
if (indent > marker_len)
|
||||||
{
|
{
|
||||||
auto it = new_line.insert(new_line.begin() + (marker_len > 0), {buffer, coord, coord});
|
auto it = new_line.insert(new_line.begin() + (marker_len > 0), {buffer, {coord, coord}});
|
||||||
it->replace(String{' ', indent - marker_len});
|
it->replace(String{' ', indent - marker_len});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ const DisplayBuffer& Window::update_display_buffer(const Context& context)
|
||||||
LineCount buffer_line = setup.first_line + line;
|
LineCount buffer_line = setup.first_line + line;
|
||||||
if (buffer_line >= buffer().line_count())
|
if (buffer_line >= buffer().line_count())
|
||||||
break;
|
break;
|
||||||
lines.emplace_back(AtomList{{buffer(), buffer_line, {buffer_line, buffer()[buffer_line].length()}}});
|
lines.emplace_back(AtomList{{buffer(), {buffer_line, {buffer_line, buffer()[buffer_line].length()}}}});
|
||||||
}
|
}
|
||||||
|
|
||||||
m_display_buffer.compute_range();
|
m_display_buffer.compute_range();
|
||||||
|
|
1
test/regression/4753-assert-in-display-line-split/cmd
Normal file
1
test/regression/4753-assert-in-display-line-split/cmd
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ypp
|
1
test/regression/4753-assert-in-display-line-split/in
Normal file
1
test/regression/4753-assert-in-display-line-split/in
Normal file
|
@ -0,0 +1 @@
|
||||||
|
🔎
|
1
test/regression/4753-assert-in-display-line-split/rc
Normal file
1
test/regression/4753-assert-in-display-line-split/rc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
add-highlighter global/ column 5 +r
|
Loading…
Reference in New Issue
Block a user