Common library code for other vc*.nvim projects.

Intervals logic.

+77
+77
lua/vclib/intervals.lua
··· 1 + local M = {} 2 + 3 + ---@class Interval 4 + ---@field l integer 5 + ---@field r integer 6 + ---@field data any 7 + local Interval = {} 8 + 9 + ---@param intervals Interval[] 10 + ---@param point integer 11 + local function _partition(intervals, point) 12 + local before = {} 13 + local on = nil 14 + local after = {} 15 + 16 + for _, interval in ipairs(intervals) do 17 + if interval.l <= point and point < interval.r then 18 + on = interval 19 + goto continue 20 + end 21 + if interval.l < point then 22 + table.insert(before, interval) 23 + end 24 + if interval.l > point then 25 + table.insert(after, interval) 26 + end 27 + ::continue:: 28 + end 29 + 30 + return before, on, after 31 + end 32 + 33 + ---@class Intervals 34 + ---@field intervals Interval[] 35 + local Intervals = {} 36 + 37 + ---@generic T 38 + ---@param elements T[] 39 + ---@param make_interval fun(element: T): Interval 40 + ---@return Intervals 41 + function Intervals:new(elements, make_interval) 42 + local obj = setmetatable({}, { __index = self }) 43 + obj.intervals = vim.iter(elements):map(make_interval):totable() 44 + return obj 45 + end 46 + 47 + ---@generic T 48 + ---@param elements T[] 49 + ---@param make_interval fun(element: T): Interval 50 + function M.from_list(elements, make_interval) 51 + return Intervals:new(elements, make_interval) 52 + end 53 + 54 + ---@param interval Interval? 55 + local function _data(interval) 56 + if interval then 57 + return interval.data 58 + end 59 + return nil 60 + end 61 + 62 + --- Get intervals around a point. 63 + ---@param point integer 64 + ---@param offset integer 65 + function Intervals:find(point, offset) 66 + local before, on, after = _partition(self.intervals, point) 67 + if offset == 0 then 68 + return _data(on) 69 + elseif offset < 0 then 70 + offset = -offset 71 + return _data(before[#before - (offset - 1)] or before[1]) 72 + else 73 + return _data(after[offset] or after[#after]) 74 + end 75 + end 76 + 77 + return M