diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/buffer.c | 2 | ||||
-rw-r--r-- | src/nvim/buffer.c | 27 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/diff.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 34 | ||||
-rw-r--r-- | src/nvim/lib/kbtree.h | 6 | ||||
-rw-r--r-- | src/nvim/mark.c | 19 | ||||
-rw-r--r-- | src/nvim/misc1.c | 6 | ||||
-rw-r--r-- | src/nvim/ops.c | 2 | ||||
-rw-r--r-- | src/nvim/undo.c | 8 |
10 files changed, 69 insertions, 39 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 94554bc4c1..82de8fd4a2 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -399,7 +399,7 @@ void nvim_buf_set_lines(uint64_t channel_id, // Only adjust marks if we managed to switch to a window that holds // the buffer, otherwise line numbers will be invalid. if (save_curbuf.br_buf == NULL) { - mark_adjust((linenr_T)start, (linenr_T)(end - 1), MAXLNUM, extra); + mark_adjust((linenr_T)start, (linenr_T)(end - 1), MAXLNUM, extra, false); } changed_lines((linenr_T)start, 0, (linenr_T)end, (long)extra); diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index ebb38fe709..b5ca6543c5 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5304,6 +5304,9 @@ void bufhl_clear_all(buf_T *buf) { bufhl_clear_line_range(buf, -1, 1, MAXLNUM); kb_destroy(bufhl, (&buf->b_bufhl_info)); + kb_init(&buf->b_bufhl_info); + kv_destroy(buf->b_bufhl_move_space); + kv_init(buf->b_bufhl_move_space); } /// Adjust a placed highlight for inserted/deleted lines. @@ -5311,19 +5314,32 @@ void bufhl_mark_adjust(buf_T* buf, linenr_T line1, linenr_T line2, long amount, - long amount_after) + long amount_after, + bool end_temp) { - // XXX: does not support move - // we need to detect this case and - kbitr_t(bufhl) itr; BufhlLine *l, t = BUFHLLINE_INIT(line1); + if (end_temp && amount < 0) { + // Move all items from b_bufhl_move_space to the btree. + for (size_t i = 0; i < kv_size(buf->b_bufhl_move_space); i++) { + l = kv_A(buf->b_bufhl_move_space, i); + l->line += amount; + kb_put(bufhl, &buf->b_bufhl_info, l); + } + kv_size(buf->b_bufhl_move_space) = 0; + return; + } + if (!kb_itr_get(bufhl, &buf->b_bufhl_info, &t, &itr)) { kb_itr_next(bufhl, &buf->b_bufhl_info, &itr); } for (; kb_itr_valid(&itr); kb_itr_next(bufhl, &buf->b_bufhl_info, &itr)) { l = kb_itr_key(&itr); if (l->line >= line1 && l->line <= line2) { + if (end_temp && amount > 0) { + kb_del_itr(bufhl, &buf->b_bufhl_info, &itr); + kv_push(buf->b_bufhl_move_space, l); + } if (amount == MAXLNUM) { if (bufhl_clear_line(l, -1, l->line) == kBLSDeleted) { kb_del_itr(bufhl, &buf->b_bufhl_info, &itr); @@ -5371,7 +5387,8 @@ bool bufhl_start_line(buf_T *buf, linenr_T lnum, BufhlLineInfo *info) /// @param info The info returned by bufhl_start_line /// @param col The column to get the attr for /// @return The highilight attr to display at the column -int bufhl_get_attr(BufhlLineInfo *info, colnr_T col) { +int bufhl_get_attr(BufhlLineInfo *info, colnr_T col) +{ if (col <= info->valid_to) { return info->current; } diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 8e928bce62..559dffb945 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -761,6 +761,8 @@ struct file_buffer { int b_mapped_ctrl_c; // modes where CTRL-C is mapped BufhlInfo b_bufhl_info; // buffer stored highlights + + kvec_t(BufhlLine *) b_bufhl_move_space; // temporary space for highlights }; /* diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 0bd3f59cf2..7da6665cb7 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -2311,7 +2311,7 @@ void ex_diffgetput(exarg_T *eap) // Adjust marks. This will change the following entries! if (added != 0) { - mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added); + mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added, false); if (curwin->w_cursor.lnum >= lnum) { // Adjust the cursor position if it's in/after the changed // lines. diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 008a44b43b..8dcb3ac449 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -597,9 +597,10 @@ void ex_sort(exarg_T *eap) // Adjust marks for deleted (or added) lines and prepare for displaying. deleted = (long)(count - (lnum - eap->line2)); if (deleted > 0) { - mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted); + mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted, + false); } else if (deleted < 0) { - mark_adjust(eap->line2, MAXLNUM, -deleted, 0L); + mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, false); } changed_lines(eap->line1, 0, eap->line2 + 1, -deleted); @@ -794,9 +795,9 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) * their final destination at the new text position -- webb */ last_line = curbuf->b_ml.ml_line_count; - mark_adjust_nofold(line1, line2, last_line - line2, 0L); + mark_adjust_nofold(line1, line2, last_line - line2, 0L, true); if (dest >= line2) { - mark_adjust_nofold(line2 + 1, dest, -num_lines, 0L); + mark_adjust_nofold(line2 + 1, dest, -num_lines, 0L, false); FOR_ALL_TAB_WINDOWS(tab, win) { if (win->w_buffer == curbuf) { foldMoveRange(&win->w_folds, line1, line2, dest); @@ -805,7 +806,7 @@ 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; } else { - mark_adjust_nofold(dest + 1, line1 - 1, num_lines, 0L); + mark_adjust_nofold(dest + 1, line1 - 1, num_lines, 0L, false); FOR_ALL_TAB_WINDOWS(tab, win) { if (win->w_buffer == curbuf) { foldMoveRange(&win->w_folds, dest + 1, line1 - 1, line2); @@ -816,7 +817,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) } curbuf->b_op_start.col = curbuf->b_op_end.col = 0; mark_adjust_nofold(last_line - num_lines + 1, last_line, - -(last_line - dest - extra), 0L); + -(last_line - dest - extra), 0L, true); /* * Now we delete the original text -- webb @@ -1212,15 +1213,14 @@ static void do_filter( if (do_in) { if (cmdmod.keepmarks || vim_strchr(p_cpo, CPO_REMMARK) == NULL) { - if (read_linecount >= linecount) - /* move all marks from old lines to new lines */ - mark_adjust(line1, line2, linecount, 0L); - else { - /* move marks from old lines to new lines, delete marks - * that are in deleted lines */ - mark_adjust(line1, line1 + read_linecount - 1, - linecount, 0L); - mark_adjust(line1 + read_linecount, line2, MAXLNUM, 0L); + if (read_linecount >= linecount) { + // move all marks from old lines to new lines + mark_adjust(line1, line2, linecount, 0L, false); + } else { + // move marks from old lines to new lines, delete marks + // that are in deleted lines + mark_adjust(line1, line1 + read_linecount - 1, linecount, 0L, false); + mark_adjust(line1 + read_linecount, line2, MAXLNUM, 0L, false); } } @@ -3758,7 +3758,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout) *p1 = NUL; // truncate up to the CR ml_append(lnum - 1, new_start, (colnr_T)(p1 - new_start + 1), false); - mark_adjust(lnum + 1, (linenr_T)MAXLNUM, 1L, 0L); + mark_adjust(lnum + 1, (linenr_T)MAXLNUM, 1L, 0L, false); if (subflags.do_ask) { appended_lines(lnum - 1, 1L); } else { @@ -3847,7 +3847,7 @@ skip: for (i = 0; i < nmatch_tl; ++i) ml_delete(lnum, (int)FALSE); mark_adjust(lnum, lnum + nmatch_tl - 1, - (long)MAXLNUM, -nmatch_tl); + (long)MAXLNUM, -nmatch_tl, false); if (subflags.do_ask) { deleted_lines(lnum, nmatch_tl); } diff --git a/src/nvim/lib/kbtree.h b/src/nvim/lib/kbtree.h index f836dec48f..a3943054e6 100644 --- a/src/nvim/lib/kbtree.h +++ b/src/nvim/lib/kbtree.h @@ -359,7 +359,10 @@ } \ static inline int kb_itr_getp_##name(kbtree_##name##_t *b, key_t * __restrict k, kbitr_##name##_t *itr) \ { \ - if (b->n_keys == 0) return 0; \ + if (b->n_keys == 0) { \ + itr->p = NULL; \ + return 0; \ + } \ int i, r = 0; \ itr->p = itr->stack; \ itr->p->x = b->root; \ @@ -420,6 +423,7 @@ #define kbtree_t(name) kbtree_##name##_t #define kbitr_t(name) kbitr_##name##_t +#define kb_init(b) ((b)->n_keys = (b)->n_nodes = 0, (b)->root = 0) #define kb_destroy(name, b) __kb_destroy(kbnode_##name##_t, b) #define kb_get(name, b, k) kb_get_##name(b, k) #define kb_put(name, b, k) kb_put_##name(b, k) diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 675fe4d57f..7889fabd45 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -888,9 +888,13 @@ void ex_changes(exarg_T *eap) * Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0); * or: mark_adjust(56, 55, MAXLNUM, 2); */ -void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) +void mark_adjust(linenr_T line1, + linenr_T line2, + long amount, + long amount_after, + bool end_temp) { - mark_adjust_internal(line1, line2, amount, amount_after, true); + mark_adjust_internal(line1, line2, amount, amount_after, true, end_temp); } // mark_adjust_nofold() does the same as mark_adjust() but without adjusting @@ -899,13 +903,14 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) // calling foldMarkAdjust() with arguments line1, line2, amount, amount_after, // for an example of why this may be necessary, see do_move(). void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount, - long amount_after) + long amount_after, bool end_temp) { - mark_adjust_internal(line1, line2, amount, amount_after, false); + mark_adjust_internal(line1, line2, amount, amount_after, false, end_temp); } -static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, - long amount_after, bool adjust_folds) +static void mark_adjust_internal(linenr_T line1, linenr_T line2, + long amount, long amount_after, + bool adjust_folds, bool end_temp) { int i; int fnum = curbuf->b_fnum; @@ -954,7 +959,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, } sign_mark_adjust(line1, line2, amount, amount_after); - bufhl_mark_adjust(curbuf, line1, line2, amount, amount_after); + bufhl_mark_adjust(curbuf, line1, line2, amount, amount_after, end_temp); } /* previous context mark */ diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 9630656f3f..835b9c7b20 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -751,7 +751,7 @@ open_line ( // Skip mark_adjust when adding a line after the last one, there can't // be marks there. if (curwin->w_cursor.lnum + 1 < curbuf->b_ml.ml_line_count) { - mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L); + mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L, false); } did_append = true; } else { @@ -1866,7 +1866,7 @@ void appended_lines_mark(linenr_T lnum, long count) // Skip mark_adjust when adding a line after the last one, there can't // be marks there. if (lnum + count < curbuf->b_ml.ml_line_count) { - mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L); + mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L, false); } changed_lines(lnum + 1, 0, lnum + 1, count); } @@ -1888,7 +1888,7 @@ void deleted_lines(linenr_T lnum, long count) */ void deleted_lines_mark(linenr_T lnum, long count) { - mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count); + mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count, false); changed_lines(lnum, 0, lnum + count, -count); } diff --git a/src/nvim/ops.c b/src/nvim/ops.c index f9153a94a7..5c6f4d0d07 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3182,7 +3182,7 @@ error: if (curbuf->b_op_start.lnum + (y_type == kMTCharWise) - 1 + nr_lines < curbuf->b_ml.ml_line_count) { mark_adjust(curbuf->b_op_start.lnum + (y_type == kMTCharWise), - (linenr_T)MAXLNUM, nr_lines, 0L); + (linenr_T)MAXLNUM, nr_lines, 0L, false); } // note changed text for displaying and folding diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 290d5d7553..81af3bfda9 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -2232,11 +2232,13 @@ static void u_undoredo(int undo) /* adjust marks */ if (oldsize != newsize) { mark_adjust(top + 1, top + oldsize, (long)MAXLNUM, - (long)newsize - (long)oldsize); - if (curbuf->b_op_start.lnum > top + oldsize) + (long)newsize - (long)oldsize, false); + if (curbuf->b_op_start.lnum > top + oldsize) { curbuf->b_op_start.lnum += newsize - oldsize; - if (curbuf->b_op_end.lnum > top + oldsize) + } + if (curbuf->b_op_end.lnum > top + oldsize) { curbuf->b_op_end.lnum += newsize - oldsize; + } } changed_lines(top + 1, 0, bot, newsize - oldsize); |