DEPM: some factorization beween both versions

Additionally, correct the cursor by an offset equal to the variation of paragraph size : if change tracking is on, deleting a space may mean that it is just marked as deleted.

Part of bug #11412.
This commit is contained in:
Jean-Marc Lasgouttes 2019-01-29 14:38:17 +01:00
parent c2091becd2
commit 5c380dcc73
2 changed files with 40 additions and 23 deletions

View File

@ -2608,7 +2608,7 @@ bool BufferView::checkDepm(Cursor & cur, Cursor & old)
return false; return false;
bool need_anchor_change = false; bool need_anchor_change = false;
bool changed = d->cursor_.text()->deleteEmptyParagraphMechanism(cur, old, bool changed = Text::deleteEmptyParagraphMechanism(cur, old,
need_anchor_change); need_anchor_change);
if (need_anchor_change) if (need_anchor_change)

View File

@ -779,6 +779,32 @@ bool Text::cursorDownParagraph(Cursor & cur)
return updated; return updated;
} }
namespace {
void deleteSpaces(Paragraph & par, pos_type const from, pos_type to,
int num_spaces, bool const trackChanges)
{
if (!num_spaces)
return;
// First, delete spaces marked as inserted
int pos = from;
while (pos < to && num_spaces > 0) {
Change const & change = par.lookupChange(pos);
if (change.inserted() && change.currentAuthor()) {
par.eraseChar(pos, trackChanges);
--num_spaces;
--to;
} else
++pos;
}
// Then remove remaining spaces
par.eraseChars(from, from + num_spaces, trackChanges);
}
}
bool Text::deleteEmptyParagraphMechanism(Cursor & cur, bool Text::deleteEmptyParagraphMechanism(Cursor & cur,
Cursor & old, bool & need_anchor_change) Cursor & old, bool & need_anchor_change)
@ -848,26 +874,14 @@ bool Text::deleteEmptyParagraphMechanism(Cursor & cur,
// Remove spaces and adapt cursor. // Remove spaces and adapt cursor.
if (num_spaces > 0) { if (num_spaces > 0) {
// delete first spaces marked as inserted pos_type const oldsize = oldpar.size();
int pos = from; deleteSpaces(oldpar, from, to, num_spaces,
int ns = num_spaces; cur.buffer()->params().track_changes);
while (pos < to && ns > 0) {
Change const & change = oldpar.lookupChange(pos);
if (change.inserted() && change.currentAuthor()) {
oldpar.eraseChar(pos, cur.buffer()->params().track_changes);
--ns;
--to;
} else
++pos;
}
// Then remove remaining spaces
oldpar.eraseChars(from, from + ns, cur.buffer()->params().track_changes);
// correct cur position // correct cur position
// FIXME: there can be other cursors pointing there, we should update them // FIXME: there can be other cursors pointing there, we should update them
if (same_par) { if (same_par) {
if (cur[depth].pos() >= to) if (cur[depth].pos() >= to)
cur[depth].pos() -= num_spaces; cur[depth].pos() -= oldsize - oldpar.size();
else if (cur[depth].pos() > from) else if (cur[depth].pos() > from)
cur[depth].pos() = min(from + 1, old.lastpos()); cur[depth].pos() = min(from + 1, old.lastpos());
need_anchor_change = true; need_anchor_change = true;
@ -952,12 +966,15 @@ void Text::deleteEmptyParagraphMechanism(pit_type first, pit_type last, bool tra
// empty? We are done // empty? We are done
if (from == to) if (from == to)
break; break;
// if inside the line, keep one space
if (from > 0 && to < par.size()) int num_spaces = to - from;
++from;
// remove the extra spaces // If we are not at the extremity of the paragraph, keep one space
if (from < to) if (from != to && from > 0 && to < par.size())
par.eraseChars(from, to, trackChanges); --num_spaces;
// Remove spaces if needed
deleteSpaces(par, from , to, num_spaces, trackChanges);
} }
// don't delete anything if this is the only remaining paragraph // don't delete anything if this is the only remaining paragraph