diffview.nvim
diffview.nvim copied to clipboard
Allow DiffviewOpen to switch to already opened diffview tab
Currently DiffviewOpen simply opens a new tab with a new Diffview instance even if it was already opened. Sometimes that is what user wants, but it would also be convenient to provide an option, such that DiffviewOpen switches to the already opened Diffview tab if it exists.
Sure, we could add something like a --use-last
option.
I also think, that this might be a good idea. Especially because in the current version the "open file" (default mapping gf
) is somewhat strange.
- I open Diffview, review some changes
- hit
gf
to open the file - do some other edits, maybe switch to another file
- open Diffview again
-> I'd think that I'm back at the "first" Diffview but instead two Diffview tabs are open now.
For me either the mentioned --use-last
or --unique
or something like that would be great, or a new option in the file panel with does "open selected file and quit diffview".
@tuxflo I personally think this is an XY problem, that should probably rather be solved by getting more familiar with tab management in vim. :DiffviewOpen
was never designed to work as a toggle. It seems that you expect the command to operate under a rather arbitrary set of rules. In actuality it's very simple: the command does exactly what it says on the tin. It always opens a diffview in a new tab page.
-> I'd think that I'm back at the "first" Diffview
Why would you think that? You wouldn't call :tabnew
or :tabe
and expect that to operate on the tab you were in before, would you?
In the problem you describe you could've just used :h g<Tab>
to achieve what you wanted. This default mapping brings you back to your last accessed tab page.
or a new option in the file panel with does "open selected file and quit diffview"
You can add this in your own config. The keymap table accepts both functions and vim commands as the rhs
. Just call the goto_file*
action first and then use :tabclose #
to close the view.
I think what's explained by @sindrets can be expressed as below (which works for me).
local actions = require 'diffview.actions'
require('diffview').setup {
keymaps = {
file_panel = {
['gf'] = function()
actions.goto_file()
vim.cmd 'tabclose #'
end,
},
},
}
I originally wanted a toggling behaviour as well but I found a way that avoid the need all together by editing the buffer right at the Diffview tab with the config below.
local actions = require 'diffview.actions'
require('diffview').setup {
keymaps = {
view = {
-- instead of cycle through another buffer, move around window
['<tab>'] = '<Cmd>wincmd w<CR>',
-- instead of closing one buffer, do `DiffviewClose`
['q'] = actions.close,
},
file_panel = {
-- just select them when moving
['j'] = actions.select_next_entry,
['k'] = actions.select_prev_entry,
['<down>'] = actions.select_next_entry,
['<up>'] = actions.select_prev_entry,
-- all of them to just go to the diff2 (right panel) so you can edit right at the Diffview tab
['gf'] = actions.focus_entry,
['<tab>'] = actions.focus_entry,
['<cr>'] = actions.focus_entry,
-- these are extra that also makes sense to me
['h'] = actions.toggle_flatten_dirs,
['l'] = actions.focus_entry,
},
},
}
This allows me to quickly be able to edit via one of gf
, <tab>
, <cr>
.
And q
to close Diffview while editing.
And <tab>
to move around between windows so I can get back to file_panel
to choose other files.
Ideally I would like to close Diffview on file_panel
as well but somehow ['q'] = actions.close
override works for view
but not for file_panel
.
Ideally I would like to close Diffview on
file_panel
as well but somehow['q'] = actions.close
override works forview
but not forfile_panel
.
@ryuheechul Many of the actions - including close
- are contextual. When invoked from a panel this action will close the panel. When invoked from the diff buffers, it will close the entire view. This is documented under :h diffview-actions
.
If you want a mapping to close the view from the file panel, just do this:
require('diffview').setup {
keymaps = {
file_panel = {
["q"] = "<Cmd>tabc<CR>",
},
},
}
@sindrets fantastic and that works like a charm, thanks!
It would be tricky you if you open diffview of different folders in different tabs...
Anyone can point me to a variable that keeps tracks of opened diffview tabs? Thanks!
It would be tricky you if you open diffview of different folders in different tabs...
@hinell What do you mean? What would be tricky?
Anyone can point me to a variable that keeps tracks of opened diffview tabs? Thanks!
require("diffview.lib").views
Keep in mind that using the internal API is not supported, and these things may change at any point without warning.
@sindrets Would be nice if you expose some of these APIs to the users in a stable fashion. Thank you.
@hinell I've stated several times that I'm willing to provide a stable API. But before that can happen we need to discuss specifically what the API should provide. And nobody has taken the initiative to start the discussion. Until that happens, offering any form of a stable API is a non-priority.
For anyone interested, I have similar toggle function with some bits specific to my configuration.
I think what's explained by @sindrets can be expressed as below (which works for me).
local actions = require 'diffview.actions' require('diffview').setup { keymaps = { file_panel = { ['gf'] = function() actions.goto_file() vim.cmd 'tabclose #' end, }, }, }
Wondering if this is something that can be passed as opts
:
require("diffview.actions").goto_file_edit( {close_diffview = true} )
I just think it makes the keymaps read nicer.
@kevintraver I think the point of the OP is to ALWAYS keep a diffview window and focus on it whenever the :DiffviewOpen
is run in given CWD
. For several different working dirs there might be one diffview stuck.