vim-patch:9.1.0170: Re-allow curwin == prevwin, but document it instead

Problem:  more places exist where curwin == prevwin, and it may even be
          expected in some cases.
Solution: revert v9.1.0001, but document that it's possible instead.
          (Sean Dewar)

I've had a change of heart for the following reasons:

- A quick 'n dirty [GitHub code search](https://github.com/search?q=%2F%28winnr%5C%28%5C%29%5Cs*%3D%3D%5Cs*winnr%5C%28%5B%27%22%5D%23%5B%27%22%5D%5C%29%7Cwinnr%5C%28%5B%27%22%5D%23%5B%27%22%5D%5C%29%5Cs*%3D%3D%5Cs*winnr%5C%28%5C%29%29%2F&type=code)
  reveals some cases where it's expected in the wild.

  Particularly, it made me aware `winnr() == winnr('#')` is possible when curwin
  is changed temporarily during the evaluation of a &statusline expression item
  (`%{...}`), and is used to show something different on the statusline
  belonging to the previous window; that behaviour wasn't changed in v9.1.0001,
  but it means curwin == prevwin makes sense in some cases.

- The definition and call sites of back_to_prevwin imply some expectation that
  prevwin == wp (== curwin) is possible, as it's used to skip entering the
  prevwin in that case.

- Prior to v9.1.0001, `:wincmd p` would not beep in the case that was patched in
  v9.1.0001, but now does. That resulted in vim/vim#14047 being opened, as it affected
  the CtrlP plugin.

  I find it odd that `:wincmd p` had cases where it wouldn't beep despite doing
  nothing, but it may be preferable to keep things that way (or instead also
  beep if curwin == prevwin, if that's preferred).

- After more digging, I found cases in win_free_mem, enter_tabpage,
  aucmd_restbuf and qf_open_new_cwindow where curwin == prevwin is possible
  (many of them from autocommands). Others probably exist too, especially in
  places where curwin is changed temporarily.

fixes: vim/vim#14047
closes: vim/vim#14186

d64801e913
This commit is contained in:
Sean Dewar 2024-03-12 21:08:50 +00:00
parent 29d0ed577c
commit ca7b603d02
No known key found for this signature in database
GPG Key ID: 08CC2C83AD41B581
6 changed files with 10 additions and 66 deletions

View File

@ -9007,7 +9007,9 @@ winnr([{arg}]) *winnr()*
# the number of the last accessed window (where # the number of the last accessed window (where
|CTRL-W_p| goes to). If there is no previous |CTRL-W_p| goes to). If there is no previous
window or it is in another tab page 0 is window or it is in another tab page 0 is
returned. returned. May refer to the current window in
some cases (e.g. when evaluating 'statusline'
expressions).
{N}j the number of the Nth window below the {N}j the number of the Nth window below the
current window (where |CTRL-W_j| goes to). current window (where |CTRL-W_j| goes to).
{N}k the number of the Nth window above the current {N}k the number of the Nth window above the current

View File

@ -10724,7 +10724,9 @@ function vim.fn.winline() end
--- # the number of the last accessed window (where --- # the number of the last accessed window (where
--- |CTRL-W_p| goes to). If there is no previous --- |CTRL-W_p| goes to). If there is no previous
--- window or it is in another tab page 0 is --- window or it is in another tab page 0 is
--- returned. --- returned. May refer to the current window in
--- some cases (e.g. when evaluating 'statusline'
--- expressions).
--- {N}j the number of the Nth window below the --- {N}j the number of the Nth window below the
--- current window (where |CTRL-W_j| goes to). --- current window (where |CTRL-W_j| goes to).
--- {N}k the number of the Nth window above the current --- {N}k the number of the Nth window above the current

View File

@ -12856,7 +12856,9 @@ M.funcs = {
# the number of the last accessed window (where # the number of the last accessed window (where
|CTRL-W_p| goes to). If there is no previous |CTRL-W_p| goes to). If there is no previous
window or it is in another tab page 0 is window or it is in another tab page 0 is
returned. returned. May refer to the current window in
some cases (e.g. when evaluating 'statusline'
expressions).
{N}j the number of the Nth window below the {N}j the number of the Nth window below the
current window (where |CTRL-W_j| goes to). current window (where |CTRL-W_j| goes to).
{N}k the number of the Nth window above the current {N}k the number of the Nth window above the current

View File

@ -363,7 +363,7 @@ EXTERN bool sys_menu INIT( = false);
// currently active window. // currently active window.
EXTERN win_T *firstwin; // first window EXTERN win_T *firstwin; // first window
EXTERN win_T *lastwin; // last window EXTERN win_T *lastwin; // last window
EXTERN win_T *prevwin INIT( = NULL); // previous window EXTERN win_T *prevwin INIT( = NULL); // previous window (may equal curwin)
#define ONE_WINDOW (firstwin == lastwin) #define ONE_WINDOW (firstwin == lastwin)
#define FOR_ALL_FRAMES(frp, first_frame) \ #define FOR_ALL_FRAMES(frp, first_frame) \
for ((frp) = first_frame; (frp) != NULL; (frp) = (frp)->fr_next) for ((frp) = first_frame; (frp) != NULL; (frp) = (frp)->fr_next)

View File

@ -4915,14 +4915,10 @@ static void win_enter_ext(win_T *const wp, const int flags)
if (wp->w_buffer != curbuf) { if (wp->w_buffer != curbuf) {
buf_copy_options(wp->w_buffer, BCO_ENTER | BCO_NOHELP); buf_copy_options(wp->w_buffer, BCO_ENTER | BCO_NOHELP);
} }
if (!curwin_invalid) { if (!curwin_invalid) {
prevwin = curwin; // remember for CTRL-W p prevwin = curwin; // remember for CTRL-W p
curwin->w_redr_status = true; curwin->w_redr_status = true;
} else if (wp == prevwin) {
prevwin = NULL; // don't want it to be the new curwin
} }
curwin = wp; curwin = wp;
curbuf = wp->w_buffer; curbuf = wp->w_buffer;

View File

@ -113,64 +113,6 @@ func Test_window_quit()
bw Xa Xb bw Xa Xb
endfunc endfunc
func Test_window_curwin_not_prevwin()
botright split
call assert_equal(2, winnr())
call assert_equal(1, winnr('#'))
quit
call assert_equal(1, winnr())
call assert_equal(0, winnr('#'))
botright split
botright split
call assert_equal(3, winnr())
call assert_equal(2, winnr('#'))
1quit
call assert_equal(2, winnr())
call assert_equal(1, winnr('#'))
botright split
call assert_equal(1, tabpagenr())
call assert_equal(3, winnr())
call assert_equal(2, winnr('#'))
wincmd T
call assert_equal(2, tabpagenr())
call assert_equal(1, winnr())
call assert_equal(0, winnr('#'))
tabfirst
call assert_equal(1, tabpagenr())
call assert_equal(2, winnr())
call assert_equal(0, winnr('#'))
tabonly
botright split
wincmd t
wincmd p
call assert_equal(3, winnr())
call assert_equal(1, winnr('#'))
quit
call assert_equal(2, winnr())
call assert_equal(1, winnr('#'))
botright split
wincmd t
wincmd p
call assert_equal(1, tabpagenr())
call assert_equal(3, winnr())
call assert_equal(1, winnr('#'))
wincmd T
call assert_equal(2, tabpagenr())
call assert_equal(1, winnr())
call assert_equal(0, winnr('#'))
tabfirst
call assert_equal(1, tabpagenr())
call assert_equal(2, winnr())
call assert_equal(1, winnr('#'))
tabonly
only
endfunc
func Test_window_horizontal_split() func Test_window_horizontal_split()
call assert_equal(1, winnr('$')) call assert_equal(1, winnr('$'))
3wincmd s 3wincmd s