summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2022-10-17 17:46:26 +1100
committerMaxime Coste <mawww@kakoune.org>2022-10-17 17:48:39 +1100
commit287217b98715faaddab019f4e17ab54fccaaec70 (patch)
tree5eeed3d98eb645f242a6f02033ac1e1be7936c69
parent360a6847be5c79a57da73c15efbbb954cd8ba749 (diff)
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
-rw-r--r--src/display_buffer.cc4
-rw-r--r--src/display_buffer.hh8
-rw-r--r--src/highlighters.cc2
-rw-r--r--src/window.cc2
-rw-r--r--test/regression/4753-assert-in-display-line-split/cmd1
-rw-r--r--test/regression/4753-assert-in-display-line-split/in1
-rw-r--r--test/regression/4753-assert-in-display-line-split/rc1
7 files changed, 13 insertions, 6 deletions
diff --git a/src/display_buffer.cc b/src/display_buffer.cc
index 335fb5de..c9b74d04 100644
--- a/src/display_buffer.cc
+++ b/src/display_buffer.cc
@@ -108,6 +108,10 @@ DisplayLine::iterator DisplayLine::split(iterator it, ColumnCount count)
auto pos = utf8::advance(get_iterator(it->buffer(), it->begin()),
get_iterator(it->buffer(), it->end()),
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);
}
diff --git a/src/display_buffer.hh b/src/display_buffer.hh
index 8008f86a..c164cb08 100644
--- a/src/display_buffer.hh
+++ b/src/display_buffer.hh
@@ -24,11 +24,11 @@ struct DisplayAtom : public UseMemoryDomain<MemoryDomain::Display>
public:
enum Type { Range, ReplacedRange, Text };
- DisplayAtom(const Buffer& buffer, BufferCoord begin, BufferCoord end, Face face = {})
- : face(face), m_type(Range), m_buffer(&buffer), m_range{begin, end} {}
+ DisplayAtom(const Buffer& buffer, BufferRange range, Face face = {})
+ : face(face), m_type(Range), m_buffer(&buffer), m_range{range} {}
- DisplayAtom(const Buffer& buffer, BufferCoord begin, BufferCoord end, String str, Face face = {})
- : face(face), m_type(ReplacedRange), m_buffer(&buffer), m_range{begin, end}, m_text{std::move(str)} {}
+ DisplayAtom(const Buffer& buffer, BufferRange range, String str, Face face = {})
+ : face(face), m_type(ReplacedRange), m_buffer(&buffer), m_range{range}, m_text{std::move(str)} {}
DisplayAtom(String str, Face face)
: face(face), m_type(Text), m_text(std::move(str)) {}
diff --git a/src/highlighters.cc b/src/highlighters.cc
index 3fe8ad11..eed8f369 100644
--- a/src/highlighters.cc
+++ b/src/highlighters.cc
@@ -747,7 +747,7 @@ struct WrapHighlighter : Highlighter
new_line.insert(new_line.begin(), {m_marker, face_marker});
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});
}
diff --git a/src/window.cc b/src/window.cc
index 455e6a2d..9aa3ea73 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -150,7 +150,7 @@ const DisplayBuffer& Window::update_display_buffer(const Context& context)
LineCount buffer_line = setup.first_line + line;
if (buffer_line >= buffer().line_count())
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();
diff --git a/test/regression/4753-assert-in-display-line-split/cmd b/test/regression/4753-assert-in-display-line-split/cmd
new file mode 100644
index 00000000..ef0f47e4
--- /dev/null
+++ b/test/regression/4753-assert-in-display-line-split/cmd
@@ -0,0 +1 @@
+ypp
diff --git a/test/regression/4753-assert-in-display-line-split/in b/test/regression/4753-assert-in-display-line-split/in
new file mode 100644
index 00000000..1bc8aba7
--- /dev/null
+++ b/test/regression/4753-assert-in-display-line-split/in
@@ -0,0 +1 @@
+🔎
diff --git a/test/regression/4753-assert-in-display-line-split/rc b/test/regression/4753-assert-in-display-line-split/rc
new file mode 100644
index 00000000..1daf1c1e
--- /dev/null
+++ b/test/regression/4753-assert-in-display-line-split/rc
@@ -0,0 +1 @@
+add-highlighter global/ column 5 +r