summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-07-14 13:05:52 +0900
committerMaxime Coste <mawww@kakoune.org>2017-07-14 13:08:29 +0900
commit8650c99f131aae8b10eb2141f7c2152fff25b7d1 (patch)
tree05ae1640cd4798d95676bca2b3ba8322dbf6d964
parent53f5b3d70983bc1d86a5c45c943a6eafc9f55344 (diff)
Fix assertion when replacing with empty strings
Replacing with empty strings is essentially a deletion, which means it can end up push some selections out of the buffer (imagine 3 a 2 empty line buffer, and deleting the second one). We are fixing the selections in SelectionList::erase, but we were not doing that in SelectionList::insert. Fixes #1504
-rw-r--r--src/selection.cc25
-rw-r--r--test/regression/1504-assertion-on-incorrect-pipe-use/cmd1
-rw-r--r--test/regression/1504-assertion-on-incorrect-pipe-use/in1
-rw-r--r--test/regression/1504-assertion-on-incorrect-pipe-use/out1
4 files changed, 21 insertions, 7 deletions
diff --git a/src/selection.cc b/src/selection.cc
index f24760c6..1c39c8a7 100644
--- a/src/selection.cc
+++ b/src/selection.cc
@@ -373,6 +373,17 @@ BufferCoord get_insert_pos(const Buffer& buffer, const Selection& sel,
}
}
+static void fix_overflowing_selections(Vector<Selection>& selections,
+ const Buffer& buffer)
+{
+ const BufferCoord back_coord = buffer.back_coord();
+ for (auto& sel : selections)
+ {
+ auto pos = buffer.clamp(sel.cursor());
+ sel.anchor() = sel.cursor() = std::min(pos, back_coord);
+ }
+}
+
void SelectionList::insert(ConstArrayView<String> strings, InsertMode mode,
Vector<BufferCoord>* out_insert_pos)
{
@@ -431,6 +442,12 @@ void SelectionList::insert(ConstArrayView<String> strings, InsertMode mode,
sel.cursor() = m_buffer->clamp(update_insert(sel.cursor(), change.begin, change.end));
}
}
+
+ // We might just have been deleting text if strings were empty,
+ // in which case we could have some selections pushed out of the buffer
+ if (mode == InsertMode::Replace)
+ fix_overflowing_selections(m_selections, *m_buffer);
+
check_invariant();
m_buffer->check_invariant();
}
@@ -453,13 +470,7 @@ void SelectionList::erase()
changes_tracker.update(*m_buffer, m_timestamp);
}
- BufferCoord back_coord = m_buffer->back_coord();
- for (auto& sel : m_selections)
- {
- auto pos = m_buffer->clamp(sel.cursor());
- sel.anchor() = sel.cursor() = std::min(pos, back_coord);
- }
-
+ fix_overflowing_selections(m_selections, *m_buffer);
m_buffer->check_invariant();
}
diff --git a/test/regression/1504-assertion-on-incorrect-pipe-use/cmd b/test/regression/1504-assertion-on-incorrect-pipe-use/cmd
new file mode 100644
index 00000000..5c38e31d
--- /dev/null
+++ b/test/regression/1504-assertion-on-incorrect-pipe-use/cmd
@@ -0,0 +1 @@
+2o<esc>|echo>&2<ret>
diff --git a/test/regression/1504-assertion-on-incorrect-pipe-use/in b/test/regression/1504-assertion-on-incorrect-pipe-use/in
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/test/regression/1504-assertion-on-incorrect-pipe-use/in
@@ -0,0 +1 @@
+
diff --git a/test/regression/1504-assertion-on-incorrect-pipe-use/out b/test/regression/1504-assertion-on-incorrect-pipe-use/out
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/test/regression/1504-assertion-on-incorrect-pipe-use/out
@@ -0,0 +1 @@
+