So, I faced a need to check a type of a window and a buffer when entering a new window so I can do some stuff automatically depending on the types of aforementioned stuff.
For example, when quickfix
is opened, I need to know that it is it, the same with command
window, help
, etc. Putting it in other words - I need to know when the new window opened is a regular window with a regular buffer in it.
The only ways that I wound was a combination of win_gettype()
and &buftype
options.
First thing I tried was an obvious WinEnter
event, which didn't work properly as I couldn't check the type of a buffer.
Then, I tried BufEnter
, but that wouldn't catch :split
without arguments, apparently in a way similar to BufWinEnter
. In addition, that wouldn't catch quickfix
when it is opened for the first time and command
.
So, coming to the question - is there any reliable way to validate window's and buffer's type automatically when a new window is opened without taking into account the way it was opened in? To summarize - there are two problems - 1) cannot catch a window at all if it is opened with :split
without arguments, 2) cannot catch types reliably (see Edit 2).
EDIT 4
Well, with EDIT 3 taken into account, WinEnter
works properly and as expected. But this is still a huge workaround. Will leave the question open in case anybody has an adequate solution.
EDIT 3
Well, I cannot see how to check things from EDIT 2 below upon window or buf entrance, but I guess it is possible to check them once again afterwords. I've come up with an idea to catch terminal
with TerminalOpen
, check command
once again with CmdWinEnter
, and fixquickfix
problem with checking its' filetype
with, well, FileType
. These are huge workarounds, but I cannot see another way of solving this yet. Unfortunatelly, :split
problem is still a thing.
EDIT 2
I've elaborated a bit on the main question and played a bit more with all this stuff. It seems like command line
is caught. But terminal behavior is weird. So, behavior of different windows with WinEnter
and BufEnter
is as follows:
|Window |WinEnter|BufEnter|
|:---------|:-------|:-------|
|quickfix | - |+, 2 |
|command | - | + |
|help | - | + |
|terminal | +, 1 |+, 1 |
1 - but only if another terminal window is opened (the first one is not being caught);
2 - but fails for the first time after Vim startup.
Sorry for the table, it forces me to indent it for some reason, and it breaks all the pretty visuals on the page.
EDIT 1
Adding a snippet of code. The whole idea of what I am trying to do is storing an information about all the windows currently opened that are regular windows with regular buffers. Each time new window is opened or an old window is closed I need this info to be updated automatically. The core code is below:
function HandleNewWindow()
let winid = win_getid()
let wi = getwininfo(winid)[0]
let bufnr = wi.bufnr
if !CorrectBufAndWinTypes(bufnr, winid)
return 1
else
" add winid to the list of regular windows' IDs
endif
endfunction
function CorrectBufAndWinTypes(bufnr, winid)
let wt = win_gettype(a:winid)
let bt = getbufvar(a:bufnr, "&buftype")
let wi = getwininfo(a:winid)[0]
let is_terminal = wi.terminal
let is_quickfix = wi.quickfix
echom "WT - " wt "BT - " bt is_terminal is_quickfix
if wt !=? "" || bt !=? "" || is_terminal || is_quickfix
return 0
else
return 1
endif
endfunction
" I was trying to handle it with the autocommands below:
" autocmd BufEnter * call HandleNewWindow()
" cannot detect quickfix window at first try
" (subsequent tries are positive, though)
" can detect help, but only via &buftype
" autocmd WimEnter * call HandleNewWindow()
" cannot detect quickfix at all
" cannot detect help at all
" both cannot handle command window (q:)