-
-
Notifications
You must be signed in to change notification settings - Fork 169
Fork changes (v0.10) #609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fork changes (v0.10) #609
Conversation
Add --no-show-signature flag to git log and show commands to prevent GPG signature output from interfering with parsing. This fixes issues when users have log.showSignature enabled in their git config. Fixes sindrets#537
Only expand environment variables in paths when the variable is actually defined. Previously, undefined variables would be replaced with their literal name (e.g., $FOO -> FOO), which could cause unexpected behaviour with paths containing dollar signs. Fixes sindrets#556
) Show untracked files when the right side of the comparison is the working tree (LOCAL), not just when comparing index vs working tree. This allows seeing untracked files in more diff scenarios. Fixes sindrets#584
When running `git rebase -i --root`, the initial commit has no parent, so `git merge-base` fails. Instead of crashing with an assertion error, gracefully handle this by using the empty tree SHA as the base. Fixes sindrets#576
Add support for mini.icons as an alternative to nvim-web-devicons for file icons. The plugin will try nvim-web-devicons first, then fall back to mini.icons if available.
Add q and <esc> keymaps to close the commit log panel, matching the behaviour of other panels like the help panel. The keymaps are configurable via keymaps.commit_log_panel. Fixes sindrets#481
…drets#606) Use the unnamed register (") instead of the system clipboard (+) when copying commit hashes. This is more consistent with Vim conventions and works regardless of clipboard support. Fixes sindrets#604
Add nil check for comp.context before accessing mapping property. Pressing <CR> on the first line of the help panel no longer errors. Fixes sindrets#469
Requiring diffview.lib directly without going through diffview.bootstrap would fail with "attempt to index global 'DiffviewGlobal' (a nil value)". Now lib.lua explicitly requires bootstrap to ensure initialisation. Fixes sindrets#511
Some colorschemes don't define diffAdded/diffRemoved/diffChanged until the diff filetype is encountered. Now we explicitly load the diff syntax file if these highlight groups don't exist, ensuring our highlight links work correctly. Fixes sindrets#351
Makes it more visually clear which items are directories, especially when not using folder icons. Closes sindrets#247
Users can now set `file_panel.show = false` to have the file panel hidden by default when opening Diffview. The panel can still be toggled using the toggle_files action. Closes sindrets#303
When multiple git operations run concurrently (e.g., staging files while other plugins like nvim-tree also make git calls), lock contention can cause significant slowdowns. Setting GIT_OPTIONAL_LOCKS=0 tells git to skip optional locking, improving performance. Fixes sindrets#535
Allows users to bind keys to specific layouts directly instead of cycling through all layouts.
The explicit definition with a "White" fallback caused invisible filenames on light colorschemes. FilePanelFileName is already linked to Normal in hl_links, which correctly inherits the theme's text color.
Use consistent highlighting for fold indicators across all views. Previously FileHistory used CursorLineNr which didn't match the rest of the UI.
Allow users to configure the maximum length for commit subject display in the file history panel. Defaults to 72 characters.
Added "Recommended Keymaps" section with common patterns: - Toggle diffview open/close - File/line/range history - Diff against main/master branch Added tips for merge-base comparisons, Neogit integration, and line evolution tracing.
Display a friendly message in the file panel when there are no changes to show instead of just an empty section.
Added view.cycle_layouts config with default and merge_tool presets to allow users to specify which layouts to cycle through. Resolves sindrets#336
Added section showing how to use Telescope for branch and commit selection when opening diffview. Resolves sindrets#279
When enabled, Changes and Staged changes sections are always shown in the file panel even when empty. Resolves sindrets#478
Uses xdg-open on Linux, open on macOS, and start on Windows. Default keymap is 'gx' matching vim's convention. Resolves sindrets#456
…ry (sindrets#569) Adds a new action diff_against_head that opens a diffview comparing HEAD with the commit under cursor in the file history panel. Bound to 'H' by default.
Save and restore the collapsed state of directory nodes when file trees are recreated. This prevents folders from expanding when switching tabs.
…ets#330) - Use window-local options (vim.wo) instead of global options (vim.o) when saving window options before opening a diff - Add explicit winopts to NULL_FILE to disable diff-related settings (scrollbind, cursorbind, etc.) preventing option cascading
- Set foldlevel=99 to keep folds open by default, preventing issues with plugins like vim-markdown that create section folds - Add explicit jump to first diff hunk when opening files, since the previous behaviour of showing the first diff was a side effect of foldlevel=0 folding away unchanged lines - Add Plugin Compatibility section to README
Diagnostics only work for working tree (LOCAL) buffers because LSP servers don't attach to non-file buffers (buftype=nowrite). When comparing commits like `main..HEAD`, users should use `DiffviewOpen main` to see diagnostics on the working tree side.
The default keymaps (<leader>e, <leader>b, <leader>c*) may conflict with user configurations. Rather than changing defaults (breaking change), document how to override them with localleader or disable them entirely.
Remove trailing periods from two keymap descriptions for consistency. All descriptions now use sentence fragments without trailing periods. Also document technical debt in OPEN_ISSUES.md: - Deprecated nvim_buf_set_option/get_option API calls - FIXME comments for null handling and Mercurial limitations
PR sindrets#587 changed the condition to show untracked files whenever the right side is LOCAL (working tree). This caused untracked files to appear when running `DiffviewOpen <commit>`, which compares a commit to the working tree. Restore the original behaviour: only show untracked files when comparing STAGE (index) vs LOCAL (working tree), i.e. standard `DiffviewOpen`.
* refactor: bump minimum Neovim version to 0.10 * fix(layouts): implement proper should_null for Diff1 * fix(api): use left_null/right_null in CDiffView * feat(sindrets#485): add pushed/unpushed commit colour distinction in file history * feat(sindrets#207): add configurable diffopt overrides
…ions (#12) Restructure Plugin Compatibility into Companion Plugins with Recommended and Known Issues subsections. Add links to all external plugins at first mention. Add character-level highlighting tip pointing to diffchar.vim.
…hting for deletions (#13)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR integrates community-maintained changes from the dlyongemallo/diffview.nvim fork (v0.10 release), addressing the inactivity of the original repository since June 2024. It includes 24 bug fixes, 30 new features, performance improvements, and breaking changes.
Changes:
- Bumps minimum Neovim version requirement to 0.10.0 and replaces all deprecated APIs
- Adds 24 bug fixes for crashes, nil guards, race conditions, scrollbind persistence, and keymap handling
- Introduces 30 new features including DiffviewToggle command, merge-base support, mini.icons compatibility, commit browser integration, and extensive configuration options
- Implements performance improvements (GIT_OPTIONAL_LOCKS=0) and comprehensive documentation updates
Reviewed changes
Copilot reviewed 46 out of 46 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| plugin/diffview.lua | Adds DiffviewToggle command |
| lua/diffview/vcs/utils.lua | Implements merge artifact filtering functionality |
| lua/diffview/vcs/log_entry.lua | Adds remote ref detection for commits |
| lua/diffview/vcs/file_dict.lua | Preserves collapsed state when updating file trees |
| lua/diffview/vcs/file.lua | Adds buffer tracking, keymap save/restore, inlay hint management, and null buffer window options |
| lua/diffview/vcs/adapters/{git,hg}/init.lua | Adds branch name retrieval, remote URL handling, commit URL construction, merge-base support, and --no-show-signature flags |
| lua/diffview/utils.lua | Adds vec_extend helper, updates deprecated APIs (vim.loop → vim.uv, vim.islist) |
| lua/diffview/ui/panels/*.lua | Implements commit log panel keymaps and help panel nil guards |
| lua/diffview/ui/models/file_tree/*.lua | Adds custom sort comparator support and collapsed state management |
| lua/diffview/scene/*.lua | Implements diffopt management, buffer flash prevention, custom fold limits, context plugin disabling, and cursor position restoration |
| lua/diffview/scene/views//.lua | Adds loading indicators, branch name display, stat styling, commit formatting, panel cursor persistence, and buffer cleanup |
| lua/diffview/scene/layouts/diff_1.lua | Implements should_null logic for single-pane layouts |
| lua/diffview/path.lua | Fixes environment variable expansion to handle undefined variables correctly |
| lua/diffview/logger.lua, lua/diffview/perf.lua, lua/diffview/job.lua, etc. | Updates vim.loop → vim.uv throughout |
| lua/diffview/init.lua | Adds toggle functionality and uses vec_extend for better performance |
| lua/diffview/hl.lua | Adds mini.icons support, status icon configuration, removes pre-0.10 compatibility code |
| lua/diffview/health.lua | Updates minimum version check to 0.10 and adds mini.icons to dependencies |
| lua/diffview/debounce.lua | Wraps timer callbacks in vim.schedule to prevent E5560 errors |
| lua/diffview/config.lua | Adds extensive new configuration options for features, icons, behaviors, and layouts |
| lua/diffview/bootstrap.lua | Updates minimum version check to 0.10 |
| lua/diffview/async.lua, lua/diffview/ffi.lua | Updates to Neovim 0.10 APIs |
| lua/diffview/actions.lua | Adds open_file_external, open_in_new_tab, diff_against_head, set_layout, and other new actions |
| lua/diffview/api/views/diff/diff_view.lua | Improves file entry creation with proper null handling |
| doc/*.txt | Updates documentation for new commands, options, and features |
| README.md | Adds fork notice, recommended keymaps, tips, and companion plugin documentation |
| .github/ISSUE_TEMPLATE/bug_report.yml | Updates colorscheme fallback |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if target ~= nil then | ||
| api.nvim_win_set_cursor(target.id, cursor) |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent indentation. Line 312 uses 4 spaces but line 311 uses 2 spaces. This should be consistent with the rest of the codebase which uses 2-space indentation.
| if env_var and uv.os_getenv(env_var) ~= nil then | ||
| segments[i] = uv.os_getenv(env_var) |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition checks if the environment variable is not nil, but then unconditionally calls uv.os_getenv(env_var) again to get the value. This results in two calls to uv.os_getenv for each variable. Consider storing the result in a local variable to avoid the duplicate call: local value = uv.os_getenv(env_var); if value ~= nil then segments[i] = value end
| if env_var and uv.os_getenv(env_var) ~= nil then | |
| segments[i] = uv.os_getenv(env_var) | |
| if env_var then | |
| local value = uv.os_getenv(env_var) | |
| if value ~= nil then | |
| segments[i] = value | |
| end |
| ---@type string[]? Saved diffopt value before diffview applied overrides. | ||
| local saved_diffopt | ||
|
|
||
| -- Boolean diffopt flags that can be toggled. | ||
| local diffopt_bool_flags = { | ||
| "indent-heuristic", "iwhite", "iwhiteall", "iwhiteeol", "iblank", "icase", | ||
| } | ||
|
|
||
| ---Apply configured diffopt overrides, saving the original value first. | ||
| local function apply_diffopt() | ||
| local conf = config.get_config().diffopt | ||
| if not conf or vim.tbl_isempty(conf) then return end | ||
|
|
||
| if not saved_diffopt then | ||
| saved_diffopt = vim.opt.diffopt:get() | ||
| end | ||
|
|
||
| if conf.algorithm then | ||
| -- Remove any existing algorithm:* entry and add the new one. | ||
| vim.opt.diffopt:remove( | ||
| vim.tbl_filter(function(v) return v:match("^algorithm:") end, vim.opt.diffopt:get()) | ||
| ) | ||
| vim.opt.diffopt:append({ "algorithm:" .. conf.algorithm }) | ||
| end | ||
|
|
||
| if conf.context ~= nil then | ||
| vim.opt.diffopt:remove( | ||
| vim.tbl_filter(function(v) return v:match("^context:") end, vim.opt.diffopt:get()) | ||
| ) | ||
| vim.opt.diffopt:append({ "context:" .. conf.context }) | ||
| end | ||
|
|
||
| for _, flag in ipairs(diffopt_bool_flags) do | ||
| -- Convert config key (underscore-separated) to diffopt flag (hyphenated). | ||
| local key = flag:gsub("-", "_") | ||
| if conf[key] ~= nil then | ||
| if conf[key] then | ||
| vim.opt.diffopt:append({ flag }) | ||
| else | ||
| vim.opt.diffopt:remove({ flag }) | ||
| end | ||
| end | ||
| end | ||
| end | ||
|
|
||
| ---Restore the original diffopt value. | ||
| local function restore_diffopt() | ||
| if saved_diffopt then | ||
| vim.opt.diffopt = saved_diffopt | ||
| saved_diffopt = nil | ||
| end | ||
| end |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The saved_diffopt is a module-level variable that persists across multiple view instances. If multiple diffview tabs are opened in sequence, only the first one will save the original diffopt. If views are opened/closed in different orders, this could lead to diffopt not being restored to the original value. Consider using a stack or making saved_diffopt view-specific to handle multiple concurrent views correctly.
| if config.get_config().clean_up_buffers then | ||
| for bufnr, _ in pairs(File.created_bufs) do | ||
| if api.nvim_buf_is_valid(bufnr) and not vim.bo[bufnr].modified then | ||
| local dominated = true | ||
| for _, winid in ipairs(utils.win_find_buf(bufnr, 0)) do | ||
| if api.nvim_win_get_tabpage(winid) ~= self.tabpage then | ||
| dominated = false | ||
| break | ||
| end | ||
| end | ||
|
|
||
| if dominated then | ||
| pcall(api.nvim_buf_delete, bufnr, { force = false }) | ||
| end | ||
| end | ||
|
|
||
| File.created_bufs[bufnr] = nil | ||
| end |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The buffer cleanup logic unconditionally deletes entries from File.created_bufs even when buffers fail to delete or when clean_up_buffers is false. This means if a buffer deletion fails (e.g., buffer has unsaved changes despite the modified check), the tracking is lost and the buffer won't be cleaned up on subsequent closes. Consider moving line 94 (File.created_bufs[bufnr] = nil) inside the if dominated then block, or only removing it after successful deletion.
| if host:match("github") then | ||
| return fmt("https://%s/%s/commit/%s", host, repo, commit_hash) | ||
| elseif host:match("gitlab") then | ||
| return fmt("https://%s/%s/-/commit/%s", host, repo, commit_hash) | ||
| elseif host:match("bitbucket") then | ||
| return fmt("https://%s/%s/commits/%s", host, repo, commit_hash) | ||
| else | ||
| -- Generic format (works for many Git hosting services). | ||
| return fmt("https://%s/%s/commit/%s", host, repo, commit_hash) |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The URL pattern matching uses simple substring matching with host:match("github"). This could incorrectly match hostnames like "mygithubclone.com" or "github.example.com" which are not GitHub. Consider using more specific patterns like host:match("github%.com$") or host:match("^github%.com$") to match only the actual service domains. Same issue applies to "gitlab" and "bitbucket" patterns.
| @@ -1,5 +1,7 @@ | |||
| # Diffview.nvim | |||
|
|
|||
| > **Note:** This is a fork of [sindrets/diffview.nvim](https://github.com/sindrets/diffview.nvim) with bug fixes and improvements applied. The original repository has not been updated since June 2024. | |||
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The note mentions "The original repository has not been updated since June 2024", but this should be updated periodically or removed before merging since the statement will become outdated. Consider using a relative time description or linking to a more detailed fork explanation elsewhere.
| > **Note:** This is a fork of [sindrets/diffview.nvim](https://github.com/sindrets/diffview.nvim) with bug fixes and improvements applied. The original repository has not been updated since June 2024. | |
| > **Note:** This is a fork of [sindrets/diffview.nvim](https://github.com/sindrets/diffview.nvim) with additional bug fixes and improvements applied. |
|
Closing in favour of a new PR from a dedicated branch. |
Sorry, replaced by #610.