Skip to content
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

Handle special windows #78

Open
naquad opened this issue Oct 13, 2022 · 13 comments
Open

Handle special windows #78

naquad opened this issue Oct 13, 2022 · 13 comments
Labels
enhancement New feature or request

Comments

@naquad
Copy link

naquad commented Oct 13, 2022

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 naquad added the enhancement New feature or request label Oct 13, 2022
@kevinhwang91
Copy link
Owner

How to choose the previous window then?

@naquad
Copy link
Author

naquad commented Oct 13, 2022

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)

@kevinhwang91
Copy link
Owner

pwinid = fn.win_getid(fn.winnr('#'))
if not isValid(pwinid) then
local tabpage = api.nvim_win_get_tabpage(winid)
for _, owinid in ipairs(api.nvim_tabpage_list_wins(tabpage)) do
if isNormalWinType(owinid) then
pwinid = owinid
break
end
end

Unfortunately, there isn't a way to get the list of accessed windows in a tabpage, only the last accessed window by winnr('#')

@naquad
Copy link
Author

naquad commented Oct 14, 2022

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.

@kevinhwang91
Copy link
Owner

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.

@naquad
Copy link
Author

naquad commented Oct 14, 2022

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.

@kevinhwang91 kevinhwang91 reopened this Oct 14, 2022
@kevinhwang91
Copy link
Owner

nvim-bqf will cache the previous window after entering qf window.

local pwinid = qs:previousWinid()

function QfSession:previousWinid()
if not utils.isWinValid(self._pwinid) or fn.win_gettype(self._pwinid) ~= '' then
self._pwinid = getPwinid(self.winid, self._list)
end
return utils.isWinValid(self._pwinid) and self._pwinid or -1
end

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.

@naquad
Copy link
Author

naquad commented Oct 14, 2022

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

asciicast

@kevinhwang91
Copy link
Owner

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

@naquad
Copy link
Author

naquad commented Oct 14, 2022

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.

@kevinhwang91
Copy link
Owner

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.

@naquad
Copy link
Author

naquad commented Oct 15, 2022

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.

@kevinhwang91
Copy link
Owner

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants