From 1f61d55ec8f75d29ec90da8a3976f7c15723c716 Mon Sep 17 00:00:00 2001
From: Fabian Missbrenner <missbrenner@ccs-labs.org>
Date: Wed, 4 Dec 2024 17:45:29 +0100
Subject: [PATCH] Use diffview as a git merge tool

---
 lazy-lock.json                  |  19 +--
 lua/custom/plugins/diffview.lua | 235 ++++++++++++++++++++++++++++++++
 2 files changed, 245 insertions(+), 9 deletions(-)
 create mode 100644 lua/custom/plugins/diffview.lua

diff --git a/lazy-lock.json b/lazy-lock.json
index b17f6741..7f303d16 100644
--- a/lazy-lock.json
+++ b/lazy-lock.json
@@ -1,9 +1,10 @@
 {
-  "LuaSnip": { "branch": "master", "commit": "0f7bbce41ea152a94d12aea286f2ce98e63c0f58" },
+  "LuaSnip": { "branch": "master", "commit": "33b06d72d220aa56a7ce80a0dd6f06c70cd82b9d" },
   "cmp-nvim-lsp": { "branch": "main", "commit": "39e2eda76828d88b773cc27a3f61d2ad782c922d" },
   "cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" },
   "cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" },
-  "conform.nvim": { "branch": "master", "commit": "a203480a350b03092e473bf3001733d547160a73" },
+  "conform.nvim": { "branch": "master", "commit": "02fd64fb3d4b18ec029c0e0683c3dc3ec6d2c5b8" },
+  "diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" },
   "fidget.nvim": { "branch": "main", "commit": "e2a175c2abe2d4f65357da1c98c59a5cfb2b543f" },
   "gitsigns.nvim": { "branch": "main", "commit": "5f808b5e4fef30bd8aca1b803b4e555da07fc412" },
   "lazy.nvim": { "branch": "main", "commit": "56ead98e05bb37a4ec28930a54d836d033cf00f2" },
@@ -12,17 +13,17 @@
   "mason-lspconfig.nvim": { "branch": "main", "commit": "8e46de9241d3997927af12196bd8faa0ed08c29a" },
   "mason-tool-installer.nvim": { "branch": "main", "commit": "c5e07b8ff54187716334d585db34282e46fa2932" },
   "mason.nvim": { "branch": "main", "commit": "e2f7f9044ec30067bc11800a9e266664b88cda22" },
-  "mini.nvim": { "branch": "main", "commit": "c8922aef8207137e66c80acdb9523668599ba62a" },
-  "nvim-cmp": { "branch": "main", "commit": "ed31156aa2cc14e3bc066c59357cc91536a2bc01" },
-  "nvim-lspconfig": { "branch": "master", "commit": "e8f9c46c99e1901167a92ab13e2357158e5aabdb" },
-  "nvim-treesitter": { "branch": "master", "commit": "02f8777252fe089c9ea19aa8e19745b505512655" },
-  "nvim-web-devicons": { "branch": "master", "commit": "edbe0a65cfacbbfff6a4a1e98ddd60c28c560509" },
+  "mini.nvim": { "branch": "main", "commit": "690a3b4c78c4956f7ecf770124b522d32084b872" },
+  "nvim-cmp": { "branch": "main", "commit": "ca4d3330d386e76967e53b85953c170658255ecb" },
+  "nvim-lspconfig": { "branch": "master", "commit": "6e385d2fe5da6714f00142afbd8d3591d330ffd7" },
+  "nvim-treesitter": { "branch": "master", "commit": "0aaf146590f3edd1dfa64fbfa2ad1cdca65afa6f" },
+  "nvim-web-devicons": { "branch": "master", "commit": "203da76ecfbb4b192cf830665b03eb651b635c94" },
   "plenary.nvim": { "branch": "master", "commit": "2d9b06177a975543726ce5c73fca176cedbffe9d" },
   "telescope-fzf-native.nvim": { "branch": "main", "commit": "cf48d4dfce44e0b9a2e19a008d6ec6ea6f01a83b" },
   "telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" },
   "telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" },
   "todo-comments.nvim": { "branch": "main", "commit": "ae0a2afb47cf7395dc400e5dc4e05274bf4fb9e0" },
-  "tokyonight.nvim": { "branch": "main", "commit": "c2725eb6d086c8c9624456d734bd365194660017" },
+  "tokyonight.nvim": { "branch": "main", "commit": "15d83cda572d7498b43bbdaa223bc75bf341183e" },
   "vim-sleuth": { "branch": "master", "commit": "be69bff86754b1aa5adcbb527d7fcd1635a84080" },
-  "which-key.nvim": { "branch": "main", "commit": "b9684c6ec54d8a8452bdcf0d613c7ad0223fc3fe" }
+  "which-key.nvim": { "branch": "main", "commit": "9b365a6428a9633e3eeb34dbef1b791511c54f70" }
 }
diff --git a/lua/custom/plugins/diffview.lua b/lua/custom/plugins/diffview.lua
new file mode 100644
index 00000000..0a6242e8
--- /dev/null
+++ b/lua/custom/plugins/diffview.lua
@@ -0,0 +1,235 @@
+return {
+  'sindrets/diffview.nvim',
+  config = function()
+    -- Optional: Any additional configuration you want for Diffview
+    local actions = require 'diffview.actions'
+
+    require('diffview').setup {
+      diff_binaries = false, -- Show diffs for binaries
+      enhanced_diff_hl = false, -- See |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 |diffview-config-view.x.layout|.
+        default = {
+          -- Config for changed files, and staged files in diff views.
+          layout = 'diff2_horizontal',
+          disable_diagnostics = false, -- Temporarily disable diagnostics for diff buffers while in the view.
+          winbar_info = false, -- See |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 diff buffers while in the view.
+          winbar_info = true, -- See |diffview-config-view.x.winbar_info|
+        },
+        file_history = {
+          -- Config for changed files in file history views.
+          layout = 'diff2_horizontal',
+          disable_diagnostics = false, -- Temporarily disable diagnostics for diff buffers while in the view.
+          winbar_info = false, -- See |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 |diffview-config-win_config|
+          position = 'left',
+          width = 35,
+          win_opts = {},
+        },
+      },
+      file_history_panel = {
+        log_options = { -- See |diffview-config-log_options|
+          git = {
+            single_file = {
+              diff_merges = 'combined',
+            },
+            multi_file = {
+              diff_merges = 'first-parent',
+            },
+          },
+          hg = {
+            single_file = {},
+            multi_file = {},
+          },
+        },
+        win_config = { -- See |diffview-config-win_config|
+          position = 'bottom',
+          height = 16,
+          win_opts = {},
+        },
+      },
+      commit_log_panel = {
+        win_config = {}, -- See |diffview-config-win_config|
+      },
+      default_args = { -- Default args prepended to the arg-list for the listed commands
+        DiffviewOpen = {},
+        DiffviewFileHistory = {},
+      },
+      hooks = {}, -- See |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', '[F', actions.select_first_entry, { desc = 'Open the diff for the first file' } },
+          { 'n', ']F', actions.select_last_entry, { desc = 'Open the diff for the last 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', '[F', actions.select_first_entry, { desc = 'Open the diff for the first file' } },
+          { 'n', ']F', actions.select_last_entry, { desc = 'Open the diff for the last 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', 'X', actions.restore_entry, { desc = 'Restore file to the state from the selected entry' } },
+          { 'n', 'zo', actions.open_fold, { desc = 'Expand fold' } },
+          { 'n', 'zc', actions.close_fold, { desc = 'Collapse fold' } },
+          { 'n', 'h', 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', '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', '<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', '[F', actions.select_first_entry, { desc = 'Open the diff for the first file' } },
+          { 'n', ']F', actions.select_last_entry, { desc = 'Open the diff for the last 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' } },
+        },
+      },
+    }
+  end,
+}