refactor: use inserted_bytes pattern from vim

This covers all "small" inserts and deletes in insert mode, as well
as a few more cases like small normal mode deletes

vim-patch:8.1.0678: text properties as not adjusted for inserted text
This commit is contained in:
Björn Linse
2019-11-14 20:06:13 +01:00
parent bdebe8516c
commit 2cc83c961c
4 changed files with 32 additions and 42 deletions

View File

@@ -359,6 +359,24 @@ void changed_bytes(linenr_T lnum, colnr_T col)
} }
} }
/// insert/delete bytes at column
///
/// Like changed_bytes() but also adjust extmark for "added" bytes.
/// When "added" is negative text was deleted.
static void inserted_bytes(linenr_T lnum, colnr_T col, int added)
{
if (added > 0) {
extmark_col_adjust(curbuf, lnum, col+1, 0, added, kExtmarkUndo);
} else if (added < 0) {
// TODO(bfredl): next revision of extmarks should handle both these
// with the same entry point. Also with more sane params..
extmark_col_adjust_delete(curbuf, lnum, col+2,
col+(-added)+1, kExtmarkUndo, 0);
}
changed_bytes(lnum, col);
}
/// Appended "count" lines below line "lnum" in the current buffer. /// Appended "count" lines below line "lnum" in the current buffer.
/// Must be called AFTER the change and after mark_adjust(). /// Must be called AFTER the change and after mark_adjust().
/// Takes care of marking the buffer to be redrawn and sets the changed flag. /// Takes care of marking the buffer to be redrawn and sets the changed flag.
@@ -630,7 +648,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
ml_replace(lnum, newp, false); ml_replace(lnum, newp, false);
// mark the buffer as changed and prepare for displaying // mark the buffer as changed and prepare for displaying
changed_bytes(lnum, (colnr_T)col); inserted_bytes(lnum, (colnr_T)col, (int)(newlen - oldlen));
// If we're in Insert or Replace mode and 'showmatch' is set, then briefly // If we're in Insert or Replace mode and 'showmatch' is set, then briefly
// show the match for right parens and braces. // show the match for right parens and braces.
@@ -676,7 +694,7 @@ void ins_str(char_u *s)
assert(bytes >= 0); assert(bytes >= 0);
memmove(newp + col + newlen, oldp + col, (size_t)bytes); memmove(newp + col + newlen, oldp + col, (size_t)bytes);
ml_replace(lnum, newp, false); ml_replace(lnum, newp, false);
changed_bytes(lnum, col); inserted_bytes(lnum, col, newlen);
curwin->w_cursor.col += newlen; curwin->w_cursor.col += newlen;
} }
@@ -797,7 +815,7 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
} }
// mark the buffer as changed and prepare for displaying // mark the buffer as changed and prepare for displaying
changed_bytes(lnum, curwin->w_cursor.col); inserted_bytes(lnum, col, -count);
return OK; return OK;
} }

View File

@@ -5599,11 +5599,7 @@ insertchar (
do_digraph(-1); /* clear digraphs */ do_digraph(-1); /* clear digraphs */
do_digraph(buf[i-1]); /* may be the start of a digraph */ do_digraph(buf[i-1]); /* may be the start of a digraph */
buf[i] = NUL; buf[i] = NUL;
colnr_T col_start = curwin->w_cursor.col;
ins_str(buf); ins_str(buf);
extmark_col_adjust(curbuf, curwin->w_cursor.lnum,
(colnr_T)(col_start + 1), 0,
(long)STRLEN(buf), kExtmarkUndo);
if (flags & INSCHAR_CTRLV) { if (flags & INSCHAR_CTRLV) {
redo_literal(*buf); redo_literal(*buf);
i = 1; i = 1;
@@ -5614,9 +5610,6 @@ insertchar (
} else { } else {
int cc; int cc;
extmark_col_adjust(curbuf, curwin->w_cursor.lnum,
(colnr_T)(curwin->w_cursor.col + 1), 0,
1, kExtmarkUndo);
if ((cc = utf_char2len(c)) > 1) { if ((cc = utf_char2len(c)) > 1) {
char_u buf[MB_MAXBYTES + 1]; char_u buf[MB_MAXBYTES + 1];
@@ -8507,14 +8500,6 @@ static bool ins_tab(void)
temp -= get_nolist_virtcol() % temp; temp -= get_nolist_virtcol() % temp;
// Move extmarks
extmark_col_adjust(curbuf,
curwin->w_cursor.lnum,
curwin->w_cursor.col,
0,
temp,
kExtmarkUndo);
/* /*
* Insert the first space with ins_char(). It will delete one char in * Insert the first space with ins_char(). It will delete one char in
* replace mode. Insert the rest with ins_str(); it will not delete any * replace mode. Insert the rest with ins_str(); it will not delete any

View File

@@ -1644,8 +1644,6 @@ int op_delete(oparg_T *oap)
curwin->w_cursor.col = 0; curwin->w_cursor.col = 0;
(void)del_bytes((colnr_T)n, !virtual_op, (void)del_bytes((colnr_T)n, !virtual_op,
oap->op_type == OP_DELETE && !oap->is_VIsual); oap->op_type == OP_DELETE && !oap->is_VIsual);
extmark_col_adjust(curbuf, curwin->w_cursor.lnum,
(colnr_T)0, 0L, (long)-n, kExtmarkUndo);
curwin->w_cursor = curpos; // restore curwin->w_cursor curwin->w_cursor = curpos; // restore curwin->w_cursor
(void)do_join(2, false, false, false, false); (void)do_join(2, false, false, false, false);
} }
@@ -1685,7 +1683,6 @@ setmarks:
if (oap->is_VIsual == false) { if (oap->is_VIsual == false) {
endcol = MAX(endcol - 1, mincol); endcol = MAX(endcol - 1, mincol);
} }
extmark_col_adjust_delete(curbuf, lnum, mincol, endcol, kExtmarkUndo, 0);
} }
return OK; return OK;
} }
@@ -2279,7 +2276,7 @@ void op_insert(oparg_T *oap, long count1)
colnr_T col = oap->start.col; colnr_T col = oap->start.col;
for (linenr_T lnum = oap->start.lnum; lnum <= oap->end.lnum; lnum++) { for (linenr_T lnum = oap->start.lnum; lnum <= oap->end.lnum; lnum++) {
extmark_col_adjust(curbuf, lnum, col, 0, 1, kExtmarkUndo); extmark_col_adjust(curbuf, lnum, col, 0, 1, kExtmarkUndo);
} }
} }
/* /*
@@ -4279,14 +4276,14 @@ format_lines(
if (next_leader_len > 0) { if (next_leader_len > 0) {
(void)del_bytes(next_leader_len, false, false); (void)del_bytes(next_leader_len, false, false);
mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L, mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L,
(long)-next_leader_len, 0, kExtmarkUndo); (long)-next_leader_len, 0, kExtmarkNOOP);
} else if (second_indent > 0) { // the "leader" for FO_Q_SECOND } else if (second_indent > 0) { // the "leader" for FO_Q_SECOND
int indent = (int)getwhitecols_curline(); int indent = (int)getwhitecols_curline();
if (indent > 0) { if (indent > 0) {
(void)del_bytes(indent, FALSE, FALSE); (void)del_bytes(indent, false, false);
mark_col_adjust(curwin->w_cursor.lnum, mark_col_adjust(curwin->w_cursor.lnum,
(colnr_T)0, 0L, (long)-indent, 0, kExtmarkUndo); (colnr_T)0, 0L, (long)-indent, 0, kExtmarkNOOP);
} }
} }
curwin->w_cursor.lnum--; curwin->w_cursor.lnum--;
@@ -4951,23 +4948,6 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
curbuf->b_op_end.col--; curbuf->b_op_end.col--;
} }
// if buf1 wasn't allocated, only a singe ASCII char was changed in-place.
if (did_change && buf1 != NULL) {
extmark_col_adjust_delete(curbuf,
pos->lnum,
startpos.col + 2,
endpos.col + 1 + length,
kExtmarkUndo,
0);
long col_amount = (long)STRLEN(buf1);
extmark_col_adjust(curbuf,
pos->lnum,
startpos.col + 1,
0,
col_amount,
kExtmarkUndo);
}
theend: theend:
xfree(buf1); xfree(buf1);
if (visual) { if (visual) {

View File

@@ -475,6 +475,13 @@ describe('Extmarks buffer api', function()
check_undo_redo(ns, marks[2], 0, 3, 1, 2) check_undo_redo(ns, marks[2], 0, 3, 1, 2)
end) end)
it('deleting right before a mark works #extmarks', function()
-- op_delete in ops.c
set_extmark(ns, marks[1], 0, 2)
feed('0lx')
check_undo_redo(ns, marks[1], 0, 2, 0, 1)
end)
it('deleting on a mark works #extmarks', function() it('deleting on a mark works #extmarks', function()
-- op_delete in ops.c -- op_delete in ops.c
set_extmark(ns, marks[1], 0, 2) set_extmark(ns, marks[1], 0, 2)