diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index e28b151a4d..f987f0e353 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -4290,53 +4290,28 @@ by |vim.Pos| objects. • {row} (`integer`) 0-based byte index. • {col} (`integer`) 0-based byte index. • {buf} (`integer`) buffer handle. - • {to_lsp} (`fun(self: vim.Pos, position_encoding: lsp.PositionEncodingKind)`) + • {to_lsp} (`fun(pos: vim.Pos, position_encoding: lsp.PositionEncodingKind)`) See |Pos:to_lsp()|. - • {to_cursor} (`fun(self: vim.Pos): integer, integer`) See + • {lsp} (`fun(buf: integer, pos: lsp.Position, position_encoding: lsp.PositionEncodingKind)`) + See |Pos:lsp()|. + • {to_cursor} (`fun(pos: vim.Pos): integer, integer`) See |Pos:to_cursor()|. - • {to_extmark} (`fun(self: vim.Pos): integer, integer`) See + • {cursor} (`fun(buf: integer, pos: [integer, integer])`) See + |Pos:cursor()|. + • {to_extmark} (`fun(pos: vim.Pos): integer, integer`) See |Pos:to_extmark()|. + • {extmark} (`fun(buf: integer, row: integer, col: integer)`) See + |Pos:extmark()|. -Pos:to_cursor() *Pos:to_cursor()* - Converts |vim.Pos| to cursor position (see |api-indexing|). - - Return (multiple): ~ - (`integer`) - (`integer`) - -Pos:to_extmark() *Pos:to_extmark()* - Converts |vim.Pos| to extmark position (see |api-indexing|). - - Return (multiple): ~ - (`integer`) - (`integer`) - -Pos:to_lsp({position_encoding}) *Pos:to_lsp()* - Converts |vim.Pos| to `lsp.Position`. - - Example: >lua - local buf = vim.api.nvim_get_current_buf() - local pos = vim.pos(buf, 3, 5) - - -- Convert to LSP position, you can call it in a method style. - local lsp_pos = pos:to_lsp('utf-16') -< - - Parameters: ~ - • {position_encoding} (`lsp.PositionEncodingKind`) - -vim.pos.cursor({buf}, {pos}) *vim.pos.cursor()* +Pos:cursor({buf}, {pos}) *Pos:cursor()* Creates a new |vim.Pos| from cursor position (see |api-indexing|). Parameters: ~ • {buf} (`integer`) • {pos} (`[integer, integer]`) - Return: ~ - (`vim.Pos`) See |vim.Pos|. - -vim.pos.extmark({buf}, {row}, {col}) *vim.pos.extmark()* +Pos:extmark({buf}, {row}, {col}) *Pos:extmark()* Creates a new |vim.Pos| from extmark position (see |api-indexing|). Parameters: ~ @@ -4344,10 +4319,7 @@ vim.pos.extmark({buf}, {row}, {col}) *vim.pos.extmark()* • {row} (`integer`) • {col} (`integer`) - Return: ~ - (`vim.Pos`) See |vim.Pos|. - -vim.pos.lsp({buf}, {pos}, {position_encoding}) *vim.pos.lsp()* +Pos:lsp({buf}, {pos}, {position_encoding}) *Pos:lsp()* Creates a new |vim.Pos| from `lsp.Position`. Example: >lua @@ -4365,8 +4337,40 @@ vim.pos.lsp({buf}, {pos}, {position_encoding}) *vim.pos.lsp()* • {pos} (`lsp.Position`) • {position_encoding} (`lsp.PositionEncodingKind`) - Return: ~ - (`vim.Pos`) See |vim.Pos|. +Pos:to_cursor({pos}) *Pos:to_cursor()* + Converts |vim.Pos| to cursor position (see |api-indexing|). + + Parameters: ~ + • {pos} (`vim.Pos`) See |vim.Pos|. + + Return (multiple): ~ + (`integer`) + (`integer`) + +Pos:to_extmark({pos}) *Pos:to_extmark()* + Converts |vim.Pos| to extmark position (see |api-indexing|). + + Parameters: ~ + • {pos} (`vim.Pos`) See |vim.Pos|. + + Return (multiple): ~ + (`integer`) + (`integer`) + +Pos:to_lsp({pos}, {position_encoding}) *Pos:to_lsp()* + Converts |vim.Pos| to `lsp.Position`. + + Example: >lua + local buf = vim.api.nvim_get_current_buf() + local pos = vim.pos(buf, 3, 5) + + -- Convert to LSP position, you can call it in a method style. + local lsp_pos = pos:to_lsp('utf-16') +< + + Parameters: ~ + • {pos} (`vim.Pos`) See |vim.Pos|. + • {position_encoding} (`lsp.PositionEncodingKind`) ============================================================================== @@ -4416,81 +4420,23 @@ Provides operations to compare, calculate, and convert ranges represented by • {buf} (`integer`) Optional buffer handle. • {is_empty} (`fun(self: vim.Range): boolean`) See |Range:is_empty()|. - • {has} (`fun(self: vim.Range, inner: vim.Range|vim.Pos): boolean`) + • {has} (`fun(outer: vim.Range, inner: vim.Range|vim.Pos): boolean`) See |Range:has()|. - • {intersect} (`fun(self: vim.Range, r2: vim.Range): vim.Range?`) See + • {intersect} (`fun(r1: vim.Range, r2: vim.Range): vim.Range?`) See |Range:intersect()|. - • {to_lsp} (`fun(self: vim.Range, position_encoding: lsp.PositionEncodingKind): lsp.Range`) + • {to_lsp} (`fun(range: vim.Range, position_encoding: lsp.PositionEncodingKind): lsp.Range`) See |Range:to_lsp()|. - • {to_extmark} (`fun(self: vim.Range)`) See |Range:to_extmark()|. - • {to_cursor} (`fun(self: vim.Range)`) See |Range:to_cursor()|. + • {lsp} (`fun(buf: integer, range: lsp.Range, position_encoding: lsp.PositionEncodingKind)`) + See |Range:lsp()|. + • {to_extmark} (`fun(range: vim.Range)`) See |Range:to_extmark()|. + • {extmark} (`fun(buf: integer, start_row: integer, start_col: integer, end_row: integer, end_col: integer)`) + See |Range:extmark()|. + • {to_cursor} (`fun(range: vim.Range)`) See |Range:to_cursor()|. + • {cursor} (`fun(buf: integer, start_pos: [integer, integer], end_pos: [integer, integer])`) + See |Range:cursor()|. -Range:has({inner}) *Range:has()* - Checks whether range contains {inner} range or position. - - Parameters: ~ - • {inner} (`vim.Range|vim.Pos`) - - Return: ~ - (`boolean`) `true` if range fully contains {inner} range or position. - -Range:intersect({r2}) *Range:intersect()* - Computes the common range shared by range and {r2} - - Parameters: ~ - • {r2} (`vim.Range`) Second range to intersect. See |vim.Range|. - - Return: ~ - (`vim.Range?`) range that is present inside both range and `r2`. `nil` - if such range does not exist. See |vim.Range|. - -Range:is_empty() *Range:is_empty()* - Checks whether the given range is empty; i.e., start >= end. - - Return: ~ - (`boolean`) `true` if the given range is empty - -Range:to_cursor() *Range:to_cursor()* - Converts |vim.Range| to mark-like range (see |api-indexing|). - - Example: >lua - local buf = vim.api.nvim_get_current_buf() - local range = vim.range(buf, 3, 5, 4, 0) - - -- Convert to cursor range, you can call it in a method style. - local cursor_range = range:to_cursor() -< - -Range:to_extmark() *Range:to_extmark()* - Converts |vim.Range| to extmark range (see |api-indexing|). - - Example: >lua - local buf = vim.api.nvim_get_current_buf() - local range = vim.range(buf, 3, 5, 4, 0) - - -- Convert to extmark range, you can call it in a method style. - local extmark_range = range:to_extmark() -< - -Range:to_lsp({position_encoding}) *Range:to_lsp()* - Converts |vim.Range| to `lsp.Range`. - - Example: >lua - local buf = vim.api.nvim_get_current_buf() - local range = vim.range(buf, 3, 5, 4, 0) - - -- Convert to LSP range, you can call it in a method style. - local lsp_range = range:to_lsp('utf-16') -< - - Parameters: ~ - • {position_encoding} (`lsp.PositionEncodingKind`) - - Return: ~ - (`lsp.Range`) - -vim.range.cursor({buf}, {start_pos}, {end_pos}) *vim.range.cursor()* +Range:cursor({buf}, {start_pos}, {end_pos}) *Range:cursor()* Creates a new |vim.Range| from mark-like range (see |api-indexing|). Example: >lua @@ -4507,11 +4453,8 @@ vim.range.cursor({buf}, {start_pos}, {end_pos}) *vim.range.cursor()* • {start_pos} (`[integer, integer]`) • {end_pos} (`[integer, integer]`) - Return: ~ - (`vim.Range`) See |vim.Range|. - - *vim.range.extmark()* -vim.range.extmark({buf}, {start_row}, {start_col}, {end_row}, {end_col}) + *Range:extmark()* +Range:extmark({buf}, {start_row}, {start_col}, {end_row}, {end_col}) Creates a new |vim.Range| from extmark range (see |api-indexing|). Example: >lua @@ -4527,10 +4470,35 @@ vim.range.extmark({buf}, {start_row}, {start_col}, {end_row}, {end_col}) • {end_row} (`integer`) • {end_col} (`integer`) - Return: ~ - (`vim.Range`) See |vim.Range|. +Range:has({outer}, {inner}) *Range:has()* + Checks whether {outer} range contains {inner} range or position. -vim.range.lsp({buf}, {range}, {position_encoding}) *vim.range.lsp()* + Parameters: ~ + • {outer} (`vim.Range`) See |vim.Range|. + • {inner} (`vim.Range|vim.Pos`) + + Return: ~ + (`boolean`) `true` if {outer} range fully contains {inner} range or + position. + +Range:intersect({r1}, {r2}) *Range:intersect()* + Computes the common range shared by the given ranges. + + Parameters: ~ + • {r1} (`vim.Range`) First range to intersect. See |vim.Range|. + • {r2} (`vim.Range`) Second range to intersect. See |vim.Range|. + + Return: ~ + (`vim.Range?`) range that is present inside both `r1` and `r2`. `nil` + if such range does not exist. See |vim.Range|. + +Range:is_empty() *Range:is_empty()* + Checks whether the given range is empty; i.e., start >= end. + + Return: ~ + (`boolean`) `true` if the given range is empty + +Range:lsp({buf}, {range}, {position_encoding}) *Range:lsp()* Creates a new |vim.Range| from `lsp.Range`. Example: >lua @@ -4548,8 +4516,51 @@ vim.range.lsp({buf}, {range}, {position_encoding}) *vim.range.lsp()* • {range} (`lsp.Range`) • {position_encoding} (`lsp.PositionEncodingKind`) +Range:to_cursor({range}) *Range:to_cursor()* + Converts |vim.Range| to mark-like range (see |api-indexing|). + + Example: >lua + local buf = vim.api.nvim_get_current_buf() + local range = vim.range(buf, 3, 5, 4, 0) + + -- Convert to cursor range, you can call it in a method style. + local cursor_range = range:to_cursor() +< + + Parameters: ~ + • {range} (`vim.Range`) See |vim.Range|. + +Range:to_extmark({range}) *Range:to_extmark()* + Converts |vim.Range| to extmark range (see |api-indexing|). + + Example: >lua + local buf = vim.api.nvim_get_current_buf() + local range = vim.range(buf, 3, 5, 4, 0) + + -- Convert to extmark range, you can call it in a method style. + local extmark_range = range:to_extmark() +< + + Parameters: ~ + • {range} (`vim.Range`) See |vim.Range|. + +Range:to_lsp({range}, {position_encoding}) *Range:to_lsp()* + Converts |vim.Range| to `lsp.Range`. + + Example: >lua + local buf = vim.api.nvim_get_current_buf() + local range = vim.range(buf, 3, 5, 4, 0) + + -- Convert to LSP range, you can call it in a method style. + local lsp_range = range:to_lsp('utf-16') +< + + Parameters: ~ + • {range} (`vim.Range`) See |vim.Range|. + • {position_encoding} (`lsp.PositionEncodingKind`) + Return: ~ - (`vim.Range`) See |vim.Range|. + (`lsp.Range`) ============================================================================== diff --git a/runtime/lua/vim/pos.lua b/runtime/lua/vim/pos.lua index 65e6a6678f..85f6cbe084 100644 --- a/runtime/lua/vim/pos.lua +++ b/runtime/lua/vim/pos.lua @@ -6,8 +6,6 @@ --- Provides operations to compare, calculate, and convert positions represented by |vim.Pos| --- objects. -local M = {} - local api = vim.api local validate = vim.validate @@ -43,8 +41,7 @@ local validate = vim.validate ---@field private [3] integer underlying representation of buf local Pos = {} -M._Pos = Pos - +---@private ---@param pos vim.Pos ---@param key any function Pos.__index(pos, key) @@ -100,14 +97,17 @@ local function cmp_pos(p1, p2) return -1 end +---@private function Pos.__lt(...) return cmp_pos(...) == -1 end +---@private function Pos.__le(...) return cmp_pos(...) ~= 1 end +---@private function Pos.__eq(...) return cmp_pos(...) == 0 end @@ -129,11 +129,13 @@ end --- -- Convert to LSP position, you can call it in a method style. --- local lsp_pos = pos:to_lsp('utf-16') --- ``` +---@param pos vim.Pos ---@param position_encoding lsp.PositionEncodingKind -function Pos:to_lsp(position_encoding) +function Pos.to_lsp(pos, position_encoding) + validate('pos', pos, 'table') validate('position_encoding', position_encoding, 'string') - local buf, row, col = self.buf, self.row, self.col + local buf, row, col = pos.buf, pos.row, pos.col -- When on the first character, -- we can ignore the difference between byte and character. if col > 0 then @@ -159,8 +161,7 @@ end ---@param buf integer ---@param pos lsp.Position ---@param position_encoding lsp.PositionEncodingKind ----@return vim.Pos -function M.lsp(buf, pos, position_encoding) +function Pos.lsp(buf, pos, position_encoding) validate('buf', buf, 'number') validate('pos', pos, 'table') validate('position_encoding', position_encoding, 'string') @@ -178,29 +179,30 @@ function M.lsp(buf, pos, position_encoding) end --- Converts |vim.Pos| to cursor position (see |api-indexing|). +---@param pos vim.Pos ---@return integer, integer -function Pos:to_cursor() - return self.row + 1, self.col +function Pos.to_cursor(pos) + return pos.row + 1, pos.col end --- Creates a new |vim.Pos| from cursor position (see |api-indexing|). ---@param buf integer ---@param pos [integer, integer] ----@return vim.Pos -function M.cursor(buf, pos) +function Pos.cursor(buf, pos) return Pos.new(buf, pos[1] - 1, pos[2]) end --- Converts |vim.Pos| to extmark position (see |api-indexing|). +---@param pos vim.Pos ---@return integer, integer -function Pos:to_extmark() - local line_num = #api.nvim_buf_get_lines(self.buf, 0, -1, true) +function Pos.to_extmark(pos) + local line_count = api.nvim_buf_line_count(pos.buf) - local row = self.row - local col = self.col - if self.col == 0 and self.row == line_num then + local row = pos.row + local col = pos.col + if pos.col == 0 and pos.row == line_count then row = row - 1 - col = #get_line(self.buf, row) + col = #get_line(pos.buf, row) end return row, col @@ -210,16 +212,16 @@ end ---@param buf integer ---@param row integer ---@param col integer ----@return vim.Pos -function M.extmark(buf, row, col) +function Pos.extmark(buf, row, col) return Pos.new(buf, row, col) end -setmetatable(M, { +-- Overload `Range.new` to allow calling this module as a function. +setmetatable(Pos, { __call = function(_, ...) return Pos.new(...) end, }) ----@cast M +fun(buf: integer, row: integer, col: integer): vim.Pos +---@cast Pos +fun(buf: integer, row: integer, col: integer): vim.Pos -return M +return Pos diff --git a/runtime/lua/vim/range.lua b/runtime/lua/vim/range.lua index 762a33f401..8c992fef9b 100644 --- a/runtime/lua/vim/range.lua +++ b/runtime/lua/vim/range.lua @@ -6,8 +6,6 @@ --- Provides operations to compare, calculate, and convert ranges represented by |vim.Range| --- objects. -local M = {} - local validate = vim.validate local api = vim.api @@ -51,6 +49,7 @@ local api = vim.api ---@field private [5] integer underlying representation of buf local Range = {} +---@private ---@param pos vim.Range ---@param key any function Range.__index(pos, key) @@ -153,6 +152,7 @@ local function to_inclusive_pos(buf, row, col) return row, col end +---@private ---@param r1 vim.Range ---@param r2 vim.Range function Range.__lt(r1, r2) @@ -161,6 +161,7 @@ function Range.__lt(r1, r2) return cmp_pos(r1_inclusive_end_row, r1_inclusive_end_col, r2.start_row, r2.start_col) == -1 end +---@private ---@param r1 vim.Range ---@param r2 vim.Range function Range.__le(r1, r2) @@ -169,6 +170,7 @@ function Range.__le(r1, r2) return cmp_pos(r1_inclusive_end_row, r1_inclusive_end_col, r2.start_row, r2.start_col) ~= 1 end +---@private ---@param r1 vim.Range ---@param r2 vim.Range function Range.__eq(r1, r2) @@ -186,28 +188,29 @@ function Range:is_empty() return cmp_pos(self.start_row, self.start_col, inclusive_end_row, inclusive_end_col) ~= -1 end ---- Checks whether range contains {inner} range or position. +--- Checks whether {outer} range contains {inner} range or position. --- +---@param outer vim.Range ---@param inner vim.Range|vim.Pos ----@return boolean `true` if range fully contains {inner} range or position. -function Range:has(inner) - if getmetatable(inner) == vim.pos._Pos then +---@return boolean `true` if {outer} range fully contains {inner} range or position. +function Range.has(outer, inner) + if getmetatable(inner) == vim.pos then ---@cast inner -vim.Range - return cmp_pos(self.start_row, self.start_col, inner.row, inner.col) ~= 1 - and cmp_pos(self.end_row, self.end_col, inner.row, inner.col) ~= -1 + return cmp_pos(outer.start_row, outer.start_col, inner.row, inner.col) ~= 1 + and cmp_pos(outer.end_row, outer.end_col, inner.row, inner.col) ~= -1 end ---@cast inner -vim.Pos local outer_inclusive_end_row, outer_inclusive_end_col = - to_inclusive_pos(self.buf, self.end_row, self.end_col) + to_inclusive_pos(outer.buf, outer.end_row, outer.end_col) local inner_inclusive_end_row, inner_inclusive_end_col = to_inclusive_pos(inner.buf, inner.end_row, inner.end_col) - return cmp_pos(self.start_row, self.start_col, inner.start_row, inner.start_col) ~= 1 - and cmp_pos(self.end_row, self.end_col, inner.end_row, inner.end_col) ~= -1 + return cmp_pos(outer.start_row, outer.start_col, inner.start_row, inner.start_col) ~= 1 + and cmp_pos(outer.end_row, outer.end_col, inner.end_row, inner.end_col) ~= -1 -- accounts for empty ranges at the start/end of `outer` that per Neovim API and LSP logic -- insert the text outside `outer` - and cmp_pos(self.start_row, self.start_col, inner_inclusive_end_row, inner_inclusive_end_col) == -1 + and cmp_pos(outer.start_row, outer.start_col, inner_inclusive_end_row, inner_inclusive_end_col) == -1 and cmp_pos( outer_inclusive_end_row, outer_inclusive_end_col, @@ -217,31 +220,32 @@ function Range:has(inner) == 1 end ---- Computes the common range shared by range and {r2} +--- Computes the common range shared by the given ranges. --- +---@param r1 vim.Range First range to intersect. ---@param r2 vim.Range Second range to intersect ----@return vim.Range? range that is present inside both range and `r2`. +---@return vim.Range? range that is present inside both `r1` and `r2`. --- `nil` if such range does not exist. -function Range:intersect(r2) - if self.buf ~= r2.buf then +function Range.intersect(r1, r2) + if r1.buf ~= r2.buf then return nil end local r1_inclusive_end_row, r1_inclusive_end_col = - to_inclusive_pos(self.buf, self.end_row, self.end_col) + to_inclusive_pos(r1.buf, r1.end_row, r1.end_col) local r2_inclusive_end_row, r2_inclusive_end_col = to_inclusive_pos(r2.buf, r2.end_row, r2.end_col) if cmp_pos(r1_inclusive_end_row, r1_inclusive_end_col, r2.start_row, r2.start_col) ~= 1 - or cmp_pos(self.start_row, self.start_col, r2_inclusive_end_row, r2_inclusive_end_col) ~= -1 + or cmp_pos(r1.start_row, r1.start_col, r2_inclusive_end_row, r2_inclusive_end_col) ~= -1 then return nil end - local rs = cmp_pos(self.start_row, self.start_col, r2.start_row, r2.start_col) ~= 1 and r2 or self - local re = cmp_pos(self.end_row, self.end_col, r2.end_row, r2.end_col) ~= -1 and r2 or self - return Range.new(self.buf, rs.start_row, rs.start_col, re.end_row, re.end_col) + local rs = cmp_pos(r1.start_row, r1.start_col, r2.start_row, r2.start_col) ~= 1 and r2 or r1 + local re = cmp_pos(r1.end_row, r1.end_col, r2.end_row, r2.end_col) ~= -1 and r2 or r1 + return Range.new(r1.buf, rs.start_row, rs.start_col, re.end_row, re.end_col) end --- Converts |vim.Range| to `lsp.Range`. @@ -254,15 +258,17 @@ end --- -- Convert to LSP range, you can call it in a method style. --- local lsp_range = range:to_lsp('utf-16') --- ``` +---@param range vim.Range ---@param position_encoding lsp.PositionEncodingKind ---@return lsp.Range -function Range:to_lsp(position_encoding) +function Range.to_lsp(range, position_encoding) + validate('range', range, 'table') validate('position_encoding', position_encoding, 'string', true) ---@type lsp.Range return { - ['start'] = vim.pos(self.buf, self.start_row, self.start_col):to_lsp(position_encoding), - ['end'] = vim.pos(self.buf, self.end_row, self.end_col):to_lsp(position_encoding), + ['start'] = vim.pos(range.buf, range.start_row, range.start_col):to_lsp(position_encoding), + ['end'] = vim.pos(range.buf, range.end_row, range.end_col):to_lsp(position_encoding), } end @@ -281,8 +287,7 @@ end ---@param buf integer ---@param range lsp.Range ---@param position_encoding lsp.PositionEncodingKind ----@return vim.Range -function M.lsp(buf, range, position_encoding) +function Range.lsp(buf, range, position_encoding) validate('buf', buf, 'number') validate('range', range, 'table') validate('position_encoding', position_encoding, 'string') @@ -305,9 +310,12 @@ end --- -- Convert to extmark range, you can call it in a method style. --- local extmark_range = range:to_extmark() --- ``` -function Range:to_extmark() - local srow, scol = vim.pos(self.buf, self.start_row, self.start_col):to_extmark() - local erow, ecol = vim.pos(self.buf, self.end_row, self.end_col):to_extmark() +---@param range vim.Range +function Range.to_extmark(range) + validate('range', range, 'table') + + local srow, scol = vim.pos(range.buf, range.start_row, range.start_col):to_extmark() + local erow, ecol = vim.pos(range.buf, range.end_row, range.end_col):to_extmark() return srow, scol, erow, ecol end @@ -324,8 +332,7 @@ end ---@param start_col integer ---@param end_row integer ---@param end_col integer ----@return vim.Range -function M.extmark(buf, start_row, start_col, end_row, end_col) +function Range.extmark(buf, start_row, start_col, end_row, end_col) validate('buf', buf, 'number') validate('start_row', start_row, 'number') validate('start_col', start_col, 'number') @@ -348,9 +355,12 @@ end --- -- Convert to cursor range, you can call it in a method style. --- local cursor_range = range:to_cursor() --- ``` -function Range:to_cursor() - local srow, scol = vim.pos(self.buf, self.start_row, self.start_col):to_cursor() - local erow, ecol = vim.pos(self.buf, self.end_row, self.end_col):to_cursor() +---@param range vim.Range +function Range.to_cursor(range) + validate('range', range, 'table') + + local srow, scol = vim.pos(range.buf, range.start_row, range.start_col):to_cursor() + local erow, ecol = vim.pos(range.buf, range.end_row, range.end_col):to_cursor() return srow, scol, erow, ecol end @@ -368,8 +378,7 @@ end ---@param buf integer ---@param start_pos [integer, integer] ---@param end_pos [integer, integer] ----@return vim.Range -function M.cursor(buf, start_pos, end_pos) +function Range.cursor(buf, start_pos, end_pos) validate('buf', buf, 'number') validate('range', start_pos, 'table') validate('range', end_pos, 'table') @@ -380,12 +389,13 @@ function M.cursor(buf, start_pos, end_pos) return Range.new(start, end_) end -setmetatable(M, { +-- Overload `Range.new` to allow calling this module as a function. +setmetatable(Range, { __call = function(_, ...) return Range.new(...) end, }) ----@cast M +fun(start: vim.Pos, end_: vim.Pos): vim.Range ----@cast M +fun(buf: integer, start_row: integer, start_col: integer, end_row: integer, end_col: integer): vim.Range +---@cast Range +fun(start: vim.Pos, end_: vim.Pos): vim.Range +---@cast Range +fun(buf: integer, start_row: integer, start_col: integer, end_row: integer, end_col: integer): vim.Range -return M +return Range