[vim/vim] How can we distinguish normal windows and aucmd_win? (#6264)

20 views
Skip to first unread message

itchyny

unread,
Jun 15, 2020, 12:22:55 PM6/15/20
to vim/vim, Subscribed

Is your feature request about something that is currently impossible or hard to do? Please describe the problem.
The :doautoall command uses the temporary window (aucmd_win) for a buffer which does not belong to the visible windows. But we cannot distinguish the temporary window for :doautoall and normal windows.

:autocmd BufEnter * echom [bufname(), winnr(), winnr('$')]

:edit a
" ['a', 1, 1]
:tabnew b
" ['b', 1, 1]

" We expect winnr('$') always returns the window count, however
:doautoall BufEnter
" ['a', 1, 2] => winnr('$') returns 2 due to aucmd_win
" ['b', 1, 1]

:autocmd! BufEnter *

:autocmd BufEnter * echom map(range(1, winnr('$')), '[bufname(winbufnr(v:val)), winnr() == v:val]')

:doautoall BufEnter
" [['a', 1], ['b', 0]]
" [['b', 1]]

:tabp
" [['a', 1]]

" We expect that the window number is equal to winnr() only for the active window, however
:doautoall BufEnter
" [['a', 1]]
" [['b', 1], ['a', 0]] " => The 'b' buffer is associated with aucmd_win

This behavior confuses plugins which assume that winnr() always returns the active window number, but this is incorrect due to :doautoall command. This happens with any events because :doautoall does not restrict the event to emit. User can :doautoall FileType or even :doautoall WinEnter. The plugins cannot tell the event is fired with :doautoall or not.

The issue occurs when using sessions too. The session file created by :mksession contains doautoall SessionLoadPost (see src/session.c#L1253), which makes the same problem happen.

Describe the solution you'd like
Provide a way to detect a window is aucmd_win or not within Vim script. Something like v:aucmd_win_used or expand('<awinused>'). Or provide a function whether or not a window is listed or not.

Describe alternatives you've considered
The :doautoall command with any events causes the problem but I'm troubled with the fact that session file contains the :doautoall command. Does it need to fire SessionLoadPost with doautoall actually? I don't need it to emit the event for all the buffers, but just want to do something once on session load. I suggest adding another event which is fired only once on session load OR just add doautocmd WinEnter at the end of the session.

Additional context
Original issue: itchyny/lightline.vim#448


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.

Yegappan Lakshmanan

unread,
Jun 15, 2020, 12:42:41 PM6/15/20
to vim_dev, reply+ACY5DGCU3NCUYOYEI3...@reply.github.com, vim/vim, Subscribed
Hi,

If the getwininfo() function returns whether a window is an autocmd window or not, will that meet
this requirement?

- Yegappan

vim-dev ML

unread,
Jun 15, 2020, 12:43:03 PM6/15/20
to vim/vim, vim-dev ML, Your activity

Hi,

On Mon, Jun 15, 2020 at 9:22 AM itchyny <vim-dev...@256bit.org> wrote:

> *Is your feature request about something that is currently impossible or
> hard to do? Please describe the problem.*

> The :doautoall command uses the temporary window (aucmd_win) for a buffer
> which does not belong to the visible windows. But we cannot distinguish the
> temporary window for :doautoall and normal windows.
>
> :autocmd BufEnter * echom [bufname(), winnr(), winnr('$')]
>
> :edit a" ['a', 1, 1]
> :tabnew b" ['b', 1, 1]
> " We expect winnr('$') always returns the window count, however
> :doautoall BufEnter" ['a', 1, 2] => winnr('$') returns 2 due to aucmd_win" ['b', 1, 1]
>
> :autocmd! BufEnter *
>
> :autocmd BufEnter * echom map(range(1, winnr('$')), '[bufname(winbufnr(v:val)), winnr() == v:val]')
>
> :doautoall BufEnter" [['a', 1], ['b', 0]]" [['b', 1]]
>
> :tabp" [['a', 1]]
> " We expect that the window number is equal to winnr() only for the active window, however
> :doautoall BufEnter" [['a', 1]]" [['b', 1], ['a', 0]] " => The 'b' buffer is associated with aucmd_win
>
> This behavior confuses plugins which assume that winnr() always returns
> the active window number, but this is incorrect due to :doautoall
> command. This happens with any events because :doautoall does not
> restrict the event to emit. User can :doautoall FileType or even :doautoall
> WinEnter. The plugins cannot tell the event is fired with :doautoall or
> not.
>
> The issue occurs when using sessions too. The session file created by
> :mksession contains doautoall SessionLoadPost (see src/session.c#L1253
> <https://github.com/vim/vim/blob/47a519a933e8bcaf703a5feaac5c01491a658ee3/src/session.c#L1253>),

> which makes the same problem happen.
>
> *Describe the solution you'd like*

> Provide a way to detect a window is aucmd_win or not within Vim script.
> Something like v:aucmd_win_used or expand('<awinused>'). Or provide a
> function whether or not a window is listed or not
> <https://github.com/vim/vim/blob/47a519a933e8bcaf703a5feaac5c01491a658ee3/src/window.c#L5044-L5048>

> .
>

If the getwininfo() function returns whether a window is an autocmd window
or not, will that meet
this requirement?

- Yegappan


> *Describe alternatives you've considered*

> The :doautoall command with any events causes the problem but I'm
> troubled with the fact that session file contains the :doautoall command.
> Does it need to fire SessionLoadPost with doautoall actually? I don't
> need it to emit the event for all the buffers, but just want to do
> something once on session load. I suggest adding another event which is
> fired only once on session load OR just add doautocmd WinEnter at the end
> of the session.
>
> *Additional context*
> Original issue: itchyny/lightline.vim#448
> <https://github.com/itchyny/lightline.vim/issues/448>

itchyny

unread,
Jun 15, 2020, 9:44:54 PM6/15/20
to vim/vim, vim-dev ML, Comment

If the getwininfo() function returns whether a window is an autocmd window
or not, will that meet
this requirement?

Less performant, but it will definitely work. Another option is changing win_gettype().


You are receiving this because you commented.

itchyny

unread,
Jun 15, 2020, 9:58:20 PM6/15/20
to vim/vim, vim-dev ML, Comment

Another solution is changing the behavior of winnr() (returns -1 for aucmd_win and winnr('$') returns the actual window count without aucmd_win), but it may break the existing scripts.


You are receiving this because you commented.

Yegappan Lakshmanan

unread,
Jun 16, 2020, 1:21:30 PM6/16/20
to vim_dev, reply+ACY5DGFMF334LWMK7M...@reply.github.com, vim/vim, vim-dev ML, Comment
Hi,

On Mon, Jun 15, 2020 at 6:44 PM itchyny <vim-dev...@256bit.org> wrote:

If the getwininfo() function returns whether a window is an autocmd window
or not, will that meet
this requirement?

Less performant, but it will definitely work. Another option is changing win_gettype().



I have created PR https://github.com/vim/vim/pull/6277 to extend win_gettype() to
return aucmdwin.

- Yegappan 

vim-dev ML

unread,
Jun 16, 2020, 1:21:47 PM6/16/20
to vim/vim, vim-dev ML, Your activity

Bram Moolenaar

unread,
Jun 16, 2020, 5:23:33 PM6/16/20
to vim/vim, vim-dev ML, Comment

Implemented in 8.2.0991


You are receiving this because you commented.

Bram Moolenaar

unread,
Jun 16, 2020, 5:23:33 PM6/16/20
to vim/vim, vim-dev ML, Comment

Closed #6264.


You are receiving this because you commented.

itchyny

unread,
Jun 16, 2020, 9:18:42 PM6/16/20
to vim/vim, vim-dev ML, Comment

Thank you so much.


You are receiving this because you commented.

Reply all
Reply to author
Forward
0 new messages