Problem: winframe functions incorrectly recompute window positions if
the altframe wasn't adjacent to the closed frame, which is
possible if adjacent windows had 'winfix{width,height}' set.
Solution: recompute for windows within the parent of the altframe and
closed frame. Skip this (as before) if the altframe was
top/left, but only if adjacent to the closed frame, as
positions won't change in that case. Also correct the return
value documentation for win_screenpos. (Sean Dewar)
The issue revealed itself after removing the win_comp_pos call below
winframe_restore in win_splitmove. Similarly, wrong positions could result from
windows closed in other tabpages, as win_free_mem uses winframe_remove (at least
until it is entered later, where enter_tabpage calls win_comp_pos).
NOTE: As win_comp_pos handles only curtab, it's possible via other means for
positions in non-current tabpages to be wrong (e.g: after changing 'laststatus',
'showtabline', etc.). Given enter_tabpage recomputes it, maybe it's intentional
as an optimization? Should probably be documented in win_screenpos then, but I
won't address that here.
closes: vim/vim#14191
Nvim: don't reuse "wp" for "topleft" in winframe_remove, so the change
integrates better with the call to winframe_find_altwin before it.
5866bc3a0f
Problem: small improvements can be made to split-move related
functions.
Solution: apply them (Sean Dewar):
Some of these changes were already applied to Nvim.
Here are the ones which were missing:
- Improve some doc comments (frame_flatten should still work for non-current
tabpages, despite the topframe check, which looks benign, though I'm unsure if
it's still needed; see vim/vim#2467).
- f_win_splitmove should check_split_disallowed on wp, not targetwin, as that's
what win_splitmove checks (though it's probably unnecessary to check
b_locked_split at all; see vim/vim#14109, which I hope to get around to
finishing at some point).
- Apply the winframe_restore comment changes, and remove win_comp_pos from after
winframe_restore in win_splitmove, as it shouldn't be necessary (no need to
remove it from nvim_win_set_config too, as it was already omitted).
Move win_append after winframe_restore in win_splitmove to match Vim.
closes: vim/vim#141855cac1a9bee
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#14047closes: vim/vim#14186d64801e913
Its corresponding test in Vim is in test_popupwin.win, so having it in
the middle of test_window_cmd.vim is strange, and it is now covered by
tests in ui/float_spec.lua anyway.
Problem: heap-use-after-free in win_splitmove if Enter/Leave
autocommands from win_split_ins immediately closes "wp".
Solution: check that "wp" is valid after win_split_ins.
(Sean Dewar)
abf7030a5c
Problem: win_gotoid() checks for textlock and other things when switching
to a window that is already current (after v9.1.0119)
Solution: return early with success when attempting to switch to curwin
(Sean Dewar)
2a65e73944
Problem: infinite loop in win_update with 'smoothscroll' set when
window width is equal to textoff, or signed integer overflow
if smaller.
Solution: don't revalidate wp->w_skipcol in that case, as no buffer text
is being shown. (Sean Dewar)
02fcae02a9
Test_window_split_no_room changes were already cherry-picked earlier.
Problem: can switch windows while textlocked via f_win_gotoid and
f_win_splitmove (which also allows switching in the cmdwin).
Solution: Check text_or_buf_locked in f_win_splitmove()
(Sean Dewar)
While at it, call text_or_buf_locked() in f_win_gotoid() instead of testing for
cmdwin_type() (which text_buf_locked() does and in addition will also verify
that the buffer is not locked).
f865895c87
Problem: win_splitmove fires WinNewPre and possibly WinNew when moving
windows, even though no new windows are created.
Solution: don't fire WinNew and WinNewPre when inserting an existing
window, even if it isn't the current window. Improve the
accuracy of related documentation. (Sean Dewar)
96cc4aef3d
Partial as WinNewPre has not been ported yet (it currently has problems anyway).
Problem: win_split_ins has no check for E36 when moving an existing
window
Solution: check for room and fix the issues in f_win_splitmove()
(Sean Dewar)
0fd44a5ad8
Omit WSP_FORCE_ROOM, as it's not needed for Nvim's autocmd window, which is
floating. Shouldn't be difficult to port later if it's used for anything else.
Make win_splitmove continue working for turning floating windows into splits.
Move the logic for "unfloating" a float to win_split_ins; unlike splits, no
changes to the window layout are needed before calling it, as floats take no
room in the window layout and cannot affect the e_noroom check.
Add missing tp_curwin-fixing logic for turning external windows into splits, and
add a test.
NOTE: there are other issues with the way "tabpage independence" is implemented
for external windows; namely, some things assume that tp_curwin is indeed a
window within that tabpage, and as such, functions like tabpage_winnr and
nvim_tabpage_get_win currently don't always work for external windows (with the
latter aborting!)
Use last_status over frame_add_statusline, as Nvim's last_status already does
this for all windows in the current tabpage. Adjust restore_full_snapshot_rec to
handle this.
This "restore everything" approach is changed in a future commit anyway, so only
ensure it's robust enough to just pass tests.
Keep check_split_disallowed's current doc comment, as it's actually a bit more
accurate here. (I should probably PR Vim to use this one)
Allow f_win_splitmove to move a floating "wp" into a split; Nvim supports this.
Continue to disallow it from moving the autocommand window into a split (funnily
enough, the check wasn't reachable before, as moving a float was disallowed),
but now return -1 in that case (win_splitmove also returns FAIL for this, but
handling it in f_win_splitmove avoids us needing to switch windows first).
Cherry-pick Test_window_split_no_room fix from v9.1.0121.
Update nvim_win_set_config to handle win_split_ins failure in later commits.
Avoid `prevwin == curwin` when closing `curwin`
Problem: When closing the current window (or when moving it to a tabpage), the
previous window may refer to the new current window
(`winnr() == winnr('#')`) if that window is selected as the
new current window.
Solution: Set `prevwin = NULL` when switching away from an invalid `curwin` and
the target window was the `prevwin`.
(Sean Dewar)
related: vim/vim#4537closes: vim/vim#13762bf44b69d1f
Co-authored-by: Sean Dewar <seandewar@users.noreply.github.com>
Problem: Cursor is adjusted in window that did not change in size by
'splitkeep'.
Solution: Only check that cursor position is valid in a window that
has changed in size.
closes: vim/vim#1250916af913eee
Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
Problem: Cursor not adjusted when near top or bottom of window and
'splitkeep' is not "cursor".
Solution: Move boundary checks to outer cursor move functions, inner
functions should only return valid cursor positions. (Luuk van
Baal, closesvim/vim#12480)
a109f39ef5
Problem: Text scrolls unnecessarily when splitting and 'splitkeep' is not
"cursor".
Solution: Avoid resetting w_skipcol. (Luuk van Baal, closesvim/vim#12334)
b926bf47d6
Problem: Checks for Dictionary argument often give a vague error message.
Solution: Give a useful error message. (Yegappan Lakshmanan, closesvim/vim#11009)
04c4c5746e
Cherry-pick removal of E922 from docs from patch 9.0.1403.
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Problem: There is no way to get a list of swap file names.
Solution: Add the swapfilelist() function. Use it in the test script to
clean up. Remove deleting individual swap files.
c216a7a21a
vim-patch:9.0.1005: a failed test may leave a swap file behind
Problem: A failed test may leave a swap file behind.
Solution: Delete the swap file to avoid another test to fail. Use another
file name.
d0f8d39d20
Cherry-pick test_window_cmd.vim changes from patch 8.2.1593.
Remove FUNC_ATTR_UNUSED from eval functions as fptr is always unused.
Co-authored-by: Bram Moolenaar <Bram@vim.org>