aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/drawscreen.c
Commit message (Collapse)AuthorAge
* fix(ui): ext_messages/ui2: stale 'rulerformat' "[+]" after :write #42315Justin M. Keyes8 days
| | | | | | | | | | | | | | Problem: With 'ruler' in the cmdline ('laststatus=0') and ext_messages (ui2), a 'rulerformat' "%m" does not update the "[+]" indicator after ":write", until a cursor-move. Analysis: `redraw_buf_status_later()` only marks windows with a statusline or winbar. The symptom is hidden by the legacy message grid because the write message overwrites the cmdline, which redraws the ruler. Solution: Also mark the cmdline 'ruler', like `status_redraw_buf()`.
* vim-patch:9.2.1165: Visual hl not updated for partially visible bottom line ↵zeertzjq2026-10-06
| | | | | | | | | | | | | (#42251) Problem: Visual highlight not updated for partially visible line at the bottom of the window. Solution: Limit the last line of update to w_botline instead of the line above (zeertzjq). fixes: vim/vim#21451 closes: vim/vim#21452 https://github.com/vim/vim/commit/f7ea0407aa2e03e66fec35beb0bca0411be0b98e
* fix(ui): missing vertical separator for a winbar only window (#41151)glepnir2026-08-05
| | | | | | | Problem: A winbar-only window with zero text height still occupies one row, but win_update() returns early on w_view_height == 0 and skips the vertical separator. Solution: Also draw the vertical separator in the early return path.
* fix(ruler)!: consistent width in last line and statuslineSébastien Hoffmann2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Traditionally, the ruler in the last line is one cell shorter than in the statusline, leaving the last cell of the screen blank. According to code comments, this is in order to prevent unwanted scrolling on "some" (unspecified, but presumably ancient) terminals. Berkeley vi is more specific in its `vs_modeline` function: dumb terminals with hardware scroll, SunOS 4.1.1 and Ultrix 4.2 curses. (n)curses still has a similar limitation in `(w)addstr`, but apparently only for historical reasons. Maintaining the different widths leads to awkward inconsistencies when the ruler is configured with 'rulerformat', except for the special case where it contains a top-level `%=`. Shifting the ruler in the last line to the left would be a solution, but the empty cell at the end doesn't seem to be relevant anymore. Solution: extend the ruler in the last line all the way to the right edge of the screen, just like in the statusline. The exact same amount of place will be available to the rest of the UI as before. BREAKING CHANGE: - the default ruler width is now 18 cells - the last cell of the screen is no longer empty Closes #41076
* feat(options): lua closure/function optionsJustin M. Keyes2026-07-31
| | | | | | | | | | | | | | | Problem: Cannot assign Lua functions/closures to "func" ('completefunc', 'tagfun', …) or "expr" ('foldexpr', 'indentexpr', …) options. Solution: - Store "func"/"expr" options as `Callback` instead of string. - Delete oceans of copy-pasted code. - BREAKING: LuaRef returned via RPC/Vimscript is now represented as `"<Lua N: file:line>"` (like what `:map` shows) instead of `nil`. - Note: `man.vim` still uses `v:lua` string, bc it's a vimscript ftplugin. Helped-by: Lewis Russell <lewis6991@gmail.com>
* refactor(exmode): Ex-mode as cmdwin + Lua #40991Justin M. Keyes2026-07-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: POSIX-compatible Ex-mode requires special-cases all over the codebase to match various quirks that don't actually matter to users. - The main utility of *interactive* Ex-mode is its REPL behavior, and that can be achieved with `cmdwin`, which also gains extra UX benefits. - The main utility of *non-interactive* `nvim -es` is for shell scripting, where Ex-mode quirks are mostly unhelpful (e.g. the "Entering Ex mode" message). Solution: - Reimplement *interactive* Ex-mode as a "persistent, insert-mode cmdwin" in Lua. - "nvim -e/-E" is simply an alias to "gQ". - Reframe *non-interactive* Ex-mode (`nvim -es`) as "script mode". - Drop POSIX Ex-mode quirks. Improvements: - "nvim -V1 -es" output ends with a final newline! - "nvim -V1 -es" no longer shows the "Entering Ex mode" msg. (This was pointless noise, unwanted for scripting purposes.) - stdin is no longer typeahead. Scripts (":lua io.read()") can read stdin as data. - Empty line is a no-op: a stray blank line no longer moves the cursor (deviates from POSIX ex "+1"), no longer exits 1 at EOF (E501). Preserved behavior: - cursor starts at "$" - mode()=="cv" (for non-interactive) - multiline commands (:append/:function/heredoc pull continuation lines) - bare-range print - :print=>stdout - -V1=>stderr - CRLF input - continue-after-error and exit codes Dropped (regressed) POSIX behavior (non-interactive): - Event loop only ticks while/between commands, not while blocked waiting for a stdin line. - ":g/pat/visual...Q" - input()/getchar()/":s/x/y/c" no longer consume stdin lines as answers: Nvim stops at end-of-input, skipping the rest of the script, exit 0. Use ":lua io.read()" instead. - If users care about this they should use interactive Ex-mode (`gQ`). - ":@r" stops at end of the register instead of continuing to read cmdline input from stdin.
* feat(options): schema, "dict" options, messagesJustin M. Keyes2026-07-24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Options parsing is still painful for dict-style options. Solution: schema-maxxing => better `opt:get()` (will be the basis for `vim.o()`), unified (and more-detailed) err msgs. - Drop bespoke structure-builder in `_core/options.lua`. - Define `schema` for all non-primitive options (except 'guicursor' and statusline-style options); generate reified keysets `OptKeyDict`). - Generate 'fillchars' => `fcs_tab`, 'listchars' => `lcs_tab`. - `nvim_set_option_value`: - Return the improved structures. Also from `vim.opt.x:get()`. - Eliminate api <=> lua roundtrip, centralize option structure handling. - Improve/unify errors. - Bump ERR_BUFLEN 80 → 256 so the "one of" list isn't truncated. - Eliminate old 'diffopt' order-dependence (`iwhiteall` before `iwhite`) Error samples: Typed-key path (opt_strings_check → diffopt/mousescroll/breakindentopt): E474: Unknown item 'foo' E474: 'context' requires a number E474: 'ver' number is out of range E474: 'algorithm' must be one of: myers, minimal, patience, histogram E474: 'filler' does not take a value Related: - #31084 - #34661 - #31820 - #14739 - #20107 - fix #18875 - :get() returns `{ sbr = true, shift = '3' }` (reified-keyset) instead of `{'sbr', 'shift:3'}` - Setting via table now works too. `object_as_optval_for` `is_map` now recognizes struct options. - fix #30296 - instead of `E474: Invalid argument`, errors now look like: ``` E474: Invalid value 'x', expected one of: single, double: ambiwidth=x E474: Unknown item 'foo': diffopt=foo E474: 'context' requires a number: diffopt=context:x ``` simplify `win_float_parse_option` from #26799.
* fix(ui): combine float border with window background #40796Artem Krinitsyn2026-07-19
| | | | | | | | | | Problem: Float border highlight groups (FloatBorder, FloatTitle and FloatFooter) fall back to Normal background highlight if no background color set. Solution: Combine border colors with window-local Normal highlight. Fix #38330
* refactor(globals): group Visual-mode globals in VisualState #40777Justin M. Keyes2026-07-16
|
* refactor(search): SearchStateJustin M. Keyes2026-07-16
|
* refactor(globals): group search state into SearchState structcarladams1299-lab2026-07-16
|
* refactor(input): rename getchar.c => input.c #40698Justin M. Keyes2026-07-12
| | | | | | | | | | | | Problem: `getchar.c` is a quirky name and doesn't align with our existing `os/input.c` and `tui/input.c` modules, which encompass the same topic at different layers. Solution: Rename `getchar.c` => `input.c` for discoverability. Introduce `dialog.c` for functionality related to showing confirm prompts, dialogs, etc.
* refactor: unify context-switching conceptsJustin M. Keyes2026-07-10
|
* fix(autocmd): no cleanup for redraw curwin change #40389luukvbaal2026-06-24
| | | | | | Problem: Unecessary/unexpected cleanup happens when restoring the current window for redraw purposes (since 28ffb334). Solution: Don't call autocmd_restbuf() to restore the current window, just do so directly.
* fix(autocmd): never draw aucmd_prepbuf temp win #40379luukvbaal2026-06-23
| | | | | | | | | | | | Problem: An autocommand that redraws may do so while curwin is temporarily set for the autocommand scope. This can result in flickering or unexpected state with UI components (statusline, winbar, decor providers...) that depend on the current window. Current workaround for statusline and winbar specifically delays the redraw, which can itself be unexpected for the autocommand. Solution: If redrawing happens with a temporary autocmd current window, temporarily restore the current window while redrawing.
* perf(redraw): don't redraw hidden windowsLuuk van Baal2026-05-31
| | | | | Problem: Hidden windows are redrawn unnecessarily. Solution: If a window is hidden, don't bother drawing it.
* fix(cmdline): avoid 'incsearch' recursion after redraw #39303luukvbaal2026-04-22
| | | | | | | Problem: A vim.ui_attach() callback that redraws to show a 'verbose' regex message during 'incsearch' results in recusive redrawing. Solution: Check that curwin was redrawn instead of just any window when determining if 'incsearch' highlighting was cleared.
* vim-patch:9.2.0365: using int as bool (#39232)zeertzjq2026-04-20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: using int as bool Solution: refactor: use bool type for internal flags in buf_T (Hirohito Higashi) Change the type of 23 internal state flag fields in buf_T from int to bool for improved type clarity and code readability. These fields are pure boolean flags that are never accessed via the option system's varp (which uses *(int *)varp = value), never compared with int fields holding non-0/1 values, and never use tristate values. Converted fields: - State flags: b_dev_valid, b_saving, b_mod_set, b_new_change, b_marks_read, b_modified_was_set, b_did_filetype, b_keep_filetype, b_au_did_filetype, b_u_synced, b_scanned, b_p_initialized - Characteristic flags: b_has_textprop, b_may_swap, b_did_warn, b_help, b_spell, b_shortname, b_has_sign_column, b_netbeans_file, b_was_netbeans_file, b_write_to_channel, b_diff_failed All TRUE/FALSE assignments to these fields have been updated to true/false accordingly. The type of temporary save variables (e.g. help_save in tag.c) has also been adjusted to bool. Option value fields (b_p_XXX) are kept as int because they are accessed via the option system and some use tristate (-1) semantics. Fields compared with int option values (b_start_eof, b_start_eol, b_start_bomb) are also kept as int to preserve comparison integrity. closes: vim/vim#20020 https://github.com/vim/vim/commit/1966a1c8963f59c00a9f25d129bec90366205e1b Co-authored-by: Hirohito Higashi <h.east.727@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(completion): update CursorColumn during completion (#39159)zeertzjq2026-04-17
| | | | Since Nvim uses a compositor, redrawing windows won't lead to flicker in the popup menu, so the pum_visible() checks in move.c can be removed.
* vim-patch:9.2.0289: 'linebreak' may lead to wrong Visual block highlighting ↵zeertzjq2026-04-04
| | | | | | | | | | | | | (#38749) Problem: 'linebreak' may lead to wrong Visual block highlighting when end char occupies multiple cells (after 7.4.467). Solution: Exclude 'linebreak' from the ending column instead of setting 'virtualedit' temporarily (zeertzjq). fixes: vim/vim#19898 closes: vim/vim#19900 https://github.com/vim/vim/commit/23be1889d1a1212445ca8bb9cd378484d3755f79
* fix(ui): repaint separator connectors after all window updates #37852Riccardo Mazzarini2026-02-13
| | | | | | | | | | | | | | | | | Problem: When a window is redrawn, `draw_vsep_win`/`draw_hsep_win` paint plain separator characters (`│`/`─`) along the window's entire edges, including cells that are connector corners belonging to other windows. Then `draw_sep_connectors_win` only fixes the corners of that same window, not connectors in the middle of its edges that belong to adjacent windows. If the window that "owns" the connector corner isn't part of the redraw, the connector is never repainted. Solution: Move connector drawing out of the per-window `win_update` and into a separate pass in `update_screen` that runs after all windows have been updated.
* feat(terminal): detect suspended PTY process (#37845)zeertzjq2026-02-13
| | | | | | | Problem: Terminal doesn't detect if the PTY process is suspended or offer a convenient way for the user to resume the process. Solution: Detect suspended PTY process on SIGCHLD and show virtual text "[Process suspended]" at the bottom-left. Resume the process when the user presses a key.
* vim-patch:8.2.2198: ml_get error when resizing window and using text propertyJan Edmund Lazo2026-01-01
| | | | | | | | | | | | | | | 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>
* fix(grid): assert crash during extreme resize layouts #36847CompileAndConquer2025-12-10
| | | | | | | | | | | | Problem: When the terminal shrinks, Neovim tries to recompute the layout and adjust every window so that the total width matches the new Columns. But in the scenario of numerous windows split horizontally, there is not enough space for all of them. The frame width (topframe->fr_width) never reaches the new Columns value, the logic tries to redistribute this negative space across child frames, but it triggers the assert. Solution: Skip this case in `win_update`.
* vim-patch:9.1.1964: Wrong display when using setline() at hit-enter prompt ↵zeertzjq2025-12-09
| | | | | | | | | | | | | (#36878) Problem: Wrong display when using setline() at hit-enter prompt (after 8.2.3204). Solution: Only skip scrolling for changed lines in top area if it's scrolled down due to w_topline change. Also add more testing for what 8.2.3204 fixed (zeertzjq). closes: vim/vim#18887 https://github.com/vim/vim/commit/e72eacceab2647e37e7d7a8a70e89dcd6ad01288
* vim-patch:9.1.1958: Wrong display with sign_unplace() and setline() in ↵zeertzjq2025-12-08
| | | | | | | | | | | | CursorMoved (#36851) Problem: Wrong display when scrolling with 'scrolloff' and calling sign_unplace() and setline() in CursorMoved (after 8.2.3204). Solution: Still scroll for changed lines below the top area when the top is scrolled down (zeertzjq) closes: vim/vim#18878 https://github.com/vim/vim/commit/2da433cff7a7fff965a1e14dbee3dc4160d0ed74
* fix(ui): close outdated cmdline pum on redraw (#36815)zeertzjq2025-12-05
|
* refactor: avoid unnecessary redraw for non-curwin cursor line (#36607)zeertzjq2025-11-20
|
* fix(ui): cmdline_show is not fired after clearing the screen (#36451)luukvbaal2025-11-08
| | | | | | | | | | | | Problem: Resize events during startup may clear an active external cmdline, which is then not redrawn. UI2 VimResized autocommand does not work. UI2 message appearance may be altered by inherited window options. The message separator uses the wrong fillchar. Solution: Unset cmdline_was_last_redrawn when clearing the screen, such that cmdline_show is re-emitted. Ensure set_pos function is called without arguments. Ensure such options are unset. Use 'fillchars'->msgsep.
* vim-patch:9.1.1888: Wrong display with cpo+=$, matchparen and wrapped line ↵zeertzjq2025-10-30
| | | | | | | | | | | | (#36385) Problem: Wrong display with cpo+=$, matchparen and wrapped line. Solution: Use old cursor line height when scrolling with cpo+=$. Also fix wrong redraw in non-current window. (zeertzjq) fixes: vim/vim#18647 closes: vim/vim#18662 https://github.com/vim/vim/commit/5c3e76263100c2c036f1febcb9e8716b719d57e3
* vim-patch:9.1.1883: Wrong display with 'smoothscroll' with -diff (#36372)zeertzjq2025-10-28
| | | | | | | | Problem: Wrong display with 'smoothscroll' when FEAT_DIFF is disabled. Solution: Use plines_correct_topline() (zeertzjq). closes: vim/vim#18649 https://github.com/vim/vim/commit/e06e70f7b129e983b307be405c44449348ac470f
* fix(statusline): redraw if Visual selection other end changes (#36281)zeertzjq2025-10-23
|
* fix(ui): 'pumborder' parsing, shadow #36127glepnir2025-10-11
| | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: 1. Setting `pumborder=+,+,+,+,+,+,+,+` failed to render the custom border characters correctly. The issue occurred in `parse_winborder()` where it incorrectly used `p_winborder` instead of the `border_opt` parameter when the option value didn't contain commas. 2. In `pum_redraw()`, calling `parse_border_style()` directly with the option string failed to parse comma-separated border characters. 3. Missing documentation for PmenuShadow and PmenuShadowThrough highlight groups used by the shadow border style. 4. Coverity reports CID 631420: passing WinConfig (480 bytes) by value in `grid_draw_border()`. 5. crash when using `shadow` value on pumborder. Solution: 1. Fix `parse_winborder()` to use `border_opt` parameter consistently, ensuring the correct option value is parsed regardless of which option (winborder/pumborder) is being set. 2. Update `pum_redraw()` to call `parse_winborder()` instead of `parse_border_style()`, properly handling both predefined styles and custom comma-separated border characters. 3. Add documentation for PmenuShadow (blended shadow areas) and PmenuShadowThrough (see-through corners) highlight groups. 4. Change `grid_draw_border()` to accept WinConfig by pointer. 5. When the "shadow" style is used, no additional row and column offset is applied, and the border width is reduced.
* feat(ui): 'pumborder' (popup menu border) #25541glepnir2025-10-10
| | | | | | | | | Problem: Popup menu cannot have a border. Solution: Support 'pumborder' option. Generalize `win_redr_border` to `grid_redr_border`, which redraws border for window grid and pum grid.
* vim-patch:partial:8.1.1939: code for handling v: variables in generic eval ↵Jan Edmund Lazo2025-10-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | file (#35968) Problem: Code for handling v: variables in generic eval file. Solution: Move v: variables to evalvars.c. (Yegappan Lakshmanan, closes vim/vim#4872) https://github.com/vim/vim/commit/e5cdf153bcb348c68011b308c8988cea42d6ddeb Remove direct reference to "vimvars" for following functions: - assert_error() - get_vim_var_nr() - get_vim_var_list() - get_vim_var_dict() - get_vim_var_str() - set_cmdarg() - set_reg_var() - set_vcount() - set_vexception() - set_vthrowpoint() - set_vim_var_bool() - set_vim_var_dict() - set_vim_var_list() - set_vim_var_nr() - set_vim_var_special() - set_vim_var_string() - set_vim_var_type() Reorder functions based on v8.2.4930 for eval_one_expr_in_str() and eval_all_expr_in_str(). Co-authored-by: Bram Moolenaar <Bram@vim.org>
* fix(floatwin): handle viewport width properly at end of window (#35490)zeertzjq2025-08-27
| | | Also avoid repeated calls of compute_foldcolumn().
* fix(column): wrong alignment and highlight with empty 'display' (#35495)zeertzjq2025-08-27
| | | This fixes a regression from #26961.
* refactor(build): remove INCLUDE_GENERATED_DECLARATIONS guardsbfredl2025-08-14
| | | | | | | | | These are not needed after #35129 but making uncrustify still play nice with them was a bit tricky. Unfortunately `uncrustify --update-config-with-doc` breaks strings with backslashes. This issue has been reported upstream, and in the meanwhile auto-update on every single run has been disabled.
* fix(ui): check for cmdline mode properly (#35202)zeertzjq2025-08-07
|
* fix(messages): only msg_clear for UPD_CLEAR #34688luukvbaal2025-06-28
| | | | Problem: "msg_clear" is emitted after resizing the screen and during startup. Solution: Only emit "msg_clear" when `redraw_type == UPD_CLEAR`.
* feat(ui): emit "msg_clear" event after clearing the screen (#34035)luukvbaal2025-06-26
| | | | | | | | Problem: ext_messages cannot tell when the screen was cleared, which is needed to clear visible messages. An empty message is also never emitted, but clears messages from the message grid. Solution: Repurpose the "msg_clear" event to be emitted when the screen was cleared. Emit an empty message with the `empty` kind to hint to a UI to clear the cmdline area.
* fix(ui)!: decouple ext_messages from message grid #27963luukvbaal2025-06-25
| | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: ext_messages is implemented to mimic the message grid implementation w.r.t. scrolling messages, clearing scrolled messages, hit-enter-prompts and replacing a previous message. Meanwhile, an ext_messages UI may not be implemented in a way where these events are wanted. Moreover, correctness of these events even assuming a "scrolled message" implementation depends on fragile "currently visible messages" global state, which already isn't correct after a previous message was supposed to have been overwritten (because that should not only happen when `msg_scroll == false`). Solution: - No longer attempt to keep track of the currently visible messages: remove the `msg_ext(_history)_visible` variables. UIs may remove messages pre-emptively (timer based), or never show messages that don't fit a certain area in the first place. - No longer emit the `msg(_history)_clear` events to clear "scrolled" messages. This opens up the `msg_clear` event to be emitted when messages should actually be cleared (e.g. when the screen is cleared). May also be useful to emit before the first message in an event loop cycle as a hint to the UI that it is a new batch of messages (vim._extui currently schedules an event to determine that). - Set `replace_last` explicitly at the few callsites that want this to be set to true to replace an incomplete status message. - Don't store a "keep" message to be re-emitted.
* fix(messages): make swapfile attention message part of prompt (#34414)luukvbaal2025-06-12
| | | | | | | | Problem: The swapfile attention message is not repeated after clearing the screen. After clearing the screen `msg_scrolled` is reset without clearing other related variables, causing an assert. Solution: Make the attention message part of the confirm prompt. Call `msg_reset_scroll()`.
* fix(messages): recognize cmdline one_key/number prompt State (#34206)luukvbaal2025-06-09
| | | | | | | | | | Problem: Since 48e2a736, prompt messages are handled by an actual active cmdline, resulting in `State` no longer being equal to `MODE_CONFIRM` which is used in some places. E.g. to specify the current `mode()` or to re-emit a confirm message. Solution: Replace `MODE_CONFIRM` with a new `MODE_CMDLINE` sub-mode when `ccline.one_key/mouse_used` is set. Use it to avoid clearing mouse_used prompt messages, and to re-emit one_key messages (when ext_messages is inactive, for which this is unnecessary).
* fix(redraw): update curswant for Visual selection (#34241)zeertzjq2025-05-30
| | | | | Problem: Blockwise Visual selection not redrawn correctly when moving cursor for more than 1 cells with 'virtualedit'. Solution: Restore the curswant update removed in 6679687bb3909f853ae97dfa01ae08ea2baf7f97.
* fix(grid): check allocated grid size when suspicious scrollingbfredl2025-05-05
| | | | fixes #33749
* fix(statusline): clear ruler when it is no longer drawn #33765luukvbaal2025-05-03
| | | | | | Problem: Ruler is not cleared from the screen/ext_messages state when it is no longer drawn after e.g. `set noruler` or when moving from a floating to a regular window. Solution: Remember if ruler was drawn and clear it.
* fix(display): adjust setting winline info for concealed lines (#33717)luukvbaal2025-05-01
| | | | | | | Problem: Wrong winline info after partial redraw. Setting `conceal_cursor_used` is unnecessarily spread out. Solution: Rather than adjusting `wl_lastlnum` for the previous winline, adjust it when setting the current winline. Set `conceal_cursor_used` when the current window is redrawn.
* refactor(ui): separate types for allocated grids and viewportsbfredl2025-04-28
|
* fix(marks): clamp conceal_lines corrected line number #33464luukvbaal2025-04-14
| | | | | | Problem: Line number corrected for conceal_lines may be set beyond eob when the last buffer line is concealed, causing ml_get errors. Solution: Avoid setting line number beyond eob.