Merge remote-tracking branch 'origin/master' into lsp-followup

This commit is contained in:
Ashkan Kiani
2019-11-23 14:28:54 -08:00
11 changed files with 307 additions and 67 deletions

View File

@@ -933,10 +933,11 @@ nvim_open_win({buffer}, {enter}, {config}) *nvim_open_win()*
'number', 'relativenumber', 'cursorline',
'cursorcolumn', 'foldcolumn', 'spell' and
'list' options. 'signcolumn' is changed to
`auto` . The end-of-buffer region is hidden
by setting `eob` flag of 'fillchars' to a
space char, and clearing the |EndOfBuffer|
region in 'winhighlight'.
`auto` and 'colorcolumn' is cleared. The
end-of-buffer region is hidden by setting
`eob` flag of 'fillchars' to a space char, and
clearing the |EndOfBuffer| region in
'winhighlight'.
Return: ~
Window handle, or 0 on error

View File

@@ -1074,9 +1074,10 @@ fail:
/// float where the text should not be edited. Disables
/// 'number', 'relativenumber', 'cursorline', 'cursorcolumn',
/// 'foldcolumn', 'spell' and 'list' options. 'signcolumn'
/// is changed to `auto`. The end-of-buffer region is hidden
/// by setting `eob` flag of 'fillchars' to a space char,
/// and clearing the |EndOfBuffer| region in 'winhighlight'.
/// is changed to `auto` and 'colorcolumn' is cleared. The
/// end-of-buffer region is hidden by setting `eob` flag of
/// 'fillchars' to a space char, and clearing the
/// |EndOfBuffer| region in 'winhighlight'.
/// @param[out] err Error details, if any
///
/// @return Window handle, or 0 on error

View File

@@ -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
///

View File

@@ -359,6 +359,24 @@ void changed_bytes(linenr_T lnum, colnr_T col)
}
}
/// insert/delete bytes at column
///
/// Like changed_bytes() but also adjust extmark for "added" bytes.
/// When "added" is negative text was deleted.
static void inserted_bytes(linenr_T lnum, colnr_T col, int added)
{
if (added > 0) {
extmark_col_adjust(curbuf, lnum, col+1, 0, added, kExtmarkUndo);
} else if (added < 0) {
// TODO(bfredl): next revision of extmarks should handle both these
// with the same entry point. Also with more sane params..
extmark_col_adjust_delete(curbuf, lnum, col+2,
col+(-added)+1, kExtmarkUndo, 0);
}
changed_bytes(lnum, col);
}
/// Appended "count" lines below line "lnum" in the current buffer.
/// Must be called AFTER the change and after mark_adjust().
/// Takes care of marking the buffer to be redrawn and sets the changed flag.
@@ -630,7 +648,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
ml_replace(lnum, newp, false);
// mark the buffer as changed and prepare for displaying
changed_bytes(lnum, (colnr_T)col);
inserted_bytes(lnum, (colnr_T)col, (int)(newlen - oldlen));
// If we're in Insert or Replace mode and 'showmatch' is set, then briefly
// show the match for right parens and braces.
@@ -676,7 +694,7 @@ void ins_str(char_u *s)
assert(bytes >= 0);
memmove(newp + col + newlen, oldp + col, (size_t)bytes);
ml_replace(lnum, newp, false);
changed_bytes(lnum, col);
inserted_bytes(lnum, col, newlen);
curwin->w_cursor.col += newlen;
}
@@ -797,7 +815,7 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
}
// mark the buffer as changed and prepare for displaying
changed_bytes(lnum, curwin->w_cursor.col);
inserted_bytes(lnum, col, -count);
return OK;
}

View File

@@ -5600,9 +5600,6 @@ insertchar (
do_digraph(buf[i-1]); /* may be the start of a digraph */
buf[i] = NUL;
ins_str(buf);
extmark_col_adjust(curbuf, curwin->w_cursor.lnum,
(colnr_T)(curwin->w_cursor.col + 1), 0,
(long)STRLEN(buf), kExtmarkUndo);
if (flags & INSCHAR_CTRLV) {
redo_literal(*buf);
i = 1;
@@ -5613,9 +5610,6 @@ insertchar (
} else {
int cc;
extmark_col_adjust(curbuf, curwin->w_cursor.lnum,
(colnr_T)(curwin->w_cursor.col + 1), 0,
1, kExtmarkUndo);
if ((cc = utf_char2len(c)) > 1) {
char_u buf[MB_MAXBYTES + 1];
@@ -8506,14 +8500,6 @@ static bool ins_tab(void)
temp -= get_nolist_virtcol() % temp;
// Move extmarks
extmark_col_adjust(curbuf,
curwin->w_cursor.lnum,
curwin->w_cursor.col,
0,
temp,
kExtmarkUndo);
/*
* Insert the first space with ins_char(). It will delete one char in
* replace mode. Insert the rest with ins_str(); it will not delete any

View File

@@ -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.

View File

@@ -1644,8 +1644,6 @@ int op_delete(oparg_T *oap)
curwin->w_cursor.col = 0;
(void)del_bytes((colnr_T)n, !virtual_op,
oap->op_type == OP_DELETE && !oap->is_VIsual);
extmark_col_adjust(curbuf, curwin->w_cursor.lnum,
(colnr_T)0, 0L, (long)-n, kExtmarkUndo);
curwin->w_cursor = curpos; // restore curwin->w_cursor
(void)do_join(2, false, false, false, false);
}
@@ -1685,7 +1683,6 @@ setmarks:
if (oap->is_VIsual == false) {
endcol = MAX(endcol - 1, mincol);
}
extmark_col_adjust_delete(curbuf, lnum, mincol, endcol, kExtmarkUndo, 0);
}
return OK;
}
@@ -2279,7 +2276,7 @@ void op_insert(oparg_T *oap, long count1)
colnr_T col = oap->start.col;
for (linenr_T lnum = oap->start.lnum; lnum <= oap->end.lnum; lnum++) {
extmark_col_adjust(curbuf, lnum, col, 0, 1, kExtmarkUndo);
}
}
}
/*
@@ -4279,14 +4276,14 @@ format_lines(
if (next_leader_len > 0) {
(void)del_bytes(next_leader_len, false, false);
mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L,
(long)-next_leader_len, 0, kExtmarkUndo);
(long)-next_leader_len, 0, kExtmarkNOOP);
} else if (second_indent > 0) { // the "leader" for FO_Q_SECOND
int indent = (int)getwhitecols_curline();
if (indent > 0) {
(void)del_bytes(indent, FALSE, FALSE);
(void)del_bytes(indent, false, false);
mark_col_adjust(curwin->w_cursor.lnum,
(colnr_T)0, 0L, (long)-indent, 0, kExtmarkUndo);
(colnr_T)0, 0L, (long)-indent, 0, kExtmarkNOOP);
}
}
curwin->w_cursor.lnum--;
@@ -4951,23 +4948,6 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
curbuf->b_op_end.col--;
}
// if buf1 wasn't allocated, only a singe ASCII char was changed in-place.
if (did_change && buf1 != NULL) {
extmark_col_adjust_delete(curbuf,
pos->lnum,
startpos.col + 2,
endpos.col + 1 + length,
kExtmarkUndo,
0);
long col_amount = (long)STRLEN(buf1);
extmark_col_adjust(curbuf,
pos->lnum,
startpos.col + 1,
0,
col_amount,
kExtmarkUndo);
}
theend:
xfree(buf1);
if (visual) {

View File

@@ -633,6 +633,12 @@ void win_set_minimal_style(win_T *wp)
xfree(wp->w_p_scl);
wp->w_p_scl = (char_u *)xstrdup("auto");
}
// colorcolumn: cleared
if (wp->w_p_cc != NULL && *wp->w_p_cc != NUL) {
xfree(wp->w_p_cc);
wp->w_p_cc = (char_u *)xstrdup("");
}
}
void win_config_float(win_T *wp, FloatConfig fconfig)

View File

@@ -422,7 +422,7 @@ describe('Extmarks buffer api', function()
set_extmark(ns, marks[1], 1, 2)
-- Insert a fullwidth (two col) tilde, NICE
feed('0i<esc>')
check_undo_redo(ns, marks[1], 1, 2, 1, 3)
check_undo_redo(ns, marks[1], 1, 2, 1, 5)
end)
it('marks move with blockwise inserts #extmarks', function()
@@ -475,6 +475,13 @@ describe('Extmarks buffer api', function()
check_undo_redo(ns, marks[2], 0, 3, 1, 2)
end)
it('deleting right before a mark works #extmarks', function()
-- op_delete in ops.c
set_extmark(ns, marks[1], 0, 2)
feed('0lx')
check_undo_redo(ns, marks[1], 0, 2, 0, 1)
end)
it('deleting on a mark works #extmarks', function()
-- op_delete in ops.c
set_extmark(ns, marks[1], 0, 2)

View File

@@ -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 {MATCH:.*}|
]]}
-- 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 {MATCH:.*}|
]]}
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 {MATCH:.*}|
]]}
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 {MATCH:.*}|
]]}
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 {MATCH:.*}|
]]}
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 {MATCH:.*}|
]]}
end)
end)
it('prioritizes latest added highlight', function()

View File

@@ -39,6 +39,7 @@ describe('floating windows', function()
[19] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray},
[20] = {bold = true, foreground = Screen.colors.Brown},
[21] = {background = Screen.colors.Gray90},
[22] = {background = Screen.colors.LightRed},
}
it('behavior', function()
@@ -398,6 +399,7 @@ describe('floating windows', function()
it("can use 'minimal' style", function()
command('set number')
command('set signcolumn=yes')
command('set colorcolumn=1')
command('set cursorline')
command('set foldcolumn=1')
command('hi NormalFloat guibg=#333333')
@@ -414,9 +416,9 @@ describe('floating windows', function()
[2:----------------------------------------]|
[3:----------------------------------------]|
## grid 2
{19: }{20: 1 }{21:^x }|
{19: }{14: 2 }y |
{19: }{14: 3 } |
{19: }{20: 1 }{22:^x}{21: }|
{19: }{14: 2 }{22:y} |
{19: }{14: 3 }{22: } |
{0:~ }|
{0:~ }|
{0:~ }|
@@ -430,9 +432,9 @@ describe('floating windows', function()
]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}}
else
screen:expect{grid=[[
{19: }{20: 1 }{21:^x }|
{19: }{14: 2 }y |
{19: }{14: 3 } {15:x } |
{19: }{20: 1 }{22:^x}{21: }|
{19: }{14: 2 }{22:y} |
{19: }{14: 3 }{22: } {15:x } |
{0:~ }{15:y }{0: }|
{0:~ }{15: }{0: }|
{0:~ }{15: }{0: }|
@@ -454,9 +456,9 @@ describe('floating windows', function()
[2:----------------------------------------]|
[3:----------------------------------------]|
## grid 2
{19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{21:^x }|
{19: }{14: 2 }y |
{19: }{14: 3 } |
{19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }|
{19: }{14: 2 }{22:y} |
{19: }{14: 3 }{22: } |
{0:~ }|
{0:~ }|
{0:~ }|
@@ -471,9 +473,9 @@ describe('floating windows', function()
else
screen:expect([[
{19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{21:^x }|
{19: }{14: 2 }y |
{19: }{14: 3 } {17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x } |
{19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }|
{19: }{14: 2 }{22:y} |
{19: }{14: 3 }{22: } {17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x } |
{0:~ }{19: }{15:y }{0: }|
{0:~ }{19: }{15: }{0: }|
{0:~ }{15: }{0: }|
@@ -495,9 +497,9 @@ describe('floating windows', function()
[2:----------------------------------------]|
[3:----------------------------------------]|
## grid 2
{19: }{20: 1 }{21:^x }|
{19: }{14: 2 }y |
{19: }{14: 3 } |
{19: }{20: 1 }{22:^x}{21: }|
{19: }{14: 2 }{22:y} |
{19: }{14: 3 }{22: } |
{0:~ }|
{0:~ }|
{0:~ }|
@@ -511,9 +513,9 @@ describe('floating windows', function()
]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}}
else
screen:expect([[
{19: }{20: 1 }{21:^x }|
{19: }{14: 2 }y |
{19: }{14: 3 } {15: } |
{19: }{20: 1 }{22:^x}{21: }|
{19: }{14: 2 }{22:y} |
{19: }{14: 3 }{22: } {15: } |
{0:~ }{15: }{0: }|
{0:~ }{15: }{0: }|
{0:~ }{15: }{0: }|