feat: cycle previewers with commit and bcommit already using it (#528)

- new git previewers
- jump to line in bcommit previewer
- vimdiff for bcommits
- dynamic preview window titles
- more previewers documentation

Cycle previewers are not mapped yet. So you need to setup yourself:
```lua
require('telescope').setup {
  defaults = {
    mappings = {
      i = {
        ["<C-s>"] = actions.cycle_previewers_next,
        ["<C-a>"] = actions.cycle_previewers_prev,
      },
    },
  }
}
```

Co-authored-by: Thore Strassburg <thore@weilbier.net>
This commit is contained in:
Simon Hauser
2021-06-14 21:50:46 +02:00
committed by GitHub
parent 0c1bc129da
commit 6ac5ee0854
11 changed files with 566 additions and 76 deletions

View File

@@ -19,6 +19,15 @@ telescope.setup({opts}) *telescope.setup()*
Valid keys for {opts.defaults}
*telescope.defaults.dynamic_preview_title*
dynamic_preview_title: ~
Will change the title of the preview window dynamically, where it
is supported. Means the preview window will for example show the
full filename.
Default: false
*telescope.defaults.entry_prefix*
entry_prefix: ~
Prefix in front of each result entry. Current selection not included.
@@ -283,6 +292,16 @@ actions.git_checkout({prompt_bufnr}) *actions.git_checkout()*
{prompt_bufnr} (number) The prompt bufnr
actions.git_switch_branch({prompt_bufnr}) *actions.git_switch_branch()*
Switch to git branch.
If the branch already exists in local, switch to that. If the branch is
only in remote, create new branch tracking remote and switch to new one.
Parameters: ~
{prompt_bufnr} (number) The prompt bufnr
actions.git_track_branch({prompt_bufnr}) *actions.git_track_branch()*
Tell git to track the currently selected remote branch in Telescope
@@ -291,6 +310,30 @@ actions.git_track_branch({prompt_bufnr}) *actions.git_track_branch()*
{prompt_bufnr} (number) The prompt bufnr
actions.git_delete_branch({prompt_bufnr}) *actions.git_delete_branch()*
Delete the currently selected branch
Parameters: ~
{prompt_bufnr} (number) The prompt bufnr
actions.git_rebase_branch({prompt_bufnr}) *actions.git_rebase_branch()*
Rebase to selected git branch
Parameters: ~
{prompt_bufnr} (number) The prompt bufnr
actions.git_checkout_current_buffer({prompt_bufnr})*actions.git_checkout_current_buffer()*
Stage/unstage selected file
Parameters: ~
{prompt_bufnr} (number) The prompt bufnr
actions.send_selected_to_qflist() *actions.send_selected_to_qflist()*
Sends the selected entries to the quickfix list, replacing the previous
entries.
@@ -378,6 +421,24 @@ actions.delete_buffer({prompt_bufnr}) *actions.delete_buffer()*
{prompt_bufnr} (number) The prompt bufnr
actions.cycle_previewers_next({prompt_bufnr})*actions.cycle_previewers_next()*
Cycle to the next previewer if there is one available.
This action is not mapped on default.
Parameters: ~
{prompt_bufnr} (number) The prompt bufnr
actions.cycle_previewers_prev({prompt_bufnr})*actions.cycle_previewers_prev()*
Cycle to the previous previewer if there is one available.
This action is not mapped on default.
Parameters: ~
{prompt_bufnr} (number) The prompt bufnr
================================================================================
*telescope.builtin*
@@ -583,16 +644,27 @@ builtin.git_commits({opts}) *builtin.git_commits()*
Parameters: ~
{opts} (table) options to pass to the picker
Fields: ~
{cwd} (string) specify the path of the repo
builtin.git_bcommits({opts}) *builtin.git_bcommits()*
Lists commits for current buffer with diff preview
- Default keymaps:
- Default keymaps or your overriden `select_` keys:
- `<cr>`: checks out the currently selected commit
- `<c-v>`: opens a diff in a vertical split
- `<c-x>`: opens a diff in a horizontal split
- `<c-t>`: opens a diff in a new tab
Parameters: ~
{opts} (table) options to pass to the picker
Fields: ~
{cwd} (string) specify the path of the repo
{current_file} (string) specify the current file that should be used
for bcommits (default: current buffer)
builtin.git_branches({opts}) *builtin.git_branches()*
List branches for current directory, with output from `git log --oneline`
@@ -1094,6 +1166,10 @@ previewers.Previewer() *previewers.Previewer()*
- `teardown` function(self): Will be called on cleanup.
- `preview_fn` function(self, entry, status): Will be called each time a
new entry was selected.
- `title` function(self): Will return the static title of the previewer.
- `dynamic_title` function(self, entry): Will return the dynamic title of
the previewer. Will only be called when config value
dynamic_preview_title is true.
- `send_input` function(self, input): This is meant for
`termopen_previewer` and it can be used to send input to the terminal
application, like less.
@@ -1118,6 +1194,11 @@ previewers.new_termopen_previewer() *previewers.new_termopen_previewer()*
return { 'bat', entry.path }
end
Additionally you can define:
- `title` a static title for example "File Preview"
- `dyn_title(self, entry)` a dynamic title function which gets called when
config value `dynamic_preview_title = true`
It's an easy way to get your first previewer going and it integrates well
with `bat` and `less`. Providing out of the box scrolling if the command
uses less.
@@ -1209,6 +1290,9 @@ previewers.new_buffer_previewer() *previewers.new_buffer_previewer()*
one file but multiple entries. This happens for grep and lsp builtins.
So to make the cache work only load content if `self.state.bufname ~=
entry.your_unique_key`
- `title` a static title for example "File Preview"
- `dyn_title(self, entry)` a dynamic title function which gets called
when config value `dynamic_preview_title = true`
`self.state` table:
- `self.state.bufnr` Is the current buffer number, in which you have to
@@ -1304,6 +1388,51 @@ previewers.vim_buffer_qflist() *previewers.vim_buffer_qflist()*
previewers.git_branch_log() *previewers.git_branch_log()*
A previewer that shows a log of a branch as graph
previewers.git_stash_diff() *previewers.git_stash_diff()*
A previewer that shows a diff of a stash
previewers.git_commit_diff_to_parent()*previewers.git_commit_diff_to_parent()*
A previewer that shows a diff of a commit to a parent commit.
The run command is `git --no-pager diff SHA^! -- $CURRENT_FILE`
The current file part is optional. So is only uses it with bcommits.
previewers.git_commit_diff_to_head() *previewers.git_commit_diff_to_head()*
A previewer that shows a diff of a commit to head.
The run command is `git --no-pager diff --cached $SHA -- $CURRENT_FILE`
The current file part is optional. So is only uses it with bcommits.
previewers.git_commit_diff_as_was() *previewers.git_commit_diff_as_was()*
A previewer that shows a diff of a commit as it was.
The run command is `git --no-pager show $SHA:$CURRENT_FILE` or `git
--no-pager show $SHA`
previewers.git_commit_message() *previewers.git_commit_message()*
A previewer that shows the commit message of a diff.
The run command is `git --no-pager log -n 1 $SHA`
previewers.git_file_diff() *previewers.git_file_diff()*
A previewer that shows the current diff of a file. Used in git_status.
The run command is `git --no-pager diff $FILE`
previewers.display_content() *previewers.display_content()*
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

View File

@@ -202,7 +202,9 @@ actions._close = function(prompt_bufnr, keepinsert)
local original_win_id = picker.original_win_id
if picker.previewer then
picker.previewer:teardown()
for _, v in ipairs(picker.all_previewers) do
v:teardown()
end
end
actions.close_pum(prompt_bufnr)
@@ -375,11 +377,10 @@ actions.git_checkout = function(prompt_bufnr)
end
end
-- TODO: add this function header back once the treesitter max-query bug is resolved
-- Switch to git branch
-- If the branch already exists in local, switch to that.
-- If the branch is only in remote, create new branch tracking remote and switch to new one.
--@param prompt_bufnr number: The prompt bufnr
--- Switch to git branch.<br>
--- If the branch already exists in local, switch to that.
--- If the branch is only in remote, create new branch tracking remote and switch to new one.
---@param prompt_bufnr number: The prompt bufnr
actions.git_switch_branch = function(prompt_bufnr)
local cwd = action_state.get_current_picker(prompt_bufnr).cwd
local selection = action_state.get_selected_entry()
@@ -419,9 +420,8 @@ actions.git_track_branch = function(prompt_bufnr)
end
end
-- TODO: add this function header back once the treesitter max-query bug is resolved
-- Delete the currently selected branch
-- @param prompt_bufnr number: The prompt bufnr
--- Delete the currently selected branch
---@param prompt_bufnr number: The prompt bufnr
actions.git_delete_branch = function(prompt_bufnr)
local cwd = action_state.get_current_picker(prompt_bufnr).cwd
local selection = action_state.get_selected_entry()
@@ -442,9 +442,8 @@ actions.git_delete_branch = function(prompt_bufnr)
end
end
-- TODO: add this function header back once the treesitter max-query bug is resolved
-- Rebase to selected git branch
-- @param prompt_bufnr number: The prompt bufnr
--- Rebase to selected git branch
---@param prompt_bufnr number: The prompt bufnr
actions.git_rebase_branch = function(prompt_bufnr)
local cwd = action_state.get_current_picker(prompt_bufnr).cwd
local selection = action_state.get_selected_entry()
@@ -465,9 +464,15 @@ actions.git_rebase_branch = function(prompt_bufnr)
end
end
-- TODO: add this function header back once the treesitter max-query bug is resolved
-- Stage/unstage selected file
-- @param prompt_bufnr number: The prompt bufnr
--- Stage/unstage selected file
---@param prompt_bufnr number: The prompt bufnr
actions.git_checkout_current_buffer = function(prompt_bufnr)
local cwd = actions.get_current_picker(prompt_bufnr).cwd
local selection = actions.get_selected_entry()
actions.close(prompt_bufnr)
utils.get_os_command_output({ 'git', 'checkout', selection.value, '--', selection.file }, cwd)
end
actions.git_staging_toggle = function(prompt_bufnr)
local cwd = action_state.get_current_picker(prompt_bufnr).cwd
local selection = action_state.get_selected_entry()
@@ -659,6 +664,20 @@ actions.delete_buffer = function(prompt_bufnr)
end)
end
--- Cycle to the next previewer if there is one available.<br>
--- This action is not mapped on default.
---@param prompt_bufnr number: The prompt bufnr
actions.cycle_previewers_next = function(prompt_bufnr)
actions.get_current_picker(prompt_bufnr):cycle_previewers(1)
end
--- Cycle to the previous previewer if there is one available.<br>
--- This action is not mapped on default.
---@param prompt_bufnr number: The prompt bufnr
actions.cycle_previewers_prev = function(prompt_bufnr)
actions.get_current_picker(prompt_bufnr):cycle_previewers(-1)
end
-- ==================================================
-- Transforms modules and sets the corect metatables.
-- ==================================================

View File

@@ -7,6 +7,7 @@ local previewers = require('telescope.previewers')
local utils = require('telescope.utils')
local entry_display = require('telescope.pickers.entry_display')
local strings = require('plenary.strings')
local Path = require('plenary.path')
local conf = require('telescope.config').values
@@ -49,7 +50,12 @@ git.commits = function(opts)
results = results,
entry_maker = opts.entry_maker or make_entry.gen_from_git_commits(opts),
},
previewer = previewers.git_commit_diff.new(opts),
previewer = {
previewers.git_commit_diff_to_parent.new(opts),
previewers.git_commit_diff_to_head.new(opts),
previewers.git_commit_diff_as_was.new(opts),
previewers.git_commit_message.new(opts),
},
sorter = conf.file_sorter(opts),
attach_mappings = function()
actions.select_default:replace(actions.git_checkout)
@@ -77,9 +83,17 @@ git.stash = function(opts)
end
}):find()
end
local get_current_buf_line = function(winnr)
local lnum = vim.api.nvim_win_get_cursor(winnr)[1]
return vim.trim(vim.api.nvim_buf_get_lines(vim.api.nvim_win_get_buf(winnr), lnum - 1, lnum, false)[1])
end
git.bcommits = function(opts)
opts.current_line = (not opts.current_file) and get_current_buf_line(0) or nil
opts.current_file = opts.current_file or vim.fn.expand('%')
local results = utils.get_os_command_output({
'git', 'log', '--pretty=oneline', '--abbrev-commit', vim.fn.expand('%')
'git', 'log', '--pretty=oneline', '--abbrev-commit', opts.current_file
}, opts.cwd)
pickers.new(opts, {
@@ -88,10 +102,62 @@ git.bcommits = function(opts)
results = results,
entry_maker = opts.entry_maker or make_entry.gen_from_git_commits(opts),
},
previewer = previewers.git_commit_diff.new(opts),
previewer = {
previewers.git_commit_diff_to_parent.new(opts),
previewers.git_commit_diff_to_head.new(opts),
previewers.git_commit_diff_as_was.new(opts),
previewers.git_commit_message.new(opts),
},
sorter = conf.file_sorter(opts),
attach_mappings = function()
actions.select_default:replace(actions.git_checkout)
actions.select_default:replace(actions.git_checkout_current_buffer)
local transfrom_file = function()
return opts.current_file and Path:new(opts.current_file):make_relative(opts.cwd) or ''
end
local get_buffer_of_orig = function(selection)
local value = selection.value .. ':' .. transfrom_file()
local content = utils.get_os_command_output({ 'git', '--no-pager', 'show', value }, opts.cwd)
local bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, content)
vim.api.nvim_buf_set_name(bufnr, 'Original')
return bufnr
end
local vimdiff = function(selection, command)
local ft = vim.bo.filetype
vim.cmd("diffthis")
local bufnr = get_buffer_of_orig(selection)
vim.cmd(string.format("%s %s", command, bufnr))
vim.bo.filetype = ft
vim.cmd("diffthis")
vim.cmd(string.format(
"autocmd WinClosed <buffer=%s> ++nested ++once :lua vim.api.nvim_buf_delete(%s, { force = true })",
bufnr,
bufnr))
end
actions.select_vertical:replace(function(prompt_bufnr)
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()
vimdiff(selection, 'leftabove vert sbuffer')
end)
actions.select_horizontal:replace(function(prompt_bufnr)
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()
vimdiff(selection, 'belowright sbuffer')
end)
actions.select_tab:replace(function(prompt_bufnr)
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()
vim.cmd('tabedit ' .. transfrom_file())
vimdiff(selection, 'leftabove vert sbuffer')
end)
return true
end
}):find()

View File

@@ -145,12 +145,18 @@ builtin.git_files = require('telescope.builtin.git').files
--- - Default keymaps:
--- - `<cr>`: checks out the currently selected commit
---@param opts table: options to pass to the picker
---@field cwd string: specify the path of the repo
builtin.git_commits = require('telescope.builtin.git').commits
--- Lists commits for current buffer with diff preview
--- - Default keymaps:
--- - Default keymaps or your overriden `select_` keys:
--- - `<cr>`: checks out the currently selected commit
--- - `<c-v>`: opens a diff in a vertical split
--- - `<c-x>`: opens a diff in a horizontal split
--- - `<c-t>`: opens a diff in a new tab
---@param opts table: options to pass to the picker
---@field cwd string: specify the path of the repo
---@field current_file string: specify the current file that should be used for bcommits (default: current buffer)
builtin.git_bcommits = require('telescope.builtin.git').bcommits
--- List branches for current directory, with output from `git log --oneline` shown in the preview window

View File

@@ -147,6 +147,14 @@ function config.set_defaults(defaults)
set("file_ignore_patterns", nil)
set("dynamic_preview_title", false, [[
Will change the title of the preview window dynamically, where it
is supported. Means the preview window will for example show the
full filename.
Default: false
]])
set("file_previewer", function(...) return require('telescope.previewers').vim_buffer_cat.new(...) end)
set("grep_previewer", function(...) return require('telescope.previewers').vim_buffer_vimgrep.new(...) end)
set("qflist_previewer", function(...) return require('telescope.previewers').vim_buffer_qflist.new(...) end)

View File

@@ -248,8 +248,7 @@ function make_entry.gen_from_git_stash()
end
end
function make_entry.gen_from_git_commits()
function make_entry.gen_from_git_commits(opts)
local displayer = entry_display.create {
separator = " ",
items = {
@@ -281,7 +280,8 @@ function make_entry.gen_from_git_commits()
value = sha,
ordinal = sha .. ' ' .. msg,
msg = msg,
display = make_display
display = make_display,
current_file = opts.current_file
}
end
end

View File

@@ -74,7 +74,10 @@ function Picker:new(opts)
finder = opts.finder,
sorter = opts.sorter or require('telescope.sorters').empty(),
previewer = opts.previewer,
all_previewers = opts.previewer,
current_previewer_index = 1,
default_selection_index = opts.default_selection_index,
cwd = opts.cwd,
@@ -124,6 +127,15 @@ function Picker:new(opts)
obj.get_window_options = opts.get_window_options or p_window.get_window_options
if obj.all_previewers ~= nil and obj.all_previewers ~= false then
if obj.all_previewers[1] == nil then
obj.all_previewers = { obj.all_previewers }
end
obj.previewer = obj.all_previewers[1]
else
obj.previewer = false
end
-- TODO: It's annoying that this is create and everything else is "new"
obj.scroller = p_scroller.create(
get_default(opts.scroll_strategy, config.values.scroll_strategy),
@@ -453,7 +465,9 @@ function Picker:find()
self.prompt_bufnr = prompt_bufnr
local preview_border_win = preview_opts and preview_opts.border and preview_opts.border.win_id
local preview_border = preview_opts and preview_opts.border
self.preview_border = preview_border
local preview_border_win = (preview_border and preview_border.win_id) and preview_border.win_id
state.set_status(prompt_bufnr, setmetatable({
prompt_bufnr = prompt_bufnr,
@@ -816,8 +830,30 @@ function Picker:refresh_previewer()
self._selection_entry,
status
)
if self.preview_border then
if config.values.dynamic_preview_title == true then
self.preview_border:change_title(self.previewer:dynamic_title(self._selection_entry))
else
self.preview_border:change_title(self.previewer:title())
end
end
end
end
function Picker:cycle_previewers(next)
local size = #self.all_previewers
if size == 1 then return end
self.current_previewer_index = self.current_previewer_index + next
if self.current_previewer_index > size then
self.current_previewer_index = 1
elseif self.current_previewer_index < 1 then
self.current_previewer_index = size
end
self.previewer = self.all_previewers[self.current_previewer_index]
self:refresh_previewer()
end
function Picker:entry_adder(index, entry, _, insert)
if not entry then return end

View File

@@ -59,6 +59,25 @@ local colorize_ls = function(bufnr, data, sections)
end
end
local search_cb_jump = function(self, bufnr, query)
if not query then return end
vim.api.nvim_buf_call(bufnr, function()
pcall(vim.fn.matchdelete, self.state.hl_id, self.state.winid)
vim.cmd "norm! gg"
vim.fn.search(query, "W")
vim.cmd "norm! zz"
self.state.hl_id = vim.fn.matchadd('TelescopePreviewMatch', query)
end)
end
local search_teardown = function(self)
if self.state and self.state.hl_id then
pcall(vim.fn.matchdelete, self.state.hl_id, self.state.hl_win)
self.state.hl_id = nil
end
end
previewers.file_maker = function(filepath, bufnr, opts)
opts = opts or {}
if opts.use_ft_detect == nil then opts.use_ft_detect = true end
@@ -107,6 +126,8 @@ previewers.new_buffer_previewer = function(opts)
local opt_setup = opts.setup
local opt_teardown = opts.teardown
local opt_title = opts.title
local opt_dyn_title = opts.dyn_title
local old_bufs = {}
local bufname_table = {}
@@ -140,6 +161,24 @@ previewers.new_buffer_previewer = function(opts)
end
end
function opts.title(self)
if opt_title then
if type(opt_title) == 'function' then
return opt_title(self)
else
return opt_title
end
end
return "Preview"
end
function opts.dyn_title(self, entry)
if opt_dyn_title then
return opt_dyn_title(self, entry)
end
return "Preview"
end
function opts.setup(self)
local state = {}
if opt_setup then vim.tbl_deep_extend("force", state, opt_setup(self)) end
@@ -228,8 +267,15 @@ previewers.new_buffer_previewer = function(opts)
return Previewer:new(opts)
end
previewers.cat = defaulter(function(_)
previewers.cat = defaulter(function(opts)
opts = opts or {}
local cwd = opts.cwd or vim.loop.cwd()
return previewers.new_buffer_previewer {
title = "File Preview",
dyn_title = function(_, entry)
return path.normalize(from_entry.path(entry, true), cwd)
end,
get_buffer_by_name = function(_, entry)
return from_entry.path(entry, true)
end,
@@ -244,7 +290,10 @@ previewers.cat = defaulter(function(_)
}
end, {})
previewers.vimgrep = defaulter(function(_)
previewers.vimgrep = defaulter(function(opts)
opts = opts or {}
local cwd = opts.cwd or vim.loop.cwd()
local jump_to_line = function(self, bufnr, lnum)
if lnum and lnum > 0 then
pcall(vim.api.nvim_buf_add_highlight, bufnr, ns_previewer, "TelescopePreviewLine", lnum - 1, 0, -1)
@@ -256,10 +305,13 @@ previewers.vimgrep = defaulter(function(_)
end
return previewers.new_buffer_previewer {
title = "Grep Preview",
dyn_title = function(_, entry)
return path.normalize(from_entry.path(entry, true), cwd)
end,
setup = function()
return {
last_set_bufnr = nil
}
return { last_set_bufnr = nil }
end,
teardown = function(self)
@@ -326,6 +378,7 @@ previewers.ctags = defaulter(function(_)
end
return previewers.new_buffer_previewer {
title = "Tags Preview",
teardown = function(self)
if self.state and self.state.hl_id then
pcall(vim.fn.matchdelete, self.state.hl_id, self.state.hl_win)
@@ -354,16 +407,8 @@ end, {})
previewers.builtin = defaulter(function(_)
return previewers.new_buffer_previewer {
setup = function()
return {}
end,
teardown = function(self)
if self.state and self.state.hl_id then
pcall(vim.fn.matchdelete, self.state.hl_id, self.state.hl_win)
self.state.hl_id = nil
end
end,
title = "Grep Preview",
teardown = search_teardown,
get_buffer_by_name = function(_, entry)
return entry.filename
@@ -381,14 +426,7 @@ previewers.builtin = defaulter(function(_)
conf.buffer_previewer_maker(entry.filename, self.state.bufnr, {
bufname = self.state.bufname,
callback = function(bufnr)
vim.api.nvim_buf_call(bufnr, function()
pcall(vim.fn.matchdelete, self.state.hl_id, self.state.winid)
vim.cmd "norm! gg"
vim.fn.search(text, "W")
vim.cmd "norm! zz"
self.state.hl_id = vim.fn.matchadd('TelescopePreviewMatch', text)
end)
search_cb_jump(self, bufnr, text)
end
})
end
@@ -397,16 +435,8 @@ end, {})
previewers.help = defaulter(function(_)
return previewers.new_buffer_previewer {
setup = function()
return {}
end,
teardown = function(self)
if self.state and self.state.hl_id then
pcall(vim.fn.matchdelete, self.state.hl_id, self.state.hl_win)
self.state.hl_id = nil
end
end,
title = "Help Preview",
teardown = search_teardown,
get_buffer_by_name = function(_, entry)
return entry.filename
@@ -420,16 +450,8 @@ previewers.help = defaulter(function(_)
conf.buffer_previewer_maker(entry.filename, self.state.bufnr, {
bufname = self.state.bufname,
callback = function(bufnr)
vim.api.nvim_buf_call(bufnr, function()
vim.cmd(':ownsyntax help')
pcall(vim.fn.matchdelete, self.state.hl_id, self.state.winid)
vim.cmd "norm! gg"
vim.fn.search(query, "W")
vim.cmd "norm! zz"
self.state.hl_id = vim.fn.matchadd('TelescopePreviewMatch', query)
end)
putils.regex_highlighter(bufnr, 'help')
search_cb_jump(self, bufnr, query)
end
})
end
@@ -441,6 +463,7 @@ previewers.man = defaulter(function(opts)
return vim.fn.executable('col') == 1 and 'col -bx' or ''
end)
return previewers.new_buffer_previewer {
title = "Man Preview",
get_buffer_by_name = function(_, entry)
return entry.value
end,
@@ -483,6 +506,7 @@ previewers.git_branch_log = defaulter(function(opts)
end
return previewers.new_buffer_previewer {
title = "Git Branch Preview",
get_buffer_by_name = function(_, entry)
return entry.value
end,
@@ -506,6 +530,7 @@ end, {})
previewers.git_stash_diff = defaulter(function(opts)
return previewers.new_buffer_previewer {
title = "Git Stash Preview",
get_buffer_by_name = function(_, entry)
return entry.value
end,
@@ -521,25 +546,128 @@ previewers.git_stash_diff = defaulter(function(opts)
}
end, {})
previewers.git_commit_diff = defaulter(function(opts)
previewers.git_commit_diff_to_parent = defaulter(function(opts)
return previewers.new_buffer_previewer {
title = "Git Diff to Parent Preview",
teardown = search_teardown,
get_buffer_by_name = function(_, entry)
return entry.value
end,
define_preview = function(self, entry, status)
putils.job_maker({ 'git', '--no-pager', 'diff', entry.value .. '^!' }, self.state.bufnr, {
local cmd = { 'git', '--no-pager', 'diff', entry.value .. '^!' }
if opts.current_file then
table.insert(cmd, '--')
table.insert(cmd, opts.current_file)
end
putils.job_maker(cmd, self.state.bufnr, {
value = entry.value,
bufname = self.state.bufname,
cwd = opts.cwd
cwd = opts.cwd,
callback = function(bufnr)
search_cb_jump(self, bufnr, opts.current_line)
end
})
putils.regex_highlighter(self.state.bufnr, 'diff')
end
}
end, {})
previewers.git_commit_diff_to_head = defaulter(function(opts)
return previewers.new_buffer_previewer {
title = "Git Diff to Head Preview",
teardown = search_teardown,
get_buffer_by_name = function(_, entry)
return entry.value
end,
define_preview = function(self, entry, status)
local cmd = { 'git', '--no-pager', 'diff', '--cached', entry.value }
if opts.current_file then
table.insert(cmd, '--')
table.insert(cmd, opts.current_file)
end
putils.job_maker(cmd, self.state.bufnr, {
value = entry.value,
bufname = self.state.bufname,
cwd = opts.cwd,
callback = function(bufnr)
search_cb_jump(self, bufnr, opts.current_line)
end
})
putils.regex_highlighter(self.state.bufnr, 'diff')
end
}
end, {})
previewers.git_commit_diff_as_was = defaulter(function(opts)
return previewers.new_buffer_previewer {
title = "Git Show Preview",
teardown = search_teardown,
get_buffer_by_name = function(_, entry)
return entry.value
end,
define_preview = function(self, entry, status)
local cmd = { 'git', '--no-pager', 'show' }
local cf = opts.current_file and path.make_relative(opts.current_file, opts.cwd)
local value = cf and (entry.value .. ':' .. cf) or (entry.value)
local ft = cf and pfiletype.detect(value) or 'diff'
table.insert(cmd, value)
putils.job_maker(cmd, self.state.bufnr, {
value = entry.value,
bufname = self.state.bufname,
cwd = opts.cwd,
callback = function(bufnr)
search_cb_jump(self, bufnr, opts.current_line)
end
})
putils.highlighter(self.state.bufnr, ft)
end
}
end, {})
previewers.git_commit_message = defaulter(function(opts)
local hl_map = {
'TelescopeResultsIdentifier',
'TelescopePreviewUser',
'TelescopePreviewDate'
}
return previewers.new_buffer_previewer {
title = "Git Message",
get_buffer_by_name = function(_, entry)
return entry.value
end,
define_preview = function(self, entry, status)
local cmd = { 'git', '--no-pager', 'log', '-n 1', entry.value }
putils.job_maker(cmd, self.state.bufnr, {
value = entry.value,
bufname = self.state.bufname,
cwd = opts.cwd,
callback = function(bufnr, content)
if not content then return end
for k, v in ipairs(hl_map) do
local _, s = content[k]:find('%s')
if s then
vim.api.nvim_buf_add_highlight(bufnr, ns_previewer, v, k - 1, s, #content[k])
end
end
end
})
end
}
end, {})
previewers.git_file_diff = defaulter(function(opts)
return previewers.new_buffer_previewer {
title = "Git File Diff Preview",
get_buffer_by_name = function(_, entry)
return entry.value
end,
@@ -565,6 +693,7 @@ end, {})
previewers.autocommands = defaulter(function(_)
return previewers.new_buffer_previewer {
title = "Autocommands Preview",
teardown = function(self)
if self.state and self.state.last_set_bufnr and vim.api.nvim_buf_is_valid(self.state.last_set_bufnr) then
pcall(vim.api.nvim_buf_clear_namespace, self.state.last_set_bufnr, ns_previewer, 0, -1)
@@ -623,6 +752,7 @@ end, {})
previewers.highlights = defaulter(function(_)
return previewers.new_buffer_previewer {
title = "Highlights Preview",
teardown = function(self)
if self.state and self.state.last_set_bufnr and vim.api.nvim_buf_is_valid(self.state.last_set_bufnr) then
vim.api.nvim_buf_clear_namespace(self.state.last_set_bufnr, ns_previewer, 0, -1)

View File

@@ -53,6 +53,11 @@ local previewers = {}
--- - `teardown` function(self): Will be called on cleanup.
--- - `preview_fn` function(self, entry, status): Will be called each time
--- a new entry was selected.
--- - `title` function(self): Will return the static title of the previewer.
--- - `dynamic_title` function(self, entry): Will return the dynamic title of
--- the previewer. Will only be called
--- when config value dynamic_preview_title
--- is true.
--- - `send_input` function(self, input): This is meant for
--- `termopen_previewer` and it can be
--- used to send input to the terminal
@@ -78,6 +83,11 @@ end
--- end
--- </pre>
---
--- Additionally you can define:
--- - `title` a static title for example "File Preview"
--- - `dyn_title(self, entry)` a dynamic title function which gets called
--- when config value `dynamic_preview_title = true`
---
--- It's an easy way to get your first previewer going and it integrates well
--- with `bat` and `less`. Providing out of the box scrolling if the command
--- uses less.
@@ -166,6 +176,9 @@ previewers.qflist = term_previewer.qflist
--- useful if you have one file but multiple entries. This happens for grep
--- and lsp builtins. So to make the cache work only load content if
--- `self.state.bufname ~= entry.your_unique_key`
--- - `title` a static title for example "File Preview"
--- - `dyn_title(self, entry)` a dynamic title function which gets called
--- when config value `dynamic_preview_title = true`
---
--- `self.state` table:
--- - `self.state.bufnr`
@@ -259,12 +272,36 @@ previewers.vim_buffer_vimgrep = buffer_previewer.vimgrep
--- case it's configured that way.
previewers.vim_buffer_qflist = buffer_previewer.qflist
--- A previewer that shows a log of a branch as graph
previewers.git_branch_log = buffer_previewer.git_branch_log
previewers.git_commit_diff = buffer_previewer.git_commit_diff
previewers.git_file_diff = buffer_previewer.git_file_diff
--- A previewer that shows a diff of a stash
previewers.git_stash_diff = buffer_previewer.git_stash_diff
--- A previewer that shows a diff of a commit to a parent commit.<br>
--- The run command is `git --no-pager diff SHA^! -- $CURRENT_FILE`
---
--- The current file part is optional. So is only uses it with bcommits.
previewers.git_commit_diff_to_parent = buffer_previewer.git_commit_diff_to_parent
--- A previewer that shows a diff of a commit to head.<br>
--- The run command is `git --no-pager diff --cached $SHA -- $CURRENT_FILE`
---
--- The current file part is optional. So is only uses it with bcommits.
previewers.git_commit_diff_to_head = buffer_previewer.git_commit_diff_to_head
--- A previewer that shows a diff of a commit as it was.<br>
--- The run command is `git --no-pager show $SHA:$CURRENT_FILE` or `git --no-pager show $SHA`
previewers.git_commit_diff_as_was = buffer_previewer.git_commit_diff_as_was
--- A previewer that shows the commit message of a diff.<br>
--- The run command is `git --no-pager log -n 1 $SHA`
previewers.git_commit_message = buffer_previewer.git_commit_message
--- A previewer that shows the current diff of a file. Used in git_status.<br>
--- The run command is `git --no-pager diff $FILE`
previewers.git_file_diff = buffer_previewer.git_file_diff
previewers.ctags = buffer_previewer.ctags
previewers.builtin = buffer_previewer.builtin

View File

@@ -6,6 +6,8 @@ function Previewer:new(opts)
return setmetatable({
state = nil,
_title_fn = opts.title,
_dyn_title_fn = opts.dyn_title,
_setup_func = opts.setup,
_teardown_func = opts.teardown,
_send_input = opts.send_input,
@@ -30,6 +32,20 @@ function Previewer:preview(entry, status)
return self:preview_fn(entry, status)
end
function Previewer:title()
if self._title_fn then
return self:_title_fn()
end
return "Preview"
end
function Previewer:dynamic_title(entry)
if self._title_fn then
return self:_dyn_title_fn(entry)
end
return "Preview"
end
function Previewer:teardown()
if self._teardown_func then
self:_teardown_func()

View File

@@ -1,5 +1,6 @@
local conf = require('telescope.config').values
local utils = require('telescope.utils')
local path = require('telescope.path')
local putils = require('telescope.previewers.utils')
local from_entry = require('telescope.from_entry')
local Previewer = require('telescope.previewers.previewer')
@@ -112,6 +113,8 @@ previewers.new_termopen_previewer = function(opts)
local opt_setup = opts.setup
local opt_teardown = opts.teardown
local opt_title = opts.title
local opt_dyn_title = opts.dyn_title
local old_bufs = {}
@@ -135,6 +138,24 @@ previewers.new_termopen_previewer = function(opts)
if self.state then self.state.termopen_bufnr = value end
end
function opts.title(self)
if opt_title then
if type(opt_title) == 'function' then
return opt_title(self)
else
return opt_title
end
end
return "Preview"
end
function opts.dyn_title(self, entry)
if opt_dyn_title then
return opt_dyn_title(self, entry)
end
return "Preview"
end
function opts.setup(self)
local state = {}
if opt_setup then vim.tbl_deep_extend("force", state, opt_setup(self)) end
@@ -210,9 +231,17 @@ previewers.new_termopen_previewer = function(opts)
end
previewers.cat = defaulter(function(opts)
opts = opts or {}
local maker = get_maker(opts)
local cwd = opts.cwd or vim.loop.cwd()
return previewers.new_termopen_previewer {
title = "File Preview",
dyn_title = function(_, entry)
return path.normalize(from_entry.path(entry, true), cwd)
end,
get_command = function(entry)
local p = from_entry.path(entry, true)
if p == nil or p == '' then return end
@@ -223,9 +252,17 @@ previewers.cat = defaulter(function(opts)
end, {})
previewers.vimgrep = defaulter(function(opts)
opts = opts or {}
local maker = get_maker(opts)
local cwd = opts.cwd or vim.loop.cwd()
return previewers.new_termopen_previewer {
title = "Grep Preview",
dyn_title = function(_, entry)
return path.normalize(from_entry.path(entry, true), cwd)
end,
get_command = function(entry, status)
local win_id = status.preview_win
local height = vim.api.nvim_win_get_height(win_id)
@@ -251,8 +288,14 @@ previewers.qflist = defaulter(function(opts)
opts = opts or {}
local maker = get_maker(opts)
local cwd = opts.cwd or vim.loop.cwd()
return previewers.new_termopen_previewer {
title = "Grep Preview",
dyn_title = function(_, entry)
return path.normalize(from_entry.path(entry, true), cwd)
end,
get_command = function(entry, status)
local win_id = status.preview_win
local height = vim.api.nvim_win_get_height(win_id)