diff options
author | Ashkan Kiani <ashkan.k.kiani@gmail.com> | 2019-11-23 14:28:54 -0800 |
---|---|---|
committer | Ashkan Kiani <ashkan.k.kiani@gmail.com> | 2019-11-23 14:28:54 -0800 |
commit | 42c53d266afb989467879de29ef2e9ccdaa4b152 (patch) | |
tree | 5e7233a958aa6964e74911d35904c28d3a2582b7 /src/nvim/buffer.c | |
parent | 73487f4130581da72c9e838189aab39c79c177c5 (diff) | |
parent | 61d2a12743bcefbdd661b446b0b0fea7a1f77b17 (diff) | |
download | rneovim-42c53d266afb989467879de29ef2e9ccdaa4b152.tar.gz rneovim-42c53d266afb989467879de29ef2e9ccdaa4b152.tar.bz2 rneovim-42c53d266afb989467879de29ef2e9ccdaa4b152.zip |
Merge remote-tracking branch 'origin/master' into lsp-followup
Diffstat (limited to 'src/nvim/buffer.c')
-rw-r--r-- | src/nvim/buffer.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 79f339b3aa..1244b8502c 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5626,6 +5626,86 @@ void bufhl_mark_adjust(buf_T* buf, } } +/// Adjust a placed highlight for column changes and joined/broken lines +bool bufhl_mark_col_adjust(buf_T *buf, + linenr_T lnum, + colnr_T mincol, + long lnum_amount, + long col_amount) +{ + bool moved = false; + BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, false); + if (!lineinfo) { + // Old line empty, nothing to do + return false; + } + // Create the new line below only if needed + BufhlLine *lineinfo2 = NULL; + + colnr_T delcol = MAXCOL; + if (lnum_amount == 0 && col_amount < 0) { + delcol = mincol+(int)col_amount; + } + + size_t newidx = 0; + for (size_t i = 0; i < kv_size(lineinfo->items); i++) { + BufhlItem *item = &kv_A(lineinfo->items, i); + bool delete = false; + if (item->start >= mincol) { + moved = true; + item->start += (int)col_amount; + if (item->stop < MAXCOL) { + item->stop += (int)col_amount; + } + if (lnum_amount != 0) { + if (lineinfo2 == NULL) { + lineinfo2 = bufhl_tree_ref(&buf->b_bufhl_info, + lnum+lnum_amount, true); + } + kv_push(lineinfo2->items, *item); + delete = true; + } + } else { + if (item->start >= delcol) { + moved = true; + item->start = delcol; + } + if (item->stop == MAXCOL || item->stop+1 >= mincol) { + if (item->stop == MAXCOL) { + if (delcol < MAXCOL + && delcol > (colnr_T)STRLEN(ml_get_buf(buf, lnum, false))) { + delete = true; + } + } else { + moved = true; + item->stop += (int)col_amount; + } + assert(lnum_amount >= 0); + if (lnum_amount > 0) { + item->stop = MAXCOL; + } + } else if (item->stop+1 >= delcol) { + moved = true; + item->stop = delcol-1; + } + // we covered the entire range with a visual delete or something + if (item->stop < item->start) { + delete = true; + } + } + + if (!delete) { + if (i != newidx) { + kv_A(lineinfo->items, newidx) = kv_A(lineinfo->items, i); + } + newidx++; + } + } + kv_size(lineinfo->items) = newidx; + + return moved; +} + /// Get highlights to display at a specific line /// |