forked from aniani/vim
patch 9.0.0993: display errors when adding or removing text property type
Problem: Display errors when adding or removing text property type. Solution: Perform a full redraw. Only use text properties for which the type is defined. (closes #11655)
This commit is contained in:
parent
500c444283
commit
89469d157a
@ -986,11 +986,15 @@ init_chartabsize_arg(
|
||||
mch_memmove(cts->cts_text_props + count, prop_start,
|
||||
count * sizeof(textprop_T));
|
||||
for (i = 0; i < count; ++i)
|
||||
if (cts->cts_text_props[i + count].tp_id < 0)
|
||||
{
|
||||
textprop_T *tp = cts->cts_text_props + i + count;
|
||||
if (tp->tp_id < 0
|
||||
&& text_prop_type_valid(wp->w_buffer, tp))
|
||||
{
|
||||
cts->cts_has_prop_with_text = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cts->cts_has_prop_with_text)
|
||||
{
|
||||
// won't use the text properties, free them
|
||||
|
14
src/move.c
14
src/move.c
@ -645,6 +645,20 @@ changed_window_setting_win(win_T *wp)
|
||||
redraw_win_later(wp, UPD_NOT_VALID);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call changed_window_setting_win() for every window containing "buf".
|
||||
*/
|
||||
void
|
||||
changed_window_setting_buf(buf_T *buf)
|
||||
{
|
||||
tabpage_T *tp;
|
||||
win_T *wp;
|
||||
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp)
|
||||
if (wp->w_buffer == buf)
|
||||
changed_window_setting_win(wp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set wp->w_topline to a certain number.
|
||||
*/
|
||||
|
@ -7,6 +7,7 @@ void update_curswant(void);
|
||||
void check_cursor_moved(win_T *wp);
|
||||
void changed_window_setting(void);
|
||||
void changed_window_setting_win(win_T *wp);
|
||||
void changed_window_setting_buf(buf_T *buf);
|
||||
void set_topline(win_T *wp, linenr_T lnum);
|
||||
void changed_cline_bef_curs(void);
|
||||
void changed_cline_bef_curs_win(win_T *wp);
|
||||
|
@ -10,6 +10,7 @@ void sort_text_props(buf_T *buf, textprop_T *props, int *idxs, int count);
|
||||
int find_visible_prop(win_T *wp, int type_id, int id, textprop_T *prop, linenr_T *found_lnum);
|
||||
void add_text_props(linenr_T lnum, textprop_T *text_props, int text_prop_count);
|
||||
proptype_T *text_prop_type_by_id(buf_T *buf, int id);
|
||||
int text_prop_type_valid(buf_T *buf, textprop_T *prop);
|
||||
void f_prop_clear(typval_T *argvars, typval_T *rettv);
|
||||
void f_prop_find(typval_T *argvars, typval_T *rettv);
|
||||
void f_prop_list(typval_T *argvars, typval_T *rettv);
|
||||
|
10
src/testdir/dumps/Test_prop_delete_updates_1.dump
Normal file
10
src/testdir/dumps/Test_prop_delete_updates_1.dump
Normal file
@ -0,0 +1,10 @@
|
||||
|s+0&#ffffff0|o|m|e| |t|e|x|t| @50
|
||||
@3|T+0&#ffd7ff255|h|e| |q|u|i|c|k| |b|r|o|w|n| |f|o|x| |j|u|m|p|s| |o|v|e|r| |t|h|e| |l|a|z|y| |d|o|g| +0&#ffffff0@13
|
||||
@5|T+0&#ffd7ff255|h|e| |q|u|i|c|k| |b|r|o|w|n| |f|o|x| |j|u|m|p|s| |o|v|e|r| |t|h|e| |l|a|z|y| |d|o|g| +0&#ffffff0@11
|
||||
|m|o|r|e| |t|e|x|t| @50
|
||||
>t|h|e| |e|n|d| @52
|
||||
|~+0#4040ff13&| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
| +0#0000000&@41|3|,|1| @10|A|l@1|
|
10
src/testdir/dumps/Test_prop_delete_updates_2.dump
Normal file
10
src/testdir/dumps/Test_prop_delete_updates_2.dump
Normal file
@ -0,0 +1,10 @@
|
||||
|s+0&#ffffff0|o|m|e| |t|e|x|t| @50
|
||||
|m|o|r|e| |t|e|x|t| @50
|
||||
>t|h|e| |e|n|d| @52
|
||||
|~+0#4040ff13&| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
| +0#0000000&@41|3|,|1| @10|A|l@1|
|
10
src/testdir/dumps/Test_prop_delete_updates_3.dump
Normal file
10
src/testdir/dumps/Test_prop_delete_updates_3.dump
Normal file
@ -0,0 +1,10 @@
|
||||
|s+0&#ffffff0|o|m|e| |t|e|x|t| @50
|
||||
>m|o|r|e| |t|e|x|t| @50
|
||||
|t|h|e| |e|n|d| @52
|
||||
|~+0#4040ff13&| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
| +0#0000000&@41|2|,|1| @10|A|l@1|
|
@ -1700,7 +1700,7 @@ func Test_prop_func_invalid_args()
|
||||
call assert_fails("call prop_type_delete([])", 'E730:')
|
||||
call assert_fails("call prop_type_delete('xyz', [])", 'E715:')
|
||||
call assert_fails("call prop_type_get([])", 'E730:')
|
||||
call assert_fails("call prop_type_get('', [])", 'E474:')
|
||||
call assert_fails("call prop_type_get('', [])", 'E475:')
|
||||
call assert_fails("call prop_type_list([])", 'E715:')
|
||||
call assert_fails("call prop_type_add('yyy', 'not_a_dict')", 'E715:')
|
||||
call assert_fails("call prop_add(1, 5, {'type':'missing_type', 'length':1})", 'E971:')
|
||||
@ -3627,5 +3627,43 @@ def Test_textprop_in_quickfix_window()
|
||||
bwipe!
|
||||
enddef
|
||||
|
||||
func Test_text_prop_delete_updates()
|
||||
CheckRunVimInTerminal
|
||||
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
|
||||
setline(1, ['some text', 'more text', 'the end'])
|
||||
prop_type_add('test', {highlight: 'DiffChange'})
|
||||
prop_add(1, 0, {
|
||||
type: 'test',
|
||||
text: 'The quick brown fox jumps over the lazy dog',
|
||||
text_align: 'below',
|
||||
text_padding_left: 3,
|
||||
})
|
||||
prop_add(1, 0, {
|
||||
type: 'test',
|
||||
text: 'The quick brown fox jumps over the lazy dog',
|
||||
text_align: 'below',
|
||||
text_padding_left: 5,
|
||||
})
|
||||
|
||||
normal! G
|
||||
END
|
||||
call writefile(lines, 'XtextPropDelete', 'D')
|
||||
let buf = RunVimInTerminal('-S XtextPropDelete', #{rows: 10, cols: 60})
|
||||
call VerifyScreenDump(buf, 'Test_prop_delete_updates_1', {})
|
||||
|
||||
" Check that after deleting the text prop type the text properties using
|
||||
" this type no longer show and are not counted for cursor positioning.
|
||||
call term_sendkeys(buf, ":call prop_type_delete('test')\<CR>")
|
||||
call VerifyScreenDump(buf, 'Test_prop_delete_updates_2', {})
|
||||
|
||||
call term_sendkeys(buf, "ggj")
|
||||
call VerifyScreenDump(buf, 'Test_prop_delete_updates_3', {})
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -3158,13 +3158,13 @@ enddef
|
||||
def Test_prop_type_add()
|
||||
v9.CheckDefAndScriptFailure(['prop_type_add({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
|
||||
v9.CheckDefAndScriptFailure(['prop_type_add("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
|
||||
assert_fails("prop_type_add('', {highlight: 'Search'})", 'E474:')
|
||||
assert_fails("prop_type_add('', {highlight: 'Search'})", 'E475:')
|
||||
enddef
|
||||
|
||||
def Test_prop_type_change()
|
||||
v9.CheckDefAndScriptFailure(['prop_type_change({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
|
||||
v9.CheckDefAndScriptFailure(['prop_type_change("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
|
||||
assert_fails("prop_type_change('', {highlight: 'Search'})", 'E474:')
|
||||
assert_fails("prop_type_change('', {highlight: 'Search'})", 'E475:')
|
||||
enddef
|
||||
|
||||
def Test_prop_type_delete()
|
||||
|
@ -653,7 +653,7 @@ prop_count_above_below(buf_T *buf, linenr_T lnum)
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
mch_memmove(&prop, props + i * sizeof(prop), sizeof(prop));
|
||||
if (prop.tp_col == MAXCOL)
|
||||
if (prop.tp_col == MAXCOL && text_prop_type_valid(buf, &prop))
|
||||
{
|
||||
if ((prop.tp_flags & TP_FLAG_ALIGN_BELOW)
|
||||
|| (next_right_goes_below
|
||||
@ -697,7 +697,8 @@ count_props(linenr_T lnum, int only_starting, int last_line)
|
||||
// previous line, or when not in the last line and it is virtual text
|
||||
// after the line.
|
||||
if ((only_starting && (prop.tp_flags & TP_FLAG_CONT_PREV))
|
||||
|| (!last_line && prop.tp_col == MAXCOL))
|
||||
|| (!last_line && prop.tp_col == MAXCOL)
|
||||
|| !text_prop_type_valid(curbuf, &prop))
|
||||
--result;
|
||||
}
|
||||
return result;
|
||||
@ -801,20 +802,24 @@ sort_text_props(
|
||||
* Returns FAIL when not found.
|
||||
*/
|
||||
int
|
||||
find_visible_prop(win_T *wp, int type_id, int id, textprop_T *prop,
|
||||
linenr_T *found_lnum)
|
||||
find_visible_prop(
|
||||
win_T *wp,
|
||||
int type_id,
|
||||
int id,
|
||||
textprop_T *prop,
|
||||
linenr_T *found_lnum)
|
||||
{
|
||||
linenr_T lnum;
|
||||
char_u *props;
|
||||
int count;
|
||||
int i;
|
||||
// return when "type_id" no longer exists
|
||||
if (text_prop_type_by_id(wp->w_buffer, type_id) == NULL)
|
||||
return FAIL;
|
||||
|
||||
// w_botline may not have been updated yet.
|
||||
validate_botline_win(wp);
|
||||
for (lnum = wp->w_topline; lnum < wp->w_botline; ++lnum)
|
||||
for (linenr_T lnum = wp->w_topline; lnum < wp->w_botline; ++lnum)
|
||||
{
|
||||
count = get_text_props(wp->w_buffer, lnum, &props, FALSE);
|
||||
for (i = 0; i < count; ++i)
|
||||
char_u *props;
|
||||
int count = get_text_props(wp->w_buffer, lnum, &props, FALSE);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
mch_memmove(prop, props + i * sizeof(textprop_T),
|
||||
sizeof(textprop_T));
|
||||
@ -985,6 +990,15 @@ text_prop_type_by_id(buf_T *buf, int id)
|
||||
return type;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if "prop" is a valid text property type.
|
||||
*/
|
||||
int
|
||||
text_prop_type_valid(buf_T *buf, textprop_T *prop)
|
||||
{
|
||||
return text_prop_type_by_id(buf, prop->tp_type) != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_clear({lnum} [, {lnum_end} [, {bufnr}]])
|
||||
*/
|
||||
@ -1745,7 +1759,7 @@ prop_type_set(typval_T *argvars, int add)
|
||||
name = tv_get_string(&argvars[0]);
|
||||
if (*name == NUL)
|
||||
{
|
||||
emsg(_(e_invalid_argument));
|
||||
semsg(_(e_invalid_argument_str), "\"\"");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1898,7 +1912,7 @@ f_prop_type_delete(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
name = tv_get_string(&argvars[0]);
|
||||
if (*name == NUL)
|
||||
{
|
||||
emsg(_(e_invalid_argument));
|
||||
semsg(_(e_invalid_argument_str), "\"\"");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1926,6 +1940,10 @@ f_prop_type_delete(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
}
|
||||
hash_remove(ht, hi, "prop type delete");
|
||||
vim_free(prop);
|
||||
|
||||
// currently visibile text properties will disappear
|
||||
redraw_all_later(UPD_CLEAR);
|
||||
changed_window_setting_buf(buf == NULL ? curbuf : buf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1945,7 +1963,7 @@ f_prop_type_get(typval_T *argvars, typval_T *rettv)
|
||||
name = tv_get_string(&argvars[0]);
|
||||
if (*name == NUL)
|
||||
{
|
||||
emsg(_(e_invalid_argument));
|
||||
semsg(_(e_invalid_argument_str), "\"\"");
|
||||
return;
|
||||
}
|
||||
if (rettv_dict_alloc(rettv) == OK)
|
||||
|
@ -695,6 +695,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
993,
|
||||
/**/
|
||||
992,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user