Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: (terminal) buffer previewer #1120

Merged
merged 13 commits into from
Aug 23, 2021
Merged
7 changes: 7 additions & 0 deletions lua/telescope/actions/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,13 @@ end
actions.delete_buffer = function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
current_picker:delete_selection(function(selection)
-- avoid preview win from closing by creating tmp buffer
local preview_win = state.get_status(prompt_bufnr).preview_win
if preview_win ~= nil and vim.api.nvim_win_is_valid(preview_win) then
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_option(buf, "bufhidden", "wipe")
vim.api.nvim_win_set_buf(preview_win, buf)
end
vim.api.nvim_buf_delete(selection.bufnr, { force = true })
end)
end
Expand Down
10 changes: 9 additions & 1 deletion lua/telescope/builtin/internal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -637,9 +637,17 @@ internal.buffers = function(opts)
results = buffers,
entry_maker = opts.entry_maker or make_entry.gen_from_buffer(opts),
},
previewer = conf.grep_previewer(opts),
previewer = previewers.buffers.new(opts),
sorter = conf.generic_sorter(opts),
default_selection_index = default_selection_idx,
attach_mappings = function(_, _)
action_set.select:enhance {
post = function()
local entry = action_state.get_selected_entry()
vim.api.nvim_win_set_cursor(0, { entry.lnum, entry.col or 0 })
end,
}
end,
}):find()
end

Expand Down
136 changes: 111 additions & 25 deletions lua/telescope/previewers/buffer_previewer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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, {})
Expand Down Expand Up @@ -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)
fdschmidt93 marked this conversation as resolved.
Show resolved Hide resolved
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))
fdschmidt93 marked this conversation as resolved.
Show resolved Hide resolved
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
1 change: 1 addition & 0 deletions lua/telescope/previewers/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ previewers.help = buffer_previewer.help
previewers.man = buffer_previewer.man
previewers.autocommands = buffer_previewer.autocommands
previewers.highlights = buffer_previewer.highlights
previewers.buffers = buffer_previewer.buffers

--- A deprecated way of displaying content more easily. Was written at a time,
--- where the buffer_previewer interface wasn't present. Nowadays it's easier
Expand Down
2 changes: 1 addition & 1 deletion lua/telescope/previewers/previewer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function Previewer:preview(entry, status)

if not self.state then
if self._setup_func then
self.state = self:_setup_func()
self.state = self:_setup_func(status)
else
self.state = {}
end
Expand Down
3 changes: 0 additions & 3 deletions lua/telescope/previewers/term_previewer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,6 @@ previewers.vimgrep = defaulter(function(opts)
if p == nil or p == "" then
return
end
if entry.bufnr and (p == "[No Name]" or vim.api.nvim_buf_get_option(entry.bufnr, "buftype") ~= "") then
return
end

local lnum = entry.lnum or 0

Expand Down