mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-05 03:08:13 +00:00
fix(picker): better handling of buffers with custom URIs. Fixes #677
This commit is contained in:
parent
7d354726ff
commit
cd5eddb1de
2 changed files with 51 additions and 5 deletions
|
@ -60,10 +60,16 @@ end
|
|||
|
||||
---@param ctx snacks.picker.preview.ctx
|
||||
function M.file(ctx)
|
||||
if ctx.item.buf and not vim.api.nvim_buf_is_valid(ctx.item.buf) then
|
||||
if ctx.item.buf and not ctx.item.file and not vim.api.nvim_buf_is_valid(ctx.item.buf) then
|
||||
ctx.preview:notify("Buffer no longer exists", "error")
|
||||
return
|
||||
end
|
||||
|
||||
-- used by some LSP servers that load buffers with custom URIs
|
||||
if ctx.item.buf and vim.uri_from_bufnr(ctx.item.buf):sub(1, 4) ~= "file" then
|
||||
vim.fn.bufload(ctx.item.buf)
|
||||
end
|
||||
|
||||
if ctx.item.buf and vim.api.nvim_buf_is_loaded(ctx.item.buf) then
|
||||
local name = vim.api.nvim_buf_get_name(ctx.item.buf)
|
||||
name = uv.fs_stat(name) and vim.fn.fnamemodify(name, ":t") or name
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
---@class snacks.picker.util
|
||||
local M = {}
|
||||
|
||||
local uv = vim.uv or vim.loop
|
||||
|
||||
---@param item snacks.picker.Item
|
||||
function M.path(item)
|
||||
if not (item and item.file) then
|
||||
|
@ -191,6 +193,36 @@ function M.resolve(item)
|
|||
return item
|
||||
end
|
||||
|
||||
--- Reads the lines of a file.
|
||||
--- This is about 8x faster than `vim.fn.readfile`
|
||||
--- and 3x faster than `io.lines` using a
|
||||
--- test files of 225KB and 8300 lines.
|
||||
---@param file string
|
||||
function M.lines(file)
|
||||
local fd = uv.fs_open(file, "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, from = {}, 1 --- @type string[], number
|
||||
while from <= #data do
|
||||
local nl = data:find("\n", from, true)
|
||||
if nl then
|
||||
local cr = data:byte(nl - 1, nl - 1) == 13 -- \r
|
||||
local line = data:sub(from, nl - (cr and 2 or 1))
|
||||
lines[#lines + 1] = line
|
||||
from = nl + 1
|
||||
else
|
||||
lines[#lines + 1] = data:sub(from)
|
||||
break
|
||||
end
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
---@param s string
|
||||
---@param index number
|
||||
---@param encoding string
|
||||
|
@ -210,13 +242,21 @@ function M.resolve_loc(item, buf)
|
|||
if not item or not item.loc or item.loc.resolved then
|
||||
return item
|
||||
end
|
||||
-- return vim._str_byteindex(s, index, encoding == 'utf-16')
|
||||
|
||||
local lines = {} ---@type string[]
|
||||
if buf and vim.api.nvim_buf_is_valid(buf) then
|
||||
if item.buf and vim.api.nvim_buf_is_loaded(item.buf) then
|
||||
-- valid and loaded buffer
|
||||
lines = vim.api.nvim_buf_get_lines(item.buf, 0, -1, false)
|
||||
elseif item.buf and vim.uri_from_bufnr(item.buf):sub(1, 4) ~= "file" then
|
||||
-- item buffer with a custom uri
|
||||
vim.fn.bufload(item.buf)
|
||||
lines = vim.api.nvim_buf_get_lines(item.buf, 0, -1, false)
|
||||
elseif buf and vim.api.nvim_buf_is_valid(buf) then
|
||||
-- custom buffer (typically for preview)
|
||||
lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
|
||||
else
|
||||
lines = vim.fn.readfile(item.file)
|
||||
elseif item.file then
|
||||
-- last resort, read the file
|
||||
lines = M.lines(item.file)
|
||||
end
|
||||
|
||||
---@param pos lsp.Position?
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue