mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
bufhl: use extmark column adjustment for bufhl
NB: this is not the final implementation. Bufhl should be made a part of the extmark tree, so that "start" adjustment just works automatically. But "stop" will still need some ad-hoc trickery, until extended marks natively support ranges (hopefully sooner than forever).
This commit is contained in:
parent
d5f14b8372
commit
bdebe8516c
@ -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
|
||||
///
|
||||
|
@ -5599,9 +5599,10 @@ insertchar (
|
||||
do_digraph(-1); /* clear digraphs */
|
||||
do_digraph(buf[i-1]); /* may be the start of a digraph */
|
||||
buf[i] = NUL;
|
||||
colnr_T col_start = curwin->w_cursor.col;
|
||||
ins_str(buf);
|
||||
extmark_col_adjust(curbuf, curwin->w_cursor.lnum,
|
||||
(colnr_T)(curwin->w_cursor.col + 1), 0,
|
||||
(colnr_T)(col_start + 1), 0,
|
||||
(long)STRLEN(buf), kExtmarkUndo);
|
||||
if (flags & INSCHAR_CTRLV) {
|
||||
redo_literal(*buf);
|
||||
|
@ -910,6 +910,9 @@ void extmark_col_adjust(buf_T *buf, linenr_T lnum,
|
||||
bool marks_moved = extmark_col_adjust_impl(buf, lnum, mincol, lnum_amount,
|
||||
false, col_amount);
|
||||
|
||||
marks_moved |= bufhl_mark_col_adjust(buf, lnum, mincol,
|
||||
lnum_amount, col_amount);
|
||||
|
||||
if (undo == kExtmarkUndo && marks_moved) {
|
||||
u_extmark_col_adjust(buf, lnum, mincol, lnum_amount, col_amount);
|
||||
}
|
||||
@ -938,6 +941,7 @@ void extmark_col_adjust_delete(buf_T *buf, linenr_T lnum,
|
||||
marks_moved = extmark_col_adjust_impl(buf, lnum, mincol, 0,
|
||||
true, (long)endcol);
|
||||
|
||||
marks_moved |= bufhl_mark_col_adjust(buf, lnum, endcol, 0, mincol-(endcol+1));
|
||||
// Deletes at the end of the line have different behaviour than the normal
|
||||
// case when deleted.
|
||||
// Cleanup any marks that are floating beyond the end of line.
|
||||
|
@ -217,6 +217,161 @@ describe('Buffer highlighting', function()
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('and adjusting columns', function()
|
||||
-- insert before
|
||||
feed('ggiquite <esc>')
|
||||
screen:expect{grid=[[
|
||||
quite^ a {5:longer} example |
|
||||
in {6:order} to {7:de}{5:monstr}{7:ate} |
|
||||
{7:combin}{8:ing}{9: hi}ghlights |
|
||||
{9:from }{8:diff}{7:erent} sources |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
|
|
||||
]]}
|
||||
|
||||
feed('u')
|
||||
screen:expect{grid=[[
|
||||
^a {5:longer} example |
|
||||
in {6:order} to {7:de}{5:monstr}{7:ate} |
|
||||
{7:combin}{8:ing}{9: hi}ghlights |
|
||||
{9:from }{8:diff}{7:erent} sources |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
1 change; before #2 0 seconds ago |
|
||||
]]}
|
||||
|
||||
-- change/insert in the middle
|
||||
feed('+fesAAAA')
|
||||
screen:expect{grid=[[
|
||||
a {5:longer} example |
|
||||
in {6:ordAAAA^r} to {7:de}{5:monstr}{7:ate} |
|
||||
{7:combin}{8:ing}{9: hi}ghlights |
|
||||
{9:from }{8:diff}{7:erent} sources |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{7:-- INSERT --} |
|
||||
]]}
|
||||
|
||||
feed('<esc>tdD')
|
||||
screen:expect{grid=[[
|
||||
a {5:longer} example |
|
||||
in {6:ordAAAAr} t^o |
|
||||
{7:combin}{8:ing}{9: hi}ghlights |
|
||||
{9:from }{8:diff}{7:erent} sources |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
|
|
||||
]]}
|
||||
|
||||
feed('u')
|
||||
screen:expect{grid=[[
|
||||
a {5:longer} example |
|
||||
in {6:ordAAAAr} to^ demonstrate |
|
||||
{7:combin}{8:ing}{9: hi}ghlights |
|
||||
{9:from }{8:diff}{7:erent} sources |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
1 change; before #4 0 seconds ago |
|
||||
]]}
|
||||
|
||||
feed('u')
|
||||
screen:expect{grid=[[
|
||||
a {5:longer} example |
|
||||
in {6:ord^er} to demonstrate |
|
||||
{7:combin}{8:ing}{9: hi}ghlights |
|
||||
{9:from }{8:diff}{7:erent} sources |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
1 change; before #3 0 seconds ago |
|
||||
]]}
|
||||
end)
|
||||
|
||||
it('and joining lines', function()
|
||||
feed('ggJJJ')
|
||||
screen:expect{grid=[[
|
||||
a {5:longer} example in {6:order} to {7:de}{5:monstr}{7:ate}|
|
||||
{7: combin}{8:ing hi}{7:ghlights^ }{8:from diff}{7:erent sou}|
|
||||
{7:rces} |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
|
|
||||
]]}
|
||||
|
||||
-- TODO(bfredl): perhaps better undo
|
||||
feed('uuu')
|
||||
screen:expect{grid=[[
|
||||
^a longer example |
|
||||
in order to demonstrate |
|
||||
combining highlights |
|
||||
from different sources |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
1 more line; before #2 0 seconds ago |
|
||||
]]}
|
||||
end)
|
||||
|
||||
it('and splitting lines', function()
|
||||
feed('2Gtti<cr>')
|
||||
screen:expect{grid=[[
|
||||
a {5:longer} example |
|
||||
in {6:order} |
|
||||
^ to {7:de}{5:monstr}{7:ate} |
|
||||
{7:combin}{8:ing}{9: hi}ghlights |
|
||||
{9:from }{8:diff}{7:erent} sources |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{7:-- INSERT --} |
|
||||
]]}
|
||||
|
||||
-- TODO(bfredl): keep both "parts" after split, requires proper extmark ranges
|
||||
feed('<esc>tsi<cr>')
|
||||
screen:expect{grid=[[
|
||||
a {5:longer} example |
|
||||
in {6:order} |
|
||||
to {7:de}{5:mo} |
|
||||
^nstrate |
|
||||
{7:combin}{8:ing}{9: hi}ghlights |
|
||||
{9:from }{8:diff}{7:erent} sources |
|
||||
{1:~ }|
|
||||
{7:-- INSERT --} |
|
||||
]]}
|
||||
|
||||
-- TODO(bfredl): perhaps better undo
|
||||
feed('<esc>u')
|
||||
screen:expect{grid=[[
|
||||
a {5:longer} example |
|
||||
in {6:order} |
|
||||
to demo{7:^nstrat}{8:e} |
|
||||
{7:combin}{8:ing}{9: hi}ghlights |
|
||||
{9:from }{8:diff}{7:erent} sources |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
1 line less; before #3 0 seconds ago |
|
||||
]]}
|
||||
|
||||
feed('<esc>u')
|
||||
screen:expect{grid=[[
|
||||
a {5:longer} example |
|
||||
in order^ to demonstrate |
|
||||
{7:combin}{8:ing}{9: hi}ghlights |
|
||||
{9:from }{8:diff}{7:erent} sources |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
1 line less; before #2 0 seconds ago |
|
||||
]]}
|
||||
end)
|
||||
end)
|
||||
|
||||
it('prioritizes latest added highlight', function()
|
||||
|
Loading…
Reference in New Issue
Block a user