aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/grid.c
Commit message (Collapse)AuthorAge
* refactor(mbyte): use StrCharInfo/ClusterInfo also for str[len] casesbfredl14 days
| | | | | | | | part of a series, next big one is gonna be bring utf_ptr2schar and friends into the New world. after that it might be worth brushing of some benchmarks and re-microoptimize the hottest loops. also some const-y constess but it is fine.
* perf(mbyte): single decoder loop for both cluster byte length and cell widthbfredl2026-09-25
| | | | | | | | | | | | | | | This applies to the callsites which already used utf_ptr2CharInfo and then utfc_next. There is more work to be done, but this is a lagom bisectable unit. A lot of code is still wounded by the historical distinction between "low" characters (c < 128) and "high" characters, with the UTF-8 specific rules behind compiler flags and virtual function calls. As a result, there are both ptr2cells() and utf_ptr2cells(). My work aims at slowly reintegrating the realms. As such, we consider ptr2cells() the "correct" abstraction as is matches what actually is printed in a displayed message and buffer text without extra bells and whistles, except for tabs.
* 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.
* perf(ui): defer title attr resolutionArtem Krinitsyn2026-07-20
| | | | | In case of an overflow, the iteration will break before the grid_line_puts call.
* perf(ui): blend and combine title default attr onceArtem Krinitsyn2026-07-20
|
* fix(ui): handle combining chunked float titlesArtem Krinitsyn2026-07-20
| | | | | | | | | | | Problem: The title is combined with window's attributes only if the title is a string (which implies the FloatTitle / FloatFooter highlight groups), but not when the title is text-hl chunks. Solution: Combine specified highlight group with window-local Normal highlight as well.
* 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
* fix(autocmd): never show autocommand windows #40032luukvbaal2026-05-30
| | | | | Problem: Redrawing in an autocommand that uses an autocommand window (more common since 5181984d) can result in flickering. Solution: Hide autocommand windows.
* fix(api): nvim_exec_autocmds({buf=x}) runs in buffer context #39061Barrett Ruth2026-05-20
| | | | | Problem: `nvim_exec_autocmds({ buf = ... })` matches the target buffer, but callbacks and modelines run with the caller buffer current rather than the target buffer. Solution: Execute the buffered path in prepared target-buffer context and restore the caller afterward.
* docs: misc, editorconfigJustin M. Keyes2025-12-15
| | | | fix https://github.com/neovim/neovim/issues/36858
* fix(float): prevent truncation of title that fits exactly #36880skewb1k2025-12-09
| | | | | | | | | | | Problem: The `over_flow` parameter in `grid_draw_bordertext` always added 1 for the '<' character. As a result, titles that fit exactly were still truncated with an unnecessary '<'. Solution: Adjust `over_flow` only when the actual overflow is greater than 0. Fix #36872
* fix(float): tail truncate long title #28387glepnir2025-12-08
| | | | | | | | | Problem: We truncate the title from start, this is somewhat inconsistent with the way vim works. Usually we use < to truncate and keep more trailing characters. Solution: Keep more trailing characters.
* 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.
* 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.
* refactor(ui): separate types for allocated grids and viewportsbfredl2025-04-28
|
* fix(grid): grid_line_start NULL access with 'redrawdebug'Justin M. Keyes2025-01-03
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: This test causes a null pointer dereference: local proc = n.spawn_wait('-l', 'test/functional/fixtures/startup-fail.lua') RUN T1565 startup -l Lua Lua-error sets Nvim exitcode: 241.00 ms OK ==================== File …/build/log/asan.13763 ==================== = …/src/nvim/grid.c:389:12: runtime error: null pointer passed as argument 1, which is declared to never be null = /usr/include/string.h:61:62: note: nonnull attribute specified here = 0 0x55cc2d869762 in grid_line_start …/src/nvim/grid.c:389:5 = 1 0x55cc2d8717ca in grid_clear …/src/nvim/grid.c:618:5 = 2 0x55cc2dbe0f6f in msg_clr_eos_force …/src/nvim/message.c:3085:3 = 3 0x55cc2dbbbdec in msg_clr_eos …/src/nvim/message.c:3061:5 = 4 0x55cc2dbbae2c in msg_multiline …/src/nvim/message.c:281:9 = 5 0x55cc2dbba2b4 in msg_keep …/src/nvim/message.c:364:5 = 6 0x55cc2dbc4992 in emsg_multiline …/src/nvim/message.c:773:10 = 7 0x55cc2dbc5d43 in semsg_multiline …/src/nvim/message.c:824:9 = 8 0x55cc2d9c5945 in nlua_error …/src/nvim/lua/executor.c:158:5 = 9 0x55cc2d9c89fd in nlua_exec_file …/src/nvim/lua/executor.c:1862:5 = 10 0x55cc2d9f4d69 in main …/src/nvim/main.c:637:19 = 11 0x7f319b62a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 = 12 0x7f319b62a28a in __libc_start_main csu/../csu/libc-start.c:360:3 = 13 0x55cc2ced0f64 in _start (…/build/bin/nvim+0xc48f64) (BuildId: 309c83f8d74297c89719dae9c271dd8ec23e64c3) Cause: The tests use `redrawdebug=invalid` by default, but `default_grid_alloc` skips calling `grid_alloc` when not `full_screen`. Solution: Check for `full_screen`.
* refactor(options): autogenerate valid values and flag enums for options (#31089)Famiu Haque2024-11-23
| | | | | | | | | | | | | | Problem: Option metadata like list of valid values for an option and option flags are not listed in the `options.lua` file and are instead manually defined in C, which means option metadata is split between several places. Solution: Put metadata such as list of valid values for an option and option flags in `options.lua`, and autogenerate the corresponding C variables and enums. Supersedes #28659 Co-authored-by: glepnir <glephunter@gmail.com>
* feat(mbyte): support extended grapheme clusters including more emojibfredl2024-08-30
| | | | | | | | | Use the grapheme break algorithm from utf8proc to support grapheme clusters from recent unicode versions. Handle variant selector VS16 turning some codepoints into double-width emoji. This means we need to use ptr2cells rather than char2cells when possible.
* docs: misc (#28609)dundargoc2024-05-15
| | | | | | | | | | | | Closes https://github.com/neovim/neovim/issues/28484. Closes https://github.com/neovim/neovim/issues/28719. Co-authored-by: Chris <crwebb85@gmail.com> Co-authored-by: Gregory Anders <greg@gpanders.com> Co-authored-by: Jake B <16889000+jakethedev@users.noreply.github.com> Co-authored-by: Jonathan Raines <jonathan.s.raines@gmail.com> Co-authored-by: Yi Ming <ofseed@foxmail.com> Co-authored-by: Zane Dufour <zane@znd4.me> Co-authored-by: zeertzjq <zeertzjq@outlook.com>
* fix(showcmd): clear the rest properly (#28420)zeertzjq2024-04-20
|
* vim-patch:9.1.0186: cursor pos wrong on mouse click after eol with 'rl', ↵zeertzjq2024-03-18
| | | | | | | | | | | | 've' and conceal (#27903) Problem: Wrong cursor position when clicking after end of line with 'rightleft', 'virtualedit' and conceal. Solution: Set values in ScreenCols[] also with SLF_RIGHTLEFT. Also fix off-by-one cursor position with 'colorcolumn' (zeertzjq). closes: vim/vim#14218 https://github.com/vim/vim/commit/deb2204bffa075ed5485415fc2dbd20e75d87ea4
* vim-patch:9.1.0184: Cursor pos wrong when clicking with conceal and wrap ↵zeertzjq2024-03-17
| | | | | | | | | | | | | | | | (#27890) Problem: Cursor position wrong when clicking with conceal and wrap. Solution: Use the virtual column of the last char for ScreenCols[] in boguscols. Remove use of MAXCOL in ScreenCols[]. Rename third argument of wlv_screen_line() to "clear_end" as that's clearer what it does (zeertzjq). related: 14192 closes: vim/vim#14200 https://github.com/vim/vim/commit/d0c1b7723f7e73763597af2f97a53d94ab7ed020 Rename win_put_linebuf() to wlv_put_linebuf().
* fix(mbyte): fix bugs in utf_cp_*_off() functionsVanaIgr2024-02-26
| | | | | | Problems: - Illegal bytes after valid UTF-8 char cause utf_cp_*_off() to fail. - When stream isn't NUL-terminated, utf_cp_*_off() may go over the end. Solution: Don't go over end of the char of end of the string.
* refactor: rename w_float_config to w_config #27419Will Hopkins2024-02-10
| | | Follows up on rename of `FloatConfig` to `WinConfig` in #27397.
* refactor: IWYU (#27186)zeertzjq2024-01-25
|
* fix(grid): handle clearing half a double-width char (#27023)zeertzjq2024-01-15
|
* refactor(IWYU): fix headersdundargoc2024-01-11
| | | | | | Remove `export` pramgas from defs headers as it causes IWYU to believe that the definitions from the defs headers comes from main header, which is not what we really want.
* refactor(screen): simplify grid_clear() and win_draw_end()bfredl2024-01-11
| | | | | | | | | | | grid_put_linebuf() used grid_clear() internally to handle clearing the left part of a rightleft line. By reimplementing that internally, we can instead use grid_put_linebuf() as the implementation of grid_clear(), which in the end is a net reduction of code as grid_fill() is used for nothing else. win_draw_end: Implement "draw_margin" on a per-row basis which closer reflects how terminals work. Also use the magic mirror for 'rightleft'
* refactor(options): use schar_T representation for fillchars and listcharsbfredl2024-01-08
| | | | | | | | | | | A bit big, but practically it was a lot simpler to change over all fillchars and all listchars at once, to not need to maintain two parallel implementations. This is mostly an internal refactor, but it also removes an arbitrary limitation: that 'fillchars' and 'listchars' values can only be single-codepoint characters. Now any character which fits into a single screen cell can be used.
* refactor: follow style guidedundargoc2023-12-30
|
* refactor: use `bool` to represent boolean valuesdundargoc2023-12-19
|
* docs: add style rule regarding initializationdundargoc2023-12-18
| | | | | Specifically, specify that each initialization should be done on a separate line.
* refactor: free more reachable memory with EXITFREE (#26349)zeertzjq2023-12-02
| | | Discovered using __sanitizer_print_memory_profile().
* refactor: move some constants out of vim_defs.h (#26298)zeertzjq2023-11-29
|
* refactor: fix headers with IWYUdundargoc2023-11-28
|
* feat(decoration): allow conceal_char to be a composing charbfredl2023-11-28
| | | | | | | | decor->text.str pointer must go. This removes it for conceal char, in preparation for a larger PR which will also handle the sign case. By actually allowing composing chars for a conceal chars, this becomes a feature and not just a refactor, as a bonus.
* refactor: rename types.h to types_defs.hdundargoc2023-11-27
|
* fix(grid): don't draw beyond max column (#26172)zeertzjq2023-11-24
|
* refactor: enable formatting for ternariesdundargoc2023-11-20
| | | | | | This requires removing the "Inner expression should be aligned" rule from clint as it prevents essentially any formatting regarding ternary operators.
* refactor(grid): make screen rendering more multibyte than ever beforebfredl2023-11-17
| | | | | | | | | | | | | | | | | | Problem: buffer text with composing chars are converted from UTF-8 to an array of up to seven UTF-32 values and then converted back to UTF-8 strings. Solution: Convert buffer text directly to UTF-8 based schar_T values. The limit of the text size is now in schar_T bytes, which is currently 31+1 but easily could be raised as it no longer multiplies the size of the entire screen grid when not used, the full size is only required for temporary scratch buffers. Also does some general cleanup to win_line text handling, which was unnecessarily complicated due to multibyte rendering being an "opt-in" feature long ago. Nowadays, a char is just a char, regardless if it consists of one ASCII byte or multiple bytes.
* refactor: follow style guidedundargoc2023-11-13
| | | | | | - reduce variable scope - prefer initialization over declaration and assignment - use bool to represent boolean values
* build: remove PVSdundargoc2023-11-12
| | | | | | | We already have an extensive suite of static analysis tools we use, which causes a fair bit of redundancy as we get duplicate warnings. PVS is also prone to give false warnings which creates a lot of work to identify and disable.
* refactor(grid): reimplement 'rightleft' as a post-processing stepbfredl2023-11-05
| | | | | | | | | | | | | problem: checks for wp->w_p_rl are all over the place, making simple things like "advance column one cell" incredibly complicated. solution: always fill linebuf_char[] using an incrementing counter, and then mirror the buffer as a post-processing step This was "easier" that I first feared, because the stupid but simple workaround for things like keeping linenumbers still left-right, e.g. "mirror them and them mirror them once more" is more or less what vim did already. So let's just keep doing that.
* refactor(grid): implement rightleftcmd as a post-processing stepbfredl2023-11-03
| | | | | | | Previously, 'rightleftcmd' was implemented by having all code which would affect msg_col or output screen cells be conditional on `cmdmsg_rl`. This change removes all that and instead implements rightleft as a mirroring post-processing step.
* docs: small fixes (#25585)dundargoc2023-10-29
| | | | Co-authored-by: tmummert <doczook@gmx.de> Co-authored-by: parikshit adhikari <parikshitadhikari@gmail.com>
* vim-patch:8.1.0822: peeking and flushing output slows down execution (#25629)zeertzjq2023-10-14
| | | | | | | Problem: Peeking and flushing output slows down execution. Solution: Do not update the mode message when global_busy is set. Do not flush when only peeking for a character. (Ken Takata) https://github.com/vim/vim/commit/cb574f415486adff645ce384979bfecf27f5be8c
* fix(grid): add start column when getting char on line (#25627)zeertzjq2023-10-13
|
* refactor(grid): do arabic shaping in one placebfredl2023-10-08
| | | | | | | | | | | | | | | | | | | | | | | | | | | The 'arabicshape' feature of vim is a transformation of unicode text to make arabic and some related scripts look better at display time. In particular the content of a cell will be adjusted depending on the (original) content of the cells just before and after it. This is implemented by the arabic_shape() function in nvim. Before this commit, shaping was invoked in four different contexts: - when rendering buffer text in win_line() - in line_putchar() for rendering virtual text - as part of grid_line_puts, used by messages and statuslines and similar - as part of draw_cmdline() for drawing the cmdline This replaces all these with a post-processing step in grid_put_linebuf(), which has become the entry point for all text rendering after recent refactors. An aim of this is to make the handling of multibyte text yet simpler. One of the main reasons multibyte chars needs to be "parsed" into codepoint arrays of composing chars is so that these could be inspected for the purpose of shaping. This can likely be vastly simplified in many contexts where only the total length (in bytes) and width of composed char is needed.