summaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
authorfdschmidt93 <39233597+fdschmidt93@users.noreply.github.com>2021-08-23 15:27:11 +0200
committerGitHub <noreply@github.com>2021-08-23 15:27:11 +0200
commit79dc995f820150d5de880c08e814af327ff7e965 (patch)
treee1eeea904e97b48200a2fadcf294f1a1d2189376 /lua
parent03c2b8f6bb8027ecdf10acc6d803886c80f99037 (diff)
fix: (terminal) buffer previewer (#1120)
Use existing buffers for buffer previewer to allow previewing special buffer types
Diffstat (limited to 'lua')
-rw-r--r--lua/telescope/actions/init.lua7
-rw-r--r--lua/telescope/builtin/internal.lua10
-rw-r--r--lua/telescope/previewers/buffer_previewer.lua136
-rw-r--r--lua/telescope/previewers/init.lua1
-rw-r--r--lua/telescope/previewers/previewer.lua2
-rw-r--r--lua/telescope/previewers/term_previewer.lua3
6 files changed, 129 insertions, 30 deletions
diff --git a/lua/telescope/actions/init.lua b/lua/telescope/actions/init.lua
index 7f82823..cda5f1d 100644
--- a/lua/telescope/actions/init.lua
+++ b/lua/telescope/actions/init.lua
@@ -807,6 +807,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
diff --git a/lua/telescope/builtin/internal.lua b/lua/telescope/builtin/internal.lua
index 226373b..4b2747b 100644
--- a/lua/telescope/builtin/internal.lua
+++ b/lua/telescope/builtin/internal.lua
@@ -655,9 +655,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
diff --git a/lua/telescope/previewers/buffer_previewer.lua b/lua/telescope/previewers/buffer_previewer.lua
index 2408366..3ba7bac 100644
--- a/lua/telescope/previewers/buffer_previewer.lua
+++ b/lua/telescope/previewers/buffer_previewer.lua
@@ -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
diff --git a/lua/telescope/previewers/init.lua b/lua/telescope/previewers/init.lua
index 849e2c1..1d7d63e 100644
--- a/lua/telescope/previewers/init.lua
+++ b/lua/telescope/previewers/init.lua
@@ -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
diff --git a/lua/telescope/previewers/previewer.lua b/lua/telescope/previewers/previewer.lua
index dffa5de..d6eb9f1 100644
--- a/lua/telescope/previewers/previewer.lua
+++ b/lua/telescope/previewers/previewer.lua
@@ -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
diff --git a/lua/telescope/previewers/term_previewer.lua b/lua/telescope/previewers/term_previewer.lua
index 8d4219c..375143d 100644
--- a/lua/telescope/previewers/term_previewer.lua
+++ b/lua/telescope/previewers/term_previewer.lua
@@ -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