local Pos = require 'u.pos' ---@class u.Extmark ---@field bufnr integer ---@field id integer ---@field nsid integer local Extmark = {} Extmark.__index = Extmark --- @param bufnr integer --- @param nsid integer --- @param id integer function Extmark.new(bufnr, nsid, id) return setmetatable({ bufnr = bufnr, nsid = nsid, id = id, }, Extmark) end --- @param range u.Range --- @param nsid integer function Extmark.from_range(range, nsid) local r = range:to_charwise() local stop = r.stop or r.start local end_row = stop.lnum - 1 local end_col = stop.col if range.mode == 'V' then end_row = end_row + 1 end_col = 0 end local id = vim.api.nvim_buf_set_extmark(r.start.bufnr, nsid, r.start.lnum - 1, r.start.col - 1, { right_gravity = false, end_right_gravity = true, end_row = end_row, end_col = end_col, }) return Extmark.new(r.start.bufnr, nsid, id) end function Extmark:range() local Range = require 'u.range' local raw_extmark = vim.api.nvim_buf_get_extmark_by_id(self.bufnr, self.nsid, self.id, { details = true }) local start_row0, start_col0, details = unpack(raw_extmark) --- @type u.Pos local start = Pos.from00(self.bufnr, start_row0, start_col0) --- @type u.Pos? local stop = details and details.end_row and details.end_col and Pos.from01(self.bufnr, details.end_row, details.end_col) local n_buf_lines = vim.api.nvim_buf_line_count(self.bufnr) if stop and stop.lnum > n_buf_lines then stop.lnum = n_buf_lines stop = stop:eol() end if stop and stop.col == 0 then stop.col = 1 stop = stop:next(-1) end return Range.new(start, stop, 'v') end function Extmark:delete() vim.api.nvim_buf_del_extmark(self.bufnr, self.nsid, self.id) end return Extmark