E1336 options.txt /*E1336*
E1337 vim9class.txt /*E1337*
E1338 vim9class.txt /*E1338*
-E1339 textprop.txt /*E1339*
E134 change.txt /*E134*
E1340 vim9class.txt /*E1340*
E1341 vim9class.txt /*E1341*
the current buffer is used
id user defined ID for the property; must be a
number, should be positive |E1510|;
- when using "text" then "id" must not be
- present and will be set automatically to a
- negative number; otherwise zero is used
+ when using "text" then any "id" value is
+ ignored and a negative number is assigned
+ automatically; otherwise zero is used
*E1305*
text text to be displayed before {col}, or
above/below the line if {col} is zero; prepend
is difficult to compute).
A negative "id" will be chosen and is returned.
- Before text properties with text were supported it was
- possible to use a negative "id", even though this was very
- rare. Now that negative "id"s are reserved for text
- properties with text an error is given when using a negative
- "id". When a text property with text already exists using a
- negative "id" results in *E1293* . If a negative "id" was
- used and later a text property with text is added results in
- *E1339* .
+ Negative "id"s are reserved for text properties with "text"
+ and cannot be used otherwise. Using a negative "id" results
+ in *E1293* .
Can also be used as a |method|: >
GetLnum()->prop_add(col, props)
EXTERN char e_cmdline_window_already_open[]
INIT(= N_("E1292: Command-line window is already open"));
#ifdef FEAT_PROP_POPUP
-EXTERN char e_cannot_use_negative_id_after_adding_textprop_with_text[]
- INIT(= N_("E1293: Cannot use a negative id after adding a textprop with text"));
+EXTERN char e_cannot_use_negative_id[]
+ INIT(= N_("E1293: Cannot use a negative id for a text property"));
EXTERN char e_can_only_use_text_align_when_column_is_zero[]
INIT(= N_("E1294: Can only use text_align when column is zero"));
#endif
INIT(= N_("E1337: Class variable \"%s\" not found in class \"%s\""));
// E1338 unused
#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
+// E1339 unused
#ifdef FEAT_EVAL
EXTERN char e_argument_already_declared_in_class_str[]
INIT(= N_("E1340: Argument already declared in the class: %s"));
msgstr ""
"Project-Id-Version: Vim\n"
"Report-Msgid-Bugs-To: vim-dev@vim.org\n"
-"POT-Creation-Date: 2026-03-13 18:26+0000\n"
+"POT-Creation-Date: 2026-03-18 21:08+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "E1292: Command-line window is already open"
msgstr ""
-msgid "E1293: Cannot use a negative id after adding a textprop with text"
+msgid "E1293: Cannot use a negative id for a text property"
msgstr ""
msgid "E1294: Can only use text_align when column is zero"
msgid "E1337: Class variable \"%s\" not found in class \"%s\""
msgstr ""
-msgid ""
-"E1339: Cannot add a textprop with text after using a textprop with a "
-"negative id"
-msgstr ""
-
#, c-format
msgid "E1340: Argument already declared in the class: %s"
msgstr ""
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()
- CheckScreendump
- " 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', {})
+ " Negative id is always rejected. Before the fix, prop_add() with a negative
+ " id succeeded when no virtual text existed, then prop_list() would dereference
+ " a NULL pointer (b_textprop_text.ga_data) and crash.
+ call assert_fails("call prop_add(1, 1, #{type: 'test1', length: 1, id: -1})", 'E1293:')
+ call assert_equal([], prop_list(1))
- call term_sendkeys(buf, ":call AddTextprop()\<CR>")
- call VerifyScreenDump(buf, 'Test_prop_negative_error_2', {})
+ " id is silently ignored when text is also specified.
+ let propid = prop_add(1, 1, #{type: 'test1', text: 'virtual', id: 42})
+ call assert_true(propid < 0)
- call StopVimInTerminal(buf)
+ call prop_type_delete('test1')
endfunc
func Test_modify_text_before_prop()
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".
if (dict_arg != NULL && get_bufnr_from_arg(dict_arg, &buf) == FAIL)
goto theend;
- if (id < 0)
- {
- 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;
- }
+ // Always assign an internal negative id; ignore any user-provided id.
id = get_textprop_id(buf);
+ else if (id < 0)
+ {
+ emsg(_(e_cannot_use_negative_id));
+ goto theend;
}
// This must be done _before_ we add the property because property changes
{
proptype_T *pt;
int buflocal = TRUE;
- int virtualtext_prop = prop->tp_id < 0;
+ // A negative tp_id normally means a virtual text property, but a user
+ // may set a negative id for a regular property when no virtual text
+ // properties exist. Guard against that by checking the index is valid.
+ int virtualtext_prop = prop->tp_id < 0
+ && -prop->tp_id - 1 < buf->b_textprop_text.ga_len;
dict_add_number(dict, "col", (prop->tp_col == MAXCOL) ? 0 : prop->tp_col);
if (!virtualtext_prop)
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 196,
/**/
195,
/**/