fix(vim.range): empty ranges semantics vs regular ranges #39474

Problem:
- Empty ranges have different `<`, `<=`, `has` and `intersect` semantics compared to regular ranges.
- `to_inclusive_pos` assumes that the end position of a range is exclusive, which is not true for empty ranges

Solution:
Special case empty ranges in these operations.
This commit is contained in:
Luis Calle
2026-05-08 04:17:00 -05:00
committed by GitHub
parent 832a68835b
commit 416f3482e7
2 changed files with 109 additions and 14 deletions

View File

@@ -90,12 +90,92 @@ describe('vim.range', function()
)
end)
it('checks whether a range does not contain an empty range just outside it', function()
it('a range does not contain an empty range just outside it', function()
eq(
false,
exec_lua(function()
local buf = vim.api.nvim_create_buf(false, true)
return vim.range(buf, 0, 0, 0, 4):has(vim.range(buf, 0, 0, 0, 0))
return vim.range(0, 0, 0, 0, 4):has(vim.range(0, 0, 0, 0, 0))
end)
)
eq(
false,
exec_lua(function()
return vim.range(0, 0, 0, 0, 4):has(vim.range(0, 0, 4, 0, 4))
end)
)
end)
it('an empty range contains no other range', function()
eq(
false,
exec_lua(function()
return vim.range(0, 1, 0, 1, 0):has(vim.range(0, 1, 0, 1, 0))
end)
)
eq(
false,
exec_lua(function()
return vim.range(0, 1, 0, 1, 0):has(vim.range(0, 1, 0, 2, 0))
end)
)
eq(
false,
exec_lua(function()
return vim.range(0, 1, 0, 1, 0):has(vim.range(0, 0, 0, 1, 0))
end)
)
end)
it('an empty range intersercts with no other range', function()
eq(
nil,
exec_lua(function()
return vim.range(0, 1, 0, 1, 0):intersect(vim.range(0, 1, 0, 1, 0))
end)
)
eq(
nil,
exec_lua(function()
return vim.range(0, 1, 0, 1, 0):intersect(vim.range(0, 1, 0, 2, 0))
end)
)
eq(
nil,
exec_lua(function()
return vim.range(0, 1, 0, 1, 0):intersect(vim.range(0, 0, 0, 1, 0))
end)
)
end)
it('empty range comparison semantics', function()
eq(
true,
exec_lua(function()
return vim.range(0, 0, 0, 0, 0) < vim.range(0, 0, 0, 0, 1)
end)
)
eq(
true,
exec_lua(function()
return vim.range(0, 1, 0, 1, 0) < vim.range(0, 1, 0, 1, 1)
end)
)
eq(
true,
exec_lua(function()
return vim.range(0, 1, 1, 1, 1) > vim.range(0, 1, 0, 1, 1)
end)
)
end)
it('1 byte wide range is not empty', function()
eq(
false,
exec_lua(function()
return vim.range(0, 1, 0, 1, 1):is_empty()
end)
)
end)