Skip to content

Commit

Permalink
feat: cycle previewers with commit and bcommit already using it (#528)
Browse files Browse the repository at this point in the history
- 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>
  • Loading branch information
Conni2461 and weilbith committed Jun 14, 2021
1 parent 0c1bc12 commit 6ac5ee0
Show file tree
Hide file tree
Showing 11 changed files with 566 additions and 76 deletions.
131 changes: 130 additions & 1 deletion doc/telescope.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand All @@ -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.
Expand Down Expand Up @@ -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*
Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
49 changes: 34 additions & 15 deletions lua/telescope/actions/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand Down Expand Up @@ -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.
-- ==================================================
Expand Down
74 changes: 70 additions & 4 deletions lua/telescope/builtin/git.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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, {
Expand All @@ -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()
Expand Down

0 comments on commit 6ac5ee0

Please sign in to comment.