diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index bdbb441dba..55c120deb2 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -4510,18 +4510,33 @@ by |vim.Pos| objects. cursor({buf}, {pos}) *vim.pos.cursor()* Creates a new |vim.Pos| from cursor position (see |api-indexing|). + Example: >lua + local cursor_pos = vim.api.nvim_win_get_cursor(0) + local pos = vim.pos.lsp(0, cursor_pos) +< + Parameters: ~ • {buf} (`integer`) - • {pos} (`[integer, integer]`) + • {pos} (`[integer, integer]`) (lnum, col) tuple + + Return: ~ + (`vim.Pos`) See |vim.Pos|. extmark({buf}, {row}, {col}) *vim.pos.extmark()* Creates a new |vim.Pos| from extmark position (see |api-indexing|). + Example: >lua + local pos = vim.pos.extmark(0, 3, 5) +< + Parameters: ~ • {buf} (`integer`) • {row} (`integer`) • {col} (`integer`) + Return: ~ + (`vim.Pos`) See |vim.Pos|. + lsp({buf}, {pos}, {position_encoding}) *vim.pos.lsp()* Creates a new |vim.Pos| from `lsp.Position`. @@ -4539,16 +4554,38 @@ lsp({buf}, {pos}, {position_encoding}) *vim.pos.lsp()* • {pos} (`lsp.Position`) • {position_encoding} (`lsp.PositionEncodingKind`) -mark({buf}, {row}, {col}) *vim.pos.mark()* + Return: ~ + (`vim.Pos`) See |vim.Pos|. + +mark({buf}, {lnum}, {col}) *vim.pos.mark()* Creates a new |vim.Pos| from mark position (see |api-indexing|). + Example: >lua + local mark_info = vim.api.nvim_get_mark('M', {}) + local lnum, col, buf, name = unpack(mark_info) + + if lnum == 0 and col == 0 and buf == 0 then + return -- mark 'M' is not set. + end + + local pos = vim.pos.mark(buf, lnum, col) +< + Parameters: ~ - • {buf} (`integer`) - • {row} (`integer`) - • {col} (`integer`) + • {buf} (`integer`) + • {lnum} (`integer`) + • {col} (`integer`) + + Return: ~ + (`vim.Pos`) See |vim.Pos|. offset({buf}, {offset}) *vim.pos.offset()* - Creates a new |vim.Pos| from buffer offset. + Creates a new |vim.Pos| from buffer (bytes) offset. + + Example: >lua + local offset = vim.api.nvim_buf_get_offset(0, vim.api.nvim_buf_line_count(0)) + local pos = vim.pos.offset(0, offset) +< Parameters: ~ • {buf} (`integer`) @@ -4572,18 +4609,25 @@ to_cursor({pos}) *vim.pos.to_cursor()* • {pos} (`vim.Pos`) See |vim.Pos|. Return (multiple): ~ - (`integer`) - (`integer`) + (`integer`) lnum + (`integer`) col to_extmark({pos}) *vim.pos.to_extmark()* Converts |vim.Pos| to extmark position (see |api-indexing|). + Example: >lua + local pos = vim.pos(0, 3, 5) + + -- Convert to extmark position, you can call it in a method style. + local extmark_pos = pos:to_extmark() +< + Parameters: ~ • {pos} (`vim.Pos`) See |vim.Pos|. Return (multiple): ~ - (`integer`) - (`integer`) + (`integer`) row + (`integer`) col to_lsp({pos}, {position_encoding}) *vim.pos.to_lsp()* Converts |vim.Pos| to `lsp.Position`. @@ -4599,18 +4643,40 @@ to_lsp({pos}, {position_encoding}) *vim.pos.to_lsp()* • {pos} (`vim.Pos`) See |vim.Pos|. • {position_encoding} (`lsp.PositionEncodingKind`) + Return: ~ + (`lsp.Position`) + to_mark({pos}) *vim.pos.to_mark()* Converts |vim.Pos| to mark position (see |api-indexing|). + Example: >lua + local pos = vim.pos(0, 3, 5) + + -- Convert to mark position, you can call it in a method style. + local lnum, col = pos:to_mark() + vim.api.nvim_buf_set_mark(0, 'M', lnum, col, {}) +< + Parameters: ~ • {pos} (`vim.Pos`) See |vim.Pos|. Return (multiple): ~ - (`integer`) - (`integer`) + (`integer`) lnum + (`integer`) col to_offset({pos}) *vim.pos.to_offset()* - Converts |vim.Pos| to buffer offset. + Converts |vim.Pos| to buffer (bytes) offset. + + Example: >lua + local p1 = vim.pos(0, 3, 5) + local p2 = vim.pos(0, 4, 0) + + -- Convert to buffer offset, you can call it in a method style. + local offset1 = p1:to_offset() + local offset2 = p2:to_offset() + -- Can be used to calculate the distance between two locations. + local distance = offset2 - offset1 +< Parameters: ~ • {pos} (`vim.Pos`) See |vim.Pos|. @@ -4681,6 +4747,9 @@ extmark({buf}, {start_row}, {start_col}, {end_row}, {end_col}) • {end_row} (`integer`) • {end_col} (`integer`) + Return: ~ + (`vim.Range`) See |vim.Range|. + has({outer}, {inner}) *vim.range.has()* Checks whether {outer} range contains {inner} range or position. @@ -4729,25 +4798,31 @@ lsp({buf}, {range}, {position_encoding}) *vim.range.lsp()* • {range} (`lsp.Range`) • {position_encoding} (`lsp.PositionEncodingKind`) + Return: ~ + (`vim.Range`) See |vim.Range|. + *vim.range.mark()* -mark({buf}, {start_row}, {start_col}, {end_row}, {end_col}) +mark({buf}, {start_lnum}, {start_col}, {end_lnum}, {end_col}) Creates a new |vim.Range| from "mark-indexed" range (see |api-indexing|). Example: >lua -- A range represented by marks may be end-inclusive (decided by 'selection' option). - local start_row, start_col = unpack(api.nvim_buf_get_mark(bufnr, '<')) - local end_row, end_col = unpack(api.nvim_buf_get_mark(bufnr, '>')) + local start_lnum, start_col = unpack(api.nvim_buf_get_mark(bufnr, '<')) + local end_lnum, end_col = unpack(api.nvim_buf_get_mark(bufnr, '>')) -- Create an end-exclusive range. - local range = vim.range.mark(0, start_row, start_col, end_row, end_col) + local range = vim.range.mark(0, start_lnum, start_col, end_lnum, end_col) < Parameters: ~ - • {buf} (`integer`) - • {start_row} (`integer`) - • {start_col} (`integer`) - • {end_row} (`integer`) - • {end_col} (`integer`) + • {buf} (`integer`) + • {start_lnum} (`integer`) + • {start_col} (`integer`) + • {end_lnum} (`integer`) + • {end_col} (`integer`) + + Return: ~ + (`vim.Range`) See |vim.Range|. to_extmark({range}) *vim.range.to_extmark()* Converts |vim.Range| to extmark range (see |api-indexing|). @@ -4762,6 +4837,12 @@ to_extmark({range}) *vim.range.to_extmark()* Parameters: ~ • {range} (`vim.Range`) See |vim.Range|. + Return (multiple): ~ + (`integer`) start_row + (`integer`) start_col + (`integer`) end_row + (`integer`) end_col + to_lsp({range}, {position_encoding}) *vim.range.to_lsp()* Converts |vim.Range| to `lsp.Range`. @@ -4786,17 +4867,17 @@ to_mark({range}) *vim.range.to_mark()* local range = vim.range(0, 3, 5, 4, 0) -- Convert to mark range, you can call it in a method style. - local start_row, start_col, end_row, end_col = range:to_mark() + local start_lnum, start_col, end_lnum, end_col = range:to_mark() < Parameters: ~ • {range} (`vim.Range`) See |vim.Range|. Return (multiple): ~ - (`integer`) - (`integer`) - (`integer`) - (`integer`) + (`integer`) start_lnum + (`integer`) start_col + (`integer`) end_lnum + (`integer`) end_col ============================================================================== diff --git a/runtime/lua/vim/pos.lua b/runtime/lua/vim/pos.lua index 93865049c3..15cc318ddd 100644 --- a/runtime/lua/vim/pos.lua +++ b/runtime/lua/vim/pos.lua @@ -112,6 +112,7 @@ end --- ``` ---@param pos vim.Pos ---@param position_encoding lsp.PositionEncodingKind +---@return lsp.Position function M.to_lsp(pos, position_encoding) validate('pos', pos, 'table') validate('position_encoding', position_encoding, 'string') @@ -133,6 +134,7 @@ end ---@param buf integer ---@param pos lsp.Position ---@param position_encoding lsp.PositionEncodingKind +---@return vim.Pos function M.lsp(buf, pos, position_encoding) validate('buf', buf, 'number') validate('pos', pos, 'table') @@ -157,49 +159,110 @@ end --- vim.api.nvim_win_set_cursor(0, cursor_pos) --- ``` ---@param pos vim.Pos ----@return integer, integer +---@return integer lnum, integer col function M.to_cursor(pos) + validate('pos', pos, 'table') return util.to_mark(pos[1], pos[2]) end --- Creates a new |vim.Pos| from cursor position (see |api-indexing|). +--- +--- Example: +--- ```lua +--- local cursor_pos = vim.api.nvim_win_get_cursor(0) +--- local pos = vim.pos.lsp(0, cursor_pos) +--- ``` ---@param buf integer ----@param pos [integer, integer] +---@param pos [integer, integer] (lnum, col) tuple +---@return vim.Pos function M.cursor(buf, pos) - return M.new(buf, util.from_mark(pos[1], pos[2])) -end + validate('buf', buf, 'number') + validate('pos', pos, 'table') ---- Converts |vim.Pos| to mark position (see |api-indexing|). ----@param pos vim.Pos ----@return integer, integer -function M.to_mark(pos) - return util.to_mark(pos[1], pos[2]) -end - ---- Creates a new |vim.Pos| from mark position (see |api-indexing|). ----@param buf integer ----@param row integer ----@param col integer -function M.mark(buf, row, col) if buf == 0 then buf = api.nvim_get_current_buf() end - return M.new(buf, util.from_mark(row, col)) + return M.new(buf, util.from_mark(pos[1], pos[2])) +end + +--- Converts |vim.Pos| to mark position (see |api-indexing|). +--- +--- Example: +--- ```lua +--- local pos = vim.pos(0, 3, 5) +--- +--- -- Convert to mark position, you can call it in a method style. +--- local lnum, col = pos:to_mark() +--- vim.api.nvim_buf_set_mark(0, 'M', lnum, col, {}) +--- ``` +---@param pos vim.Pos +---@return integer lnum, integer col +function M.to_mark(pos) + validate('pos', pos, 'table') + return util.to_mark(pos[1], pos[2]) +end + +--- Creates a new |vim.Pos| from mark position (see |api-indexing|). +--- +--- Example: +--- ```lua +--- local mark_info = vim.api.nvim_get_mark('M', {}) +--- local lnum, col, buf, name = unpack(mark_info) +--- +--- if lnum == 0 and col == 0 and buf == 0 then +--- return -- mark 'M' is not set. +--- end +--- +--- local pos = vim.pos.mark(buf, lnum, col) +--- ``` +---@param buf integer +---@param lnum integer +---@param col integer +---@return vim.Pos +function M.mark(buf, lnum, col) + validate('buf', buf, 'number') + validate('lnum', lnum, 'number') + validate('col', col, 'number') + + if buf == 0 then + buf = api.nvim_get_current_buf() + end + + return M.new(buf, util.from_mark(lnum, col)) end --- Converts |vim.Pos| to extmark position (see |api-indexing|). +--- +--- Example: +--- ```lua +--- local pos = vim.pos(0, 3, 5) +--- +--- -- Convert to extmark position, you can call it in a method style. +--- local extmark_pos = pos:to_extmark() +--- ``` ---@param pos vim.Pos ----@return integer, integer +---@return integer row, integer col function M.to_extmark(pos) + validate('pos', pos, 'table') return pos[1], pos[2] end --- Creates a new |vim.Pos| from extmark position (see |api-indexing|). +--- +--- Example: +--- ```lua +--- local pos = vim.pos.extmark(0, 3, 5) +--- ``` ---@param buf integer ---@param row integer ---@param col integer +---@return vim.Pos function M.extmark(buf, row, col) + validate('buf', buf, 'number') + validate('row', row, 'number') + validate('col', col, 'number') + if buf == 0 then buf = api.nvim_get_current_buf() end @@ -207,18 +270,40 @@ function M.extmark(buf, row, col) return M.new(buf, row, col) end ---- Converts |vim.Pos| to buffer offset. +--- Converts |vim.Pos| to buffer (bytes) offset. +--- +--- Example: +--- ```lua +--- local p1 = vim.pos(0, 3, 5) +--- local p2 = vim.pos(0, 4, 0) +--- +--- -- Convert to buffer offset, you can call it in a method style. +--- local offset1 = p1:to_offset() +--- local offset2 = p2:to_offset() +--- -- Can be used to calculate the distance between two locations. +--- local distance = offset2 - offset1 +--- ``` ---@param pos vim.Pos ---@return integer function M.to_offset(pos) + validate('pos', pos, 'table') return api.nvim_buf_get_offset(pos.buf, pos[1]) + pos[2] end ---- Creates a new |vim.Pos| from buffer offset. +--- Creates a new |vim.Pos| from buffer (bytes) offset. +--- +--- Example: +--- ```lua +--- local offset = vim.api.nvim_buf_get_offset(0, vim.api.nvim_buf_line_count(0)) +--- local pos = vim.pos.offset(0, offset) +--- ``` ---@param buf integer ---@param offset integer ---@return vim.Pos function M.offset(buf, offset) + validate('buf', buf, 'number') + validate('offset', offset, 'number') + local lnum = vim.list.bisect( setmetatable({}, { __index = function(_, lnum) diff --git a/runtime/lua/vim/range.lua b/runtime/lua/vim/range.lua index 6ba3281526..489b41e2b3 100644 --- a/runtime/lua/vim/range.lua +++ b/runtime/lua/vim/range.lua @@ -183,6 +183,7 @@ end ---@param range vim.Range ---@return boolean `true` if the given range is empty. function M.is_empty(range) + validate('range', range, 'table') return util.cmp_pos.ge(range[1], range[2], range[3], range[4]) end @@ -192,6 +193,9 @@ end ---@param inner vim.Range|vim.Pos ---@return boolean `true` if {outer} range fully contains {inner} range or position. function M.has(outer, inner) + validate('outer', outer, 'table') + validate('inner', inner, 'table') + if getmetatable(inner) == vim.pos then ---@cast inner -vim.Range return util.cmp_pos.le(outer[1], outer[2], inner[1], inner[2]) @@ -225,6 +229,9 @@ end ---@return vim.Range? range that is present inside both `r1` and `r2`. --- `nil` if such range does not exist. function M.intersect(r1, r2) + validate('r1', r1, 'table') + validate('r2', r2, 'table') + if r1.buf ~= r2.buf then return nil end @@ -285,6 +292,7 @@ end ---@param buf integer ---@param range lsp.Range ---@param position_encoding lsp.PositionEncodingKind +---@return vim.Range function M.lsp(buf, range, position_encoding) validate('buf', buf, 'number') validate('range', range, 'table') @@ -306,10 +314,10 @@ end --- local range = vim.range(0, 3, 5, 4, 0) --- --- -- Convert to mark range, you can call it in a method style. ---- local start_row, start_col, end_row, end_col = range:to_mark() +--- local start_lnum, start_col, end_lnum, end_col = range:to_mark() --- ``` ---@param range vim.Range ----@return integer, integer, integer, integer +---@return integer start_lnum, integer start_col, integer end_lnum, integer end_col function M.to_mark(range) validate('range', range, 'table') @@ -329,35 +337,36 @@ end --- Example: --- ```lua --- -- A range represented by marks may be end-inclusive (decided by 'selection' option). ---- local start_row, start_col = unpack(api.nvim_buf_get_mark(bufnr, '<')) ---- local end_row, end_col = unpack(api.nvim_buf_get_mark(bufnr, '>')) +--- local start_lnum, start_col = unpack(api.nvim_buf_get_mark(bufnr, '<')) +--- local end_lnum, end_col = unpack(api.nvim_buf_get_mark(bufnr, '>')) --- --- -- Create an end-exclusive range. ---- local range = vim.range.mark(0, start_row, start_col, end_row, end_col) +--- local range = vim.range.mark(0, start_lnum, start_col, end_lnum, end_col) --- ``` ---@param buf integer ----@param start_row integer +---@param start_lnum integer ---@param start_col integer ----@param end_row integer +---@param end_lnum integer ---@param end_col integer -function M.mark(buf, start_row, start_col, end_row, end_col) +---@return vim.Range +function M.mark(buf, start_lnum, start_col, end_lnum, end_col) validate('buf', buf, 'number') - validate('start_row', start_row, 'number') + validate('start_lnum', start_lnum, 'number') validate('start_col', start_col, 'number') - validate('end_row', end_row, 'number') + validate('end_lnum', end_lnum, 'number') validate('end_col', end_col, 'number') if buf == 0 then buf = api.nvim_get_current_buf() end - start_row, start_col = util.from_mark(start_row, start_col) - end_row, end_col = util.from_mark(end_row, end_col) + start_lnum, start_col = util.from_mark(start_lnum, start_col) + end_lnum, end_col = util.from_mark(end_lnum, end_col) if vim.o.selection ~= 'exclusive' then - end_row, end_col = to_exclusive_pos(buf, end_row, end_col) + end_lnum, end_col = to_exclusive_pos(buf, end_lnum, end_col) end - return M.new(buf, start_row, start_col, end_row, end_col) + return M.new(buf, start_lnum, start_col, end_lnum, end_col) end --- Converts |vim.Range| to extmark range (see |api-indexing|). @@ -370,6 +379,7 @@ end --- local extmark_range = range:to_extmark() --- ``` ---@param range vim.Range +---@return integer start_row, integer start_col, integer end_row, integer end_col function M.to_extmark(range) validate('range', range, 'table') @@ -406,6 +416,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) validate('buf', buf, 'number') validate('start_row', start_row, 'number')