sindrets / diffview.nvim

Single tabpage interface for easily cycling through diffs for all modified files for any git rev.
Other
3.57k stars 101 forks source link

[Bug] Diffview somehow doesn't restore buffer local keymaps on close #442

Open wustho opened 7 months ago

wustho commented 7 months ago

Description

I have this keymaps setting for buffer on lsp attach

vim.api.nvim_create_autocmd('LspAttach', {
    callback = function(ev)
        local bufnr = ev.buf
        map('n', '<leader>e', '<CMD>Trouble document_diagnostics<CR>',
            { desc = 'Buffer diagnostics', buffer = bufnr }) -- vim.diagnostic.setloclist
    end
})

and my diffview config in the minimal config section below.

Whenever I enter diffview using DiffviewOpen, then focus the cursor on all available windows (file panel, and 2 diff windows) then close it either with tabc or DiffviewClose. Somehow my <leader>e keymap set above disappear.

Expected behavior

Diffview should restore buffer keymaps

Actual behavior

Seems like diffview override my buffer keymap <leader>e to focus file panel action, but not restoring it on close.

Steps to reproduce

  1. Map something with <leader>e to buffer: nmap <buffer> <leader>e :lua vim.notify("test")<CR>
  2. Make changes to current buffer and save, so that it will appear as modified git file.
  3. Open diffview: DiffviewOpen
  4. (Optionally) focus on all windows on diff view
  5. Close diffview: DiffviewClose
  6. Somehow map set in step 1 missing

Health check

Output of :checkhealth diffview ``` ============================================================================== diffview: require("diffview.health").check() Checking plugin dependencies ~ - OK nvim-web-devicons installed. Checking VCS tools ~ - The plugin requires at least one of the supported VCS tools to be valid. - OK Git found. - OK Git is up-to-date. (2.39.1) - WARNING Configured `hg_cmd` is not executable: 'hg' ```

Log info

Relevant info from :DiffviewLog ``` [INFO 2023-11-22 30:02:58.921 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:02:59.051 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 1 files successfully (50.062 ms) [INFO 2023-11-22 30:03:29.514 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:74: [command call] :DiffviewFileHistory % [INFO 2023-11-22 30:03:29.621 +0700] ...azy/diffview.nvim/lua/diffview/vcs/adapters/git/init.lua:884: [FileHistory] Updating with options: { flags = { "--follow", "-n256", "--diff-merges=first-parent" }, path_args = { "bases/pureprofile/admin_site/feasibility/helpers.py" } } [INFO 2023-11-22 30:03:30.112 +0700] ...diffview/scene/views/file_history/file_history_panel.lua:248: [FileHistory] Completed update for 22 entries successfully (495.414 ms). [INFO 2023-11-22 30:03:37.090 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:03:37.227 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 1 files successfully (51.585 ms) [INFO 2023-11-22 30:04:33.391 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:04:33.529 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 1 files successfully (51.752 ms) [INFO 2023-11-22 30:05:39.595 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:05:39.745 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 1 files successfully (59.758 ms) [INFO 2023-11-22 30:08:24.379 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:08:24.534 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 1 files successfully (61.965 ms) [INFO 2023-11-22 30:13:08.741 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:13:08.870 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 1 files successfully (45.271 ms) [INFO 2023-11-22 30:13:15.082 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:13:15.246 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 1 files successfully (47.118 ms) [INFO 2023-11-22 30:17:04.176 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:17:04.324 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 1 files successfully (51.876 ms) [INFO 2023-11-22 30:17:07.308 +0700] ...share/nvim/lazy/diffview.nvim/lua/diffview/vcs/utils.lua:166: File restored from index. Undo with :sp ~/Projects/backend-services/bases/pureprofile/admin_site/feasibility/helpers.py | %!git show 8a2694c80f9 [INFO 2023-11-22 30:17:07.421 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 0 files successfully (112.775 ms) [INFO 2023-11-22 30:17:07.509 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 0 files successfully (60.195 ms) [INFO 2023-11-22 30:21:40.232 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:21:40.372 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 0 files successfully (42.185 ms) [INFO 2023-11-22 30:21:43.210 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:21:43.352 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 0 files successfully (34.617 ms) [INFO 2023-11-22 30:21:50.130 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:21:50.301 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 1 files successfully (52.511 ms) [INFO 2023-11-22 30:32:52.017 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:32:52.208 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 1 files successfully (56.793 ms) [INFO 2023-11-22 30:33:09.885 +0700] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-11-22 30:33:10.062 +0700] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 1 files successfully (53.734 ms) [ERROR 2023-11-22 30:36:07.124 +0700] ...lazy/diffview.nvim/lua/diffview/vcs/adapters/hg/init.lua:53: [HgAdapter] Configured `hg_cmd` is not executable: 'hg' ```

Neovim version

NVIM v0.9.4
Build type: Release
LuaJIT 2.1.1692716794

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/__w/neovim/neovim/build/nvim.AppDir/usr/share/nvim"

Run :checkhealth for more info

Operating system and version

Linux 6.2.0-36-generic x86_64 GNU/Linux

Minimal config

{
        'sindrets/diffview.nvim',
        cmd = { 'DiffviewOpen', 'DiffviewFileHistory' },
        config = function()
            local actions = require('diffview.actions')

            require('diffview').setup({
                enhanced_diff_hl = false,
                use_icons = false,
                show_help_hints = false,
                signs = {
                    fold_closed = 'ï‘  ',
                    fold_open = ' ',
                    done = '✓',
                },
                file_panel = {
                    listing_style = 'tree',
                    -- listing_style = 'list',
                    -- win_config = {
                    --   position = 'bottom',
                    --   height = 16,
                    -- type = 'float'
                    -- },
                },
                -- https://github.com/sindrets/diffview.nvim/issues/143
                hooks = {
                    diff_buf_win_enter = function(bufnr, winid, ctx)
                        vim.opt_local.signcolumn = 'no'
                    end,
                    view_enter = function()
                        require('barbecue.ui').toggle(false)
                    end,
                    view_leave = function()
                        require('barbecue.ui').toggle(true)
                    end,
                },
                -- https://github.com/sindrets/diffview.nvim/issues/348
                -- view = {
                --     default = {
                --         winbar_info = true,
                --     },
                --     file_history = {
                --         winbar_info = true,
                --     },
                -- },
                keymaps = {
                    -- disable_defaults = false,
                    view = {
                        -- { 'n', 'q', '<CMD>tabclose<CR>', { desc = 'Close' } },
                        { 'n', '<C-q>', '<CMD>DiffviewClose<CR>', { desc = 'Close' } },
                        { 'n', 'q', '<CMD>DiffviewClose<CR>', { desc = 'Close' } },
                        { 'n', 'J', actions.scroll_view(1), { desc = 'Scroll Down' } },
                        { 'n', 'K', actions.scroll_view(-1), { desc = 'Scroll Up' } },
                    },
                    file_panel = {
                        -- { 'n', 'q', '<CMD>tabclose<CR>', { desc = 'Close' } },
                        { 'n', '<C-q>', '<CMD>DiffviewClose<CR>', { desc = 'Close' } },
                        { 'n', 'q', '<CMD>DiffviewClose<CR>', { desc = 'Close' } },
                        { 'n', 'J', actions.scroll_view(1), { desc = 'Scroll Down' } },
                        { 'n', 'K', actions.scroll_view(-1), { desc = 'Scroll Up' } },
                    },
                    file_history_panel = {
                        -- { 'n', 'q', '<CMD>tabclose<CR>', { desc = 'Close' } },
                        { 'n', '<C-q>', '<CMD>DiffviewClose<CR>', { desc = 'Close' } },
                        { 'n', 'q', '<CMD>DiffviewClose<CR>', { desc = 'Close' } },
                        { 'n', 'J', actions.scroll_view(1), { desc = 'Scroll Down' } },
                        { 'n', 'K', actions.scroll_view(-1), { desc = 'Scroll Up' } },
                    }
                }
            })
        end
    },
isakbm commented 1 week ago

Should I open another issue, or is the following behavior similar enough to this original issue description:

  1. create the following keymap
vim.keymap.set('n', '<leader>JJ', function()
  print 'registering leader>ca'
  local buf = vim.api.nvim_get_current_buf()
  vim.keymap.set('n', '<leader>ca', function()
    print 'code action ...'
    -- vim.lsp.buf.code_action()
  end, { buffer = buf, desc = '[C]ode [A]ction' })
end)
  1. open a file and do <leader>JJ followed by <leader>ca , it works and you see "code action ..."
  2. open diffview :DiffviewOpen
  3. close diffview :DiffviewClose
  4. now you're back in the original buffer and you can try <leader>ca which no longer prints "code action ..." since it is still somehow triggering the "diffview local" keymap <leader>ca.

I find this behavior confusing since reading the Diffview source, I see that there's code in there specifically intending to remove all Diffview related keymaps when a buffer is left or destroyed, but this code is apparently not called.

I could try to look into this and figure out a fix if nobody else is.

NOTE: perhaps it's not possible to fix this due to limitations of buffer local keymaps? nvim apis would need to support the ability to restore some older buffer local keymap 🤔 ?

isakbm commented 1 week ago

Maybe related.

When exiting diffview, which-key will still list all buffer local keybindings even though they were deleted.

isakbm commented 1 week ago

https://github.com/sindrets/diffview.nvim/issues/382

opened but ignored ...

yungthai commented 3 days ago

I briefly looked into this issue ...

NOTE: perhaps it's not possible to fix this due to limitations of buffer local keymaps? nvim apis would need to support the ability to restore some older buffer local keymap 🤔 ?

It may be possible using the functions maparg and mapset for the affected buffer mappings?

So prior to calling vim.keymap.set(...), check for the same keymap for the bufid and if it already exists, save it to a table. Ensure the bufid is saved with each table entry.

Then restore all the keymaps from that table with mapset prior to closing Diffview. I am just not sure where would a sensible place to hold this table.

I find this behavior confusing since reading the Diffview source, I see that there's code in there specifically intending to remove all Diffview related keymaps when a buffer is left or destroyed, but this code is apparently not called.

Would you please point me to the relevant sections where this is done?