fix: (terminal) buffer previewer (#1120)
Use existing buffers for buffer previewer to allow previewing special buffer types
This commit is contained in:
@@ -81,6 +81,19 @@ local search_teardown = function(self)
|
||||
end
|
||||
end
|
||||
|
||||
local scroll_fn = function(self, direction)
|
||||
if not self.state then
|
||||
return
|
||||
end
|
||||
|
||||
local input = direction > 0 and [[]] or [[]]
|
||||
local count = math.abs(direction)
|
||||
|
||||
vim.api.nvim_win_call(self.state.winid, function()
|
||||
vim.cmd([[normal! ]] .. count .. input)
|
||||
end)
|
||||
end
|
||||
|
||||
previewers.file_maker = function(filepath, bufnr, opts)
|
||||
opts = opts or {}
|
||||
if opts.use_ft_detect == nil then
|
||||
@@ -282,18 +295,7 @@ previewers.new_buffer_previewer = function(opts)
|
||||
end
|
||||
|
||||
if not opts.scroll_fn then
|
||||
function opts.scroll_fn(self, direction)
|
||||
if not self.state then
|
||||
return
|
||||
end
|
||||
|
||||
local input = direction > 0 and [[]] or [[]]
|
||||
local count = math.abs(direction)
|
||||
|
||||
vim.api.nvim_buf_call(self.state.bufnr, function()
|
||||
vim.cmd([[normal! ]] .. count .. input)
|
||||
end)
|
||||
end
|
||||
opts.scroll_fn = scroll_fn
|
||||
end
|
||||
|
||||
return Previewer:new(opts)
|
||||
@@ -370,19 +372,12 @@ previewers.vimgrep = defaulter(function(opts)
|
||||
pcall(vim.api.nvim_buf_clear_namespace, self.state.last_set_bufnr, ns_previewer, 0, -1)
|
||||
end
|
||||
|
||||
-- Workaround for unnamed buffer when using builtin.buffer
|
||||
if entry.bufnr and (p == "[No Name]" or vim.api.nvim_buf_get_option(entry.bufnr, "buftype") ~= "") then
|
||||
local lines = vim.api.nvim_buf_get_lines(entry.bufnr, 0, -1, false)
|
||||
vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, lines)
|
||||
jump_to_line(self, self.state.bufnr, entry.lnum)
|
||||
else
|
||||
conf.buffer_previewer_maker(p, self.state.bufnr, {
|
||||
bufname = self.state.bufname,
|
||||
callback = function(bufnr)
|
||||
jump_to_line(self, bufnr, entry.lnum)
|
||||
end,
|
||||
})
|
||||
end
|
||||
conf.buffer_previewer_maker(p, self.state.bufnr, {
|
||||
bufname = self.state.bufname,
|
||||
callback = function(bufnr)
|
||||
jump_to_line(self, bufnr, entry.lnum)
|
||||
end,
|
||||
})
|
||||
end,
|
||||
}
|
||||
end, {})
|
||||
@@ -872,4 +867,95 @@ previewers.display_content = defaulter(function(_)
|
||||
}
|
||||
end, {})
|
||||
|
||||
previewers.buffers = defaulter(function(opts)
|
||||
opts = opts or {}
|
||||
local cwd = opts.cwd or vim.loop.cwd()
|
||||
local previewer_active = true -- decouple provider from preview_win
|
||||
return Previewer:new {
|
||||
title = function()
|
||||
return "Buffers"
|
||||
end,
|
||||
setup = function(_, status)
|
||||
local win_id = status.picker.original_win_id
|
||||
-- required because of see `:h local-options` as
|
||||
-- buffers not yet attached to a current window take the options from the `minimal` popup ...
|
||||
local state = {
|
||||
["previewed_buffers"] = {},
|
||||
["winid"] = status.preview_win,
|
||||
["win_options"] = {
|
||||
["colorcolumn"] = vim.api.nvim_win_get_option(win_id, "colorcolumn"),
|
||||
["cursorline"] = vim.api.nvim_win_get_option(win_id, "cursorline"),
|
||||
["foldlevel"] = vim.api.nvim_win_get_option(win_id, "foldlevel"),
|
||||
["list"] = vim.api.nvim_win_get_option(win_id, "list"),
|
||||
["number"] = vim.api.nvim_win_get_option(win_id, "number"),
|
||||
["relativenumber"] = vim.api.nvim_win_get_option(win_id, "relativenumber"),
|
||||
["signcolumn"] = vim.api.nvim_win_get_option(win_id, "signcolumn"),
|
||||
["spell"] = vim.api.nvim_win_get_option(win_id, "spell"),
|
||||
["winhl"] = vim.api.nvim_win_get_option(win_id, "winhl"),
|
||||
["wrap"] = vim.api.nvim_win_get_option(win_id, "wrap"),
|
||||
},
|
||||
}
|
||||
-- TODO clear explicitly once API should become available
|
||||
-- decoration provider is hierachical on_start -> win
|
||||
vim.api.nvim_set_decoration_provider(ns_previewer, {
|
||||
on_start = function()
|
||||
-- defacto disable provider if status.preview_win does not exist anymore
|
||||
return previewer_active
|
||||
end,
|
||||
on_win = function(_, winid, bufnr, _)
|
||||
if winid ~= status.preview_win then
|
||||
return false -- skip setting extmark for any window other than status.preview_win
|
||||
end
|
||||
local lnum, _ = unpack(vim.api.nvim_win_get_cursor(winid))
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, lnum - 1, lnum, false)[1]
|
||||
-- only set if winid and rows are matching
|
||||
pcall(vim.api.nvim_buf_set_extmark, bufnr, ns_previewer, lnum - 1, 0, {
|
||||
end_col = #line,
|
||||
virt_text_pos = "overlay",
|
||||
hl_group = "TelescopePreviewLine",
|
||||
ephemeral = true,
|
||||
priority = 101, -- 1 higher than treesitter
|
||||
})
|
||||
end,
|
||||
})
|
||||
return state
|
||||
end,
|
||||
teardown = function(self)
|
||||
-- reapply proper buffer-window options..
|
||||
for opt, value in pairs(self.state.win_options) do
|
||||
vim.api.nvim_win_set_option(self.state.winid, opt, value)
|
||||
end
|
||||
-- TODO precautious clearing of extmark though likely no effect due to ephemeral
|
||||
-- clear extmarks for previewed buffers
|
||||
for buf, _ in pairs(self.state.previewed_buffers) do
|
||||
if vim.api.nvim_buf_is_valid(buf) then
|
||||
vim.api.nvim_buf_clear_namespace(buf, ns_previewer, 0, -1)
|
||||
end
|
||||
end
|
||||
previewer_active = false
|
||||
end,
|
||||
dyn_title = function(_, entry)
|
||||
return Path:new(from_entry.path(entry, true)):normalize(cwd)
|
||||
end,
|
||||
preview_fn = function(self, entry, status)
|
||||
if vim.api.nvim_buf_is_valid(entry.bufnr) then
|
||||
vim.api.nvim_win_set_buf(status.preview_win, entry.bufnr)
|
||||
vim.api.nvim_win_set_option(status.preview_win, "winhl", "Normal:TelescopePreviewNormal")
|
||||
vim.api.nvim_win_set_option(status.preview_win, "signcolumn", "no")
|
||||
vim.api.nvim_win_set_option(status.preview_win, "foldlevel", 100)
|
||||
vim.api.nvim_win_set_option(status.preview_win, "wrap", false)
|
||||
self.state.bufnr = entry.bufnr
|
||||
if not entry.col then
|
||||
local _, col = unpack(vim.api.nvim_win_get_cursor(status.preview_win))
|
||||
entry.col = col + 1
|
||||
end
|
||||
if self.state.previewed_buffers[entry.bufnr] ~= true then
|
||||
self.state.previewed_buffers[entry.bufnr] = true
|
||||
end
|
||||
end
|
||||
end,
|
||||
scroll_fn = scroll_fn,
|
||||
}
|
||||
end, {})
|
||||
|
||||
return previewers
|
||||
|
||||
Reference in New Issue
Block a user