From f42aa95fbc7b949213ed204dfd0310e182e7e378 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 18 Jan 2020 13:19:36 +0100 Subject: extmark: separate extmark_splice_cols for column-only change as the byte logic will be the same for all of these --- src/nvim/extmark.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/nvim/extmark.c') diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index c9b1c72828..91ca525533 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -552,6 +552,7 @@ void extmark_adjust(buf_T *buf, } } + void extmark_splice(buf_T *buf, int start_row, colnr_T start_col, int oldextent_row, colnr_T oldextent_col, @@ -631,12 +632,10 @@ void extmark_splice(buf_T *buf, void extmark_splice_cols(buf_T *buf, int start_row, colnr_T start_col, - colnr_T old_col, colnr_T new_col, + colnr_T oldextent, colnr_T newextent, ExtmarkOp undo) { - extmark_splice(buf, start_row, start_col, - 0, old_col, - 0, new_col, undo); + extmark_splice(buf, start_row, start_col, 0, oldextent, 0, newextent, undo); } void extmark_move_region(buf_T *buf, -- cgit From 333bfd5a29905b0cc4684657f0d0539238b6dbc4 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 18 Jan 2020 13:22:25 +0100 Subject: extmark: use resonable names in extmark_splice --- src/nvim/extmark.c | 62 +++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) (limited to 'src/nvim/extmark.c') diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index 91ca525533..bda7829507 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -481,15 +481,15 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo) if (undo) { extmark_splice(curbuf, splice.start_row, splice.start_col, - splice.newextent_row, splice.newextent_col, - splice.oldextent_row, splice.oldextent_col, + splice.new_row, splice.new_col, + splice.old_row, splice.old_col, kExtmarkNoUndo); } else { extmark_splice(curbuf, splice.start_row, splice.start_col, - splice.oldextent_row, splice.oldextent_col, - splice.newextent_row, splice.newextent_col, + splice.old_row, splice.old_col, + splice.new_row, splice.new_col, kExtmarkNoUndo); } // kExtmarkSavePos @@ -555,29 +555,29 @@ void extmark_adjust(buf_T *buf, void extmark_splice(buf_T *buf, int start_row, colnr_T start_col, - int oldextent_row, colnr_T oldextent_col, - int newextent_row, colnr_T newextent_col, + int old_row, colnr_T old_col, + int new_row, colnr_T new_col, ExtmarkOp undo) { buf_updates_send_splice(buf, start_row, start_col, - oldextent_row, oldextent_col, - newextent_row, newextent_col); + old_row, old_col, + new_row, new_col); - if (undo == kExtmarkUndo && (oldextent_row > 0 || oldextent_col > 0)) { + if (undo == kExtmarkUndo && (old_row > 0 || old_col > 0)) { // Copy marks that would be effected by delete // TODO(bfredl): Be "smart" about gravity here, left-gravity at the // beginning and right-gravity at the end need not be preserved. // Also be smart about marks that already have been saved (important for // merge!) - int end_row = start_row + oldextent_row; - int end_col = (oldextent_row ? 0 : start_col) + oldextent_col; + int end_row = start_row + old_row; + int end_col = (old_row ? 0 : start_col) + old_col; u_extmark_copy(buf, start_row, start_col, end_row, end_col); } marktree_splice(buf->b_marktree, start_row, start_col, - oldextent_row, oldextent_col, - newextent_row, newextent_col); + old_row, old_col, + new_row, new_col); if (undo == kExtmarkUndo) { u_header_T *uhp = u_force_get_undo_header(buf); @@ -589,25 +589,25 @@ void extmark_splice(buf_T *buf, // TODO(bfredl): this is quite rudimentary. We merge small (within line) // inserts with each other and small deletes with each other. Add full // merge algorithm later. - if (oldextent_row == 0 && newextent_row == 0 && kv_size(uhp->uh_extmark)) { + if (old_row == 0 && new_row == 0 && kv_size(uhp->uh_extmark)) { ExtmarkUndoObject *item = &kv_A(uhp->uh_extmark, kv_size(uhp->uh_extmark)-1); if (item->type == kExtmarkSplice) { ExtmarkSplice *splice = &item->data.splice; - if (splice->start_row == start_row && splice->oldextent_row == 0 - && splice->newextent_row == 0) { - if (oldextent_col == 0 && start_col >= splice->start_col - && start_col <= splice->start_col+splice->newextent_col) { - splice->newextent_col += newextent_col; + if (splice->start_row == start_row && splice->old_row == 0 + && splice->new_row == 0) { + if (old_col == 0 && start_col >= splice->start_col + && start_col <= splice->start_col+splice->new_col) { + splice->new_col += new_col; merged = true; - } else if (newextent_col == 0 - && start_col == splice->start_col+splice->newextent_col) { - splice->oldextent_col += oldextent_col; + } else if (new_col == 0 + && start_col == splice->start_col+splice->new_col) { + splice->old_col += old_col; merged = true; - } else if (newextent_col == 0 - && start_col + oldextent_col == splice->start_col) { + } else if (new_col == 0 + && start_col + old_col == splice->start_col) { splice->start_col = start_col; - splice->oldextent_col += oldextent_col; + splice->old_col += old_col; merged = true; } } @@ -618,10 +618,10 @@ void extmark_splice(buf_T *buf, ExtmarkSplice splice; splice.start_row = start_row; splice.start_col = start_col; - splice.oldextent_row = oldextent_row; - splice.oldextent_col = oldextent_col; - splice.newextent_row = newextent_row; - splice.newextent_col = newextent_col; + splice.old_row = old_row; + splice.old_col = old_col; + splice.new_row = new_row; + splice.new_col = new_col; kv_push(uhp->uh_extmark, ((ExtmarkUndoObject){ .type = kExtmarkSplice, @@ -632,10 +632,10 @@ void extmark_splice(buf_T *buf, void extmark_splice_cols(buf_T *buf, int start_row, colnr_T start_col, - colnr_T oldextent, colnr_T newextent, + colnr_T old_col, colnr_T new_col, ExtmarkOp undo) { - extmark_splice(buf, start_row, start_col, 0, oldextent, 0, newextent, undo); + extmark_splice(buf, start_row, start_col, 0, old_col, 0, new_col, undo); } void extmark_move_region(buf_T *buf, -- cgit From bc86f76c0a1d3234b749a105c9aae65f84c51320 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 29 Feb 2020 15:27:17 +0100 Subject: 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! --- src/nvim/extmark.c | 135 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 84 insertions(+), 51 deletions(-) (limited to 'src/nvim/extmark.c') diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index bda7829507..bb981cb2f6 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -479,18 +479,18 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo) // Undo ExtmarkSplice splice = undo_info.data.splice; if (undo) { - extmark_splice(curbuf, - splice.start_row, splice.start_col, - splice.new_row, splice.new_col, - splice.old_row, splice.old_col, - kExtmarkNoUndo); + extmark_splice_impl(curbuf, + splice.start_row, splice.start_col, splice.start_byte, + splice.new_row, splice.new_col, splice.new_byte, + splice.old_row, splice.old_col, splice.old_byte, + kExtmarkNoUndo); } else { - extmark_splice(curbuf, - splice.start_row, splice.start_col, - splice.old_row, splice.old_col, - splice.new_row, splice.new_col, - kExtmarkNoUndo); + extmark_splice_impl(curbuf, + splice.start_row, splice.start_col, splice.start_byte, + splice.old_row, splice.old_col, splice.old_byte, + splice.new_row, splice.new_col, splice.new_byte, + kExtmarkNoUndo); } // kExtmarkSavePos } else if (undo_info.type == kExtmarkSavePos) { @@ -509,15 +509,15 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo) ExtmarkMove move = undo_info.data.move; if (undo) { extmark_move_region(curbuf, - move.new_row, move.new_col, - move.extent_row, move.extent_col, - move.start_row, move.start_col, + move.new_row, move.new_col, move.new_byte, + move.extent_row, move.extent_col, move.extent_byte, + move.start_row, move.start_col, move.start_byte, kExtmarkNoUndo); } else { extmark_move_region(curbuf, - move.start_row, move.start_col, - move.extent_row, move.extent_col, - move.new_row, move.new_col, + move.start_row, move.start_col, move.start_byte, + move.extent_row, move.extent_col, move.extent_byte, + move.new_row, move.new_col, move.new_byte, kExtmarkNoUndo); } } @@ -532,36 +532,57 @@ void extmark_adjust(buf_T *buf, long amount_after, ExtmarkOp undo) { - if (!curbuf_splice_pending) { - int old_extent, new_extent; - if (amount == MAXLNUM) { - old_extent = (int)(line2 - line1+1); - new_extent = (int)(amount_after + old_extent); - } else { - // A region is either deleted (amount == MAXLNUM) or - // added (line2 == MAXLNUM). The only other case is :move - // which is handled by a separate entry point extmark_move_region. - assert(line2 == MAXLNUM); - old_extent = 0; - new_extent = (int)amount; - } - extmark_splice(buf, - (int)line1-1, 0, - old_extent, 0, - new_extent, 0, undo); + if (curbuf_splice_pending) { + return; } -} + bcount_t start_byte = ml_find_line_or_offset(buf, line1, NULL, true); + bcount_t old_byte = 0, new_byte = 0; + int old_row, new_row; + if (amount == MAXLNUM) { + old_row = (int)(line2 - line1+1); + // TODO: ej kasta? + old_byte = (bcount_t)buf->deleted_bytes2; + new_row = (int)(amount_after + old_row); + } else { + // A region is either deleted (amount == MAXLNUM) or + // added (line2 == MAXLNUM). The only other case is :move + // which is handled by a separate entry point extmark_move_region. + assert(line2 == MAXLNUM); + old_row = 0; + new_row = (int)amount; + } + if (new_row > 0) { + new_byte = ml_find_line_or_offset(buf, line1+new_row, NULL, true)-start_byte; + } + extmark_splice_impl(buf, + (int)line1-1, 0, start_byte, + old_row, 0, old_byte, + new_row, 0, new_byte, undo); +} void extmark_splice(buf_T *buf, - int start_row, colnr_T start_col, - int old_row, colnr_T old_col, - int new_row, colnr_T new_col, - ExtmarkOp undo) + int start_row, colnr_T start_col, + int old_row, colnr_T old_col, bcount_t old_byte, + int new_row, colnr_T new_col, bcount_t new_byte, + ExtmarkOp undo) { - buf_updates_send_splice(buf, start_row, start_col, - old_row, old_col, - new_row, new_col); + long offset = ml_find_line_or_offset(buf, start_row+1, NULL, true); + extmark_splice_impl(buf, start_row, start_col, offset+start_col, + old_row, old_col, old_byte, new_row, new_col, new_byte, + undo); +} + +void extmark_splice_impl(buf_T *buf, + int start_row, colnr_T start_col, bcount_t start_byte, + int old_row, colnr_T old_col, bcount_t old_byte, + int new_row, colnr_T new_col, bcount_t new_byte, + ExtmarkOp undo) +{ + curbuf->deleted_bytes2 = 0; + buf_updates_send_splice(buf, start_row, start_col, start_byte, + old_row, old_col, old_byte, + new_row, new_col, new_byte); if (undo == kExtmarkUndo && (old_row > 0 || old_col > 0)) { // Copy marks that would be effected by delete @@ -599,15 +620,19 @@ void extmark_splice(buf_T *buf, if (old_col == 0 && start_col >= splice->start_col && start_col <= splice->start_col+splice->new_col) { splice->new_col += new_col; + splice->new_byte += new_byte; merged = true; } else if (new_col == 0 && start_col == splice->start_col+splice->new_col) { splice->old_col += old_col; + splice->old_byte += old_byte; merged = true; } else if (new_col == 0 && start_col + old_col == splice->start_col) { splice->start_col = start_col; + splice->start_byte = start_byte; splice->old_col += old_col; + splice->old_byte += old_byte; merged = true; } } @@ -618,10 +643,13 @@ void extmark_splice(buf_T *buf, ExtmarkSplice splice; splice.start_row = start_row; splice.start_col = start_col; + splice.start_byte = start_byte; splice.old_row = old_row; splice.old_col = old_col; + splice.old_byte = old_byte; splice.new_row = new_row; splice.new_col = new_col; + splice.new_byte = new_byte; kv_push(uhp->uh_extmark, ((ExtmarkUndoObject){ .type = kExtmarkSplice, @@ -635,29 +663,31 @@ void extmark_splice_cols(buf_T *buf, colnr_T old_col, colnr_T new_col, ExtmarkOp undo) { - extmark_splice(buf, start_row, start_col, 0, old_col, 0, new_col, undo); + extmark_splice(buf, start_row, start_col, + 0, old_col, old_col, + 0, new_col, new_col, undo); } void extmark_move_region(buf_T *buf, - int start_row, colnr_T start_col, - int extent_row, colnr_T extent_col, - int new_row, colnr_T new_col, + int start_row, colnr_T start_col, bcount_t start_byte, + int extent_row, colnr_T extent_col, bcount_t extent_byte, + int new_row, colnr_T new_col, bcount_t new_byte, ExtmarkOp undo) { // TODO(bfredl): this is not synced to the buffer state inside the callback. // But unless we make the undo implementation smarter, this is not ensured // anyway. - buf_updates_send_splice(buf, start_row, start_col, - extent_row, extent_col, - 0, 0); + buf_updates_send_splice(buf, start_row, start_col, start_byte, + extent_row, extent_col, extent_byte, + 0, 0, 0); marktree_move_region(buf->b_marktree, start_row, start_col, extent_row, extent_col, new_row, new_col); - buf_updates_send_splice(buf, new_row, new_col, - 0, 0, - extent_row, extent_col); + buf_updates_send_splice(buf, new_row, new_col, new_byte, + 0, 0, 0, + extent_row, extent_col, extent_byte); if (undo == kExtmarkUndo) { @@ -669,10 +699,13 @@ void extmark_move_region(buf_T *buf, ExtmarkMove move; move.start_row = start_row; move.start_col = start_col; + move.start_byte = start_byte; move.extent_row = extent_row; move.extent_col = extent_col; + move.extent_byte = extent_byte; move.new_row = new_row; move.new_col = new_col; + move.new_byte = new_byte; kv_push(uhp->uh_extmark, ((ExtmarkUndoObject){ .type = kExtmarkMove, -- cgit From 82fb6a881805658359777ab172f91d1a84b91b8d Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Mon, 29 Jun 2020 18:34:45 +0200 Subject: fix lints --- src/nvim/extmark.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src/nvim/extmark.c') diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index bb981cb2f6..3a04908ccb 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -540,7 +540,7 @@ void extmark_adjust(buf_T *buf, int old_row, new_row; if (amount == MAXLNUM) { old_row = (int)(line2 - line1+1); - // TODO: ej kasta? + // TODO(bfredl): ej kasta? old_byte = (bcount_t)buf->deleted_bytes2; new_row = (int)(amount_after + old_row); @@ -553,7 +553,8 @@ void extmark_adjust(buf_T *buf, new_row = (int)amount; } if (new_row > 0) { - new_byte = ml_find_line_or_offset(buf, line1+new_row, NULL, true)-start_byte; + new_byte = ml_find_line_or_offset(buf, line1+new_row, NULL, true) + - start_byte; } extmark_splice_impl(buf, (int)line1-1, 0, start_byte, @@ -562,10 +563,10 @@ void extmark_adjust(buf_T *buf, } void extmark_splice(buf_T *buf, - int start_row, colnr_T start_col, - int old_row, colnr_T old_col, bcount_t old_byte, - int new_row, colnr_T new_col, bcount_t new_byte, - ExtmarkOp undo) + int start_row, colnr_T start_col, + int old_row, colnr_T old_col, bcount_t old_byte, + int new_row, colnr_T new_col, bcount_t new_byte, + ExtmarkOp undo) { long offset = ml_find_line_or_offset(buf, start_row+1, NULL, true); extmark_splice_impl(buf, start_row, start_col, offset+start_col, @@ -668,11 +669,12 @@ void extmark_splice_cols(buf_T *buf, 0, new_col, new_col, undo); } -void extmark_move_region(buf_T *buf, - int start_row, colnr_T start_col, bcount_t start_byte, - int extent_row, colnr_T extent_col, bcount_t extent_byte, - int new_row, colnr_T new_col, bcount_t new_byte, - ExtmarkOp undo) +void extmark_move_region( + buf_T *buf, + int start_row, colnr_T start_col, bcount_t start_byte, + int extent_row, colnr_T extent_col, bcount_t extent_byte, + int new_row, colnr_T new_col, bcount_t new_byte, + ExtmarkOp undo) { // TODO(bfredl): this is not synced to the buffer state inside the callback. // But unless we make the undo implementation smarter, this is not ensured -- cgit