Better handling of linewise inserting when we have multiple selections per line
Fixes #1053
This commit is contained in:
parent
cdb2c766a5
commit
cd89531bd9
|
@ -481,7 +481,8 @@ void SelectionList::avoid_eol()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord prepare_insert(Buffer& buffer, const Selection& sel, InsertMode mode)
|
BufferCoord get_insert_pos(const Buffer& buffer, const Selection& sel,
|
||||||
|
InsertMode mode)
|
||||||
{
|
{
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
|
@ -489,8 +490,6 @@ BufferCoord prepare_insert(Buffer& buffer, const Selection& sel, InsertMode mode
|
||||||
return sel.min();
|
return sel.min();
|
||||||
case InsertMode::InsertCursor:
|
case InsertMode::InsertCursor:
|
||||||
return sel.cursor();
|
return sel.cursor();
|
||||||
case InsertMode::Replace:
|
|
||||||
return {}; // replace is handled specially, by calling Buffer::replace
|
|
||||||
case InsertMode::Append:
|
case InsertMode::Append:
|
||||||
{
|
{
|
||||||
// special case for end of lines, append to current line instead
|
// special case for end of lines, append to current line instead
|
||||||
|
@ -503,14 +502,11 @@ BufferCoord prepare_insert(Buffer& buffer, const Selection& sel, InsertMode mode
|
||||||
return {sel.max().line, buffer[sel.max().line].length() - 1};
|
return {sel.max().line, buffer[sel.max().line].length() - 1};
|
||||||
case InsertMode::InsertAtNextLineBegin:
|
case InsertMode::InsertAtNextLineBegin:
|
||||||
return sel.max().line+1;
|
return sel.max().line+1;
|
||||||
case InsertMode::OpenLineBelow:
|
default:
|
||||||
return buffer.insert(sel.max().line + 1, "\n");
|
|
||||||
case InsertMode::OpenLineAbove:
|
|
||||||
return buffer.insert(sel.min().line, "\n");
|
|
||||||
}
|
|
||||||
kak_assert(false);
|
kak_assert(false);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SelectionList::insert(ConstArrayView<String> strings, InsertMode mode,
|
void SelectionList::insert(ConstArrayView<String> strings, InsertMode mode,
|
||||||
Vector<BufferCoord>* out_insert_pos)
|
Vector<BufferCoord>* out_insert_pos)
|
||||||
|
@ -519,13 +515,21 @@ void SelectionList::insert(ConstArrayView<String> strings, InsertMode mode,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
Vector<BufferCoord> insert_pos;
|
||||||
|
if (mode != InsertMode::Replace)
|
||||||
|
{
|
||||||
|
for (auto& sel : m_selections)
|
||||||
|
insert_pos.push_back(get_insert_pos(*m_buffer, sel, mode));
|
||||||
|
}
|
||||||
|
|
||||||
ForwardChangesTracker changes_tracker;
|
ForwardChangesTracker changes_tracker;
|
||||||
for (size_t index = 0; index < m_selections.size(); ++index)
|
for (size_t index = 0; index < m_selections.size(); ++index)
|
||||||
{
|
{
|
||||||
auto& sel = m_selections[index];
|
auto& sel = m_selections[index];
|
||||||
|
|
||||||
sel.anchor() = changes_tracker.get_new_coord(sel.anchor());
|
sel.anchor() = changes_tracker.get_new_coord_tolerant(sel.anchor());
|
||||||
sel.cursor() = changes_tracker.get_new_coord(sel.cursor());
|
sel.cursor() = changes_tracker.get_new_coord_tolerant(sel.cursor());
|
||||||
kak_assert(m_buffer->is_valid(sel.anchor()) and
|
kak_assert(m_buffer->is_valid(sel.anchor()) and
|
||||||
m_buffer->is_valid(sel.cursor()));
|
m_buffer->is_valid(sel.cursor()));
|
||||||
|
|
||||||
|
@ -533,14 +537,13 @@ void SelectionList::insert(ConstArrayView<String> strings, InsertMode mode,
|
||||||
|
|
||||||
const auto pos = (mode == InsertMode::Replace) ?
|
const auto pos = (mode == InsertMode::Replace) ?
|
||||||
replace(*m_buffer, sel, str)
|
replace(*m_buffer, sel, str)
|
||||||
: m_buffer->insert(prepare_insert(*m_buffer, sel, mode), str);
|
: m_buffer->insert(changes_tracker.get_new_coord(insert_pos[index]), str);
|
||||||
|
|
||||||
|
changes_tracker.update(*m_buffer, m_timestamp);
|
||||||
|
|
||||||
if (out_insert_pos)
|
if (out_insert_pos)
|
||||||
out_insert_pos->push_back(pos);
|
out_insert_pos->push_back(pos);
|
||||||
|
|
||||||
changes_tracker.update(*m_buffer, m_timestamp);
|
|
||||||
m_timestamp = m_buffer->timestamp();
|
|
||||||
|
|
||||||
if (mode == InsertMode::Replace)
|
if (mode == InsertMode::Replace)
|
||||||
{
|
{
|
||||||
if (str.empty())
|
if (str.empty())
|
||||||
|
|
1
test/regression/1053-crash-on-deletion-and-paste/cmd
Normal file
1
test/regression/1053-crash-on-deletion-and-paste/cmd
Normal file
|
@ -0,0 +1 @@
|
||||||
|
xSo<ret>dp
|
1
test/regression/1053-crash-on-deletion-and-paste/in
Normal file
1
test/regression/1053-crash-on-deletion-and-paste/in
Normal file
|
@ -0,0 +1 @@
|
||||||
|
foobar
|
4
test/regression/1053-crash-on-deletion-and-paste/out
Normal file
4
test/regression/1053-crash-on-deletion-and-paste/out
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
o
|
||||||
|
f
|
||||||
|
o
|
||||||
|
bar
|
Loading…
Reference in New Issue
Block a user