mirror of
https://github.com/neovim/neovim.git
synced 2026-08-27 09:31:47 +00:00
feat(pos,range): pos:to_mark(), pos.mark(), range:to_mark(), range.mark()
Problem: Ranges represented by marks are usually end-inclusive, but the range utilities we provided are end-exclusive. Solution: Add pos:to_mark(), pos.mark(), range:to_mark(), and range.mark().
This commit is contained in:
@@ -291,6 +291,25 @@ function M.cursor(buf, pos)
|
||||
return M.new(buf, pos[1] - 1, pos[2])
|
||||
end
|
||||
|
||||
--- Converts |vim.Pos| to mark position (see |api-indexing|).
|
||||
---@param pos vim.Pos
|
||||
---@return integer, integer
|
||||
function M.to_mark(pos)
|
||||
return pos[1] + 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, row - 1, col)
|
||||
end
|
||||
|
||||
--- Converts |vim.Pos| to extmark position (see |api-indexing|).
|
||||
---@param pos vim.Pos
|
||||
---@return integer, integer
|
||||
|
||||
@@ -160,6 +160,21 @@ local function to_inclusive_pos(buf, row, col)
|
||||
return row, col
|
||||
end
|
||||
|
||||
---@param row integer
|
||||
---@param col integer
|
||||
---@param buf integer
|
||||
---@return integer, integer
|
||||
local function to_exclusive_pos(buf, row, col)
|
||||
if col >= #get_line(buf, row) then
|
||||
row = row + 1
|
||||
col = 0
|
||||
else
|
||||
col = col + 1
|
||||
end
|
||||
|
||||
return row, col
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param r1 vim.Range
|
||||
---@param r2 vim.Range
|
||||
@@ -314,6 +329,67 @@ function M.lsp(buf, range, position_encoding)
|
||||
return M.new(start, end_)
|
||||
end
|
||||
|
||||
--- Converts |vim.Range| to extmark range (see |api-indexing|).
|
||||
---
|
||||
--- Example:
|
||||
--- ```lua
|
||||
--- 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()
|
||||
--- ```
|
||||
---@param range vim.Range
|
||||
---@return integer, integer, integer, integer
|
||||
function M.to_mark(range)
|
||||
validate('range', range, 'table')
|
||||
|
||||
local buf = range.buf
|
||||
local start_row, start_col, end_row, end_col = range[1], range[2], range[3], range[4]
|
||||
if vim.o.selection ~= 'exclusive' then
|
||||
end_row, end_col = to_inclusive_pos(buf, end_row, end_col)
|
||||
end
|
||||
|
||||
start_row, start_col = vim.pos(buf, start_row, start_col):to_mark()
|
||||
end_row, end_col = vim.pos(buf, end_row, end_col):to_mark()
|
||||
return start_row, start_col, end_row, end_col
|
||||
end
|
||||
|
||||
--- 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, '>'))
|
||||
---
|
||||
--- -- Create an end-exclusive range.
|
||||
--- local range = vim.range.mark(0, start_row, start_col, end_row, end_col)
|
||||
--- ```
|
||||
---@param buf integer
|
||||
---@param start_row integer
|
||||
---@param start_col integer
|
||||
---@param end_row integer
|
||||
---@param end_col integer
|
||||
function M.mark(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')
|
||||
validate('end_row', end_row, 'number')
|
||||
validate('end_col', end_col, 'number')
|
||||
|
||||
if buf == 0 then
|
||||
buf = api.nvim_get_current_buf()
|
||||
end
|
||||
|
||||
local start = vim.pos.mark(buf, start_row, start_col)
|
||||
local end_ = vim.pos.mark(buf, end_row, end_col)
|
||||
|
||||
if vim.o.selection ~= 'exclusive' then
|
||||
end_[1], end_[2] = to_exclusive_pos(buf, end_[1], end_[2])
|
||||
end
|
||||
return M.new(start, end_)
|
||||
end
|
||||
|
||||
--- Converts |vim.Range| to extmark range (see |api-indexing|).
|
||||
---
|
||||
--- Example:
|
||||
|
||||
Reference in New Issue
Block a user