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
|
/// Get highlights to display at a specific line
|
||||||
///
|
///
|
||||||
|
@ -5599,9 +5599,10 @@ insertchar (
|
|||||||
do_digraph(-1); /* clear digraphs */
|
do_digraph(-1); /* clear digraphs */
|
||||||
do_digraph(buf[i-1]); /* may be the start of a digraph */
|
do_digraph(buf[i-1]); /* may be the start of a digraph */
|
||||||
buf[i] = NUL;
|
buf[i] = NUL;
|
||||||
|
colnr_T col_start = curwin->w_cursor.col;
|
||||||
ins_str(buf);
|
ins_str(buf);
|
||||||
extmark_col_adjust(curbuf, curwin->w_cursor.lnum,
|
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);
|
(long)STRLEN(buf), kExtmarkUndo);
|
||||||
if (flags & INSCHAR_CTRLV) {
|
if (flags & INSCHAR_CTRLV) {
|
||||||
redo_literal(*buf);
|
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,
|
bool marks_moved = extmark_col_adjust_impl(buf, lnum, mincol, lnum_amount,
|
||||||
false, col_amount);
|
false, col_amount);
|
||||||
|
|
||||||
|
marks_moved |= bufhl_mark_col_adjust(buf, lnum, mincol,
|
||||||
|
lnum_amount, col_amount);
|
||||||
|
|
||||||
if (undo == kExtmarkUndo && marks_moved) {
|
if (undo == kExtmarkUndo && marks_moved) {
|
||||||
u_extmark_col_adjust(buf, lnum, mincol, lnum_amount, col_amount);
|
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,
|
marks_moved = extmark_col_adjust_impl(buf, lnum, mincol, 0,
|
||||||
true, (long)endcol);
|
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
|
// Deletes at the end of the line have different behaviour than the normal
|
||||||
// case when deleted.
|
// case when deleted.
|
||||||
// Cleanup any marks that are floating beyond the end of line.
|
// Cleanup any marks that are floating beyond the end of line.
|
||||||
|
@ -217,6 +217,161 @@ describe('Buffer highlighting', function()
|
|||||||
|
|
|
|
||||||
]])
|
]])
|
||||||
end)
|
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)
|
end)
|
||||||
|
|
||||||
it('prioritizes latest added highlight', function()
|
it('prioritizes latest added highlight', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user