# HG changeset patch # User Bram Moolenaar # Date 1671457504 -3600 # Node ID 966c87c579128ab22024d593384665e75b062908 # Parent c81f178ad4333f8afd6dd773f73bd9f5a1da7419 patch 9.0.1077: can add text property with negative ID before virtual text Commit: https://github.com/vim/vim/commit/4ce1f99a2d58b809ab5a5c602bd031426f8527e8 Author: Bram Moolenaar Date: Mon Dec 19 13:31:06 2022 +0000 patch 9.0.1077: can add text property with negative ID before virtual text Problem: Can add text property with negative ID before virtual text property. Solution: Remember that a text property with a negative ID was used and give an appropriate error message. (closes #11725) Fix index computation. diff --git a/src/charset.c b/src/charset.c --- a/src/charset.c +++ b/src/charset.c @@ -1181,7 +1181,7 @@ win_lbr_chartabsize( ? col == 0 : (s[0] == NUL || s[1] == NUL) && cts->cts_with_trailing))) - && tp->tp_id - 1 < gap->ga_len) + && -tp->tp_id - 1 < gap->ga_len) { char_u *p = ((char_u **)gap->ga_data)[-tp->tp_id - 1]; diff --git a/src/errors.h b/src/errors.h --- a/src/errors.h +++ b/src/errors.h @@ -3397,3 +3397,7 @@ EXTERN char e_class_member_not_found_str EXTERN char e_member_not_found_on_class_str_str[] INIT(= N_("E1338: Member not found on class \"%s\": %s")); #endif +#ifdef FEAT_PROP_POPUP +EXTERN char e_cannot_add_textprop_with_text_after_using_textprop_with_negative_id[] + INIT(= N_("E1339: Cannot add a textprop with text after using a textprop with a negative id")); +#endif diff --git a/src/testdir/dumps/Test_prop_negative_error_1.dump b/src/testdir/dumps/Test_prop_negative_error_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_negative_error_1.dump @@ -0,0 +1,8 @@ +>o+0&#ffffff0|n|e| @56 +|t|w|o| @56 +|t+0#ffffff16#ff404010|h|r|e@1| +0#0000000#ffffff0@54 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +|~| @58 +| +0#0000000&@41|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_prop_negative_error_2.dump b/src/testdir/dumps/Test_prop_negative_error_2.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_negative_error_2.dump @@ -0,0 +1,8 @@ +|~+0#4040ff13#ffffff0| @58 +|~| @58 +|~| @58 +|E+0#ffffff16#e000002|r@1|o|r| |d|e|t|e|c|t|e|d| |w|h|i|l|e| |p|r|o|c|e|s@1|i|n|g| |f|u|n|c|t|i|o|n| |A|d@1|T|e|x|t|p|r|o|p|:| +0#0000000#ffffff0@6 +|l+0#af5f00255&|i|n|e| @3|5|:| +0#0000000&@49 +|E+0#ffffff16#e000002|1|3@1|9|:| |C|a|n@1|o|t| |a|d@1| |a| |t|e|x|t|p|r|o|p| |w|i|t|h| |t|e|x|t| |a|f|t|e|r| |u|s|i|n|g| |a| |t|e|x|t|p|r|o +|p| |w|i|t|h| |a| |n|e|g|a|t|i|v|e| |i|d| +0#0000000#ffffff0@39 +|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@20 diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -3725,6 +3725,50 @@ func Test_text_prop_diff_mode() call StopVimInTerminal(buf) endfunc + +func Test_error_when_using_negative_id() + call prop_type_add('test1', #{highlight: 'ErrorMsg'}) + call prop_add(1, 1, #{type: 'test1', text: 'virtual'}) + call assert_fails("call prop_add(1, 1, #{type: 'test1', length: 1, id: -1})", 'E1293:') + + call prop_type_delete('test1') +endfunc + +func Test_error_after_using_negative_id() + " This needs to run a separate Vim instance because the + " "did_use_negative_pop_id" will be set. + CheckRunVimInTerminal + + let lines =<< trim END + vim9script + + setline(1, ['one', 'two', 'three']) + prop_type_add('test_1', {highlight: 'Error'}) + prop_type_add('test_2', {highlight: 'WildMenu'}) + + prop_add(3, 1, { + type: 'test_1', + length: 5, + id: -1 + }) + + def g:AddTextprop() + prop_add(1, 0, { + type: 'test_2', + text: 'The quick fox', + text_padding_left: 2 + }) + enddef + END + call writefile(lines, 'XtextPropError', 'D') + let buf = RunVimInTerminal('-S XtextPropError', #{rows: 8, cols: 60}) + call VerifyScreenDump(buf, 'Test_prop_negative_error_1', {}) + + call term_sendkeys(buf, ":call AddTextprop()\") + call VerifyScreenDump(buf, 'Test_prop_negative_error_2', {}) + + call StopVimInTerminal(buf) +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/textprop.c b/src/textprop.c --- a/src/textprop.c +++ b/src/textprop.c @@ -424,6 +424,10 @@ get_textprop_id(buf_T *buf) return -(buf->b_textprop_text.ga_len + 1); } +// Flag that is set when a negative ID isused for a normal text property. +// It is then impossible to use virtual text properties. +static int did_use_negative_pop_id = FALSE; + /* * Shared between prop_add() and popup_create(). * "dict_arg" is the function argument of a dict containing "bufnr". @@ -576,13 +580,25 @@ prop_add_common( if (dict_arg != NULL && get_bufnr_from_arg(dict_arg, &buf) == FAIL) goto theend; - if (id < 0 && buf->b_textprop_text.ga_len > 0) + if (id < 0) { - emsg(_(e_cannot_use_negative_id_after_adding_textprop_with_text)); - goto theend; + if (buf->b_textprop_text.ga_len > 0) + { + emsg(_(e_cannot_use_negative_id_after_adding_textprop_with_text)); + goto theend; + } + did_use_negative_pop_id = TRUE; } + if (text != NULL) + { + if (did_use_negative_pop_id) + { + emsg(_(e_cannot_add_textprop_with_text_after_using_textprop_with_negative_id)); + goto theend; + } id = get_textprop_id(buf); + } // This must be done _before_ we add the property because property changes // trigger buffer (memline) reorganisation, which needs this flag to be diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1077, +/**/ 1076, /**/ 1075,