mirror of
https://github.com/neovim/neovim.git
synced 2025-11-24 19:20:39 +00:00
feat(vim.version): add vim.version.intersect()
Problem: No way to compute intersection of two version ranges, which is useful when computing version range that fits inside several reference ranges. Solution: Add `vim.version.intersect()`.
This commit is contained in:
@@ -4035,6 +4035,21 @@ vim.version.gt({v1}, {v2}) *vim.version.gt()*
|
|||||||
Return: ~
|
Return: ~
|
||||||
(`boolean`)
|
(`boolean`)
|
||||||
|
|
||||||
|
vim.version.intersect({r1}, {r2}) *vim.version.intersect()*
|
||||||
|
WARNING: This feature is experimental/unstable.
|
||||||
|
|
||||||
|
Computes the common range shared by the given ranges.
|
||||||
|
|
||||||
|
Parameters: ~
|
||||||
|
• {r1} (`vim.VersionRange`) First range to intersect. See
|
||||||
|
|vim.VersionRange|.
|
||||||
|
• {r2} (`vim.VersionRange`) Second range to intersect. See
|
||||||
|
|vim.VersionRange|.
|
||||||
|
|
||||||
|
Return: ~
|
||||||
|
(`vim.VersionRange?`) Maximal range that is present inside both `r1`
|
||||||
|
and `r2`. `nil` if such range does not exist. See |vim.VersionRange|.
|
||||||
|
|
||||||
vim.version.last({versions}) *vim.version.last()*
|
vim.version.last({versions}) *vim.version.last()*
|
||||||
TODO: generalize this, move to func.lua
|
TODO: generalize this, move to func.lua
|
||||||
|
|
||||||
|
|||||||
@@ -200,6 +200,7 @@ LUA
|
|||||||
• |vim.tbl_extend()| and |vim.tbl_deep_extend()| now accept a function behavior argument.
|
• |vim.tbl_extend()| and |vim.tbl_deep_extend()| now accept a function behavior argument.
|
||||||
• |vim.fs.root()| can define "equal priority" via nested lists.
|
• |vim.fs.root()| can define "equal priority" via nested lists.
|
||||||
• |vim.version.range()| output can be converted to human-readable string with |tostring()|.
|
• |vim.version.range()| output can be converted to human-readable string with |tostring()|.
|
||||||
|
• |vim.version.intersect()| computes intersection of two version ranges.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
|
|
||||||
|
|||||||
@@ -361,6 +361,24 @@ function M.range(spec) -- Adapted from https://github.com/folke/lazy.nvim
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Computes the common range shared by the given ranges.
|
||||||
|
---
|
||||||
|
--- @since 14
|
||||||
|
--- @param r1 vim.VersionRange First range to intersect.
|
||||||
|
--- @param r2 vim.VersionRange Second range to intersect.
|
||||||
|
--- @return vim.VersionRange? Maximal range that is present inside both `r1` and `r2`.
|
||||||
|
--- `nil` if such range does not exist.
|
||||||
|
function M.intersect(r1, r2)
|
||||||
|
assert(getmetatable(r1) == range_mt)
|
||||||
|
assert(getmetatable(r2) == range_mt)
|
||||||
|
|
||||||
|
local from = r1.from <= r2.from and r2.from or r1.from
|
||||||
|
local to = (r1.to == nil or (r2.to ~= nil and r2.to <= r1.to)) and r2.to or r1.to
|
||||||
|
if to == nil or from < to or (from == to and r1:has(from) and r2:has(from)) then
|
||||||
|
return setmetatable({ from = from, to = to }, VersionRange)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---@param v string|vim.Version
|
---@param v string|vim.Version
|
||||||
---@return string
|
---@return string
|
||||||
local function create_err_msg(v)
|
local function create_err_msg(v)
|
||||||
|
|||||||
@@ -145,6 +145,131 @@ describe('version', function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe('intersect', function()
|
||||||
|
local check = function(input, output)
|
||||||
|
local r1 = vim.version.range(input[1])
|
||||||
|
local r2 = vim.version.range(input[2])
|
||||||
|
if output == nil then
|
||||||
|
eq(vim.version.intersect(r1, r2), nil)
|
||||||
|
eq(vim.version.intersect(r2, r1), nil)
|
||||||
|
else
|
||||||
|
local ref = vim.version.range(output)
|
||||||
|
eq(vim.version.intersect(r1, r2), ref)
|
||||||
|
eq(vim.version.intersect(r2, r1), ref)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it('returns biggest common range', function()
|
||||||
|
check({ '>=1.2.3', '>=2.0.0' }, '>=2.0.0')
|
||||||
|
check({ '>=1.2.3', '>=1.3.0' }, '>=1.3.0')
|
||||||
|
check({ '>=1.2.3', '>=1.2.4' }, '>=1.2.4')
|
||||||
|
check({ '>=1.2.3', '>=1.2.3' }, '>=1.2.3')
|
||||||
|
check({ '>=1.2.3', '>1.2.4' }, '>1.2.4')
|
||||||
|
check({ '>=1.2.3', '>1.2.3' }, '>1.2.3')
|
||||||
|
check({ '>=1.2.3', '>1.2.2' }, '>=1.2.3')
|
||||||
|
check({ '>1.2.3', '>1.2.4' }, '>1.2.4')
|
||||||
|
check({ '>1.2.3', '>1.2.3' }, '>1.2.3')
|
||||||
|
|
||||||
|
check({ '>=1.2.3', '1.2.0 - 1.2.2' }, nil)
|
||||||
|
check({ '>=1.2.3', '1.2.0 - 1.2.2' }, nil)
|
||||||
|
check({ '>=1.2.3', '1.2.0 - 1.2.3' }, nil)
|
||||||
|
check({ '>=1.2.3', '1.2.0 - 1.2.4' }, '1.2.3 - 1.2.4')
|
||||||
|
check({ '>=1.2.3', '1.2.3 - 1.2.4' }, '1.2.3 - 1.2.4')
|
||||||
|
check({ '>=1.2.3', '1.2.4 - 1.3.0' }, '1.2.4 - 1.3.0')
|
||||||
|
check({ '>1.2.3', '1.2.0 - 1.2.2' }, nil)
|
||||||
|
check({ '>1.2.3', '1.2.0 - 1.2.2' }, nil)
|
||||||
|
check({ '>1.2.3', '1.2.0 - 1.2.3' }, nil)
|
||||||
|
check({ '>1.2.3', '1.2.0 - 1.2.4' }, '1.2.4-0 - 1.2.4')
|
||||||
|
check({ '>1.2.3', '1.2.3 - 1.2.4' }, '1.2.4-0 - 1.2.4')
|
||||||
|
check({ '>1.2.3', '1.2.4 - 1.3.0' }, '1.2.4 - 1.3.0')
|
||||||
|
|
||||||
|
check({ '>=1.2.3', '=1.2.4' }, '=1.2.4')
|
||||||
|
check({ '>=1.2.3', '=1.2.3' }, '=1.2.3')
|
||||||
|
check({ '>=1.2.3', '=1.2.2' }, nil)
|
||||||
|
check({ '>1.2.3', '=1.2.4' }, '=1.2.4')
|
||||||
|
check({ '>1.2.3', '=1.2.3' }, nil)
|
||||||
|
check({ '>1.2.3', '=1.2.2' }, nil)
|
||||||
|
|
||||||
|
check({ '>=1.2.3', '<=1.3.0' }, '1.2.3 - 1.3.1-0')
|
||||||
|
check({ '>=1.2.3', '<1.3.0' }, '1.2.3 - 1.3.0')
|
||||||
|
check({ '>=1.2.3', '<=1.2.3' }, '1.2.3 - 1.2.4-0') -- A better result would be '=1.2.3'
|
||||||
|
check({ '>=1.2.3', '<1.2.3' }, nil)
|
||||||
|
check({ '>=1.2.3', '<=1.2.2' }, nil)
|
||||||
|
check({ '>=1.2.3', '<1.2.2' }, nil)
|
||||||
|
check({ '>1.2.3', '<=1.3.0' }, '1.2.4-0 - 1.3.1-0')
|
||||||
|
check({ '>1.2.3', '<1.3.0' }, '1.2.4-0 - 1.3.0')
|
||||||
|
check({ '>1.2.3', '<=1.2.3' }, nil)
|
||||||
|
check({ '>1.2.3', '<1.2.3' }, nil)
|
||||||
|
check({ '>1.2.3', '<=1.2.2' }, nil)
|
||||||
|
check({ '>1.2.3', '<1.2.2' }, nil)
|
||||||
|
|
||||||
|
check({ '1.2.3 - 1.3.0', '1.3.1 - 1.4.0' }, nil)
|
||||||
|
check({ '1.2.3 - 1.3.0', '1.3.0 - 1.4.0' }, nil)
|
||||||
|
check({ '1.2.3 - 1.3.0', '1.2.4 - 1.4.0' }, '1.2.4 - 1.3.0')
|
||||||
|
check({ '1.2.3 - 1.3.0', '1.2.3 - 1.4.0' }, '1.2.3 - 1.3.0')
|
||||||
|
check({ '1.2.3 - 1.3.0', '1.2.2 - 1.4.0' }, '1.2.3 - 1.3.0')
|
||||||
|
check({ '1.2.3 - 1.3.0', '1.2.4 - 1.3.0' }, '1.2.4 - 1.3.0')
|
||||||
|
check({ '1.2.3 - 1.3.0', '1.2.3 - 1.3.0' }, '1.2.3 - 1.3.0')
|
||||||
|
|
||||||
|
check({ '1.2.3 - 1.3.0', '=1.4.0' }, nil)
|
||||||
|
check({ '1.2.3 - 1.3.0', '=1.3.0' }, nil)
|
||||||
|
check({ '1.2.3 - 1.3.0', '=1.2.4' }, '=1.2.4')
|
||||||
|
check({ '1.2.3 - 1.3.0', '=1.2.3' }, '=1.2.3')
|
||||||
|
check({ '1.2.3 - 1.3.0', '=1.2.2' }, nil)
|
||||||
|
|
||||||
|
check({ '1.2.3 - 1.3.0', '<=1.4.0' }, '1.2.3 - 1.3.0')
|
||||||
|
check({ '1.2.3 - 1.3.0', '<1.4.0' }, '1.2.3 - 1.3.0')
|
||||||
|
check({ '1.2.3 - 1.3.0', '<=1.3.0' }, '1.2.3 - 1.3.0')
|
||||||
|
check({ '1.2.3 - 1.3.0', '<1.3.0' }, '1.2.3 - 1.3.0')
|
||||||
|
check({ '1.2.3 - 1.3.0', '<=1.2.4' }, '1.2.3 - 1.2.5-0')
|
||||||
|
check({ '1.2.3 - 1.3.0', '<1.2.5' }, '1.2.3 - 1.2.5')
|
||||||
|
check({ '1.2.3 - 1.3.0', '<=1.2.3' }, '1.2.3 - 1.2.4-0') -- A better result would be '=1.2.3'
|
||||||
|
check({ '1.2.3 - 1.3.0', '<1.2.3' }, nil)
|
||||||
|
check({ '1.2.3 - 1.3.0', '<=1.2.2' }, nil)
|
||||||
|
check({ '1.2.3 - 1.3.0', '<1.2.2' }, nil)
|
||||||
|
|
||||||
|
check({ '=1.2.3', '=1.2.4' }, nil)
|
||||||
|
check({ '=1.2.3', '=1.2.3' }, '=1.2.3')
|
||||||
|
|
||||||
|
check({ '=1.2.3', '<1.2.3' }, nil)
|
||||||
|
check({ '<=1.2.2', '=1.2.3' }, nil)
|
||||||
|
|
||||||
|
check({ '=1.2.3', '<=1.3.0' }, '=1.2.3')
|
||||||
|
check({ '=1.2.3', '<1.3.0' }, '=1.2.3')
|
||||||
|
check({ '=1.2.3', '<=1.2.3' }, '=1.2.3')
|
||||||
|
check({ '=1.2.3', '<1.2.3' }, nil)
|
||||||
|
check({ '=1.2.3', '<=1.2.2' }, nil)
|
||||||
|
check({ '=1.2.3', '<1.2.2' }, nil)
|
||||||
|
|
||||||
|
check({ '<=1.2.3', '<=1.3.0' }, '<=1.2.3')
|
||||||
|
check({ '<=1.2.3', '<1.3.0' }, '<=1.2.3')
|
||||||
|
check({ '<=1.2.3', '<=1.2.3' }, '<=1.2.3')
|
||||||
|
check({ '<=1.2.3', '<1.2.3' }, '<1.2.3')
|
||||||
|
check({ '<=1.2.3', '<=1.2.2' }, '<=1.2.2')
|
||||||
|
check({ '<=1.2.3', '<1.2.2' }, '<1.2.2')
|
||||||
|
check({ '<1.2.3', '<=1.3.0' }, '<1.2.3')
|
||||||
|
check({ '<1.2.3', '<1.3.0' }, '<1.2.3')
|
||||||
|
check({ '<1.2.3', '<=1.2.3' }, '<1.2.3')
|
||||||
|
check({ '<1.2.3', '<1.2.3' }, '<1.2.3')
|
||||||
|
check({ '<1.2.3', '<=1.2.2' }, '<=1.2.2')
|
||||||
|
check({ '<1.2.3', '<1.2.2' }, '<1.2.2')
|
||||||
|
|
||||||
|
-- Selective coverage of ranges with pre-releases
|
||||||
|
check({ '>=1.2.3-0', '>=1.2.3-1' }, '>=1.2.3-1')
|
||||||
|
check({ '>=1.2.3-alpha', '>=1.2.3-beta' }, '>=1.2.3-beta')
|
||||||
|
check({ '>=1.2.3-0', '>=1.2.3-alpha' }, '>=1.2.3-alpha')
|
||||||
|
check({ '>=1.2.3-0', '<1.2.3' }, '1.2.3-0 - 1.2.3')
|
||||||
|
check({ '>=1.2.3-0', '<1.2.3-1' }, '1.2.3-0 - 1.2.3-1')
|
||||||
|
check({ '>=1.2.3-alpha', '<1.2.3-beta' }, '1.2.3-alpha - 1.2.3-beta')
|
||||||
|
check({ '>=1.2.3-0', '1.2.2 - 1.2.3' }, '1.2.3-0 - 1.2.3')
|
||||||
|
check({ '>=1.2.3-0', '<=1.2.2' }, nil)
|
||||||
|
|
||||||
|
check({ '<=1.2.3-0', '>=1.2.3' }, nil)
|
||||||
|
check({ '<=1.2.3-0', '=1.2.3' }, nil)
|
||||||
|
check({ '>=1.2.3-0', '<1.2.3-2' }, '1.2.3-0 - 1.2.3-2')
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
describe('cmp()', function()
|
describe('cmp()', function()
|
||||||
local testcases = {
|
local testcases = {
|
||||||
{ v1 = 'v0.0.99', v2 = 'v9.0.0', want = -1 },
|
{ v1 = 'v0.0.99', v2 = 'v9.0.0', want = -1 },
|
||||||
|
|||||||
Reference in New Issue
Block a user