api/buffer: add "on_bytes" callback to nvim_buf_attach

This implements byte-resolution updates of buffer changes.
Note: there is no promise that the buffer state is valid inside
the callback!
This commit is contained in:
Björn Linse
2020-02-29 15:27:17 +01:00
parent 81fa107f59
commit bc86f76c0a
13 changed files with 280 additions and 125 deletions

View File

@@ -851,6 +851,11 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
return OK;
}
bcount_t start_byte = ml_find_line_or_offset(curbuf, line1, NULL, true);
bcount_t end_byte = ml_find_line_or_offset(curbuf, line2+1, NULL, true);
bcount_t extent_byte = end_byte-start_byte;
bcount_t dest_byte = ml_find_line_or_offset(curbuf, dest+1, NULL, true);
num_lines = line2 - line1 + 1;
/*
@@ -885,6 +890,8 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
last_line = curbuf->b_ml.ml_line_count;
mark_adjust_nofold(line1, line2, last_line - line2, 0L, kExtmarkNOOP);
changed_lines(last_line - num_lines + 1, 0, last_line + 1, num_lines, false);
int line_off = 0;
bcount_t byte_off = 0;
if (dest >= line2) {
mark_adjust_nofold(line2 + 1, dest, -num_lines, 0L, kExtmarkNOOP);
FOR_ALL_TAB_WINDOWS(tab, win) {
@@ -894,6 +901,8 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
}
curbuf->b_op_start.lnum = dest - num_lines + 1;
curbuf->b_op_end.lnum = dest;
line_off = -num_lines;
byte_off = -extent_byte;
} else {
mark_adjust_nofold(dest + 1, line1 - 1, num_lines, 0L, kExtmarkNOOP);
FOR_ALL_TAB_WINDOWS(tab, win) {
@@ -909,11 +918,10 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
-(last_line - dest - extra), 0L, kExtmarkNOOP);
// extmarks are handled separately
int size = line2-line1+1;
int off = dest >= line2 ? -size : 0;
extmark_move_region(curbuf, line1-1, 0,
line2-line1+1, 0,
dest+off, 0, kExtmarkUndo);
extmark_move_region(curbuf, line1-1, 0, start_byte,
line2-line1+1, 0, extent_byte,
dest+line_off, 0, dest_byte+byte_off,
kExtmarkUndo);
changed_lines(last_line - num_lines + 1, 0, last_line + 1, -extra, false);
@@ -3913,6 +3921,18 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
ADJUST_SUB_FIRSTLNUM();
// TODO(bfredl): adjust also in preview, because decorations?
// this has some robustness issues, will look into later.
bool do_splice = !preview;
bcount_t replaced_bytes = 0;
lpos_T start = regmatch.startpos[0], end = regmatch.endpos[0];
if (do_splice) {
for (i = 0; i < nmatch-1; i++) {
replaced_bytes += STRLEN(ml_get(lnum_start+i)) + 1;
}
replaced_bytes += end.col - start.col;
}
// Now the trick is to replace CTRL-M chars with a real line
// break. This would make it impossible to insert a CTRL-M in
@@ -3956,17 +3976,14 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
current_match.end.col = new_endcol;
current_match.end.lnum = lnum;
// TODO(bfredl): adjust in preview, because decorations?
// this has some robustness issues, will look into later.
if (!preview) {
lpos_T start = regmatch.startpos[0], end = regmatch.endpos[0];
if (do_splice) {
int matchcols = end.col - ((end.lnum == start.lnum)
? start.col : 0);
int subcols = new_endcol - ((lnum == lnum_start) ? start_col : 0);
extmark_splice(curbuf, lnum_start-1, start_col,
end.lnum-start.lnum, matchcols,
lnum-lnum_start, subcols, kExtmarkUndo);
}
end.lnum-start.lnum, matchcols, replaced_bytes,
lnum-lnum_start, subcols, sublen-1, kExtmarkUndo);
}
}