mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-06 11:48:23 +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
|
---@param ctx snacks.picker.preview.ctx
|
||||||
function M.file(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")
|
ctx.preview:notify("Buffer no longer exists", "error")
|
||||||
return
|
return
|
||||||
end
|
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
|
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)
|
local name = vim.api.nvim_buf_get_name(ctx.item.buf)
|
||||||
name = uv.fs_stat(name) and vim.fn.fnamemodify(name, ":t") or name
|
name = uv.fs_stat(name) and vim.fn.fnamemodify(name, ":t") or name
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
---@class snacks.picker.util
|
---@class snacks.picker.util
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
local uv = vim.uv or vim.loop
|
||||||
|
|
||||||
---@param item snacks.picker.Item
|
---@param item snacks.picker.Item
|
||||||
function M.path(item)
|
function M.path(item)
|
||||||
if not (item and item.file) then
|
if not (item and item.file) then
|
||||||
|
@ -191,6 +193,36 @@ function M.resolve(item)
|
||||||
return item
|
return item
|
||||||
end
|
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 s string
|
||||||
---@param index number
|
---@param index number
|
||||||
---@param encoding string
|
---@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
|
if not item or not item.loc or item.loc.resolved then
|
||||||
return item
|
return item
|
||||||
end
|
end
|
||||||
-- return vim._str_byteindex(s, index, encoding == 'utf-16')
|
|
||||||
|
|
||||||
local lines = {} ---@type string[]
|
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)
|
lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
|
||||||
else
|
elseif item.file then
|
||||||
lines = vim.fn.readfile(item.file)
|
-- last resort, read the file
|
||||||
|
lines = M.lines(item.file)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param pos lsp.Position?
|
---@param pos lsp.Position?
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue