summaryrefslogtreecommitdiffstatshomepage
path: root/src/nvim/extmark.c
AgeCommit message (Collapse)AuthorFiles
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-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-11-16docs: misc #36580Justin M. Keyes1
Co-authored-by: nguyenkd27 <nguyenkd27@gmail.com> Co-authored-by: dundargoc <gocdundar@gmail.com> Co-authored-by: Yochem van Rosmalen <git@yochem.nl> Co-authored-by: Tuure Piitulainen <tuure.piitulainen@gmail.com> Co-authored-by: Maria Solano <majosolano99@gmail.com> Co-authored-by: tao <2471314@gmail.com>
2025-08-14refactor(build): remove INCLUDE_GENERATED_DECLARATIONS guardsbfredl1
These are not needed after #35129 but making uncrustify still play nice with them was a bit tricky. Unfortunately `uncrustify --update-config-with-doc` breaks strings with backslashes. This issue has been reported upstream, and in the meanwhile auto-update on every single run has been disabled.
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-04-11fix(column): don't count signs on lines beyond eob #33410luukvbaal1
Problem: Computed previous buffer line count may be beyond end of buffer. This results in signs being removed from `b_signcols` that were never included in it, tripping an assertion. Solution: Store the previous line count as it was before appending or deleting lines. Use it to clamp the edited region when clearing signs before a splice, after which it is reset.
2025-03-19fix(marks): ensure decor is removed with proper range (#32973)luukvbaal1
Problem: Paired mark whose end is in front of its start should not have its decor removed (as fixed by 72f630f9), but may still need to have its range redrawn. Solution: Still call `buf_decor_remove()` but ensure it is not called with an inverse range when `extmark_del()` is called on an end mark.
2025-03-16fix(marks): issues with invalid marks and marks beyond eob (#32862)luukvbaal1
Problem: Marks that go beyond the end of the buffer, and paired marks whose end is in front of its start mark are added to and removed from the decor. This results in incorrect tracking of the signcolumn. Solution: Ensure such marks are not added to and removed from the decor.
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
2025-01-09fix(decoration): fix crash when on_lines decor provider modifies marktreebfredl1
If a "on_lines" callback changes the structure of the marktree, the iterator (which is used for an entire window viewport) might now point to invalid memory. Restore the iterator to the beginning of the line in this case. fixes #29484
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-09-04fix(decor): exclude invalid marks from meta totalLuuk van Baal1
Problem: Marktree meta count still includes invalidated marks, making guards that check the meta total ineffective. Solution: Revise marktree metadata when in/revalidating a mark.
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-06-07feat: get/set namespace properties #28728altermo1
ref https://github.com/neovim/neovim/pull/28432 ref https://github.com/neovim/neovim/issues/28469
2024-05-26fix(extmarks): issues with revalidating marks #28961luukvbaal1
Problem: Invalid marks appear to be revalidated multiple times, and decor is added at the old position for unpaired marks. Solution: Avoid revalidating already valid marks, and don't use old position to add to decor for unpaired marks.
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-02-21feat(extmark): window scoped extmarkaltermo1
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
2024-02-17fix(decorations): crash with revised mark with changed decoration flagsbfredl1
fixes #27211
2024-02-12fix(extmarks): redraw pre-undo position (#27437)zeertzjq1
Problem: Virtual text not redrawn properly after undo moves its extmark. Solution: Redraw the moved extmark's pre-undo position.
2024-02-12perf(extmarks): avoid unnecessary invalidations for virt_text (#27435)zeertzjq1
Invalidation of most w_valid flags isn't needed when adding or removing virtual text below cursor.
2024-01-27fix(column): clear "b_signcols" before moving saved marksLuuk van Baal1
Problem: Marks moved by undo may be lost to "b_signcols.count". Solution: Count signs for each undo object separately instead of once for the entire undo.
2024-01-26fix(extmarks): do not remove decor from invalid old marksLuuk van Baal1
2024-01-25refactor: IWYU (#27186)zeertzjq1
2024-01-22fix(column): clear "b_signcols" when marktree is clearedLuuk van Baal1
2024-01-22perf(extmarks): add metadata for efficient filtering of special decorationsbfredl1
This expands on the global "don't pay for what you don't use" rules for these special extmark decorations: - inline virtual text, which needs to be processed in plines.c when we calculate the size of text on screen - virtual lines, which are needed when calculating "filler" lines - signs, with text and/or highlights, both of which needs to be processed for the entire line already at the beginning of a line. This adds a count to each node of the marktree, for how many special marks of each kind can be found in the subtree for this node. This makes it possible to quickly skip over these extra checks, when working in regions of the buffer not containing these kind of marks, instead of before where this could just be skipped if the entire _buffer_ didn't contain such marks.
2024-01-18refactor(extmarks): remove unused new pos from ExtmarkSavePosLuuk van Baal1
2024-01-17fix(extmarks): do not remove invalid marks from decor upon deletionLuuk van Baal1
2024-01-15fix(column): keep track of number of lines with number of signsLuuk van Baal1
Problem: Some edge cases to the old (pre-#26406) and current "b_signcols" structure result in an incorrectly sized "auto" 'signcolumn'. Solution: * Implement a simpler 'signcolumn' validation strategy by immediately counting the number of signs in a range upon sign insertion and deletion. Decrease in performance here but there is a clear path forward to decreasing this performance hit by moving signs to a dedicated marktree, or by adding meta-data to the existing marktree which may be queried more efficiently? * Also replace "max_count" and keep track of the number of lines with a certain number of signs. This makes it so that it is no longer necessary to scan the entire buffer when the maximum number of signs decreases. This likely makes the commit a net increase in performance. * To ensure correctness we also have re-initialize the count for an edited region that spans multiple lines. Such an edit may move the signs within it. Thus we count and decrement before splicing the marktree and count and increment after.
2024-01-13refactor(marktree): unpaired marktree_get_alt() returns itselfLuuk van Baal1
Avoids checking for invalid mark at callsite.
2024-01-11refactor(IWYU): fix headersdundargoc1
Remove `export` pramgas from defs headers as it causes IWYU to believe that the definitions from the defs headers comes from main header, which is not what we really want.
2023-12-20refactor: eliminate cyclic includesdundargoc1
2023-12-18docs: add style rule regarding initializationdundargoc1
Specifically, specify that each initialization should be done on a separate line.
2023-12-14fix(extmark): only invalidate unpaired marks on deleted rowsLuuk van Baal1
Problem: Unpaired marks are invalidated if its column is deleted, which may just be a "placeholder" column, e.g. for signs. Solution: Only remove unpaired marks if its entire row is deleted.
2023-12-07perf(column): keep track of number of lines that hold up the 'signcolumn'Luuk van Baal1
Problem: The entire marktree needs to be traversed each time a sign is removed from the sentinel line. Solution: Remove sentinel line and instead keep track of the number of lines that hold up the 'signcolumn' in "max_count". Adjust this number for added/removed signs, and set it to 0 when the maximum number of signs on a line changes. Only when "max_count" is decremented to 0 due to sign removal do we need to check the entire buffer. Also replace "invalid_top" and "invalid_bot" with a map of invalid ranges, further reducing the number of lines to be checked. Also improve tree traversal when counting the number of signs. Instead of looping over the to be checked range and counting the overlap for each row, keep track of the overlap in an array and add this to the count.
2023-12-02fix(extmarks): restore old position before revalidatingLuuk van Baal1
2023-11-29fix(extmark): restore extmarks when completing original textLuuk van Baal1
2023-11-29refactor: move some constants out of vim_defs.h (#26298)zeertzjq1
2023-11-28refactor: fix headers with IWYUdundargoc1
2023-11-28fix(column): redraw and update signcols for paired extmarkLuuk van Baal1
Problem: Signcolumn width does not increase when ranged sign does not start at sentinel line. Solution: Handle paired range of added sign when checking signcols.
2023-11-27build(IWYU): fix includes for undo_defs.hdundargoc1
2023-11-26refactor: move garray_T to garray_defs.h (#26227)zeertzjq1
2023-11-25build: rework IWYU mapping filesdundargoc1
Create mapping to most of the C spec and some POSIX specific functions. This is more robust than relying files shipped with IWYU.
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-18refactor(extmark): redundant ExtmarkInfo delenda est, use MTPair insteadbfredl1
2023-11-18Merge pull request #25724 from luukvbaal/signmergebfredl1
refactor(sign): move legacy signs to extmarks
2023-11-17refactor(sign): move legacy signs to extmarksLuuk van Baal1
Problem: The legacy signlist data structures and associated functions are redundant since the introduction of extmark signs. Solution: Store signs defined through the legacy commands in a hashmap, placed signs in the extmark tree. Replace signlist associated functions. Usage of the legacy sign commands should yield no change in behavior with the exception of: - "orphaned signs" are now always removed when the line it is placed on is deleted. This used to depend on the value of 'signcolumn'. - It is no longer possible to place multiple signs with the same identifier in a single group on multiple lines. This will now move the sign instead. Moreover, both signs placed through the legacy sign commands and through |nvim_buf_set_extmark()|: - Will show up in both |sign-place| and |nvim_buf_get_extmarks()|. - Are displayed by increasing sign identifier, left to right. Extmark signs used to be ordered decreasingly as opposed to legacy signs.
2023-11-16refactor: iwyu (#26062)zeertzjq1
2023-11-12build: remove PVSdundargoc1
We already have an extensive suite of static analysis tools we use, which causes a fair bit of redundancy as we get duplicate warnings. PVS is also prone to give false warnings which creates a lot of work to identify and disable.
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.