aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/range.lua
diff options
context:
space:
mode:
authorYi Ming <ofseed@foxmail.com>2025-08-17 11:54:48 +0800
committerYi Ming <ofseed@foxmail.com>2025-08-17 12:13:24 +0800
commit9f5b309d824a7b8a7496fbd23b54d96798a4f2c2 (patch)
tree27ae00c761e2b3defeb130a9f4f9a87d9879ccff /runtime/lua/vim/range.lua
parent98f8224c1948fd8440f13f84f19a0adb78171fe4 (diff)
downloadrneovim-9f5b309d824a7b8a7496fbd23b54d96798a4f2c2.tar.gz
rneovim-9f5b309d824a7b8a7496fbd23b54d96798a4f2c2.tar.bz2
rneovim-9f5b309d824a7b8a7496fbd23b54d96798a4f2c2.zip
feat(lua): conversion between vim and lsp position/range
Diffstat (limited to 'runtime/lua/vim/range.lua')
-rw-r--r--runtime/lua/vim/range.lua53
1 files changed, 53 insertions, 0 deletions
diff --git a/runtime/lua/vim/range.lua b/runtime/lua/vim/range.lua
index 8302c74337..7fdb170874 100644
--- a/runtime/lua/vim/range.lua
+++ b/runtime/lua/vim/range.lua
@@ -129,6 +129,59 @@ function Range.intersect(r1, r2)
return Range.new(rs.start, re.end_)
end
+--- Converts |vim.Range| to `lsp.Range`.
+---
+--- Example:
+--- ```lua
+--- -- `buf` is required for conversion to LSP range.
+--- local buf = vim.api.nvim_get_current_buf()
+--- local range = vim.range(3, 5, 4, 0, { buf = buf })
+---
+--- -- 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
+function Range.to_lsp(range, position_encoding)
+ validate('range', range, 'table')
+ validate('position_encoding', position_encoding, 'string', true)
+
+ ---@type lsp.Range
+ return {
+ ['start'] = range.start:to_lsp(position_encoding),
+ ['end'] = range.end_:to_lsp(position_encoding),
+ }
+end
+
+--- Creates a new |vim.Range| from `lsp.Range`.
+---
+--- Example:
+--- ```lua
+--- local buf = vim.api.nvim_get_current_buf()
+--- local lsp_range = {
+--- ['start'] = { line = 3, character = 5 },
+--- ['end'] = { line = 4, character = 0 }
+--- }
+---
+--- -- `buf` is mandatory, as LSP ranges are always associated with a buffer.
+--- local range = vim.range.lsp(buf, lsp_range, 'utf-16')
+--- ```
+---@param buf integer
+---@param range lsp.Range
+---@param position_encoding lsp.PositionEncodingKind
+function Range.lsp(buf, range, position_encoding)
+ validate('buf', buf, 'number')
+ validate('range', range, 'table')
+ validate('position_encoding', position_encoding, 'string')
+
+ -- TODO(ofseed): avoid using `Pos:lsp()` here,
+ -- as they need reading files separately if buffer is unloaded.
+ local start = vim.pos.lsp(buf, range['start'], position_encoding)
+ local end_ = vim.pos.lsp(buf, range['end'], position_encoding)
+
+ return Range.new(start, end_)
+end
+
-- Overload `Range.new` to allow calling this module as a function.
setmetatable(Range, {
__call = function(_, ...)