mirror of
https://github.com/neovim/neovim.git
synced 2026-08-31 03:13:48 +00:00
refactor(pos): move get_lines from lsp.util to pos
This commit is contained in:
@@ -133,98 +133,9 @@ local function sort_by_key(fn)
|
||||
end
|
||||
end
|
||||
|
||||
--- Gets the zero-indexed lines from the given buffer.
|
||||
--- Works on unloaded buffers by reading the file using libuv to bypass buf reading events.
|
||||
--- Falls back to loading the buffer and nvim_buf_get_lines for buffers with non-file URI.
|
||||
---
|
||||
---@param bufnr integer bufnr to get the lines from
|
||||
---@param rows integer[] zero-indexed line numbers
|
||||
---@return table<integer, string> # a table mapping rows to lines
|
||||
local function get_lines(bufnr, rows)
|
||||
--- @type integer[]
|
||||
rows = type(rows) == 'table' and rows or { rows }
|
||||
local get_lines = vim.pos._get_lines
|
||||
|
||||
-- This is needed for bufload and bufloaded
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
local function buf_lines()
|
||||
local lines = {} --- @type table<integer,string>
|
||||
for _, row in ipairs(rows) do
|
||||
lines[row] = (api.nvim_buf_get_lines(bufnr, row, row + 1, false) or { '' })[1]
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
-- use loaded buffers if available
|
||||
if vim.fn.bufloaded(bufnr) == 1 then
|
||||
return buf_lines()
|
||||
end
|
||||
|
||||
local uri = vim.uri_from_bufnr(bufnr)
|
||||
|
||||
-- load the buffer if this is not a file uri
|
||||
-- Custom language server protocol extensions can result in servers sending URIs with custom schemes. Plugins are able to load these via `BufReadCmd` autocmds.
|
||||
if uri:sub(1, 4) ~= 'file' then
|
||||
vim.fn.bufload(bufnr)
|
||||
return buf_lines()
|
||||
end
|
||||
|
||||
local filename = api.nvim_buf_get_name(bufnr)
|
||||
if vim.fn.isdirectory(filename) ~= 0 then
|
||||
return {}
|
||||
end
|
||||
|
||||
-- get the data from the file
|
||||
local fd = uv.fs_open(filename, 'r', 438)
|
||||
if not fd then
|
||||
return {}
|
||||
end
|
||||
local stat = assert(uv.fs_fstat(fd))
|
||||
local data = assert(uv.fs_read(fd, stat.size, 0))
|
||||
uv.fs_close(fd)
|
||||
|
||||
local lines = {} --- @type table<integer,true|string> rows we need to retrieve
|
||||
local need = 0 -- keep track of how many unique rows we need
|
||||
for _, row in pairs(rows) do
|
||||
if not lines[row] then
|
||||
need = need + 1
|
||||
end
|
||||
lines[row] = true
|
||||
end
|
||||
|
||||
local found = 0
|
||||
local lnum = 0
|
||||
|
||||
for line in string.gmatch(data, '([^\n]*)\n?') do
|
||||
if lines[lnum] == true then
|
||||
lines[lnum] = line
|
||||
found = found + 1
|
||||
if found == need then
|
||||
break
|
||||
end
|
||||
end
|
||||
lnum = lnum + 1
|
||||
end
|
||||
|
||||
-- change any lines we didn't find to the empty string
|
||||
for i, line in pairs(lines) do
|
||||
if line == true then
|
||||
lines[i] = ''
|
||||
end
|
||||
end
|
||||
return lines --[[@as table<integer,string>]]
|
||||
end
|
||||
|
||||
--- Gets the zero-indexed line from the given buffer.
|
||||
--- Works on unloaded buffers by reading the file using libuv to bypass buf reading events.
|
||||
--- Falls back to loading the buffer and nvim_buf_get_lines for buffers with non-file URI.
|
||||
---
|
||||
---@param bufnr integer
|
||||
---@param row integer zero-indexed line number
|
||||
---@return string the line at row in filename
|
||||
local function get_line(bufnr, row)
|
||||
return get_lines(bufnr, { row })[row]
|
||||
end
|
||||
local get_line = vim.pos._get_line
|
||||
|
||||
--- Position is a https://microsoft.github.io/language-server-protocol/specifications/specification-current/#position
|
||||
---@param position lsp.Position
|
||||
|
||||
Reference in New Issue
Block a user