{"id":42173824,"url":"https://github.com/dimfeld/diffview.nvim","last_synced_at":"2026-01-26T21:38:33.736Z","repository":{"id":333013402,"uuid":"1134591738","full_name":"dimfeld/diffview.nvim","owner":"dimfeld","description":"Single tabpage interface for easily cycling through diffs for all modified files for any git rev -- fork with review functionality added","archived":false,"fork":false,"pushed_at":"2026-01-16T20:50:16.000Z","size":2109,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-17T09:23:21.651Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dimfeld.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":["sindrets"]}},"created_at":"2026-01-14T23:35:57.000Z","updated_at":"2026-01-16T20:50:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dimfeld/diffview.nvim","commit_stats":null,"previous_names":["dimfeld/diffview.nvim"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/dimfeld/diffview.nvim","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimfeld%2Fdiffview.nvim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimfeld%2Fdiffview.nvim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimfeld%2Fdiffview.nvim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimfeld%2Fdiffview.nvim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dimfeld","download_url":"https://codeload.github.com/dimfeld/diffview.nvim/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimfeld%2Fdiffview.nvim/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28788548,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T21:13:08.818Z","status":"ssl_error","status_checked_at":"2026-01-26T21:13:08.448Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-26T21:38:32.920Z","updated_at":"2026-01-26T21:38:33.730Z","avatar_url":"https://github.com/dimfeld.png","language":"Lua","funding_links":["https://github.com/sponsors/sindrets"],"categories":[],"sub_categories":[],"readme":"# Diffview.nvim\n\nSingle tabpage interface for easily cycling through diffs for all modified files\nfor any git rev.\n\nThis is a fork of [sindrets/diffview.nvim](https://github.com/sindrets/diffview.nvim), with extra support for\nreviewing PRs and other diffs.\n\n![preview](https://user-images.githubusercontent.com/2786478/131269942-e34100dd-cbb9-48fe-af31-6e518ce06e9e.png)\n\n\n## Introduction\n\nVim's diff mode is pretty good, but there is no convenient way to quickly bring\nup all modified files in a diffsplit. This plugin aims to provide a simple,\nunified, single tabpage interface that lets you easily review all changed files\nfor any git rev.\n\n## Requirements\n\n- Git ≥ 2.31.0 (for Git support)\n- Mercurial ≥ 5.4.0 (for Mercurial support)\n- Neovim ≥ 0.7.0 (with LuaJIT)\n- [nvim-web-devicons](https://github.com/nvim-tree/nvim-web-devicons) (optional) For file icons\n\n## Installation\n\nInstall the plugin with your package manager of choice.\n\n```vim\n\" Plug\nPlug 'sindrets/diffview.nvim'\n```\n\n```lua\n-- Packer\nuse \"sindrets/diffview.nvim\" \n```\n\n## Merge Tool\n\n![merge tool showcase](https://user-images.githubusercontent.com/2786478/188286293-13bbf0ab-3595-425d-ba4a-12f514c17eb6.png)\n\nOpening a diff view during a merge or a rebase will list the conflicted files in\ntheir own section. When opening a conflicted file, it will open in a 3-way diff\nallowing you to resolve the merge conflicts with the context of the target\nbranch's version, as well as the version from the branch which is being merged.\n\nThe 3-way diff is only the default layout for merge conflicts. There are\nmultiple variations on this layout, a 4-way diff layout, and a single window\nlayout available.\n\nIn addition to the normal `:h copy-diffs` mappings, there are default mappings\nprovided for jumping between conflict markers, obtaining a hunk directly from\nany of the diff buffers, and accepting any one, all, or none of the versions of\na file given by a conflict region.\n\nFor more information on the merge tool, mappings, layouts and how to\nconfigure them, see:\n\n- `:h diffview-merge-tool`\n- `:h diffview-config-view.x.layout`\n\n## File History\n\n![file history showcase](https://user-images.githubusercontent.com/2786478/188331057-f9ec9a0d-8cda-4ff8-ac98-febcc7aa4010.png)\n\nThe file history view allows you to list all the commits that affected a given\nset of paths, and view the changes made in a diff split. This is a porcelain\ninterface for git-log, and supports a good number of its options. Things like:\n\n- Filtering commits by grepping commit messages and commit authors.\n- Tracing the line evolution of a given set of line ranges for multiple files.\n- Only listing changes for a specific commit range, branch, or tag.\n- Following file changes through renames.\n\nGet started by opening file history for:\n\n- The current branch: `:DiffviewFileHistory`\n- The current file: `:DiffviewFileHistory %`\n\nFor more info, see `:h :DiffviewFileHistory`.\n\n## JSON Grouped Views\n\nYou can open a diff view with files organized into custom named groups using a\nJSON file. This is useful for:\n\n- **Code review workflows**: Organize files by logical feature areas (frontend,\n  backend, tests) rather than alphabetically\n- **Automated tooling**: Generate curated file lists from external tools (e.g.,\n  AI code analysis, dependency impact analysis)\n- **Educational walkthroughs**: Show specific files in a specific order\n\n### Basic Usage\n\nCreate a JSON file defining your groups:\n\n```json\n{\n  \"title\": \"PR #123: Add authentication\",\n  \"groups\": [\n    {\n      \"name\": \"Frontend\",\n      \"files\": [\n        { \"path\": \"src/components/Login.tsx\" },\n        { \"path\": \"src/components/Signup.tsx\" }\n      ]\n    },\n    {\n      \"name\": \"Backend\",\n      \"files\": [\n        { \"path\": \"src/api/auth.ts\" }\n      ]\n    }\n  ]\n}\n```\n\nThen open it with:\n\n```vim\n:DiffviewOpenJson review.json HEAD~5\n:DiffviewOpenJson review.json main..feature-branch\n```\n\nThe command accepts the same revision arguments as `:DiffviewOpen`. File status\nand diffs are computed from git based on the specified revisions.\n\n### Filtering\n\n- Files with no changes at the specified revisions are automatically filtered out\n- Missing files show a warning, but the view continues with valid files\n- Empty groups (after filtering) are hidden\n- If all groups are empty, an error is shown\n\nFor more details, see `:h :DiffviewOpenJson`.\n\n## Review Tracking\n\nThis fork adds review tracking functionality to help you keep track of which\nfiles you've reviewed in a diff. This is particularly useful when reviewing\nlarge PRs or diffs that span multiple sessions.\n\n### How It Works\n\nWhen you mark a file as reviewed, diffview stores the file's blob hash (the\ncontent hash) along with a timestamp. This has several advantages:\n\n- **Survives rebases and amends**: Since the blob hash is content-based, your\n  review state persists even if commit hashes change (common when using tools\n  like Jujutsu or when force-pushing).\n- **Detects changes**: If a file is modified after you reviewed it, diffview\n  detects this by comparing blob hashes and marks it as \"changed\".\n\n### Review Statuses\n\nFiles in the file panel show indicators based on their review status:\n\n- **Unreviewed** (blank): File has never been marked as reviewed\n- **Reviewed** (●): File was marked as reviewed and hasn't changed\n- **Changed** (◐): File was marked as reviewed but has been modified since\n\n### Key Features\n\n**Mark files as reviewed:**\n- `\u003cleader\u003erm` - Mark current file as reviewed\n- `\u003cleader\u003erM` - Mark all files as reviewed\n\n**Navigate by review status:**\n- `]r` / `[r` - Jump to next/previous file pending review (unreviewed or changed)\n- `]R` / `[R` - Jump to next/previous unreviewed file\n\n**Review filter:**\n- `\u003cleader\u003erf` - Toggle filter to show only files pending review\n\n**Since-review diff mode:**\n- `\u003cleader\u003ers` - Toggle since-review mode. When enabled, files marked as\n  \"changed\" show only the diff since your last review, not the full diff.\n  This helps you focus on what changed since you last looked at a file.\n\n**Clear review state:**\n- `\u003cleader\u003erc` - Clear review status for current file\n- `\u003cleader\u003erC` - Clear all review state for this branch\n- `\u003cleader\u003erX` - Clear all review state for this repository\n\n### Configuration\n\n```lua\nreview = {\n  enabled = true,              -- Enable review tracking\n  cache_dir = nil,             -- Storage location (default: ~/.cache/diffview.nvim/reviews/)\n  auto_cleanup = false,        -- Auto-cleanup stale branch data on DiffView open\n  cleanup_age_days = 30,       -- Age threshold for auto-cleanup (days)\n  auto_advance = \"stay\",       -- \"stay\", \"next\", or \"next_pending\"\n  symbols = {\n    unreviewed = \" \",          -- No indicator\n    reviewed = \"●\",            -- Filled circle (green)\n    changed = \"◐\",             -- Half-filled circle (yellow)\n  },\n}\n```\n\n### Cleanup\n\nReview state is stored per-branch. Over time, you may accumulate review data\nfor branches that no longer exist. Use `:DiffviewReviewCleanup` to remove\nstale data:\n\n- `:DiffviewReviewCleanup` - Interactively clean up stale branch data\n- `:DiffviewReviewCleanup!` - Preview what would be cleaned up (dry run)\n\nYou can also enable `auto_cleanup = true` in the config to automatically clean\nup stale data when opening a DiffView.\n\n## Usage\n\n### `:DiffviewOpen [git rev] [options] [ -- {paths...}]`\n\nCalling `:DiffviewOpen` with no args opens a new Diffview that compares against\nthe current index. You can also provide any valid git rev to view only changes\nfor that rev.\n\nExamples:\n\n- `:DiffviewOpen`\n- `:DiffviewOpen HEAD~2`\n- `:DiffviewOpen HEAD~4..HEAD~2`\n- `:DiffviewOpen d4a7b0d`\n- `:DiffviewOpen d4a7b0d^!`\n- `:DiffviewOpen d4a7b0d..519b30e`\n- `:DiffviewOpen origin/main...HEAD`\n\nYou can also provide additional paths to narrow down what files are shown:\n\n- `:DiffviewOpen HEAD~2 -- lua/diffview plugin`\n\nFor information about additional `[options]`, visit the\n[documentation](https://github.com/sindrets/diffview.nvim/blob/main/doc/diffview.txt).\n\nAdditional commands for convenience:\n\n- `:DiffviewClose`: Close the current diffview. You can also use `:tabclose`.\n- `:DiffviewToggleFiles`: Toggle the file panel.\n- `:DiffviewFocusFiles`: Bring focus to the file panel.\n- `:DiffviewRefresh`: Update stats and entries in the file list of the current\n  Diffview.\n\nWith a Diffview open and the default key bindings, you can cycle through changed\nfiles with `\u003ctab\u003e` and `\u003cs-tab\u003e` (see configuration to change the key bindings).\n\n#### Staging\n\nYou can stage individual hunks by editing any buffer that represents the index\n(after running `:DiffviewOpen` with no `[git-rev]` the entries under \"Changes\"\nwill have the index buffer on the left side, and the entries under \"Staged\nchanges\" will have it on the right side). Once you write to an index buffer the\nindex will be updated.\n\n### `:[range]DiffviewFileHistory [paths] [options]`\n\nOpens a new file history view that lists all commits that affected the given\npaths. This is a porcelain interface for git-log. Both `[paths]` and\n`[options]` may be specified in any order, even interchangeably.\n\nIf no `[paths]` are given, defaults to the top-level of the working tree. The\ntop-level will be inferred from the current buffer when possible, otherwise the\ncwd is used. Multiple `[paths]` may be provided and git pathspec is supported.\n\nIf `[range]` is given, the file history view will trace the line evolution of the\ngiven range in the current file (for more info, see the `-L` flag in the docs).\n\nExamples:\n\n- `:DiffviewFileHistory`\n- `:DiffviewFileHistory %`\n- `:DiffviewFileHistory path/to/some/file.txt`\n- `:DiffviewFileHistory path/to/some/directory`\n- `:DiffviewFileHistory include/this and/this :!but/not/this`\n- `:DiffviewFileHistory --range=origin..HEAD`\n- `:DiffviewFileHistory --range=feat/example-branch`\n- `:'\u003c,'\u003eDiffviewFileHistory`\n\n\u003e [!IMPORTANT]\n\u003e ### Familiarize Yourself With `:h diff-mode`\n\u003e\n\u003e This plugin assumes you're familiar with all the features already provided by\n\u003e nvim's builtin diff-mode. These features include:\n\u003e\n\u003e - Jumping between hunks (`:h jumpto-diffs`).\n\u003e - Applying the changes of a diff hunk from any of the diffed buffers\n\u003e   (`:h copy-diffs`).\n\u003e - And more...\n\u003e\n\u003e Read the help page for more info.\n\n---\n\n\u003cbr\u003e\n\n\u003e [!NOTE]\n\u003e Additionally check out [USAGE](USAGE.md) for examples of some more specific\n\u003e use-cases.\n\n\u003cbr\u003e\n\n---\n\n## Configuration\n\n\u003cp\u003e\n\u003cdetails\u003e\n\u003csummary style='cursor: pointer'\u003e\u003cb\u003eExample config with default values\u003c/b\u003e\u003c/summary\u003e\n\n```lua\n-- Lua\nlocal actions = require(\"diffview.actions\")\n\nrequire(\"diffview\").setup({\n  diff_binaries = false,    -- Show diffs for binaries\n  enhanced_diff_hl = false, -- See |diffview-config-enhanced_diff_hl|\n  git_cmd = { \"git\" },      -- The git executable followed by default args.\n  hg_cmd = { \"hg\" },        -- The hg executable followed by default args.\n  use_icons = true,         -- Requires nvim-web-devicons\n  show_help_hints = true,   -- Show hints for how to open the help panel\n  watch_index = true,       -- Update views and index buffers when the git index changes.\n  icons = {                 -- Only applies when use_icons is true.\n    folder_closed = \"\",\n    folder_open = \"\",\n  },\n  signs = {\n    fold_closed = \"\",\n    fold_open = \"\",\n    done = \"✓\",\n  },\n  view = {\n    -- Configure the layout and behavior of different types of views.\n    -- Available layouts:\n    --  'diff1_plain'\n    --    |'diff2_horizontal'\n    --    |'diff2_vertical'\n    --    |'diff3_horizontal'\n    --    |'diff3_vertical'\n    --    |'diff3_mixed'\n    --    |'diff4_mixed'\n    -- For more info, see |diffview-config-view.x.layout|.\n    default = {\n      -- Config for changed files, and staged files in diff views.\n      layout = \"diff2_horizontal\",\n      disable_diagnostics = false,  -- Temporarily disable diagnostics for diff buffers while in the view.\n      winbar_info = false,          -- See |diffview-config-view.x.winbar_info|\n    },\n    merge_tool = {\n      -- Config for conflicted files in diff views during a merge or rebase.\n      layout = \"diff3_horizontal\",\n      disable_diagnostics = true,   -- Temporarily disable diagnostics for diff buffers while in the view.\n      winbar_info = true,           -- See |diffview-config-view.x.winbar_info|\n    },\n    file_history = {\n      -- Config for changed files in file history views.\n      layout = \"diff2_horizontal\",\n      disable_diagnostics = false,  -- Temporarily disable diagnostics for diff buffers while in the view.\n      winbar_info = false,          -- See |diffview-config-view.x.winbar_info|\n    },\n  },\n  file_panel = {\n    listing_style = \"tree\",             -- One of 'list' or 'tree'\n    tree_options = {                    -- Only applies when listing_style is 'tree'\n      flatten_dirs = true,              -- Flatten dirs that only contain one single dir\n      folder_statuses = \"only_folded\",  -- One of 'never', 'only_folded' or 'always'.\n    },\n    win_config = {                      -- See |diffview-config-win_config|\n      position = \"left\",\n      width = 35,\n      win_opts = {},\n    },\n  },\n  file_history_panel = {\n    log_options = {   -- See |diffview-config-log_options|\n      git = {\n        single_file = {\n          diff_merges = \"combined\",\n        },\n        multi_file = {\n          diff_merges = \"first-parent\",\n        },\n      },\n      hg = {\n        single_file = {},\n        multi_file = {},\n      },\n    },\n    win_config = {    -- See |diffview-config-win_config|\n      position = \"bottom\",\n      height = 16,\n      win_opts = {},\n    },\n  },\n  commit_log_panel = {\n    win_config = {},  -- See |diffview-config-win_config|\n  },\n  default_args = {    -- Default args prepended to the arg-list for the listed commands\n    DiffviewOpen = {},\n    DiffviewFileHistory = {},\n  },\n  review = {          -- See |diffview-config-review|\n    enabled = true,   -- Enable review tracking\n    cache_dir = nil,  -- Review state storage (default: ~/.cache/diffview.nvim/reviews/)\n    auto_cleanup = false,    -- Auto-cleanup stale branch review data on DiffView open\n    cleanup_age_days = 30,   -- Age threshold for cleanup (days)\n    auto_advance = \"stay\",   -- \"stay\", \"next\", or \"next_pending\"\n    symbols = {       -- Symbols for review state indicator in file panel\n      unreviewed = \" \",  -- Blank space (no indicator)\n      reviewed = \"●\",    -- Filled circle (green)\n      changed = \"◐\",     -- Half-filled circle (yellow)\n    },\n  },\n  hooks = {},         -- See |diffview-config-hooks|\n  keymaps = {\n    disable_defaults = false, -- Disable the default keymaps\n    view = {\n      -- The `view` bindings are active in the diff buffers, only when the current\n      -- tabpage is a Diffview.\n      { \"n\", \"\u003ctab\u003e\",       actions.select_next_entry,              { desc = \"Open the diff for the next file\" } },\n      { \"n\", \"\u003cs-tab\u003e\",     actions.select_prev_entry,              { desc = \"Open the diff for the previous file\" } },\n      { \"n\", \"[F\",          actions.select_first_entry,             { desc = \"Open the diff for the first file\" } },\n      { \"n\", \"]F\",          actions.select_last_entry,              { desc = \"Open the diff for the last file\" } },\n      { \"n\", \"gf\",          actions.goto_file_edit,                 { desc = \"Open the file in the previous tabpage\" } },\n      { \"n\", \"\u003cC-w\u003e\u003cC-f\u003e\",  actions.goto_file_split,                { desc = \"Open the file in a new split\" } },\n      { \"n\", \"\u003cC-w\u003egf\",     actions.goto_file_tab,                  { desc = \"Open the file in a new tabpage\" } },\n      { \"n\", \"\u003cleader\u003ee\",   actions.focus_files,                    { desc = \"Bring focus to the file panel\" } },\n      { \"n\", \"\u003cleader\u003eb\",   actions.toggle_files,                   { desc = \"Toggle the file panel.\" } },\n      { \"n\", \"g\u003cC-x\u003e\",      actions.cycle_layout,                   { desc = \"Cycle through available layouts.\" } },\n      { \"n\", \"[x\",          actions.prev_conflict,                  { desc = \"In the merge-tool: jump to the previous conflict\" } },\n      { \"n\", \"]x\",          actions.next_conflict,                  { desc = \"In the merge-tool: jump to the next conflict\" } },\n      { \"n\", \"[r\",          actions.review_prev_pending,            { desc = \"Jump to the previous file pending review\" } },\n      { \"n\", \"]r\",          actions.review_next_pending,            { desc = \"Jump to the next file pending review\" } },\n      { \"n\", \"[R\",          actions.review_prev_unreviewed,         { desc = \"Jump to the previous unreviewed file\" } },\n      { \"n\", \"]R\",          actions.review_next_unreviewed,         { desc = \"Jump to the next unreviewed file\" } },\n      { \"n\", \"\u003cleader\u003erf\",  actions.review_toggle_filter,           { desc = \"Toggle review filter (show only pending)\" } },\n      { \"n\", \"\u003cleader\u003ers\",  actions.review_toggle_since_review,    { desc = \"Toggle since-review diff mode\" } },\n      { \"n\", \"\u003cleader\u003erm\",  actions.review_mark_file,              { desc = \"Mark the current file as reviewed\" } },\n      { \"n\", \"\u003cleader\u003erM\",  actions.review_mark_all,               { desc = \"Mark all files as reviewed\" } },\n      { \"n\", \"\u003cleader\u003erc\",  actions.review_clear_file,             { desc = \"Clear review status for the current file\" } },\n      { \"n\", \"\u003cleader\u003erC\",  actions.review_clear_all,              { desc = \"Clear all review state for this branch\" } },\n      { \"n\", \"\u003cleader\u003erX\",  actions.review_clear_repo,             { desc = \"Clear all review state for this repository\" } },\n      { \"n\", \"\u003cleader\u003eco\",  actions.conflict_choose(\"ours\"),        { desc = \"Choose the OURS version of a conflict\" } },\n      { \"n\", \"\u003cleader\u003ect\",  actions.conflict_choose(\"theirs\"),      { desc = \"Choose the THEIRS version of a conflict\" } },\n      { \"n\", \"\u003cleader\u003ecb\",  actions.conflict_choose(\"base\"),        { desc = \"Choose the BASE version of a conflict\" } },\n      { \"n\", \"\u003cleader\u003eca\",  actions.conflict_choose(\"all\"),         { desc = \"Choose all the versions of a conflict\" } },\n      { \"n\", \"dx\",          actions.conflict_choose(\"none\"),        { desc = \"Delete the conflict region\" } },\n      { \"n\", \"\u003cleader\u003ecO\",  actions.conflict_choose_all(\"ours\"),    { desc = \"Choose the OURS version of a conflict for the whole file\" } },\n      { \"n\", \"\u003cleader\u003ecT\",  actions.conflict_choose_all(\"theirs\"),  { desc = \"Choose the THEIRS version of a conflict for the whole file\" } },\n      { \"n\", \"\u003cleader\u003ecB\",  actions.conflict_choose_all(\"base\"),    { desc = \"Choose the BASE version of a conflict for the whole file\" } },\n      { \"n\", \"\u003cleader\u003ecA\",  actions.conflict_choose_all(\"all\"),     { desc = \"Choose all the versions of a conflict for the whole file\" } },\n      { \"n\", \"dX\",          actions.conflict_choose_all(\"none\"),    { desc = \"Delete the conflict region for the whole file\" } },\n    },\n    diff1 = {\n      -- Mappings in single window diff layouts\n      { \"n\", \"g?\", actions.help({ \"view\", \"diff1\" }), { desc = \"Open the help panel\" } },\n    },\n    diff2 = {\n      -- Mappings in 2-way diff layouts\n      { \"n\", \"g?\", actions.help({ \"view\", \"diff2\" }), { desc = \"Open the help panel\" } },\n    },\n    diff3 = {\n      -- Mappings in 3-way diff layouts\n      { { \"n\", \"x\" }, \"2do\",  actions.diffget(\"ours\"),            { desc = \"Obtain the diff hunk from the OURS version of the file\" } },\n      { { \"n\", \"x\" }, \"3do\",  actions.diffget(\"theirs\"),          { desc = \"Obtain the diff hunk from the THEIRS version of the file\" } },\n      { \"n\",          \"g?\",   actions.help({ \"view\", \"diff3\" }),  { desc = \"Open the help panel\" } },\n    },\n    diff4 = {\n      -- Mappings in 4-way diff layouts\n      { { \"n\", \"x\" }, \"1do\",  actions.diffget(\"base\"),            { desc = \"Obtain the diff hunk from the BASE version of the file\" } },\n      { { \"n\", \"x\" }, \"2do\",  actions.diffget(\"ours\"),            { desc = \"Obtain the diff hunk from the OURS version of the file\" } },\n      { { \"n\", \"x\" }, \"3do\",  actions.diffget(\"theirs\"),          { desc = \"Obtain the diff hunk from the THEIRS version of the file\" } },\n      { \"n\",          \"g?\",   actions.help({ \"view\", \"diff4\" }),  { desc = \"Open the help panel\" } },\n    },\n    file_panel = {\n      { \"n\", \"j\",              actions.next_entry,                     { desc = \"Bring the cursor to the next file entry\" } },\n      { \"n\", \"\u003cdown\u003e\",         actions.next_entry,                     { desc = \"Bring the cursor to the next file entry\" } },\n      { \"n\", \"k\",              actions.prev_entry,                     { desc = \"Bring the cursor to the previous file entry\" } },\n      { \"n\", \"\u003cup\u003e\",           actions.prev_entry,                     { desc = \"Bring the cursor to the previous file entry\" } },\n      { \"n\", \"\u003ccr\u003e\",           actions.select_entry,                   { desc = \"Open the diff for the selected entry\" } },\n      { \"n\", \"o\",              actions.select_entry,                   { desc = \"Open the diff for the selected entry\" } },\n      { \"n\", \"l\",              actions.select_entry,                   { desc = \"Open the diff for the selected entry\" } },\n      { \"n\", \"\u003c2-LeftMouse\u003e\",  actions.select_entry,                   { desc = \"Open the diff for the selected entry\" } },\n      { \"n\", \"-\",              actions.toggle_stage_entry,             { desc = \"Stage / unstage the selected entry\" } },\n      { \"n\", \"s\",              actions.toggle_stage_entry,             { desc = \"Stage / unstage the selected entry\" } },\n      { \"n\", \"S\",              actions.stage_all,                      { desc = \"Stage all entries\" } },\n      { \"n\", \"U\",              actions.unstage_all,                    { desc = \"Unstage all entries\" } },\n      { \"n\", \"X\",              actions.restore_entry,                  { desc = \"Restore entry to the state on the left side\" } },\n      { \"n\", \"L\",              actions.open_commit_log,                { desc = \"Open the commit log panel\" } },\n      { \"n\", \"zo\",             actions.open_fold,                      { desc = \"Expand fold\" } },\n      { \"n\", \"h\",              actions.close_fold,                     { desc = \"Collapse fold\" } },\n      { \"n\", \"zc\",             actions.close_fold,                     { desc = \"Collapse fold\" } },\n      { \"n\", \"za\",             actions.toggle_fold,                    { desc = \"Toggle fold\" } },\n      { \"n\", \"zR\",             actions.open_all_folds,                 { desc = \"Expand all folds\" } },\n      { \"n\", \"zM\",             actions.close_all_folds,                { desc = \"Collapse all folds\" } },\n      { \"n\", \"\u003cc-b\u003e\",          actions.scroll_view(-0.25),             { desc = \"Scroll the view up\" } },\n      { \"n\", \"\u003cc-f\u003e\",          actions.scroll_view(0.25),              { desc = \"Scroll the view down\" } },\n      { \"n\", \"\u003ctab\u003e\",          actions.select_next_entry,              { desc = \"Open the diff for the next file\" } },\n      { \"n\", \"\u003cs-tab\u003e\",        actions.select_prev_entry,              { desc = \"Open the diff for the previous file\" } },\n      { \"n\", \"[F\",             actions.select_first_entry,             { desc = \"Open the diff for the first file\" } },\n      { \"n\", \"]F\",             actions.select_last_entry,              { desc = \"Open the diff for the last file\" } },\n      { \"n\", \"gf\",             actions.goto_file_edit,                 { desc = \"Open the file in the previous tabpage\" } },\n      { \"n\", \"\u003cC-w\u003e\u003cC-f\u003e\",     actions.goto_file_split,                { desc = \"Open the file in a new split\" } },\n      { \"n\", \"\u003cC-w\u003egf\",        actions.goto_file_tab,                  { desc = \"Open the file in a new tabpage\" } },\n      { \"n\", \"i\",              actions.listing_style,                  { desc = \"Toggle between 'list' and 'tree' views\" } },\n      { \"n\", \"f\",              actions.toggle_flatten_dirs,            { desc = \"Flatten empty subdirectories in tree listing style\" } },\n      { \"n\", \"R\",              actions.refresh_files,                  { desc = \"Update stats and entries in the file list\" } },\n      { \"n\", \"\u003cleader\u003ee\",      actions.focus_files,                    { desc = \"Bring focus to the file panel\" } },\n      { \"n\", \"\u003cleader\u003eb\",      actions.toggle_files,                   { desc = \"Toggle the file panel\" } },\n      { \"n\", \"g\u003cC-x\u003e\",         actions.cycle_layout,                   { desc = \"Cycle available layouts\" } },\n      { \"n\", \"[x\",             actions.prev_conflict,                  { desc = \"Go to the previous conflict\" } },\n      { \"n\", \"]x\",             actions.next_conflict,                  { desc = \"Go to the next conflict\" } },\n      { \"n\", \"[r\",             actions.review_prev_pending,            { desc = \"Jump to the previous file pending review\" } },\n      { \"n\", \"]r\",             actions.review_next_pending,            { desc = \"Jump to the next file pending review\" } },\n      { \"n\", \"[R\",             actions.review_prev_unreviewed,         { desc = \"Jump to the previous unreviewed file\" } },\n      { \"n\", \"]R\",             actions.review_next_unreviewed,         { desc = \"Jump to the next unreviewed file\" } },\n      { \"n\", \"\u003cleader\u003erf\",     actions.review_toggle_filter,           { desc = \"Toggle review filter (show only pending)\" } },\n      { \"n\", \"\u003cleader\u003ers\",    actions.review_toggle_since_review,    { desc = \"Toggle since-review diff mode\" } },\n      { \"n\", \"\u003cleader\u003erm\",    actions.review_mark_file,              { desc = \"Mark the current file as reviewed\" } },\n      { \"n\", \"\u003cleader\u003erM\",    actions.review_mark_all,               { desc = \"Mark all files as reviewed\" } },\n      { \"n\", \"\u003cleader\u003erc\",    actions.review_clear_file,             { desc = \"Clear review status for the current file\" } },\n      { \"n\", \"\u003cleader\u003erC\",  actions.review_clear_all,              { desc = \"Clear all review state for this branch\" } },\n      { \"n\", \"\u003cleader\u003erX\",  actions.review_clear_repo,             { desc = \"Clear all review state for this repository\" } },\n      { \"n\", \"g?\",             actions.help(\"file_panel\"),             { desc = \"Open the help panel\" } },\n      { \"n\", \"\u003cleader\u003ecO\",     actions.conflict_choose_all(\"ours\"),    { desc = \"Choose the OURS version of a conflict for the whole file\" } },\n      { \"n\", \"\u003cleader\u003ecT\",     actions.conflict_choose_all(\"theirs\"),  { desc = \"Choose the THEIRS version of a conflict for the whole file\" } },\n      { \"n\", \"\u003cleader\u003ecB\",     actions.conflict_choose_all(\"base\"),    { desc = \"Choose the BASE version of a conflict for the whole file\" } },\n      { \"n\", \"\u003cleader\u003ecA\",     actions.conflict_choose_all(\"all\"),     { desc = \"Choose all the versions of a conflict for the whole file\" } },\n      { \"n\", \"dX\",             actions.conflict_choose_all(\"none\"),    { desc = \"Delete the conflict region for the whole file\" } },\n    },\n    file_history_panel = {\n      { \"n\", \"g!\",            actions.options,                     { desc = \"Open the option panel\" } },\n      { \"n\", \"\u003cC-A-d\u003e\",       actions.open_in_diffview,            { desc = \"Open the entry under the cursor in a diffview\" } },\n      { \"n\", \"y\",             actions.copy_hash,                   { desc = \"Copy the commit hash of the entry under the cursor\" } },\n      { \"n\", \"L\",             actions.open_commit_log,             { desc = \"Show commit details\" } },\n      { \"n\", \"X\",             actions.restore_entry,               { desc = \"Restore file to the state from the selected entry\" } },\n      { \"n\", \"zo\",            actions.open_fold,                   { desc = \"Expand fold\" } },\n      { \"n\", \"zc\",            actions.close_fold,                  { desc = \"Collapse fold\" } },\n      { \"n\", \"h\",             actions.close_fold,                  { desc = \"Collapse fold\" } },\n      { \"n\", \"za\",            actions.toggle_fold,                 { desc = \"Toggle fold\" } },\n      { \"n\", \"zR\",            actions.open_all_folds,              { desc = \"Expand all folds\" } },\n      { \"n\", \"zM\",            actions.close_all_folds,             { desc = \"Collapse all folds\" } },\n      { \"n\", \"j\",             actions.next_entry,                  { desc = \"Bring the cursor to the next file entry\" } },\n      { \"n\", \"\u003cdown\u003e\",        actions.next_entry,                  { desc = \"Bring the cursor to the next file entry\" } },\n      { \"n\", \"k\",             actions.prev_entry,                  { desc = \"Bring the cursor to the previous file entry\" } },\n      { \"n\", \"\u003cup\u003e\",          actions.prev_entry,                  { desc = \"Bring the cursor to the previous file entry\" } },\n      { \"n\", \"\u003ccr\u003e\",          actions.select_entry,                { desc = \"Open the diff for the selected entry\" } },\n      { \"n\", \"o\",             actions.select_entry,                { desc = \"Open the diff for the selected entry\" } },\n      { \"n\", \"l\",             actions.select_entry,                { desc = \"Open the diff for the selected entry\" } },\n      { \"n\", \"\u003c2-LeftMouse\u003e\", actions.select_entry,                { desc = \"Open the diff for the selected entry\" } },\n      { \"n\", \"\u003cc-b\u003e\",         actions.scroll_view(-0.25),          { desc = \"Scroll the view up\" } },\n      { \"n\", \"\u003cc-f\u003e\",         actions.scroll_view(0.25),           { desc = \"Scroll the view down\" } },\n      { \"n\", \"\u003ctab\u003e\",         actions.select_next_entry,           { desc = \"Open the diff for the next file\" } },\n      { \"n\", \"\u003cs-tab\u003e\",       actions.select_prev_entry,           { desc = \"Open the diff for the previous file\" } },\n      { \"n\", \"[F\",            actions.select_first_entry,          { desc = \"Open the diff for the first file\" } },\n      { \"n\", \"]F\",            actions.select_last_entry,           { desc = \"Open the diff for the last file\" } },\n      { \"n\", \"gf\",            actions.goto_file_edit,              { desc = \"Open the file in the previous tabpage\" } },\n      { \"n\", \"\u003cC-w\u003e\u003cC-f\u003e\",    actions.goto_file_split,             { desc = \"Open the file in a new split\" } },\n      { \"n\", \"\u003cC-w\u003egf\",       actions.goto_file_tab,               { desc = \"Open the file in a new tabpage\" } },\n      { \"n\", \"\u003cleader\u003ee\",     actions.focus_files,                 { desc = \"Bring focus to the file panel\" } },\n      { \"n\", \"\u003cleader\u003eb\",     actions.toggle_files,                { desc = \"Toggle the file panel\" } },\n      { \"n\", \"g\u003cC-x\u003e\",        actions.cycle_layout,                { desc = \"Cycle available layouts\" } },\n      { \"n\", \"g?\",            actions.help(\"file_history_panel\"),  { desc = \"Open the help panel\" } },\n    },\n    option_panel = {\n      { \"n\", \"\u003ctab\u003e\", actions.select_entry,          { desc = \"Change the current option\" } },\n      { \"n\", \"q\",     actions.close,                 { desc = \"Close the panel\" } },\n      { \"n\", \"g?\",    actions.help(\"option_panel\"),  { desc = \"Open the help panel\" } },\n    },\n    help_panel = {\n      { \"n\", \"q\",     actions.close,  { desc = \"Close help menu\" } },\n      { \"n\", \"\u003cesc\u003e\", actions.close,  { desc = \"Close help menu\" } },\n    },\n  },\n})\n```\n\n\u003c/details\u003e\n\u003c/p\u003e\n\n### Hooks\n\nThe `hooks` table allows you to define callbacks for various events emitted from\nDiffview. The available hooks are documented in detail in\n`:h diffview-config-hooks`. The hook events are also available as User\nautocommands. See `:h diffview-user-autocmds` for more details.\n\nExamples:\n\n```lua\nhooks = {\n  diff_buf_read = function(bufnr)\n    -- Change local options in diff buffers\n    vim.opt_local.wrap = false\n    vim.opt_local.list = false\n    vim.opt_local.colorcolumn = { 80 }\n  end,\n  view_opened = function(view)\n    print(\n      (\"A new %s was opened on tab page %d!\")\n      :format(view.class:name(), view.tabpage)\n    )\n  end,\n}\n```\n\n### Keymaps\n\nThe keymaps config is structured as a table with sub-tables for various\ndifferent contexts where mappings can be declared. In these sub-tables\nkey-value pairs are treated as the `{lhs}` and `{rhs}` of a normal mode\nmapping. These mappings all use the `:map-arguments` `silent`, `nowait`, and\n`noremap`. The implementation uses `vim.keymap.set()`, so the `{rhs}` can be\neither a vim command in the form of a string, or it can be a lua function:\n\n```lua\n  view = {\n    -- Vim command:\n    [\"a\"] = \"\u003cCmd\u003eechom 'foo'\u003cCR\u003e\",\n    -- Lua function:\n    [\"b\"] = function() print(\"bar\") end,\n  }\n```\n\nFor more control (i.e. mappings for other modes), you can also define index\nvalues as list-like tables containing the arguments for `vim.keymap.set()`.\nThis way you can also change all the `:map-arguments` with the only exception\nbeing the `buffer` field, as this will be overridden with the target buffer\nnumber:\n\n```lua\nview = {\n  -- Normal and visual mode mapping to vim command:\n  { { \"n\", \"v\" }, \"\u003cleader\u003ea\", \"\u003cCmd\u003eechom 'foo'\u003cCR\u003e\", { silent = true } },\n  -- Visual mode mapping to lua function:\n  { \"v\", \"\u003cleader\u003eb\", function() print(\"bar\") end, { nowait = true } },\n}\n```\n\nTo disable any single mapping without disabling them all, set its `{rhs}` to\n`false`:\n\n```lua\n  view = {\n    -- Disable the default normal mode mapping for `\u003ctab\u003e`:\n    [\"\u003ctab\u003e\"] = false,\n    -- Disable the default visual mode mapping for `gf`:\n    { \"x\", \"gf\", false },\n  }\n```\n\nMost of the mapped file panel actions also work from the view if they are added\nto the view maps (and vice versa). The exception is for actions that only\nreally make sense specifically in the file panel, such as `next_entry`,\n`prev_entry`. Actions such as `toggle_stage_entry` and `restore_entry` work\njust fine from the view. When invoked from the view, these will target the file\ncurrently open in the view rather than the file under the cursor in the file\npanel.\n\n**For more details on how to set mappings for other modes, actions, and more see:**\n- `:h diffview-config-keymaps`\n- `:h diffview-actions`\n\n## Restoring Files\n\nIf the right side of the diff is showing the local state of a file, you can\nrestore the file to the state from the left side of the diff (key binding `X`\nfrom the file panel by default). The current state of the file is stored in the\ngit object database, and a command is echoed that shows how to undo the change.\n\n## Tips and FAQ\n\n- **Hide untracked files:**\n  - `DiffviewOpen -uno`\n- **Exclude certain paths:**\n  - `DiffviewOpen -- :!exclude/this :!and/this`\n- **Run as if git was started in a specific directory:**\n  - `DiffviewOpen -C/foo/bar/baz`\n- **Diff the index against a git rev:**\n  - `DiffviewOpen HEAD~2 --cached`\n  - Defaults to `HEAD` if no rev is given.\n- **Q: How do I get the diagonal lines in place of deleted lines in\n  diff-mode?**\n  - A: Change your `:h 'fillchars'`:\n    - (vimscript): `set fillchars+=diff:╱`\n    - (Lua): `vim.opt.fillchars:append { diff = \"╱\" }`\n  - Note: whether or not the diagonal lines will line up nicely will depend on\n    your terminal emulator. The terminal used in the screenshots is Kitty.\n- **Q: How do I jump between hunks in the diff?**\n  - A: Use `[c` and `]c`\n  - `:h jumpto-diffs`\n\n\u003c!-- vim: set tw=80 --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdimfeld%2Fdiffview.nvim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdimfeld%2Fdiffview.nvim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdimfeld%2Fdiffview.nvim/lists"}