Coder Social home page Coder Social logo

sindrets / diffview.nvim Goto Github PK

View Code? Open in Web Editor NEW
3.4K 16.0 94.0 1.59 MB

Single tabpage interface for easily cycling through diffs for all modified files for any git rev.

License: Other

Lua 99.93% Makefile 0.07%
neovim neovim-plugin neovim-lua neovim-lua-plugin git diff

diffview.nvim's Introduction

Diffview.nvim

Single tabpage interface for easily cycling through diffs for all modified files for any git rev.

preview

Introduction

Vim's diff mode is pretty good, but there is no convenient way to quickly bring up all modified files in a diffsplit. This plugin aims to provide a simple, unified, single tabpage interface that lets you easily review all changed files for any git rev.

Requirements

  • Git ≥ 2.31.0 (for Git support)
  • Mercurial ≥ 5.4.0 (for Mercurial support)
  • Neovim ≥ 0.7.0 (with LuaJIT)
  • nvim-web-devicons (optional) For file icons

Installation

Install the plugin with your package manager of choice.

" Plug
Plug 'sindrets/diffview.nvim'
-- Packer
use "sindrets/diffview.nvim" 

Merge Tool

merge tool showcase

Opening a diff view during a merge or a rebase will list the conflicted files in their own section. When opening a conflicted file, it will open in a 3-way diff allowing you to resolve the merge conflicts with the context of the target branch's version, as well as the version from the branch which is being merged.

The 3-way diff is only the default layout for merge conflicts. There are multiple variations on this layout, a 4-way diff layout, and a single window layout available.

In addition to the normal :h copy-diffs mappings, there are default mappings provided for jumping between conflict markers, obtaining a hunk directly from any of the diff buffers, and accepting any one, all, or none of the versions of a file given by a conflict region.

For more information on the merge tool, mappings, layouts and how to configure them, see:

  • :h diffview-merge-tool
  • :h diffview-config-view.x.layout

File History

file history showcase

The file history view allows you to list all the commits that affected a given set of paths, and view the changes made in a diff split. This is a porcelain interface for git-log, and supports a good number of its options. Things like:

  • Filtering commits by grepping commit messages and commit authors.
  • Tracing the line evolution of a given set of line ranges for multiple files.
  • Only listing changes for a specific commit range, branch, or tag.
  • Following file changes through renames.

Get started by opening file history for:

  • The current branch: :DiffviewFileHistory
  • The current file: :DiffviewFileHistory %

For more info, see :h :DiffviewFileHistory.

Usage

:DiffviewOpen [git rev] [options] [ -- {paths...}]

Calling :DiffviewOpen with no args opens a new Diffview that compares against the current index. You can also provide any valid git rev to view only changes for that rev.

Examples:

  • :DiffviewOpen
  • :DiffviewOpen HEAD~2
  • :DiffviewOpen HEAD~4..HEAD~2
  • :DiffviewOpen d4a7b0d
  • :DiffviewOpen d4a7b0d^!
  • :DiffviewOpen d4a7b0d..519b30e
  • :DiffviewOpen origin/main...HEAD

You can also provide additional paths to narrow down what files are shown:

  • :DiffviewOpen HEAD~2 -- lua/diffview plugin

For information about additional [options], visit the documentation.

Additional commands for convenience:

  • :DiffviewClose: Close the current diffview. You can also use :tabclose.
  • :DiffviewToggleFiles: Toggle the file panel.
  • :DiffviewFocusFiles: Bring focus to the file panel.
  • :DiffviewRefresh: Update stats and entries in the file list of the current Diffview.

With a Diffview open and the default key bindings, you can cycle through changed files with <tab> and <s-tab> (see configuration to change the key bindings).

Staging

You can stage individual hunks by editing any buffer that represents the index (after running :DiffviewOpen with no [git-rev] the entries under "Changes" will have the index buffer on the left side, and the entries under "Staged changes" will have it on the right side). Once you write to an index buffer the index will be updated.

:[range]DiffviewFileHistory [paths] [options]

Opens a new file history view that lists all commits that affected the given paths. This is a porcelain interface for git-log. Both [paths] and [options] may be specified in any order, even interchangeably.

If no [paths] are given, defaults to the top-level of the working tree. The top-level will be inferred from the current buffer when possible, otherwise the cwd is used. Multiple [paths] may be provided and git pathspec is supported.

If [range] is given, the file history view will trace the line evolution of the given range in the current file (for more info, see the -L flag in the docs).

Examples:

  • :DiffviewFileHistory
  • :DiffviewFileHistory %
  • :DiffviewFileHistory path/to/some/file.txt
  • :DiffviewFileHistory path/to/some/directory
  • :DiffviewFileHistory include/this and/this :!but/not/this
  • :DiffviewFileHistory --range=origin..HEAD
  • :DiffviewFileHistory --range=feat/example-branch
  • :'<,'>DiffviewFileHistory

Familiarize Yourself With :h diff-mode

ℹ️ This plugin assumes you're familiar with all the features already provided by nvim's builtin diff-mode

These features include:

  • Jumping between hunks (:h jumpto-diffs).
  • Applying the changes of a diff hunk from any of the diffed buffers (:h copy-diffs).
  • And more...

Visit the help page for more info.



ℹ️ Additionally check out USAGE for examples of some more specific use-cases



Configuration

Example config with default values
-- Lua
local actions = require("diffview.actions")

require("diffview").setup({
  diff_binaries = false,    -- Show diffs for binaries
  enhanced_diff_hl = false, -- See ':h diffview-config-enhanced_diff_hl'
  git_cmd = { "git" },      -- The git executable followed by default args.
  hg_cmd = { "hg" },        -- The hg executable followed by default args.
  use_icons = true,         -- Requires nvim-web-devicons
  show_help_hints = true,   -- Show hints for how to open the help panel
  watch_index = true,       -- Update views and index buffers when the git index changes.
  icons = {                 -- Only applies when use_icons is true.
    folder_closed = "",
    folder_open = "",
  },
  signs = {
    fold_closed = "",
    fold_open = "",
    done = "",
  },
  view = {
    -- Configure the layout and behavior of different types of views.
    -- Available layouts:
    --  'diff1_plain'
    --    |'diff2_horizontal'
    --    |'diff2_vertical'
    --    |'diff3_horizontal'
    --    |'diff3_vertical'
    --    |'diff3_mixed'
    --    |'diff4_mixed'
    -- For more info, see ':h diffview-config-view.x.layout'.
    default = {
      -- Config for changed files, and staged files in diff views.
      layout = "diff2_horizontal",
      winbar_info = false,          -- See ':h diffview-config-view.x.winbar_info'
    },
    merge_tool = {
      -- Config for conflicted files in diff views during a merge or rebase.
      layout = "diff3_horizontal",
      disable_diagnostics = true,   -- Temporarily disable diagnostics for conflict buffers while in the view.
      winbar_info = true,           -- See ':h diffview-config-view.x.winbar_info'
    },
    file_history = {
      -- Config for changed files in file history views.
      layout = "diff2_horizontal",
      winbar_info = false,          -- See ':h diffview-config-view.x.winbar_info'
    },
  },
  file_panel = {
    listing_style = "tree",             -- One of 'list' or 'tree'
    tree_options = {                    -- Only applies when listing_style is 'tree'
      flatten_dirs = true,              -- Flatten dirs that only contain one single dir
      folder_statuses = "only_folded",  -- One of 'never', 'only_folded' or 'always'.
    },
    win_config = {                      -- See ':h diffview-config-win_config'
      position = "left",
      width = 35,
      win_opts = {}
    },
  },
  file_history_panel = {
    log_options = {   -- See ':h diffview-config-log_options'
      git = {
        single_file = {
          diff_merges = "combined",
        },
        multi_file = {
          diff_merges = "first-parent",
        },
      },
      hg = {
        single_file = {},
        multi_file = {},
      },
    },
    win_config = {    -- See ':h diffview-config-win_config'
      position = "bottom",
      height = 16,
      win_opts = {}
    },
  },
  commit_log_panel = {
    win_config = {   -- See ':h diffview-config-win_config'
      win_opts = {},
    }
  },
  default_args = {    -- Default args prepended to the arg-list for the listed commands
    DiffviewOpen = {},
    DiffviewFileHistory = {},
  },
  hooks = {},         -- See ':h diffview-config-hooks'
  keymaps = {
    disable_defaults = false, -- Disable the default keymaps
    view = {
      -- The `view` bindings are active in the diff buffers, only when the current
      -- tabpage is a Diffview.
      { "n", "<tab>",       actions.select_next_entry,              { desc = "Open the diff for the next file" } },
      { "n", "<s-tab>",     actions.select_prev_entry,              { desc = "Open the diff for the previous file" } },
      { "n", "gf",          actions.goto_file_edit,                 { desc = "Open the file in the previous tabpage" } },
      { "n", "<C-w><C-f>",  actions.goto_file_split,                { desc = "Open the file in a new split" } },
      { "n", "<C-w>gf",     actions.goto_file_tab,                  { desc = "Open the file in a new tabpage" } },
      { "n", "<leader>e",   actions.focus_files,                    { desc = "Bring focus to the file panel" } },
      { "n", "<leader>b",   actions.toggle_files,                   { desc = "Toggle the file panel." } },
      { "n", "g<C-x>",      actions.cycle_layout,                   { desc = "Cycle through available layouts." } },
      { "n", "[x",          actions.prev_conflict,                  { desc = "In the merge-tool: jump to the previous conflict" } },
      { "n", "]x",          actions.next_conflict,                  { desc = "In the merge-tool: jump to the next conflict" } },
      { "n", "<leader>co",  actions.conflict_choose("ours"),        { desc = "Choose the OURS version of a conflict" } },
      { "n", "<leader>ct",  actions.conflict_choose("theirs"),      { desc = "Choose the THEIRS version of a conflict" } },
      { "n", "<leader>cb",  actions.conflict_choose("base"),        { desc = "Choose the BASE version of a conflict" } },
      { "n", "<leader>ca",  actions.conflict_choose("all"),         { desc = "Choose all the versions of a conflict" } },
      { "n", "dx",          actions.conflict_choose("none"),        { desc = "Delete the conflict region" } },
      { "n", "<leader>cO",  actions.conflict_choose_all("ours"),    { desc = "Choose the OURS version of a conflict for the whole file" } },
      { "n", "<leader>cT",  actions.conflict_choose_all("theirs"),  { desc = "Choose the THEIRS version of a conflict for the whole file" } },
      { "n", "<leader>cB",  actions.conflict_choose_all("base"),    { desc = "Choose the BASE version of a conflict for the whole file" } },
      { "n", "<leader>cA",  actions.conflict_choose_all("all"),     { desc = "Choose all the versions of a conflict for the whole file" } },
      { "n", "dX",          actions.conflict_choose_all("none"),    { desc = "Delete the conflict region for the whole file" } },
    },
    diff1 = {
      -- Mappings in single window diff layouts
      { "n", "g?", actions.help({ "view", "diff1" }), { desc = "Open the help panel" } },
    },
    diff2 = {
      -- Mappings in 2-way diff layouts
      { "n", "g?", actions.help({ "view", "diff2" }), { desc = "Open the help panel" } },
    },
    diff3 = {
      -- Mappings in 3-way diff layouts
      { { "n", "x" }, "2do",  actions.diffget("ours"),            { desc = "Obtain the diff hunk from the OURS version of the file" } },
      { { "n", "x" }, "3do",  actions.diffget("theirs"),          { desc = "Obtain the diff hunk from the THEIRS version of the file" } },
      { "n",          "g?",   actions.help({ "view", "diff3" }),  { desc = "Open the help panel" } },
    },
    diff4 = {
      -- Mappings in 4-way diff layouts
      { { "n", "x" }, "1do",  actions.diffget("base"),            { desc = "Obtain the diff hunk from the BASE version of the file" } },
      { { "n", "x" }, "2do",  actions.diffget("ours"),            { desc = "Obtain the diff hunk from the OURS version of the file" } },
      { { "n", "x" }, "3do",  actions.diffget("theirs"),          { desc = "Obtain the diff hunk from the THEIRS version of the file" } },
      { "n",          "g?",   actions.help({ "view", "diff4" }),  { desc = "Open the help panel" } },
    },
    file_panel = {
      { "n", "j",              actions.next_entry,                     { desc = "Bring the cursor to the next file entry" } },
      { "n", "<down>",         actions.next_entry,                     { desc = "Bring the cursor to the next file entry" } },
      { "n", "k",              actions.prev_entry,                     { desc = "Bring the cursor to the previous file entry" } },
      { "n", "<up>",           actions.prev_entry,                     { desc = "Bring the cursor to the previous file entry" } },
      { "n", "<cr>",           actions.select_entry,                   { desc = "Open the diff for the selected entry" } },
      { "n", "o",              actions.select_entry,                   { desc = "Open the diff for the selected entry" } },
      { "n", "l",              actions.select_entry,                   { desc = "Open the diff for the selected entry" } },
      { "n", "<2-LeftMouse>",  actions.select_entry,                   { desc = "Open the diff for the selected entry" } },
      { "n", "-",              actions.toggle_stage_entry,             { desc = "Stage / unstage the selected entry" } },
      { "n", "s",              actions.toggle_stage_entry,             { desc = "Stage / unstage the selected entry" } },
      { "n", "S",              actions.stage_all,                      { desc = "Stage all entries" } },
      { "n", "U",              actions.unstage_all,                    { desc = "Unstage all entries" } },
      { "n", "X",              actions.restore_entry,                  { desc = "Restore entry to the state on the left side" } },
      { "n", "L",              actions.open_commit_log,                { desc = "Open the commit log panel" } },
      { "n", "zo",             actions.open_fold,                      { desc = "Expand fold" } },
      { "n", "h",              actions.close_fold,                     { desc = "Collapse fold" } },
      { "n", "zc",             actions.close_fold,                     { desc = "Collapse fold" } },
      { "n", "za",             actions.toggle_fold,                    { desc = "Toggle fold" } },
      { "n", "zR",             actions.open_all_folds,                 { desc = "Expand all folds" } },
      { "n", "zM",             actions.close_all_folds,                { desc = "Collapse all folds" } },
      { "n", "<c-b>",          actions.scroll_view(-0.25),             { desc = "Scroll the view up" } },
      { "n", "<c-f>",          actions.scroll_view(0.25),              { desc = "Scroll the view down" } },
      { "n", "<tab>",          actions.select_next_entry,              { desc = "Open the diff for the next file" } },
      { "n", "<s-tab>",        actions.select_prev_entry,              { desc = "Open the diff for the previous file" } },
      { "n", "gf",             actions.goto_file_edit,                 { desc = "Open the file in the previous tabpage" } },
      { "n", "<C-w><C-f>",     actions.goto_file_split,                { desc = "Open the file in a new split" } },
      { "n", "<C-w>gf",        actions.goto_file_tab,                  { desc = "Open the file in a new tabpage" } },
      { "n", "i",              actions.listing_style,                  { desc = "Toggle between 'list' and 'tree' views" } },
      { "n", "f",              actions.toggle_flatten_dirs,            { desc = "Flatten empty subdirectories in tree listing style" } },
      { "n", "R",              actions.refresh_files,                  { desc = "Update stats and entries in the file list" } },
      { "n", "<leader>e",      actions.focus_files,                    { desc = "Bring focus to the file panel" } },
      { "n", "<leader>b",      actions.toggle_files,                   { desc = "Toggle the file panel" } },
      { "n", "g<C-x>",         actions.cycle_layout,                   { desc = "Cycle available layouts" } },
      { "n", "[x",             actions.prev_conflict,                  { desc = "Go to the previous conflict" } },
      { "n", "]x",             actions.next_conflict,                  { desc = "Go to the next conflict" } },
      { "n", "g?",             actions.help("file_panel"),             { desc = "Open the help panel" } },
      { "n", "<leader>cO",     actions.conflict_choose_all("ours"),    { desc = "Choose the OURS version of a conflict for the whole file" } },
      { "n", "<leader>cT",     actions.conflict_choose_all("theirs"),  { desc = "Choose the THEIRS version of a conflict for the whole file" } },
      { "n", "<leader>cB",     actions.conflict_choose_all("base"),    { desc = "Choose the BASE version of a conflict for the whole file" } },
      { "n", "<leader>cA",     actions.conflict_choose_all("all"),     { desc = "Choose all the versions of a conflict for the whole file" } },
      { "n", "dX",             actions.conflict_choose_all("none"),    { desc = "Delete the conflict region for the whole file" } },
    },
    file_history_panel = {
      { "n", "g!",            actions.options,                     { desc = "Open the option panel" } },
      { "n", "<C-A-d>",       actions.open_in_diffview,            { desc = "Open the entry under the cursor in a diffview" } },
      { "n", "y",             actions.copy_hash,                   { desc = "Copy the commit hash of the entry under the cursor" } },
      { "n", "L",             actions.open_commit_log,             { desc = "Show commit details" } },
      { "n", "zR",            actions.open_all_folds,              { desc = "Expand all folds" } },
      { "n", "zM",            actions.close_all_folds,             { desc = "Collapse all folds" } },
      { "n", "j",             actions.next_entry,                  { desc = "Bring the cursor to the next file entry" } },
      { "n", "<down>",        actions.next_entry,                  { desc = "Bring the cursor to the next file entry" } },
      { "n", "k",             actions.prev_entry,                  { desc = "Bring the cursor to the previous file entry." } },
      { "n", "<up>",          actions.prev_entry,                  { desc = "Bring the cursor to the previous file entry." } },
      { "n", "<cr>",          actions.select_entry,                { desc = "Open the diff for the selected entry." } },
      { "n", "o",             actions.select_entry,                { desc = "Open the diff for the selected entry." } },
      { "n", "<2-LeftMouse>", actions.select_entry,                { desc = "Open the diff for the selected entry." } },
      { "n", "<c-b>",         actions.scroll_view(-0.25),          { desc = "Scroll the view up" } },
      { "n", "<c-f>",         actions.scroll_view(0.25),           { desc = "Scroll the view down" } },
      { "n", "<tab>",         actions.select_next_entry,           { desc = "Open the diff for the next file" } },
      { "n", "<s-tab>",       actions.select_prev_entry,           { desc = "Open the diff for the previous file" } },
      { "n", "gf",            actions.goto_file_edit,              { desc = "Open the file in the previous tabpage" } },
      { "n", "<C-w><C-f>",    actions.goto_file_split,             { desc = "Open the file in a new split" } },
      { "n", "<C-w>gf",       actions.goto_file_tab,               { desc = "Open the file in a new tabpage" } },
      { "n", "<leader>e",     actions.focus_files,                 { desc = "Bring focus to the file panel" } },
      { "n", "<leader>b",     actions.toggle_files,                { desc = "Toggle the file panel" } },
      { "n", "g<C-x>",        actions.cycle_layout,                { desc = "Cycle available layouts" } },
      { "n", "g?",            actions.help("file_history_panel"),  { desc = "Open the help panel" } },
    },
    option_panel = {
      { "n", "<tab>", actions.select_entry,          { desc = "Change the current option" } },
      { "n", "q",     actions.close,                 { desc = "Close the panel" } },
      { "n", "g?",    actions.help("option_panel"),  { desc = "Open the help panel" } },
    },
    help_panel = {
      { "n", "q",     actions.close,  { desc = "Close help menu" } },
      { "n", "<esc>", actions.close,  { desc = "Close help menu" } },
    },
  },
})

Hooks

The hooks table allows you to define callbacks for various events emitted from Diffview. The available hooks are documented in detail in :h diffview-config-hooks. The hook events are also available as User autocommands. See :h diffview-user-autocmds for more details.

Examples:

hooks = {
  diff_buf_read = function(bufnr)
    -- Change local options in diff buffers
    vim.opt_local.wrap = false
    vim.opt_local.list = false
    vim.opt_local.colorcolumn = { 80 }
  end,
  view_opened = function(view)
    print(
      ("A new %s was opened on tab page %d!")
      :format(view.class:name(), view.tabpage)
    )
  end,
}

Keymaps

The keymaps config is structured as a table with sub-tables for various different contexts where mappings can be declared. In these sub-tables key-value pairs are treated as the {lhs} and {rhs} of a normal mode mapping. These mappings all use the :map-arguments silent, nowait, and noremap. The implementation uses vim.keymap.set(), so the {rhs} can be either a vim command in the form of a string, or it can be a lua function:

  view = {
    -- Vim command:
    ["a"] = "<Cmd>echom 'foo'<CR>",
    -- Lua function:
    ["b"] = function() print("bar") end,
  }

For more control (i.e. mappings for other modes), you can also define index values as list-like tables containing the arguments for vim.keymap.set(). This way you can also change all the :map-arguments with the only exception being the buffer field, as this will be overridden with the target buffer number:

view = {
  -- Normal and visual mode mapping to vim command:
  { { "n", "v" }, "<leader>a", "<Cmd>echom 'foo'<CR>", { silent = true } },
  -- Visual mode mapping to lua function:
  { "v", "<leader>b", function() print("bar") end, { nowait = true } },
}

To disable any single mapping without disabling them all, set its {rhs} to false:

  view = {
    -- Disable the default normal mode mapping for `<tab>`:
    ["<tab>"] = false,
    -- Disable the default visual mode mapping for `gf`:
    { "x", "gf", false },
  }

Most of the mapped file panel actions also work from the view if they are added to the view maps (and vice versa). The exception is for actions that only really make sense specifically in the file panel, such as next_entry, prev_entry. Actions such as toggle_stage_entry and restore_entry work just fine from the view. When invoked from the view, these will target the file currently open in the view rather than the file under the cursor in the file panel.

For more details on how to set mappings for other modes, actions, and more see:

  • :h diffview-config-keymaps
  • :h diffview-actions

Restoring Files

If the right side of the diff is showing the local state of a file, you can restore the file to the state from the left side of the diff (key binding X from the file panel by default). The current state of the file is stored in the git object database, and a command is echoed that shows how to undo the change.

Tips and FAQ

  • Hide untracked files:
    • DiffviewOpen -uno
  • Exclude certain paths:
    • DiffviewOpen -- :!exclude/this :!and/this
  • Run as if git was started in a specific directory:
    • DiffviewOpen -C/foo/bar/baz
  • Diff the index against a git rev:
    • DiffviewOpen HEAD~2 --cached
    • Defaults to HEAD if no rev is given.
  • Q: How do I get the diagonal lines in place of deleted lines in diff-mode?
    • A: Change your :h 'fillchars':
      • (vimscript): set fillchars+=diff:╱
      • (Lua): vim.opt.fillchars:append { diff = "╱" }
    • Note: whether or not the diagonal lines will line up nicely will depend on your terminal emulator. The terminal used in the screenshots is Kitty.
  • Q: How do I jump between hunks in the diff?
    • A: Use [c and ]c
    • :h jumpto-diffs

diffview.nvim's People

Contributors

616b2f avatar adrian5 avatar anatolelucet avatar briandipalma avatar cathaysia avatar ceuk avatar charbelnicolas avatar emmanueltouzery avatar farbodsz avatar felisnivalis avatar harrisoncramer avatar hezhizhen avatar jimzk avatar jmarkin avatar lintaoamons avatar litearc avatar matejkastak avatar ngpong avatar ofirgall avatar pagliacii avatar pappasam avatar przepompownia avatar raw1z avatar refractalize avatar shatur avatar sindrets avatar splitdev avatar wookayin avatar xxvunborn avatar zegervdv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

diffview.nvim's Issues

Compare two files

Hi! Thank you a lot for your plugin!
I would like to suggest to add the ability to compare two files.

Something like DiffviewOpen file1 file2. When I trying to do so I have the following error:

E5108: Error executing lua ...nvim/pack/plugins/opt/diffview.nvim/lua/diffview/lib.lua:67: attempt to index a nil value

[feature] Highlight moved lines in a different way

Hey! Thanks for making this plugin, I really appreciate it. It looks like a more robust solution to what I had done locally in my init.vim, but uses nicer UI 👍

I have an idea about a feature for the way diffs are displayed, and I'm not sure how to tackle it. It's probably not related to this plugin, but I don't have certainty, so maybe you could at least point me in the right direction.

Background

Git has a color-moved functionality that highlights moved code in a different way than regular additions/deletions.

After I enable it in my git config, the functionality works well in the terminal using regular git diff and using delta:
image
(notice the blue/purple lines - those represent the move)

However, it does not affect the way diffs are shown inside neovim - the moved code is highlighted as if it was a delete/add operation, there is no way to distinguish them from actual deletes/adds:

image

Feature

Ideally, there would be a separate highlight for code that is moved in a diff

Nor working when neovim is opened not in git root

Hi, great plugin! Wanted to have something like this for some time now.

One issue though - if neovim is started in subdirectory of repository the :DiffviewOpen right window is empty - the current file state is not displayed. It looks that there is some issue with file resolution as file path is resolved to git root, but as the vim is started it subdirectory it can not find the right file.

groups names

I'm trying to apply colors to the viewer via vim.cmd('higlight ...'). Map the following groups:

DiffAdd
DiffDelete
DiffChange
DiffText

Are there more groups?

[feature] DiffViewOpen support a single file

I found that DiffViewOpen only support dir. Sometimes I only want to diff the current file that I an editing. Can DiffViewOpen add support for the diff of a single file with files panel off?

Question: Sidebar tabline title

Hey, in the screenshot the tabline shows "Source Control", how can I enable that? Is there an autocmd/callback that is fired when the view is openeds/closed?

Edit: and while I'm here, how do you get the removed hunks to show like this?
Screenshot from 2021-08-15 23-09-26

Current file on left sometimes loses sync

First off, wow, this plugin is tremendous. Great job.

One nitpick for me though is that when I tab through changed files, the highlighted file in the file list doesn't change to update which one I'm currently on.

EDIT: I just noticed it does work for me sometimes, so I wonder if there's a state or interaction that causes it to lose sync? Can anyone else confirm they've ever experienced this?

Partially staging files

Thank you very much for developing this plugin, it's very useful.

Would it be possible to add support to stage hunks?

In Fugitive's :Gdiff view one can run :diffput on a visual selection to partially stage a hunk.

DiffviewOpen into DiffviewToggle?

Hi Sindre!
Your plugin is amazin looks way more cleanier for me checking diff's than fugitive.
But the problem is that closing multiple buffers manually feels weird, and writing DiffviewClose seems bit hassle.
Is it possible to change this into DiffviewToggle to easily open and close it?

Question: How can I see files changed in DiffViewFileHistory similar to the screen shot?

Hi,

Thanks for the plugin, I have been using it and it's been wonderful.
I started using the file history regularly but I noticed that I can only see the changes in the file itself and I don't get the fold that allows me to see other files changed in the same commit

When I press <C-d> I get the diff view and there I can see changes in other files but I don't see them in the history view.

My config is a copy paste of the defaults in the readme:

local cb = require("diffview.config").diffview_callback

require("diffview").setup({
  diff_binaries = false, -- Show diffs for binaries
  use_icons = true, -- Requires nvim-web-devicons
  file_panel = {
    position = "left", -- One of 'left', 'right', 'top', 'bottom'
    width = 35, -- Only applies when position is 'left' or 'right'
    height = 10, -- Only applies when position is 'top' or 'bottom'
  },
  file_history_panel = {
    position = "bottom",
    width = 35,
    height = 16,
    log_options = {
      max_count = 256, -- Limit the number of commits
      follow = false, -- Follow renames (only for single file)
      all = false, -- Include all refs under 'refs/' including HEAD
      merges = false, -- List only merge commits
      no_merges = false, -- List no merge commits
      reverse = false, -- List commits in reverse order
    },
  },
  key_bindings = {
    disable_defaults = false, -- Disable the default key bindings
    -- The `view` bindings are active in the diff buffers, only when the current
    -- tabpage is a Diffview.
    view = {
      ["<tab>"] = cb("select_next_entry"), -- Open the diff for the next file
      ["<s-tab>"] = cb("select_prev_entry"), -- Open the diff for the previous file
      ["<leader>e"] = cb("focus_files"), -- Bring focus to the files panel
      ["<leader>b"] = cb("toggle_files"), -- Toggle the files panel.
    },
    file_panel = {
      ["j"] = cb("next_entry"), -- Bring the cursor to the next file entry
      ["<down>"] = cb("next_entry"),
      ["k"] = cb("prev_entry"), -- Bring the cursor to the previous file entry.
      ["<up>"] = cb("prev_entry"),
      ["<cr>"] = cb("select_entry"), -- Open the diff for the selected entry.
      ["o"] = cb("select_entry"),
      ["<2-LeftMouse>"] = cb("select_entry"),
      ["-"] = cb("toggle_stage_entry"), -- Stage / unstage the selected entry.
      ["S"] = cb("stage_all"), -- Stage all entries.
      ["U"] = cb("unstage_all"), -- Unstage all entries.
      ["X"] = cb("restore_entry"), -- Restore entry to the state on the left side.
      ["R"] = cb("refresh_files"), -- Update stats and entries in the file list.
      ["<tab>"] = cb("select_next_entry"),
      ["<s-tab>"] = cb("select_prev_entry"),
      ["<leader>e"] = cb("focus_files"),
      ["<leader>b"] = cb("toggle_files"),
    },
    file_history_panel = {
      ["g!"] = cb("options"), -- Open the option panel
      ["<C-d>"] = cb("open_in_diffview"), -- Open the entry under the cursor in a diffview
      ["zR"] = cb("open_all_folds"),
      ["zM"] = cb("close_all_folds"),
      ["j"] = cb("next_entry"),
      ["<down>"] = cb("next_entry"),
      ["k"] = cb("prev_entry"),
      ["<up>"] = cb("prev_entry"),
      ["<cr>"] = cb("select_entry"),
      ["o"] = cb("select_entry"),
      ["<2-LeftMouse>"] = cb("select_entry"),
      ["<tab>"] = cb("select_next_entry"),
      ["<s-tab>"] = cb("select_prev_entry"),
      ["<leader>e"] = cb("focus_files"),
      ["<leader>b"] = cb("toggle_files"),
    },
    option_panel = {
      ["<tab>"] = cb("select"),
      ["q"] = cb("close"),
    },
  },
})

Thank you very much!

[Feature] Discard changes

Hi! First, a big thanks for the plugin, I'm a big fan. As a colemak user, I'm very appreciative of the disable_defaults option.

However I occasionally find myself needing to discard an entire file. As far as I can see, this isn't a operation in your plugin.

Do you think this is a feature you would be willing to add at some point?

Keymaps

Hi,

Is there a way to configure keybindings without using the setup function? Eg nmap j DiffViewSelectNextEntry?
It would be nice if the mappings were public so I can remap them freely. Ideally having the diffview panel have its own filetype is the best because one can then use the native ftplugin/after mechanism to set custom options & keybindings for that filetype.

Thanks

Keybindings are not working for me

Hi,

I've setup the plugin according to the docs but some keybindings are not working for me. It could be that I am understanding the plugin incorrectly

I can use and focus_files and toggle_files but when I press j and k in the right_panel, it moves just one line ahead like in normal mode instead of to the next diff.

Also is the X key supposed to revert the state back to original? That's also not working for me.

Please let me know what I may be doing wrong here.

return require('packer').startup(function()
  -- Packer can manage itself
  use 'wbthomason/packer.nvim'

  -- tpope
  use 'tpope/vim-surround'
  use 'tpope/vim-fugitive'
  -- git
  use { 'lewis6991/gitsigns.nvim',
	  requires = {
		  'nvim-lua/plenary.nvim'
	  }
  }
  use 'sindrets/diffview.nvim'
  -- colors
  use 'norcalli/nvim-colorizer.lua'
  -- File explorer
  use 'kyazdani42/nvim-web-devicons'
  use 'kyazdani42/nvim-tree.lua'
  -- lsp
  use 'neovim/nvim-lspconfig'
  use 'glepnir/lspsaga.nvim'
  use {'folke/trouble.nvim',
    requires = 'kyazdani42/nvim-web-devicons'
  }
  -- formatter
  use 'sbdchd/neoformat'
  -- autocomplete
  use 'hrsh7th/nvim-compe'
  use 'hrsh7th/vim-vsnip'
  use 'rafamadriz/friendly-snippets'
  -- file and string search
  use {'nvim-telescope/telescope.nvim',
    requires = { 
			'nvim-lua/popup.nvim', 
			'nvim-lua/plenary.nvim'
		}
  }
  use 'nvim-telescope/telescope-fzy-native.nvim'
  use 'nvim-telescope/telescope-project.nvim'
  
  -- syntax highlights
  use 'Yagua/nebulous.nvim'
  use {'nvim-treesitter/nvim-treesitter', run = ":TSUpdate"}
  use 'andymass/vim-matchup'
  -- comments
  use 'terrortylor/nvim-comment'
  use 'JoosepAlviste/nvim-ts-context-commentstring'
  -- status and buffer line
  use 'glepnir/galaxyline.nvim'
	use 'akinsho/nvim-bufferline.lua'
	-- debugger
	use 'sakhnik/nvim-gdb'

end)


require'nvim_comment'.setup()

require'nvim-treesitter.configs'.setup {
    ensure_installed = O.treesitter.ensure_installed, -- one of "all", "maintained" (parsers with maintainers), or a list of languages
    ignore_install = O.treesitter.ignore_install,
    matchup = {
        enable = true,              -- mandatory, false will disable the whole extension
        -- disable = { "c", "ruby" },  -- optional, list of language that will be disabled
    },
    highlight = {
        enable = O.treesitter.highlight.enabled -- false will disable the whole extension
    },
    context_commentstring = {
        enable = true,
        config = {
          css = '// %s'
        }
      },
    -- indent = {enable = true, disable = {"python", "html", "javascript"}},
    --indent = {enable = true},
    autotag = {enable = true},
}

require("nebulous").setup()

require('gitsigns').setup()

local cb = require'diffview.config'.diffview_callback

require'diffview'.setup {
  diff_binaries = false,    -- Show diffs for binaries
  file_panel = {
    width = 35,
    use_icons = true        -- Requires nvim-web-devicons
  },
  key_bindings = {
    disable_defaults = false,                   -- Disable the default key bindings
    -- The `view` bindings are active in the diff buffers, only when the current
    -- tabpage is a Diffview.
    view = {
      ["<tab>"]     = cb("select_next_entry"),  -- Open the diff for the next file 
      ["<s-tab>"]   = cb("select_prev_entry"),  -- Open the diff for the previous file
      ["<leader>e"] = cb("focus_files"),        -- Bring focus to the files panel
      ["<leader>b"] = cb("toggle_files"),       -- Toggle the files panel.
    },
    file_panel = {
      ["j"]             = cb("next_entry"),         -- Bring the cursor to the next file entry
      ["<down>"]        = cb("next_entry"),
      ["k"]             = cb("prev_entry"),         -- Bring the cursor to the previous file entry.
      ["<up>"]          = cb("prev_entry"),
      ["<cr>"]          = cb("select_entry"),       -- Open the diff for the selected entry.
      ["o"]             = cb("select_entry"),
      ["<2-LeftMouse>"] = cb("select_entry"),
      ["-"]             = cb("toggle_stage_entry"), -- Stage / unstage the selected entry.
      ["S"]             = cb("stage_all"),          -- Stage all entries.
      ["U"]             = cb("unstage_all"),        -- Unstage all entries.
      ["X"]             = cb("restore_entry"),      -- Restore entry to the state on the left side.
      ["R"]             = cb("refresh_files"),      -- Update stats and entries in the file list.
      ["<tab>"]         = cb("select_next_entry"),
      ["<s-tab>"]       = cb("select_prev_entry"),
      ["<leader>e"]     = cb("focus_files"),
      ["<leader>b"]     = cb("toggle_files"),
    }
  }
}

Merge user keybindings with defaults

Hi 👋🏾 ,

Thanks for your work on this, I was sorely missing a way to diff things.
I just tried configuring some keybindings and was surprised to find that if I added just a single override to my keybindings setup it removes all default keybindings. This seems like pretty unexpected behaviour since I think most plugins will usually maintain the rest of their keybindings and just overwrite the ones you specify.

-- If the user provides key bindings: use only the user bindings.

This looks like it was a conscious decision though, so not sure how open you are to it but I was thinking that you could do a merge on that line instead of either or and if a user wanted everything disabled which is the only reason I think that behaviour would be preferable maybe add a config option so users can turn off all default mappings?

anyway just though I'd raise it for discussion, despite it being easy enough to work around

Better command completion: branches / tags / files in the completion menu

What I'm missing from this incredibly useful plugin is a nice completion for the :DiffviewOpen command. When I toggle the completion with vim fugitive's :Gvdiffsplit for example, I get a list of all tags, branches and files. :DiffviewOpen only provides a list of hashes, which I find hard to utilize and files after closing arguments with --.

A comparison between the two:
gvdiffvsdiffview

Any chance we can get something like this for diffview.nvim?

Neogit integration

Hello!

I really like the look of your plugin so I would like to integrate your plugin with neogit.

Some things are still a bit unclear for me so I'd appreciate it if you could help me with a few things:

  • Is there a way to get notified when something happens?
    • for example you commit a change; how can I get notified?
  • Are you going to provide an API which can be used by other plugins?
    • I am mainly looking for ensurance that the API won't have any breaking changes too often
  • Could you support feeding the plugin the files myself? Right now opening the diff is a bit too slow for my taste and neogit already has the information when trying to open the diff.
  • Is any merge conflict support planned or even wanted?

Scrolling sometimes buggy

Hi! Thank you a lot for the awesome plugin!

But I have some issues with scrolling. Sometimes one of the parts does not move and sometimes it moves, but the position is incorrect. It happens only if I use mouse wheel for scrolling:

asciicast

Open currently diffed file in index

Thank you for the nice plugin 👍

One thing I'm currently struggling with is the "missing" Ge[dit] from fugitive.
When diffing a file I'd love to have a way to open the currently selected file as a normal buffer.

Main use case is when checking changes of a commit and noticing an error, fix it and return to diffview.

Diff panes behave weird with popups

First of all, thank you very much for making this!

When the cursor is in one of the diff buffers, then all popup windows like Telescope, or WhichKey, also get a weird diff view.

Do you have any idea how to fix this?

Focusing the file list and then opening a poup is ok

Merge Conflicts

This stackoverflow question is a great starting point for understanding how merge conflict resolution works with the builtin diffing tool.

One thing I noticed right away is that by default 4 splits appear. I'm not really a fan of this kind of resolution so I would propose either a traditional 2 or 3 way split approach. We could also try to replicate VSCode's way of doing this as it is very space efficient and based on my experience it is not too confusing.

We would also need to think about how we could reshape the API to support both normal diffing and merge conflict resolution.

@sindrets have you thought about how you want to implement this before?

Toggle stage entry in view

Thank you so much for this plugin, I have been enjoying it with Neogit.

Here is a quick question on whether it is possible to toggle stage entry in view like the one we have in the file panel?
My workflow is something like this after I am done with a feature, I will go through all the changes locally through Diffview but I see myself going back and forth between the view and the file panel to stage a file.

Not sure if this is a good idea or possible. But will love to hear from you. Thanks again for this amazing plugin.

    view = {
      ["<tab>"]     = cb("select_next_entry"),  -- Open the diff for the next file 
      ["<s-tab>"]   = cb("select_prev_entry"),  -- Open the diff for the previous file
      ["<leader>e"] = cb("focus_files"),        -- Bring focus to the files panel
      ["<leader>b"] = cb("toggle_files"),       -- Toggle the files panel.
      -- ["-"] = cb("toggle_stage_entry")
    },

Error executing lua ...

Hello everyone,

I have some problems to run your plugin.

E5108: Error executing lua .../plugged/diffview.nvim/lua/diffview/views/file_entry.lua:154: attempt to index field 'opt' (a nil value)

Can anyone help me?

NVIM v0.5.0-dev+1295-g3fc71ea22 Build type: RelWithDebInfo LuaJIT 2.1.0-beta3 Compilation: /usr/bin/cc -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/home/runner/work/neovim/neovim/build/config -I/home/runner/work/neovim/neovim/src -I/home/runner/work/neovim/neovim/.deps/usr/include -I/usr/include -I/home/runner/work/neovim/neovim/build/src/nvim/auto -I/home/runner/work/neovim/neovim/build/include Compiled by runner@fv-az64-704

Thanks for help.

Questions on example image

Hi! This plugin looks great and I can't wait to try it out! The example image in the README looks very cool and I had a few questions about that setup.

  1. Which plugin are you using to get both listchars and indent guides to show together? The indent guide plugin I'm using currently doesn't support this.
  2. What colorscheme is being used? I really like the look.

Great work on this plugin. Along with Neogit this will be so helpful.

I can't interact with the plugin apart from moving up and down

I open the plugin with the :DiffviewOpen and I can "j" and "k" but when I press anything else like "tab" or "enter" the file doesn't change, I lose my pointer and I can't interact with neovim. I can't even quit.

The only thing I have done to installed it was adding this line use 'sindrets/diffview.nvim'
My Nvim version is: VIM v0.6.0-dev+8-g75f758b99

Hooks for tweaking diff highlights

I realise this is a bit of an odd request, but here goes anyway:

Highlighting of diffs in (Neo)Vim is a counter-intuitive. When you have version A and B of a file and diff them, A will show the diff relative to B, while B shows the diff relative to A. In practise this means that e.g. a line removed by B shows up as an addition in A, while not showing up in B. Here's an example of that:

Screenshot from 2021-08-02 18-02-24

In addition, changes in B tend to highlighted using the DiffText highlight group. This can result in diffs largely looking similar highlight wise, making it difficult to see what actually changed.

For vim-fugitive I have a hack to fix this (see here). This basically uses winhl to overwrite highlight groups in the appropriate fugitive buffer. The result is something that looks like this:

Screenshot from 2021-08-02 18-05-06

Note how in the old version (left) deletions are shown in red, while additions in the new file (right) are in green. This is what you'd expect when looking at a diff, instead of the default Vim mess.

For diffview.nvim this doesn't work. Buffer names don't have predictable names I can use to inject my winhl rules. There are no hooks of any kind that I can tap into either. Which brings me to my request:

Would it be possible to somehow expose a hook that runs for old/new versions in a diff, or perhaps use specific buffer names (e.g. before: diffview/XXX.rb) for old/new versions? That would make it possible to fix the diff highlights.

File entry error on opening diff view

Hi 👋🏾 ,

I've recently noticed some errors whilst opening diffview with no arguments via DiffViewOpen in a couple of different projects. The error that occurs is

E5108: Error executing lua ...ack/packer/opt/diffview.nvim/lua/diffview/file-entry.lua:133: Vim(lua):E5108: Error executing lua Vim:E5300: Expected a Number or a String

It seems to then prevent the diff for that file from showing correctly. Not a 100% sure what's going on but for a bit more context on my setup.

I lazy load diffview using packer not sure if this relevant using

use {"sindrets/diffview.nvim", module = "diffview", cmd = "DiffviewOpen"}

This all seems to have begun shortly after the api PR was merged if that helps which is when I think maybe the file entry structure was added?

Renames displayed wrong

If you move a file and add it to tracking, then Diffview displays an error instead of the file content: fatal: path 'path/to/file' does not exist (neither on disk nor in the index)

Plugin failed to execute without 'nvim-web-devicons'

In the README, 'nvim-web-devicons' is optional, but 'DiffviewOpen' executes failed:

E5108: Error executing lua ...nter/.vim/bundle/diffview.nvim/lua/diffview/renderer.lua:82: module 'nvim-web-devicons' not found:
        no field package.preload['nvim-web-devicons']
        no file './nvim-web-devicons.lua'
        no file '/home/runner/work/neovim/neovim/.deps/usr/share/luajit-2.1.0-beta3/nvim-web-devicons.lua'
        no file '/usr/local/share/lua/5.1/nvim-web-devicons.lua'
        no file '/usr/local/share/lua/5.1/nvim-web-devicons/init.lua'
        no file '/home/runner/work/neovim/neovim/.deps/usr/share/lua/5.1/nvim-web-devicons.lua'
        no file '/home/runner/work/neovim/neovim/.deps/usr/share/lua/5.1/nvim-web-devicons/init.lua'
        no file './nvim-web-devicons.so'
        no file '/usr/local/lib/lua/5.1/nvim-web-devicons.so'
        no file '/home/runner/work/neovim/neovim/.deps/usr/lib/lua/5.1/nvim-web-devicons.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'

feat: file tree UI in file panel?

Thanks so much for writing this plugin!

I was wondering what you think of showing the file panel as a file tree, which I think would give you a better idea of which files have changed and how the overall project structure has changed in a diff.

Something like:

/path/to/project/

Changes:
M  backend/
M    file_1.py
A    file_2.py
D    file_3.py
M  frontend/
A    components/
A      file_4.tsx
A      file_5.tsx
D    common/
D      file_6.tsx

Showing changes for:
abcdef..bcdefg

(obviously with the nice colors that already exist)

This also avoids the problem of having a really long line width since we currently have the file name, the additions/deletions, and the file path:

M  example_file.hs 5, 14 src/MyApp/components/internal/

view side by side vertically

Hi, thanks for the plugin.
Is there any config to make itu side by side vertically top and bottom instead?
I have a trouble since my screen isn't that wide for side by side left and right
thank you

[feature] option for unified- / inline-diff

I love this plugin, so thank you very much for your work.

One thing I'm missing though is the ability to use inline-diffs, instead of side by side.

For lots of minor changes, I find it's a lot easier to read.

Sth like this:
Screenshot 2021-07-08 at 09 12 37

Is this anything that is planned?

Show diff of current file git history

It would be great if we could load every revision of a file into the left pane and then browse the diff.
I feel I could be able to do this if you are interested. (maybe with a little bit of guidance)

[Feature] An option to show the directory structure

I would love to see the directory structure in the files panel. That will give me immediate clarity how the files relate to each other (are they in the same directory?).

I would imagine there could be a mapping that would change the files view to either a directory view (hierarchical) or a flat list (as it is now).

Being able to collapse/open directories would be an additional benefit

theme

What theme vim do you use image screenshot?

Is the documentation up-to-date?

Hi, I installed this plugin, mainly because of DiffviewFileHistory, however that doesn't seem to be a command I can run, despite being mentioned in the documentation (README basically)

Thank you

[feature] Standard vimdiff commands and git add on save

Hey! Thank you for making this plugin!
I think the interaction with the diffs should function on the repo (sorry, but I do not know how to word this). It should work as a standard vimdiff view.

The example of usage that would be nice:

  • If I am in the Index diff, then :diffput and :diffget should work on the hunk as in a vimdiff. Now this returns an error as the diff is not marked as modifiable
  • If I save the "Head" diff (the one on the left) this should stage the the changes added so that I can now commit

Here is a cast of the error now and how I would expect it to work (demostrated on :Gvdiffsplit from fugitive)
asciicast§

Empty view when submodule.recurse = true

Hi,

Thank you for your plugin, I really like it but unfortunately it just displays the right buffer (sometimes both buffers) as empty when opening :DiffviewOpen.

I digged a little and found out that in my ~/.gitconfig

[submodule]
recurse = true

is responsible for this behavior. When setting it to false everything works fine. I would be glad if you could fix it :-)

OS: Linux
Neovim: 0.5
diffview.nvim: latest commit #36

Best regard Andy

bug: missing commits in file history panel when following renames

When running :DiffviewFileHistory on a file that has been renamed/moved, I'm not getting commits before the rename commit in the file history panel. There are only a couple commits after the rename/move commit like so:

M | ... ... | some change
A | ... ... | move file to ...

However if I run !git log --follow %, then I get all the commits after the rename commit as expected (around 60). I get the same output of around 60 commits after running :0Gclog (from vim-fugitive).

Here's my configuration:

 local cb = require("diffview.config").diffview_callback

require("diffview").setup({
  diff_binaries = false,
  use_icons = false,

  file_panel = {
    position = "left",
    width = 40,
  },

  file_history_panel = {
    position = "bottom",
    height = 16,
    follow = true,
  },

  key_bindings = {
    disable_defaults = false,
    file_panel = {
      ["k"] = cb("prev_entry"),
      ["j"] = cb("next_entry"),
      ["[f"] = cb("select_prev_entry"),
      ["]f"] = cb("select_next_entry"),
      ["<leader>t"] = cb("toggle_files"),
    },
    file_history_panel = {
      ["k"] = cb("prev_entry"),
      ["j"] = cb("next_entry"),
      ["[f"] = cb("select_prev_entry"),
      ["]f"] = cb("select_next_entry"),
      ["<leader>t"] = cb("toggle_files"),
      ["g?"] = cb("options"),
      ["zC"] = cb("close_all_folds"),
      ["zM"] = cb("close_all_folds"),
      ["zO"] = cb("open_all_folds"),
      ["zR"] = cb("open_all_folds"),
      ["<leader>gD"] = cb("open_in_diffview"),
    },
    option_panel = {
      ["<return>"] = cb("select"),
      ["q"] = cb("close"),
    },
    view = {
      ["[f"] = cb("select_prev_entry"),
      ["]f"] = cb("select_next_entry"),
      ["<leader>t"] = cb("toggle_files"),
    },
  },
})

I'll take a closer look at this when I get home, though I'm wondering if you know what might be causing this?

[feature request] Callback/Keybinding for DiffviewClose

So we could use something like:

local cb = require('diffview.config').diffview_callback

require('diffview').setup({
  key_bindings = {
    view = {
      ['<leader>c'] = cb('diffview_close'),
      -- ...
    },
    file_panel = {
      ['<leader>c'] = cb('diffview_close'),
      -- ...
    }
  }
})

To would avoid the need of creating a normal ("global") keybinding to execute :DiffviewClose (which makes sense because we only need to run this when we're using diffview).

Awesome plugin btw

Global Swapfile

It seems that diffview uses a global swap file. This means its features cannot be used in multiple neovim sessions at the same time:

:DiffviewFileHistory
Found a swap file by the name "~/.local/share/nvim/swap//diffview:%%%null.swp"
          owned by: galli   dated: Wed Sep 01 10:04:59 2021
         file name: diffview:///null
          modified: no
         user name: galli   host name: galli-miro
        process ID: 721982 (STILL RUNNING)
While opening file "diffview:///null"
      CANNOT BE FOUND
(1) Another program may be editing the same file.  If this is the case,
    be careful not to end up with two different instances of the same
    file when making changes.  Quit, or continue with caution.
(2) An edit session for this file crashed.
    If this is the case, use ":recover" or "vim -r diffview:///null"
    to recover the changes (see ":help recovery").
    If you did this already, delete the swap file "/home/galli/.local/share/nvim/swap//diffview:%%%null.swp"
    to avoid this message

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.