| Age | Commit message (Collapse) | Author | Files |
|
Problem: Cannot apply 'scrolloff' context lines at end of file
Solution: Add the 'scrolloffpad' option to keep 'scrolloff' context even
when at the end of the file (McAuley Penney).
closes: vim/vim#19040
https://github.com/vim/vim/commit/a414630393f81c9a5b8fa4d0fcc1287155f67751
Co-authored-by: McAuley Penney <jacobmpenney@gmail.com>
|
|
|
|
Problem:
- Unable to "pin" a window to prevent closing without specifically
being targeted.
- :fclose closes hidden windows (even before visible windows).
Solution:
- Add 'winpinned' window-local option. When set, window is skipped by
:fclose and :only. Pin the ui2 cmdline window (which should always be
visible), so that it is not closed by :only/fclose.
- Skip over hidden (and pinned) windows with :fclose.
Co-authored-by: glepnir <glephunter@gmail.com>
|
|
Problem: When closing floating windows to close a tabpage, if the current
buffer will unload, buffers contained in those floating windows
will too (unexpectedly).
Solution: Don't pass along "free_buf" argument; check 'bufhidden' for
the buffer in the to be closed float.
|
|
- `src/nvim/ex_cmds_defs.h`: use "U" instead of "u" per
`readability-uppercase-literal-suffix`
|
|
Problem: When 'ruler' is in last line of the screen and the current
floating window is closed, the ruler is not cleared.
Solution: When closing the current floating window, redraw the cmdline
if that contained, and will no longer contain the 'ruler'.
|
|
Problem: w_locked can be bypassed when recursively set if not restored
to its prior value.
Solution: Rather than save/restore everywhere, just make it a count,
like other locks (Sean Dewar)
Requires the previous commit, otherwise b_nwindows will be wrong in
tests, which causes a bunch of weird failures.
closes: vim/vim#19728
https://github.com/vim/vim/commit/7cb43f286e55853cf21b9d8870a430390c1cc8f1
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
|
|
Problem: close_buffer() callers incorrectly handle b_nwindows,
especially after nasty autocmds, allowing it to go
out-of-sync. May lead to buffers that can't be unloaded, or
buffers that are prematurely freed whilst displayed.
Solution: Modify close_buffer() and review its callers; let them
decrement b_nwindows if it didn't unload the buffer. Remove
some now unneeded workarounds like 8.2.2354, 9.1.0143,
9.1.0764, which didn't always work (Sean Dewar)
(endless yapping omitted)
related: vim/vim#19728
https://github.com/vim/vim/commit/bf21df1c7bc772e3a29961c961d0821584d50ee0
b_nwindows = 0 change for free_all_mem() was already ported.
Originally Nvim returned true when b_nwindows was decremented before the end was
reached (to better indicate the decrement). That's not needed anymore, so just
return true only at the end, like Vim. (retval isn't used anywhere now anyways)
Set textlock for dict watchers at the end of close_buffer() to prevent them from
switching windows, as that can leave a window with a NULL buffer. (possible
before this PR, but the new assert catches it; added a test)
Despite textlock, things still aren't ideal, as watchers may observe the buffer
as unloaded and hidden (b_nwindows was decremented), yet still in a window...
Likewise, for Nvim, wipe_qf_buffer()'s comment may not be entirely accurate;
autocmds are blocked, but on_detach callbacks (textlocked) and dict watchers may
still run. Might be problematic, but those aren't new issues.
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
|
|
Problem: possible crash with winminheight=0
(Emilien Breton)
Solution: Use <= instead of < when checking reserved room in
frame_setheight() to correctly handle the zero-height
boundary case (Hirohito Higashi).
In frame_setheight(), when shrinking the current window and the only
other window has 'winfixheight' with 'winminheight'=0, room_reserved
was not cleared because the condition used '<' instead of '<='.
The freed rows were discarded, leaving fr_height sum less than
topframe fr_height. Subsequent resize operations then computed a
wrong room_cmdline that expanded topframe beyond the screen, causing
a crash.
fixes: vim/vim#19706
closes: vim/vim#19712
https://github.com/vim/vim/commit/a5d9654620648ea6d3f2f8dc2a3e42de219cf860
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
|
|
- Cleanup, remove redundant comments, add more tests.
- Enhance win_new_tabpage rather than create a new function for !enter, and use
a different approach that minimizes side-effects. Return the tabpage_T * and
first win_T * it allocated.
- Disallow during textlock, like other APIs that open windows.
- Remove existing win_alloc_firstwin error handling from win_new_tabpage; it's
not needed, and looks incorrect. (enter_tabpage is called for curtab, which is
not the old tabpage! Plus newtp is not freed)
- Fix checks after creating the tabpage:
- Don't fail if buf wasn't set successfully; the tab page may still be valid
regardless. Set buffer like nvim_open_win, possibly blocking Enter/Leave
events. (except BufWinEnter)
- tp_curwin may not be the initial window opened by win_new_tabpage. Use the
win_T * it returns instead, which is the real first window it allocated,
regardless of autocmd shenanigans.
- Properly check whether tab page was freed; it may have also been freed
before win_set_buf. Plus, it may not be safe to read its handle!
|
|
Problem: no API function for opening a new tab page and returning its handle, or
to open without entering.
Solution: add nvim_open_tabpage.
|
|
Problem:
`K` in help files may fail in some noisy text. Example:
(`fun(config: vim.lsp.ClientConfig): boolean`)
^cursor
Solution:
- `:help!` (bang, no args) activates DWIM behavior: tries `<cWORD>`,
then trims punctuation until a valid tag is found.
- Set `keywordprg=:help!` by default.
- Does not affect `CTRL-]`, that is still fully "tags" based.
|
|
Problem: more cases where it may not be safe to move a window between tabpages.
Solution: check them.
Rather speculative... I haven't spend much time looking, but I didn't find
existing code that sets these locks to skip checking win_valid. (what I did find
called it anyway, like in win_close) Still, I think it's a good precaution for
what future code might do.
If the fact that nvim_win_set_config *actually* moves windows between tabpages
causes unforeseen issues, "faking" it like ":wincmd T" may be an alternative:
split a new window, close the old one, but instead also block autocmds, copy the
old window's config, and give it its handle?
|
|
|
|
Problem: discarding saved option values in the WinInfo of closed style=minimal
windows leaks memory.
Solution: also free the nested folds.
|
|
Problem: nvim_win_set_config may merge configs despite failing to configure a
split, and without applying necessary side-effects (like setting style=minimal
options). Plus, autocommands may apply a different config after the merge,
causing side-effects to apply for an outdated config.
Solution: merge configs last, only on success. Include fields only relevant to
splits. Properly set _cmdline_offset for splits.
Maybe better to disallow _cmdline_offset for splits instead, as the pum is
relative to cmdline_row anyway? (I didn't want to change behaviour too much)
Also use expect_unchanged in an unrelated test to quash a warning.
|
|
#38138
Problem: 5943a81 skips saving window options in `buflist_altfpos` for
style=minimal windows, which also prevents the window from restoring its own
options when switching buffers.
Solution: revert the change. In `get_winopts`, don't restore options from the
`WinInfo` of style=minimal windows when reusing values for a different window.
In `win_free`, clear `wi_optset` for minimal windows.
|
|
:startinsert/:stopinsert (#37881)
Problem: Changing hidden prompt buffer cancels :startinsert/:stopinsert
(after 9.0.1439).
Solution: Don't change mode for a prompt buffer in an autocommand
window (zeertzjq).
closes: vim/vim#19410
https://github.com/vim/vim/commit/8b81a6b6e1d514cf0544e0c6d12412ba813564b0
|
|
Problem: When a float window with style='minimal' is converted to a
split window and then changes buffer, the minimal style options get
overridden. This happens because merge_win_config() clears the style
field, so get_winopts() doesn't know to re-apply minimal style after
restoring options from the buffer's wininfo.
Solution: Save and restore the style field when clearing the config
during float-to-split conversion.
|
|
Problem: close_buffer autocmds may switch buffers at the last moment when
closing a window, causing terminal_check_size to prefer the size of a closed
window, or TabClosed to set an old <abuf>.
Solution: use the actual last buffer, similar to what TabClosed did before.
NOTE: If buffer was unloaded/deleted (not wiped), then TabClosed's <abuf> may
not use it. (w_buffer = NULL) Maybe odd, but it's how it worked before anyhow.
Relies on close_buffer reliably setting w_buffer to NULL if freed, otherwise
buf_valid is better. Only concern I see is if the window wasn't in the window
list after closing the buffer (close_buffer won't set it to NULL then), but then
win_close{_othertab} should've returned earlier.
|
|
Problem: win_free_mem can free w_buffer (via qf_free_all), which may cause a
heap use-after-free if used as TabClosed's <abuf>. I think TabClosed is also the
only event to conditionally set <abuf> not based on event type.
Solution: use the buffer saved by the bufref. Fall back to curbuf if invalid,
like WinResized/WinScrolled.
NOTE: Not always equivalent if close_buffer autocmds switch buffers at the last
moment; previously <abuf> would be set to that buffer. Fixed in next commit.
https://github.com/neovim/neovim/actions/runs/21765657455/job/62800643599?pr=37758#step:9:159
for an example of qf_free_all being a nuisance.
|
|
Problem: terminal's size may not update after one of its windows close.
Solution: call terminal_check_size after closing a window.
Disable test for Windows, as for some reason it only shows a few lines...
|
|
Problem: TabClosedPre may be triggered twice for the same tab page when
closing another tab page in BufWinLeave (after 9.1.1211).
Solution: Store whether TabClosedPre was triggered in tabpage_T
(zeertzjq).
Also fix the inconsistency that :tabclose! triggers TabClosedPre after
a failed :tabclose, but :close! doesn't even if there is only one window
in the tab page.
closes: vim/vim#19211
https://github.com/vim/vim/commit/9168a04e0c63c95eec643dab14a8e0a8933d90e7
|
|
Problem: heap-use-after-free when wiping buffer in TabClosedPre.
Solution: Check window_layout_locked() when closing window(s) in another
tabpage (zeertzjq).
closes: vim/vim#19196
https://github.com/vim/vim/commit/8fc7042b3da3939213bb3f4216dc581703a954dd
|
|
Problem: TabClosedPre is triggered just before the tab is being freed,
which limited its functionality.
Solution: Trigger it a bit earlier and also on :tabclose and :tabonly
(Jim Zhou)
closes: vim/vim#16890
https://github.com/vim/vim/commit/bcf66e014141982192e2743829bceef60ce77727
Co-authored-by: Jim Zhou <jimzhouzzy@gmail.com>
|
|
Problem: Missing TabClosedPre autocommand
(zoumi)
Solution: Add the TabClosedPre autcommand (Jim Zhou).
fixes: vim/vim#16518
closes: vim/vim#16855
https://github.com/vim/vim/commit/5606ca5349982fe53cc6a2ec6345aa66f0613d40
Co-authored-by: Jim Zhou <jimzhouzzy@gmail.com>
|
|
Problem: Crash when using :tabonly in BufUnload.
Solution: Set curbuf when setting curwin->w_buffer. Don't wipe out a
buffer if there are no other buffers. Don't decrement
b_nwindows if it was 0 before buf_freeall() (zeertzjq).
fixes: vim/vim#19088#issuecomment-3710172769
closes: vim/vim#19186
https://github.com/vim/vim/commit/fa64f92f6ab8b8080bdba77155e7bb3530fa21f6
|
|
(#37436)
Problem: Error message for layout change does not match action.
Solution: Pass the command to where the error is given. (closes vim/vim#11573)
https://github.com/vim/vim/commit/9fda81515b26ecd3c1e99f95334aaed3f7b6fea3
Thinking about this again, it's actually OK to check split_disallowed in
window_layout_locked(), so add the check.
Also add missing window_layout_locked() in tabpage_close().
Co-authored-by: Bram Moolenaar <Bram@vim.org>
|
|
Problem: crash with WinNewPre autocommand, because window
structures are not yet safe to use
Solution: Don't trigger WinNewPre on :tabnew
https://github.com/vim/vim/commit/fb3f9699362f8d51c3b48fcaea1eb2ed16c81454
Cherry-pick doc updates from latest Vim runtime.
Co-authored-by: Christian Brabandt <cb@256bit.org>
|
|
autocommands
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)
related: vim/vim#14038
https://github.com/vim/vim/commit/96cc4aef3d47d0fd70e68908af3d48a0dce8ea70
Most of the patch was already ported. This includes the remaining part.
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
|
|
Problem: No event is triggered before creating a window.
(Sergey Vlasov)
Solution: Add the WinNewPre event (Sergey Vlasov)
fixes: vim/vim#10635
closes: vim/vim#12761
https://github.com/vim/vim/commit/1f47db75fdc8c53c5c778b26ecfa0942ac801f22
Not sure if this should be triggered before creating a floating window,
as its use case is related to window layout.
Co-authored-by: Sergey Vlasov <sergey@vlasov.me>
|
|
Problem: Use-after-free in winframe_remove() (henices)
Solution: Set window_layout_locked() inside winframe_remove()
and check that writing diff files is disallowed when the
window layout is locked.
It can happen with a custom diff expression when removing a window:
1. Buffer was removed, so win_frame_remove() is called to remove the
window.
2. win_frame_remove() → frame_new_height() → scroll_to_fraction()
→ diff_check_fill() (checks for filler lines)
3. diff_check_fill() ends up causing a diff_try_update, and because we
are not using internal diff, it has to first write the file to a
buffer using buf_write()
4. buf_write() is called for a buffer that is not contained within a
window, so it first calls aucmd_prepbuf() to create a new temporary
window before writing the buffer and then later calls
aucmd_restbuf(), which restores the previous window layout, calling
winframe_remove() again, which will free the window/frame structure,
eventually freeing stuff that will still be accessed at step 2.
closes: vim/vim#19064
https://github.com/vim/vim/commit/ead1dda74a485ef0470e7252d07c1a36b8cde517
Nvim doesn't have this bug as Nvim uses a floating window as autocommand
window, and removing it doesn't need winframe_remove().
Co-authored-by: Christian Brabandt <cb@256bit.org>
|
|
Problem: b:undo_ftplugin not executed when re-using buffer
(archy3)
Solution: explicitly execute b:undo_ftplugin in buflist_new() when
re-using the current buffer
fixes: vim/vim#17113
closes: vim/vim#17133
https://github.com/vim/vim/commit/baa8c90cc0d214e036a3a7980d5cf95cae88a68d
Cherry-pick test_filetype.vim changes from patch 9.1.1325.
Co-authored-by: Christian Brabandt <cb@256bit.org>
|
|
Problem: Restoring window after WinScrolled may fail.
Solution: Lock the window layout when triggering WinScrolled.
https://github.com/vim/vim/commit/d63a85592cef0ee4f0fec5efe2f8d66b31f01f05
Only check close_disallowed in window_layout_locked() for now.
Also don't check window_layout_locked() when closing a floating window,
as it's not checked when creating a floating window.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
|
|
Problem: printf format not checked for semsg().
Solution: Add GNUC attribute and fix reported problems. (Dominique Pelle,
closes vim/vim#3805)
https://github.com/vim/vim/commit/b5443cc46dd1485d6c785dd8c65a2c07bd5a17f3
Cherry-pick a change from patch 8.2.3830.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
|
|
Problem: Crash when closing a split window if autocmds close other
split windows but there are still floating windows.
Solution: Bail out and give the window back its buffer.
|
|
Problem: null pointer member access when closing the only non-float in the
current tab page if autocommands after closing all floats also close all other
tab pages. (making it the last window)
Solution: check last_window again after closing the floats.
Also reduce the scope of "wp"; it would be bugprone to use it before it's later
reassigned to the rv of win_free_mem if freed by Buf/WinLeave.
|
|
Problem: ml_get error when resizing window and using text property.
Solution: Validate botline of the right window. (closes vim/vim#7528)
https://github.com/vim/vim/commit/23999d799cfe844b604f193183f8f84052c8e746
Migrate to Vim's (in)validate_botline_win() API.
Nvim wants to pass "curwin" instead of hiding them
behind alias/macro/inline-function.
https://github.com/neovim/neovim/pull/37164#discussion_r2655006908
Co-authored-by: Bram Moolenaar <Bram@vim.org>
|
|
Problem: use-after-free in win_move_after if win_enter autocommands free win1/2.
Solution: set w_pos_changed before calling win_enter.
|
|
(#37056)
Problem: After :botright copen and closing the quikfix window, the
cursor ends up in the wrong window. The problem is fr_child
always points to the first (leftmost for FR_ROW, topmost for
FR_COL) child frame. When do :vsplit, the new window is
created on the left, and frame_insert() updates the parent's
fr_child to point to this new left window.
Solution: Create a snapshot before open the quickfix window and restore
it when close it (glepnir).
closes: vim/vim#18961
https://github.com/vim/vim/commit/b43f9ded7e98261e3e662a8e919f54e7399b0316
Co-authored-by: glepnir <glephunter@gmail.com>
|
|
This matches the gettabvar() behavior change in Vim 8.1.1218.
|
|
Problem:
Can't show 'statusline' in floating windows.
Solution:
Use window-local 'statusline' to control floating window statusline visibility.
|
|
Problem: apply_autocmds function can free both buf_T and win_T pointers
Solution: instead retain winids for WinResized and WinScrolled
autocmds and use curbuf pointer, which is consistent with other uses
of apply_autocmds function
|
|
(#36567)
Problem: WinEnter autocommand may confuse Vim when closing tabpage
(hokorobi)
Solution: Verify that curwin did not change in close_others()
fixes: vim/vim#18722
closes: vim/vim#18733
https://github.com/vim/vim/commit/61b73b89a3114b4bf62ffbedc8d0d3aa321bdcd5
Co-authored-by: Christian Brabandt <cb@256bit.org>
|
|
Problem: Previous window is made current while it is unfocusable/hidden.
Solution: Treat hidden/unfocusable window as an invalid previous window.
|
|
Problem: when splitkeep=screen, after enlarge float window with
nvim_win_set_height, lines("w$") return stale value
Solution: update in win_set_inner_size
|
|
Problem: 'cursorlineopt' "screenline" isn't redrawn when moving cursor
and then using line("w0") and :retab that does nothing.
Solution: Call redraw_for_cursorcolumn() when setting a valid w_virtcol
(zeertzjq).
closes: vim/vim#18506
https://github.com/vim/vim/commit/a0849143614e687a305b6195dd8724840786e372
|
|
Problem: vertical separator of 'winfixwidth' windows may remain if they
become right-most windows from closing windows to the right.
Solution: Don't implicitly rely on frame_new_width to fix vseps, as the
call may be skipped for 'winfixwidth' windows to preserve
their width; do it explicitly in winframe_remove (Sean Dewar).
Note that I prefer win_new_width here over setting w_width directly, which
would've previously been done by win_split_ins after frame_add_vsep, as this
wasn't true for winframe_remove.
Though the equivalent issue of bottom 'winfixheight' windows leaving stray
statuslines with &ls=0 doesn't seem to exist, test it anyway.
closes: vim/vim#18481
https://github.com/vim/vim/commit/620c6556778a0df15be4fa33647fff1f6ab36255
Nvim: calling win_new_width over setting w_width directly is especially
important in making sure stuff like w_view_width is correct here.
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
|
|
(#35830)
Problem: Crash in BufLeave/WinLeave/TabLeave when closing window after
BufUnload closes all other windows in the tab page.
Solution: Avoid duplicate BufLeave/WinLeave events. Trigger TabLeave
before removing the buffer (zeertzjq).
related: vim/vim#14166
related: neovim/neovim#33603
closes: vim/vim#18330
https://github.com/vim/vim/commit/0c70820015c7a37425c07bf30ad277ee2656d496
|
|
Problem:
Multigrid UIs have to find out which window to send the input by using
the Nvim focus rules, which are not fully documented.
Furthermore,`getmousepos()` has several problems when multigrid is
enabled, with the main one being that screenrow and screencol are window
relative instead of screen relative, due to the fact that the UI don't
send any absolute coordinates.
Solution:
Allow passing 0 as grid to `nvim_input_mouse`, with absolute
coordinates, which lets nvim determine the actual window to send the
mouse input to. This works as long as nvim is in charge of the window
positioning. If the UI repositions or resizes the windows, it can still
pass the grid it determines like before.
|