summaryrefslogtreecommitdiffstatshomepage
path: root/test/functional/api/extmark_spec.lua
AgeCommit message (Collapse)AuthorFiles
2026-04-18fix(marks): adjust marks when unloading "nofile" buffer #39118luukvbaal1
Problem: Marks are not adjusted unloading a buffer that doesn't exist on disk. E.g. extmarks are still valid (and will be beyond the end of the buffer if the buffer is reloaded), even though the text is lost. Solution: Adjust marks for a cleared buffer when unloading a buffer that doesn't exist on disk.
2026-03-16fix(api): use standard error messagesJustin M. Keyes1
2026-03-09feat(extmark): support end_col=-1 if strict=false #28169Stefan Novaković1
Problem: There is an inconsistency between extmarks/highlights regarding the `end_col` param. Solution: Allow end_col=-1 to mean "end of line" (if strict=false). Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-02-16Merge #37875 prompt-buffer fixesJustin M. Keyes1
2026-02-16fix(extmark): adjust invalidate range by one for deleted lines #37897luukvbaal1
Problem: A multi-line extmark that ends exactly at a deleted range end is not invalidated. Revalidated sign mark is added with incorrect range. Solution: Remove questionable invalidation range condition which was originally added to avoid deleting a mark that ends below a deleted line. Since splicing for a deleted line, and a replaced range that explicitly ends at column 0 beyond a deleted line is identical, we can't try to distinguish these two cases. I.e. :1delete 1 and nvim_buf_set_text(0, 0, 0, 1, 0, {}) yield the same splice operation. This means that a multi-line sign_text mark should now span at least one column beyond its end_row, as seen in the adjusted test. This is still somewhat unexpected/inconvenient to me which is what prompted me to try to avoid it with the original condition. Add revalidated sign mark back to decor with correct range; third sign mark added to test exposed a crash.
2026-02-15fix(prompt): wrong changed lnum in init_promptSean Dewar1
Problem: if init_prompt replaces the prompt line at the ': mark, it calls inserted_bytes with the wrong lnum. Solution: use the correct lnum. Call appended_lines_mark instead when appending the prompt at the end.
2026-02-15fix(prompt): prompt_setprompt does not adjust extmarks, no on_bytesSean Dewar1
Problem: prompt_setprompt does not adjust extmarks or trigger on_bytes buffer-updates when fixing the prompt line. Solution: adjust them, trigger on_bytes. Notably, hides extmarks when replacing the entire line (and clearing user input). Otherwise, when just replacing the prompt text, hides extmarks there, but moves those after (in the user input area) to the correct spot.
2026-01-02fix(api): buffer overflow in nvim_buf_get_extmarks overlap #37184Francisco Giordano1
With `overlap=true`, more extmarks than the requested limit may be collected in `extmark_get`. This then leads to an out of bounds write of `rv` in `nvim_buf_get_extmarks`.
2025-04-21fix(api): wrong return value with reverse range + overlap #32956luukvbaal1
Problem: When iterating in reverse with {start} > {end} in `nvim_buf_get_extmarks()`, marks that overlap {start} and are greater than {end} are included in the return value twice. Marks that overlap {end} and do not overlap {start} are not not included in the return value at all. Marks are not actually returned in a meaningful "traversal order". Solution: Rather than actually iterating in reverse, (also possible but requires convoluted conditions and would require fetching overlapping marks for both the {start} and {end} position, while still ending up with non-traversal ordered marks), iterate normally and reverse the return value.
2025-03-07feat(defaults): jump between :terminal shell prompts with ]]/[[ #32736Gregory Anders1
2025-02-25feat(marks): add conceal_lines to nvim_buf_set_extmark()Luuk van Baal1
Implement an extmark property that conceals lines vertically.
2025-02-20feat(marks): virtual lines support horizontal scrolling (#32497)zeertzjq1
Add a new field `virt_lines_overflow` that enables horizontal scrolling for virtual lines when set to "scroll".
2025-01-15fix(marks): revise metadata for start mark of revalidated pair #32017luukvbaal1
Problem: Metadata may be revised for end mark of a revalidated pair. Solution: Revise metadata for start mark of a revalidated pair.
2025-01-10fix(decor): set invalid flag for end of invalidated paired marksLuuk van Baal1
2024-12-14feat(ui): sign/statuscolumn can combine highlight attrs #31575luukvbaal1
Problem: Since e049c6e4c08a, most statusline-like UI elements can combine highlight attrs, except for sign/statuscolumn. Solution: Implement for sign/statuscolumn.
2024-12-06fix(marks): skip right_gravity marks when deleting textLuuk van Baal1
Problem: Marks that are properly restored by the splice associated with an undo edit, are unnecessarily pushed to the undo header. This results in incorrect mark tracking in the "copy_only" save/restore completion path. Solution: Avoid pushing left gravity marks at the beginning of the range, and right gravity marks at the end of the range to the undo header.
2024-11-14fix(messages)!: vim.ui_attach message callbacks are unsafeLuuk van Baal1
Problem: Lua callbacks for "msg_show" events with vim.ui_attach() are executed when it is not safe. Solution: Disallow non-fast API calls for "msg_show" event callbacks. Automatically detach callback after excessive errors. Make sure fast APIs do not modify Nvim state.
2024-11-14fix(tests): needing two calls to setup a screen is cringebfredl1
Before calling "attach" a screen object is just a dummy container for (row, col) values whose purpose is to be sent as part of the "attach" function call anyway. Just create the screen in an attached state directly. Keep the complete (row, col, options) config together. It is still completely valid to later detach and re-attach as needed, including to another session.
2024-08-20fix(decor): don't use separate DecorSignHighlight for url (#30096)zeertzjq1
2024-07-20fix(marks): revalidate marks whose position did not changeLuuk van Baal1
Problem: Marks whose position did not change with the action that invalidated them (right_gravity = false) are not revalidated upon undo. Solution: Remove early return when restoring a marks saved position so that it is still revalidated. Add "move" guards instead.
2024-05-21feat(signs)!: place higher-priority signs from the left #27781Tobias Schmitz1
Problem: Higher-priority signs may be hidden by lower-priority signs. Solution: Place higher-priority signs from the left. Example: nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='H', priority=1}) nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='W', priority=2}) nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='E', priority=3}) Before: | | H | W E | ^ | | Not visible After: | | | E W | H | | ^ Not visible Fixes #16632
2024-05-12fix(api): make getting explicit empty hl in virtual text work (#28697)zeertzjq1
2024-05-03perf(extmarks): better track whether namespace has extmarks (#28615)zeertzjq1
This avoids redraw when adding/removing an empty namespace for a window. This also avoids marktree traversal when clearing a namespace that has already been cleared, which is added as a benchmark.
2024-04-23test: improve test conventionsdundargoc1
Specifically, functions that are run in the context of the test runner are put in module `test/testutil.lua` while the functions that are run in the context of the test session are put in `test/functional/testnvim.lua`. Closes https://github.com/neovim/neovim/issues/27004.
2024-04-10refactor(test): inject after_each differentlyLewis Russell1
2024-04-08test: improve test conventionsdundargoc1
Work on https://github.com/neovim/neovim/issues/27004.
2024-03-23refactor(tests): all screen tests should use highlightsbfredl1
This is the first installment of a multi-PR series significantly refactoring how highlights are being specified. The end goal is to have a base set of 20 ish most common highlights, and then specific files only need to add more groups to that as needed. As a complicating factor, we also want to migrate to the new default color scheme eventually. But by sharing a base set, that future PR will hopefully be a lot smaller since a lot of tests will be migrated just simply by updating the base set in place. As a first step, fix the anti-pattern than Screen defaults to ignoring highlights. Highlights are integral part of the screen state, not something "extra" which we only test "sometimes". For now, we still allow opt-out via the intentionally ugly screen._default_attr_ids = nil The end goal is to get rid of all of these eventually (which will be easier as part of the color scheme migration)
2024-01-28feat(extmarks): subpriorities (relative to declaration order) (#27131)Gregory Anders1
The "priority" field of extmarks can be used to set priorities of extmarks which dictates which highlight group a range will actually have when there are multiple extmarks applied. However, when multiple extmarks have the same priority, the only way to enforce an actual priority is through the order in which the extmarks are set. It is not always possible or desirable to set extmarks in a specific order, however, so we add a new "subpriority" field that explicitly enforces the ordering of extmarks that have the same priority. For now this will be used only to enforce priority of treesitter highlights. A single node in a treesitter tree may match multiple captures, in which case that node will have multiple extmarks set. The order in which captures are returned from the treesitter API is not _necessarily_ in the same order they are defined in a query file, so we use the new subpriority field to force that ordering. For now subpriorites are not documented and are not meant to be used by external code, and it only applies to ephemeral extmarks. We indicate the "private" nature of subpriorities by prefixing the field name with an "_".
2024-01-24feat(ui): add support for OSC 8 hyperlinks (#27109)Gregory Anders1
Extmarks can contain URLs which can then be drawn in any supporting UI. In the TUI, for example, URLs are "drawn" by emitting the OSC 8 control sequence to the TTY. On terminals which support the OSC 8 sequence this will create clickable hyperlinks. URLs are treated as inline highlights in the decoration subsystem, so are included in the `DecorSignHighlight` structure. However, unlike other inline highlights they use allocated memory which must be freed, so they set the `ext` flag in `DecorInline` so that their lifetimes are managed along with other allocated memory like virtual text. The decoration subsystem then adds the URLs as a new highlight attribute. The highlight subsystem maintains a set of unique URLs to avoid duplicating allocations for the same string. To attach a URL to an existing highlight attribute we call `hl_add_url` which finds the URL in the set (allocating and adding it if it does not exist) and sets the `url` highlight attribute to the index of the URL in the set (using an index helps keep the size of the `HlAttrs` struct small). This has the potential to lead to an increase in highlight attributes if a URL is used over a range that contains many different highlight attributes, because now each existing attribute must be combined with the URL. In practice, however, URLs typically span a range containing a single highlight (e.g. link text in Markdown), so this is likely just a pathological edge case. When a new highlight attribute is defined with a URL it is copied to all attached UIs with the `hl_attr_define` UI event. The TUI manages its own set of URLs (just like the highlight subsystem) to minimize allocations. The TUI keeps track of which URL is "active" for the cell it is printing. If no URL is active and a cell containing a URL is printed, the opening OSC 8 sequence is emitted and that URL becomes the actively tracked URL. If the cursor is moved while in the middle of a URL span, we emit the terminating OSC sequence to prevent the hyperlink from spanning multiple lines. This does not support nested hyperlinks, but that is a rare (and, frankly, bizarre) use case. If a valid use case for nested hyperlinks ever presents itself we can address that issue then.
2024-01-22fix(extmarks): missing "spell" and "conceal" in details (#27116)zeertzjq1
2024-01-17fix(extmarks): do not remove invalid marks from decor upon deletionLuuk van Baal1
2024-01-16test: use integers for API Buffer/Window/Tabpage EXT typesLewis Russell1
2024-01-12test: rename (meths, funcs) -> (api, fn)Lewis Russell1
2024-01-12test: normalise nvim bridge functionsLewis Russell1
- remove helpers.cur*meths - remove helpers.nvim
2024-01-12test: typing for helpers.methsLewis Russell1
2024-01-03refactor: format test/*Justin M. Keyes1
2023-12-26feat(extmarks): add virt_text_repeat_linebreak flag (#26625)luukvbaal1
Problem: Unable to predict which byte-offset to place virtual text to make it repeat visually in the wrapped part of a line. Solution: Add a flag to nvim_buf_set_extmark() that causes virtual text to repeat in wrapped lines.
2023-12-25refactor(drawline): reduce size of wlv.extra[] (#26733)zeertzjq1
It's now only used for transchar_hex(), which only needs 11 bytes.
2023-12-25test(extmarks): improve tests for ui_watched (#26732)zeertzjq1
2023-12-09test: avoid repeated screen lines in expected stateszeertzjq1
This is the command invoked repeatedly to make the changes: :%s/^\(.*\)|\%(\*\(\d\+\)\)\?$\n\1|\%(\*\(\d\+\)\)\?$/\=submatch(1)..'|*'..(max([str2nr(submatch(2)),1])+max([str2nr(submatch(3)),1]))/g
2023-12-02fix(extmarks): restore old position before revalidatingLuuk van Baal1
2023-11-22feat(extmarks): add sign name to extmark "details" arrayLuuk van Baal1
Problem: Unable to identify legacy signs when fetching extmarks with `nvim_buf_get_extmarks()`. Solution: Add "sign_name" to the extmark detail array. Add some misc. changes as follow-up to #25724
2023-11-22refactor(decorations): break up Decoration struct into smaller piecesbfredl1
Remove the monolithic Decoration struct. Before this change, each extmark could either represent just a hl_id + priority value as a inline decoration, or it would take a pointer to this monolitic 112 byte struct which has to be allocated. This change separates the decorations into two pieces: DecorSignHighlight for signs, highlights and simple set-flag decorations (like spell, ui-watched), and DecorVirtText for virtual text and lines. The main separation here is whether they are expected to allocate more memory. Currently this is not really true as sign text has to be an allocated string, but the plan is to get rid of this eventually (it can just be an array of two schar_T:s). Further refactors are expected to improve the representation of each decoration kind individually. The goal of this particular PR is to get things started by cutting the Gordian knot which was the monolithic struct Decoration. Now, each extmark can either contain chained indicies/pointers to these kinds of objects, or it can fit a subset of DecorSignHighlight inline. The point of this change is not only to make decorations smaller in memory. In fact, the main motivation is to later allow them to grow _larger_, but on a dynamic, on demand fashion. As a simple example, it would be possible to augment highlights to take a list of multiple `hl_group`:s, which then would trivially map to a chain of multiple DecorSignHighlight entries. One small feature improvement included with this refactor itself, is that the restriction that extmarks cannot be removed inside a decoration provider has been lifted. These are instead safely lifetime extended on a "to free" list until the current iteration of screen drawing is done. NB: flags is a mess. but DecorLevel is useless, this slightly less so
2023-11-08feat(extmarks): add 'invalidate' property to extmarksLuuk van Baal1
Problem: No way to have extmarks automatically removed when the range it is attached to is deleted. Solution: Add new 'invalidate' property that will hide a mark when the entirety of its range is deleted. When "undo_restore" is set to false, delete the mark from the buffer instead.
2023-09-22fix(api): get virtual text with multiple hl properly (#25307)zeertzjq1
2023-09-16fix(marktree): off-by-one error in `marktree_move`L Lllvvuu1
If you would insert element X at position j, then if you are moving that same element X from position i < j, you should move it to position j - 1, because you are losing an element. This error caused a gap to be left in the array, so that it looked like [x, null, y] instead of [x, y], where len = 2. This triggered #25147. Fixes: #25147
2023-09-12feat(extmark): support proper multiline rangesbfredl1
The removes the previous restriction that nvim_buf_set_extmark() could not be used to highlight arbitrary multi-line regions The problem can be summarized as follows: let's assume an extmark with a hl_group is placed covering the region (5,0) to (50,0) Now, consider what happens if nvim needs to redraw a window covering the lines 20-30. It needs to be able to ask the marktree what extmarks cover this region, even if they don't begin or end here. Therefore the marktree needs to be augmented with the information covers a point, not just what marks begin or end there. To do this, we augment each node with a field "intersect" which is a set the ids of the marks which overlap this node, but only if it is not part of the set of any parent. This ensures the number of nodes that need to be explicitly marked grows only logarithmically with the total number of explicitly nodes (and thus the number of of overlapping marks). Thus we can quickly iterate all marks which overlaps any query position by looking up what leaf node contains that position. Then we only need to consider all "start" marks within that leaf node, and the "intersect" set of that node and all its parents. Now, and the major source of complexity is that the tree restructuring operations (to ensure that each node has T-1 <= size <= 2*T-1) also need to update these sets. If a full inner node is split in two, one of the new parents might start to completely overlap some ranges and its ids will need to be moved from its children's sets to its own set. Similarly, if two undersized nodes gets joined into one, it might no longer completely overlap some ranges, and now the children which do needs to have the have the ids in its set instead. And then there are the pivots! Yes the pivot operations when a child gets moved from one parent to another.
2023-08-07refactor(api): use typed keysetsbfredl1
Initially this is just for geting rid of boilerplate, but eventually the types could get exposed as metadata
2023-06-22fix(api): wrong nvim_buf_set_extmark error for invalid hl_modezeertzjq1
2023-05-22test: don't unnecessarily specify win/buf for `nvim_(get|set)_option_value`Famiu Haque1
`nvim_(get|set)_option_value` pick the current buffer / window by default for buffer-local/window-local (but not global-local) options. So specifying `buf = 0` or `win = 0` in opts is unnecessary for those options. This PR removes those to reduce code clutter.