fix(api): wrong return value with reverse range + overlap #32956

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.
(cherry picked from commit 65170e8dad)
This commit is contained in:
luukvbaal
2025-04-22 01:18:03 +02:00
committed by github-actions[bot]
parent 3b0c88a537
commit fb71d631a5
5 changed files with 62 additions and 43 deletions

View File

@@ -2777,8 +2777,11 @@ nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {opts})
vim.api.nvim_buf_get_extmarks(0, my_ns, {0,0}, {-1,-1}, {})
<
If `end` is less than `start`, traversal works backwards. (Useful with
`limit`, to get the first marks prior to a given position.)
If `end` is less than `start`, marks are returned in reverse order.
(Useful with `limit`, to get the first marks prior to a given position.)
Note: For a reverse range, `limit` does not actually affect the traversed
range, just how many marks are returned
Note: when using extmark ranges (marks with a end_row/end_col position)
the `overlap` option might be useful. Otherwise only the start position of

View File

@@ -369,8 +369,11 @@ function vim.api.nvim_buf_get_extmark_by_id(buffer, ns_id, id, opts) end
--- vim.api.nvim_buf_get_extmarks(0, my_ns, {0,0}, {-1,-1}, {})
--- ```
---
--- If `end` is less than `start`, traversal works backwards. (Useful
--- with `limit`, to get the first marks prior to a given position.)
--- If `end` is less than `start`, marks are returned in reverse order.
--- (Useful with `limit`, to get the first marks prior to a given position.)
---
--- Note: For a reverse range, `limit` does not actually affect the traversed
--- range, just how many marks are returned
---
--- Note: when using extmark ranges (marks with a end_row/end_col position)
--- the `overlap` option might be useful. Otherwise only the start position