codekingpro/portable-devtools
114k
1*textprop.txt* For Vim version 9.2. Last change: 2026 Apr 072 3 4 VIM REFERENCE MANUAL by Bram Moolenaar5 6 7Displaying text with properties attached. *textprop* *text-properties*8 9 101. Introduction |text-prop-intro|112. Functions |text-prop-functions|123. When text changes |text-prop-changes|13 14 15{not able to use text properties when the |+textprop| feature was16disabled at compile time}17 18==============================================================================191. Introduction *text-prop-intro*20 21Text properties can be attached to text in a buffer. They will move with the22text: If lines are deleted or inserted the properties move with the text they23are attached to. Also when inserting/deleting text in the line before the24text property. And when inserting/deleting text inside the text property, it25will increase/decrease in size.26 27The main use for text properties is to highlight text. This can be seen as a28replacement for syntax highlighting. Instead of defining patterns to match29the text, the highlighting is set by a script, possibly using the output of an30external parser. This only needs to be done once, not every time when31redrawing the screen, thus can be much faster, after the initial cost of32attaching the text properties.33 34Text properties can also be used for other purposes to identify text. For35example, add a text property on a function name, so that a search can be36defined to jump to the next/previous function.37 38A text property is attached at a specific line and column, and has a specified39length. The property can span multiple lines.40 41A text property has these fields:42 "id" a number to be used as desired43 "type" the name of a property type44 45 46Property Types ~47 *E971*48A text property normally has the name of a property type, which defines49how to highlight the text. The property type can have these entries:50 "highlight" name of the highlight group to use51 "combine" when omitted or TRUE the text property highlighting is52 combined with any syntax highlighting; when FALSE the53 text property highlighting replaces the syntax54 highlighting55 "priority" when properties overlap, the one with the highest56 priority will be used.57 "start_incl" when TRUE inserts at the start position will be58 included in the text property59 "end_incl" when TRUE inserts at the end position will be60 included in the text property61 62 63Example ~64 65Suppose line 11 in a buffer has this text (excluding the indent):66 67 The number 123 is smaller than 4567.68 69To highlight the numbers in this text: >70 call prop_type_add('number', {'highlight': 'Constant'})71 call prop_add(11, 12, {'length': 3, 'type': 'number'})72 call prop_add(11, 32, {'length': 4, 'type': 'number'})73 74Try inserting or deleting lines above the text, you will see that the text75properties stick to the text, thus the line number is adjusted as needed.76 77Setting "start_incl" and "end_incl" is useful when white space surrounds the78text, e.g. for a function name. Using false is useful when the text starts79and/or ends with a specific character, such as the quote surrounding a string.80 81 func FuncName(arg) ~82 ^^^^^^^^ property with start_incl and end_incl set83 84 var = "text"; ~85 ^^^^^^ property with start_incl and end_incl not set86 87Nevertheless, when text is inserted or deleted the text may need to be parsed88and the text properties updated. But this can be done asynchronously.89 90 91Internal error *E967*92 93If you see E967, please report the bug. You can do this at Github:94https://github.com/vim/vim/issues/new95 96==============================================================================972. Functions *text-prop-functions*98 99Manipulating text property types:100 101prop_type_add({name}, {props}) define a new property type102prop_type_change({name}, {props}) change an existing property type103prop_type_delete({name} [, {props}]) delete a property type104prop_type_get({name} [, {props}]) get property type values105prop_type_list([{props}]) get list of property types106 107 108Manipulating text properties:109 110prop_add({lnum}, {col}, {props}) add a text property111prop_add_list({props}, [{item}, ...])112 add a text property at multiple113 positions.114prop_clear({lnum} [, {lnum-end} [, {bufnr}]])115 remove all text properties116prop_find({props} [, {direction}]) search for a text property117prop_list({lnum} [, {props}]) text properties in {lnum}118prop_remove({props} [, {lnum} [, {lnum-end}]])119 remove a text property120 121 *text-prop-functions-details*122 123 *prop_add()* *E965*124prop_add({lnum}, {col}, {props})125 Attach a text property at position {lnum}, {col}. {col} is126 counted in bytes, use one for the first column.127 If {lnum} is invalid an error is given. *E966*128 If {col} is invalid an error is given. *E964*129 130 {props} is a dictionary with these fields:131 type name of the text property type132 length length of text in bytes, can only be used133 for a property that does not continue in134 another line; can be zero135 end_lnum line number for the end of text (inclusive)136 end_col column just after the text; not used when137 "length" is present; when {col} and "end_col"138 are equal, and "end_lnum" is omitted or equal139 to {lnum}, this is a zero-width text property140 bufnr buffer to add the property to; when omitted141 the current buffer is used142 id user defined ID for the property; must be a143 number, should be positive |E1510|;144 when using "text" then any "id" value is145 ignored and a negative number is assigned146 automatically; otherwise zero is used147 *E1305*148 text text to be displayed before {col}, or149 above/below the line if {col} is zero; prepend150 and/or append spaces for padding with151 highlighting; cannot be used with "length",152 "end_lnum" and "end_col"153 See |virtual-text| for more information.154 *E1294*155 text_align when "text" is present and {col} is zero;156 specifies where to display the text:157 after after the end of the line158 right right aligned in the window (unless159 the text wraps to the next screen160 line)161 below in the next screen line162 above just above the line163 When omitted "after" is used. Only one164 "right" property can fit in each line, if165 there are two or more these will go in a166 separate line (still right aligned).167 text_padding_left *E1296*168 used when "text" is present and {col} is zero;169 padding between the end of the text line170 (leftmost column for "above" and "below") and171 the virtual text, not highlighted172 text_wrap when "text" is present and {col} is zero,173 specifies what happens if the text doesn't174 fit:175 wrap wrap the text to the next line176 truncate truncate the text to make it fit177 When omitted "truncate" is used.178 Note that this applies to the individual text179 property, the 'wrap' option sets the overall180 behavior181 All fields except "type" are optional.182 183 It is an error when both "length" and "end_lnum" or "end_col"184 are given. Either use "length" or "end_col" for a property185 within one line, or use "end_lnum" and "end_col" for a186 property that spans more than one line.187 When neither "length" nor "end_col" are given the property188 will be zero-width. That means it will move with the text, as189 a kind of mark. One character will be highlighted, if the190 type specifies highlighting.191 The property can end exactly at the last character of the192 text, or just after it. In the last case, if text is appended193 to the line, the text property size will increase, also when194 the property type does not have "end_incl" set.195 196 "type" will first be looked up in the buffer the property is197 added to. When not found, the global property types are used.198 If not found an error is given.199 *virtual-text*200 When "text" is used and the column is non-zero then this text201 will be displayed at the specified start location of the text202 property. The text of the buffer line will be shifted to make203 room. This is called "virtual text".204 When the column is zero the virtual text will appear above,205 after or below the buffer text. The "text_align" and206 "text_wrap" arguments determine how it is displayed.207 To separate the virtual text from the buffer text prepend208 and/or append spaces to the "text" field or use the209 "text_padding_left" value.210 211 Make sure to use a highlight that makes clear to the user that212 this is virtual text, otherwise it will be very confusing that213 the text cannot be edited. When using "above" you need to214 make clear this text belongs to the text line below it, when215 using "below" you need to make sure it belongs to the text216 line above it.217 218 The text will be displayed but it is not part of the actual219 buffer line, the cursor cannot be placed on it. A mouse click220 in the text will move the cursor to the first character after221 the text, or the last character of the line.222 Any Tab and other control character in the text will be223 changed to a space (Rationale: otherwise the size of the text224 is difficult to compute).225 A negative "id" will be chosen and is returned.226 227 Negative "id"s are reserved for text properties with "text"228 and cannot be used otherwise. Using a negative "id" results229 in *E1293* .230 231 Can also be used as a |method|: >232 GetLnum()->prop_add(col, props)233<234 Return type: |Number|235 236 237prop_add_list({props}, [{item}, ...]) *prop_add_list()*238 Similar to prop_add(), but attaches a text property at239 multiple positions in a buffer.240 241 {props} is a dictionary with these fields:242 bufnr buffer to add the property to; when omitted243 the current buffer is used244 id user defined ID for the property; must be a245 number; when omitted zero is used246 type name of the text property type247 All fields except "type" are optional.248 249 The second argument is a List of items, where each {item} is a250 list that specifies the starting and ending position of the251 text: [{lnum}, {col}, {end-lnum}, {end-col}]252 or: [{lnum}, {col}, {end-lnum}, {end-col}, {id}]253 254 The first two items {lnum} and {col} specify the starting255 position of the text where the property will be attached.256 The next two items {end-lnum} and {end-col} specify the257 position just after the text.258 An optional fifth item {id} can be used to give a different ID259 to a property. When omitted the ID from {props} is used,260 falling back to zero if none are present.261 262 It is not possible to add a text property with a "text" field263 here.264 265 Example: >266 call prop_add_list(#{type: 'MyProp', id: 2},267 \ [[1, 4, 1, 7],268 \ [1, 15, 1, 20],269 \ [2, 30, 3, 30]])270<271 Can also be used as a |method|: >272 GetProp()->prop_add_list([[1, 1, 1, 2], [1, 4, 1, 8]])273<274 Return type: void275 276 277prop_clear({lnum} [, {lnum-end} [, {props}]]) *prop_clear()*278 Remove all text properties from line {lnum}.279 When {lnum-end} is given, remove all text properties from line280 {lnum} to {lnum-end} (inclusive).281 282 When {props} contains a "bufnr" item use this buffer,283 otherwise use the current buffer.284 285 Can also be used as a |method|: >286 GetLnum()->prop_clear()287<288 Return type: void289 290 291prop_find({props} [, {direction}]) *prop_find()*292 Search for a text property as specified with {props}:293 id property with this ID294 type property with this type name295 both "id" and "type" must both match296 bufnr buffer to search in; when present a297 start position with "lnum" and "col"298 must be given; when omitted the299 current buffer is used300 lnum start in this line (when omitted start301 at the cursor)302 col start at this column (when omitted303 and "lnum" is given: use column 1,304 otherwise start at the cursor)305 skipstart do not look for a match at the start306 position307 308 A property matches when either "id" or "type" matches.309 {direction} can be "f" for forward and "b" for backward. When310 omitted forward search is performed.311 312 If a match is found then a Dict is returned with the entries313 as with prop_list(), and additionally an "lnum" entry.314 If no match is found then an empty Dict is returned.315 316 Return type: dict<any>317 318 319prop_list({lnum} [, {props}]) *prop_list()*320 Returns a List with all the text properties in line {lnum}.321 322 The following optional items are supported in {props}:323 bufnr use this buffer instead of the current buffer324 end_lnum return text properties in all the lines325 between {lnum} and {end_lnum} (inclusive).326 A negative value is used as an offset from the327 last buffer line; -1 refers to the last buffer328 line.329 types List of property type names. Return only text330 properties that match one of the type names.331 ids List of property identifiers. Return only332 text properties with one of these identifiers.333 334 The properties are ordered by starting column and priority.335 Each property is a Dict with these entries:336 lnum starting line number. Present only when337 returning text properties between {lnum} and338 {end_lnum}.339 col starting column340 length length in bytes, one more if line break is341 included342 id property ID343 text text to be displayed before {col}. Only344 present for |virtual-text| properties.345 text_align alignment property of |virtual-text|.346 text_padding_left347 left padding used for virtual text.348 text_wrap specifies whether |virtual-text| is wrapped.349 type name of the property type, omitted if350 the type was deleted351 type_bufnr buffer number for which this type was defined;352 0 if the type is global353 start when TRUE property starts in this line354 end when TRUE property ends in this line355 356 When "start" is zero the property started in a previous line,357 the current one is a continuation.358 When "end" is zero the property continues in the next line.359 The line break after this line is included.360 361 Returns an empty list on error.362 363 Examples: >364 " get text properties placed in line 5365 echo prop_list(5)366 " get text properties placed in line 20 in buffer 4367 echo prop_list(20, {'bufnr': 4})368 " get all the text properties between line 1 and 20369 echo prop_list(1, {'end_lnum': 20})370 " get all the text properties of type 'myprop'371 echo prop_list(1, {'types': ['myprop'],372 \ 'end_lnum': -1})373 " get all the text properties of type 'prop1' or 'prop2'374 echo prop_list(1, {'types': ['prop1', 'prop2'],375 \ 'end_lnum': -1})376 " get all the text properties with ID 8377 echo prop_list(1, {'ids': [8], 'end_lnum': line('$')})378 " get all the text properties with ID 10 and 20379 echo prop_list(1, {'ids': [10, 20], 'end_lnum': -1})380 " get text properties with type 'myprop' and ID 100381 " in buffer 4.382 echo prop_list(1, {'bufnr': 4, 'types': ['myprop'],383 \ 'ids': [100], 'end_lnum': -1})384<385 Can also be used as a |method|: >386 GetLnum()->prop_list()387<388 Return type: list<dict<any>> or list<any>389 390 *prop_remove()* *E968* *E860*391prop_remove({props} [, {lnum} [, {lnum-end}]])392 Remove a matching text property from line {lnum}. When393 {lnum-end} is given, remove matching text properties from line394 {lnum} to {lnum-end} (inclusive).395 When {lnum} is omitted remove matching text properties from396 all lines (this requires going over all lines, thus will be a397 bit slow for a buffer with many lines).398 399 {props} is a dictionary with these fields:400 id remove text properties with this ID401 type remove text properties with this type name402 types remove text properties with type names in this403 List404 both "id" and "type"/"types" must both match405 bufnr use this buffer instead of the current one406 all when TRUE remove all matching text properties,407 not just the first one408 Only one of "type" and "types" may be supplied. *E1295*409 410 A property matches when either "id" or one of the supplied411 types matches.412 If buffer "bufnr" does not exist you get an error message.413 If buffer "bufnr" is not loaded then nothing happens.414 415 Returns the number of properties that were removed.416 417 Can also be used as a |method|: >418 GetProps()->prop_remove()419<420 Return type: |Number|421 422 423prop_type_add({name}, {props}) *prop_type_add()* *E969* *E970*424 Add a text property type {name}. If a property type with this425 name already exists an error is given. Nothing is returned.426 {props} is a dictionary with these optional fields:427 bufnr define the property only for this buffer; this428 avoids name collisions and automatically429 clears the property types when the buffer is430 deleted.431 highlight name of highlight group to use432 priority when a character has multiple text433 properties the one with the highest priority434 will be used; negative values can be used, the435 default priority is zero436 combine when omitted or TRUE combine the highlight437 with any syntax highlight; when FALSE syntax438 highlight will not be used439 override when TRUE the highlight overrides any other,440 including 'cursorline' and Visual441 start_incl when TRUE inserts at the start position will442 be included in the text property443 end_incl when TRUE inserts at the end position will be444 included in the text property445 446 Can also be used as a |method|: >447 GetPropName()->prop_type_add(props)448<449 Return type: void450 451 452prop_type_change({name}, {props}) *prop_type_change()*453 Change properties of an existing text property type. If a454 property with this name does not exist an error is given.455 The {props} argument is just like |prop_type_add()|.456 457 Can also be used as a |method|: >458 GetPropName()->prop_type_change(props)459<460 Return type: void461 462 463prop_type_delete({name} [, {props}]) *prop_type_delete()*464 Remove the text property type {name}. When text properties465 using the type {name} are still in place, they will not have466 an effect and can no longer be removed by name.467 468 {props} can contain a "bufnr" item. When it is given, delete469 a property type from this buffer instead of from the global470 property types.471 472 When text property type {name} is not found there is no error.473 474 Can also be used as a |method|: >475 GetPropName()->prop_type_delete()476<477 Return type: void478 479 480prop_type_get({name} [, {props}]) *prop_type_get()*481 Returns the properties of property type {name}. This is a482 dictionary with the same fields as was given to483 prop_type_add().484 When the property type {name} does not exist, an empty485 dictionary is returned.486 487 {props} can contain a "bufnr" item. When it is given, use488 this buffer instead of the global property types.489 490 Can also be used as a |method|: >491 GetPropName()->prop_type_get()492<493 Return type: dict<any>494 495 496prop_type_list([{props}]) *prop_type_list()*497 Returns a list with all property type names.498 499 {props} can contain a "bufnr" item. When it is given, use500 this buffer instead of the global property types.501 502 Return type: list<string> or list<any>503 504 505==============================================================================5063. When text changes *text-prop-changes*507 508Vim will do its best to keep the text properties on the text where it was509attached. When inserting or deleting text the properties after the change510will move accordingly.511 512When text is deleted and a text property no longer includes any text, it is513deleted. However, a text property that was defined as zero-width will remain,514unless the whole line is deleted. When lines are joined by a multi-line515substitute command, virtual text properties on the deleted lines are moved to516the resulting joined line.517 *E275*518When a buffer is unloaded, all the text properties are gone. There is no way519to store the properties in a file. You can only re-create them. When a520buffer is hidden the text is preserved and so are the text properties. It is521not possible to add text properties to an unloaded buffer.522 523When using replace mode, the text properties stay on the same character524positions, even though the characters themselves change.525 526To update text properties after the text was changed, install a callback with527`listener_add()`. E.g, if your plugin does spell checking, you can have the528callback update spelling mistakes in the changed text. Vim will move the529properties below the changed text, so that they still highlight the same text,530thus you don't need to update these.531 532 *text-prop-cleared*533Text property columns are not updated or copied: ~534 535- When setting the line with |setline()| or through an interface, such as Lua,536 Tcl or Python. Vim does not know what text got inserted or deleted.537- With a command like `:move`, which takes a line of text out of context.538 539 540 vim:tw=78:ts=8:noet:ft=help:norl:541 