nvim-bqf icon indicating copy to clipboard operation
nvim-bqf copied to clipboard

Handle special windows

Open naquad opened this issue 1 year ago • 13 comments

Feature description

Currently, if NvimTree is open and a split is requested the split will happen in the NvimTree window (if it is the previous window) rather than the editing one.

This is how it looks: image

Add handling of special buffer types and do not split them.

Describe the solution you'd like

Add a configuration parameter that would indicate which buffer types should be ignored. It can be either a table of file types or a callback receiving a buffer number returning a boolean if it can be split.

Additional context

No response

naquad avatar Oct 13 '22 20:10 naquad

How to choose the previous window then?

kevinhwang91 avatar Oct 13 '22 22:10 kevinhwang91

Iterate backward from the last to the first available, if there's nothing available then create a window and use it. Maybe not the best solution, but "practicality beats purity" (c)

naquad avatar Oct 13 '22 22:10 naquad

https://github.com/kevinhwang91/nvim-bqf/blob/c33b5c57ff82d71f8004b37c8c17a7928da76d08/lua/bqf/qfwin/session.lua#L24-L32 Unfortunately, there isn't a way to get the list of accessed windows in a tabpage, only the last accessed window by winnr('#')

kevinhwang91 avatar Oct 13 '22 22:10 kevinhwang91

Just modify the isNormalWinType to check if the filetype is in the user-provided exclusion list or call a user-defined predicate. The solution won't be perfect but it will be still better that the current behavior. Currently, when the split opens in the NvimTree I need to: close the split, navigate to the target window, open quickfix again, and open the file again. Split in the wrong window is not that bad.

naquad avatar Oct 14 '22 06:10 naquad

Wrap cw by yourself. If the current buffer is like nvimtree:

call win_execute(win_getid(winnr('#')), 'bo cw')

This solution is better both for you and nvim-bqf.

kevinhwang91 avatar Oct 14 '22 10:10 kevinhwang91

How does that help? In case I have quickfix open and I switch between windows with <C-w> NvimTree or some other panel may get in the way and become the last window, :bo cw is not a solution.

naquad avatar Oct 14 '22 11:10 naquad

nvim-bqf will cache the previous window after entering qf window. https://github.com/kevinhwang91/nvim-bqf/blob/c33b5c57ff82d71f8004b37c8c17a7928da76d08/lua/bqf/main.lua#L41 https://github.com/kevinhwang91/nvim-bqf/blob/c33b5c57ff82d71f8004b37c8c17a7928da76d08/lua/bqf/qfwin/session.lua#L53-L58

Add below code snippet in ~/.config/nvim/ftplugin/qf.vim

function ChooseLastWin(winid) abort
    for owinid in nvim_tabpage_list_wins(nvim_win_get_tabpage(a:winid))
        if a:winid != owinid && win_gettype(owinid) == ''
            return owinid
        endif
    endfor
    return -1
endfunction

let lastWinid = win_getid(winnr('#'))
let lastBufnr = nvim_win_get_buf(lastWinid)
if nvim_buf_get_option(lastBufnr, 'filetype') == 'NvimTree'
    let curWinid = nvim_get_current_win()
    let lastWinid = ChooseLastWin(lastWinid)
    if lastWinid != -1
        noa call nvim_set_current_win(lastWinid)
        noa call nvim_set_current_win(curWinid)
    end
end

~/.config/nvim/ftplugin/qf.lua is buggy that doesn't before after/ftplugin, bqf is fired under after/ftplugin.

kevinhwang91 avatar Oct 14 '22 12:10 kevinhwang91

Nice hack. Unfortunately, it works only once, so:

asciicast

naquad avatar Oct 14 '22 12:10 naquad

No idea why doesn't work for you, add echom for the snippet code to check out whether the code has run may help.

kevinhwang91 avatar Oct 14 '22 12:10 kevinhwang91

It works when the quickfix opens, but after I navigate through other windows it stops working.

P. S. There are quite a few plugins out there that create their own windows with a special purpose and should not be modified by other plugins. There's a really high chance that bqf will be used in conjunction with one of them, so providing a way to skip particular windows makes sense even if the handling won't be perfect.

naquad avatar Oct 14 '22 12:10 naquad

It works when the quickfix opens, but after I navigate through other windows it stops working.

I can't reproduce it, I think this script should work for you.

There's a really high chance that bqf will be used in conjunction with one of them

Not at all, bqf has been created for more than one year, this is the first issue for that. For me, I never run qf under a special window.

As a maintainer of a plugin, exposing an unperfect config for users is not a good idea. The behavior of this config is difficult to be understood correctly, at least for unprofessional users.

kevinhwang91 avatar Oct 15 '22 01:10 kevinhwang91

I can't reproduce it, I think this script should work for you. Screencast shows it doesn't :(

As a maintainer of a plugin, exposing an unperfect config for users is not a good idea. The behavior of this config is difficult to be understood correctly, at least for unprofessional users.

Well, as a user I don't agree that a separate hack is better than at least some kind of handling in the plugin itself. But your plugin your rules. Given, all the cool features, I think it's worth to continue the discussion.

So, let's switch the approach.

To enhance the plugin flexibility and allow power users to implement their own layouting, please expose a function in the configuration that will take care of the file opening:

local function user_defined_opener(how, path, line, col)
  -- @param how string one of: split, vsplit, previous [window], [new] tab
  -- @param path string file to be opened
  -- line & col define position in the file
end

require('bqf').setup {
  opener = user_defined_opener,
  -- ...
}

This is a somewhat improved version of QFEnter's custom functions to specify a target window.

naquad avatar Oct 15 '22 07:10 naquad

Make sense. Actually, I'm not very interested in this feature, but PR is welcome.

kevinhwang91 avatar Oct 15 '22 22:10 kevinhwang91