aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/bufwrite.c
Commit message (Collapse)AuthorAge
* vim-patch:9.2.1176: Vim writes test file "4913" (#42310)zeertzjq8 days
| | | | | | | | | | | | | | | | | | | | Problem: Vim writes test file "4913". Solution: Write probe file as (hidden) swap file, so file watchers can apply standard ignore patterns (Keith Smiley). This logic creates and deletes an arbitrary numbered filename. I found that some file system watchers that otherwise respect VCS ignore patterns can pick this file up and potentially rerun because of that. This changes the arbitrary filename to use the swp extension so it's more likely to already be ignored by the VCS. related: vim/vim#5145 related: neovim/neovim#3460 closes: vim/vim#21468 https://github.com/vim/vim/commit/7eb646597d6b6be42f5941cf194938afa3af5208 Co-authored-by: Keith Smiley <keithbsmiley@gmail.com>
* fix(write): crash when pre-write autocmd changes cwd #41840Shantanu Raj2026-09-11
| | | | | | | | | | Problem: A :cd, or a window-context restore (nvim_win_call(), win_execute()), in a pre-write autocmd clears the short name of a buffer outside the current directory. buf_write then copies a NULL filename and crashes. Solution: Rebind short-name aliases to b_fname, which retains the effective filename. Add a regression for a BufWritePre autocmd changing cwd away from the file.
* vim-patch:9.2.1005: backupcopy=auto overwrites a file in place with umask ↵zeertzjq2026-08-26
| | | | | | | | | | | | | | | | (#41502) Problem: backupcopy=auto overwrites a file in place when umask is restrictive. The probe treats permission restore as impossible and writes in place, keeping the same inode. Solution: When creating the probe file, open() applies umask, so a 0644 file becomes 0600 with umask 0077. Use fchmod() to fix the permissions of the probe (Pranav Dwivedi). closes: vim/vim#21137 https://github.com/vim/vim/commit/fd8aea135d146915e921699cd23887b654182810 Co-authored-by: Pranav Dwivedi <dwivedipranav2021@gmail.com>
* fix(write): :write can target a garbage filename #41432Justin M. Keyes2026-08-22
| | | | | | | | | | | | | | | | | | | | | | | | | Problem: `buf_write()` captures the buffer's `fname`/`sfname`/`ffname`, then emits its progress-message before opening the file. This may run user code synchronously: the `Progress` autocmd, and the `msg_show` handler of an in-process UI (ui2). Either can change the CWD, and `shorten_fnames()` then frees/reallocs every buffer's short name. The rest of `buf_write()` reads the freed name... "foldtext()" [New] 41L, 997B written E212: Can't open file for writing: illegal byte sequence ASAN, with ui2 enabled and a `BufEnter` handler that runs `:lcd`: READ path_skip_sep <- path_tail <- match_file_list <- buf_write FREE shorten_buf_fname <- shorten_fnames <- update_cwd <- set_curbuf <- win_set_buf <- nvim_open_win <- ui2 msg_show handler <- ui_call_msg_show <- msg_ext_ui_flush <- buf_write Solution: Copy the names after the `*Pre` autocmds. Note: `readfile()` has the same shape, but its messages pass no progress-id, so they skip `msg_progress()`. Safe, for now...
* refactor(path): pathcmp() #41035tao2026-08-07
| | | | | | | | | | | | | | | | | | | | | | Problem: Redudant code Solution: Add `path_fold_char()` to normalize path sep. Refactor `pathcmp()` and `path_fnamencmp()` into `path_cmp`. | feature | pathcmp | path_fnamencmp | path_cmp(now) | | ------------------------ | -------------- | -------------- | ------------- | | case folding | `mb_toupper()` | `utf_fold()` | `utf_fold()` | | consults fileignorecase | ✅ | ✅ | `ic` param | | `maxlen` | ✅ | ✅ | ✅ | | `/` == `\` | ✅ | ✅ | ✅ | | MSWIN drive letter | ❌ | ✅ | ✅ | | sep affects sorting | ✅ | ❌ | ✅ | | ignores a trailing slash | ✅ | ❌ | ✅ | Refactor `path_fnamecmp` and `path_full_compare` into `path_equal`, with flags controlling "no filesystem" comparison (i.e. `path_cmp`), env variables expansion, absolute path resolution and filesystem access.
* fix(progress): ins-compl progress-msg during pum #41226Justin M. Keyes2026-08-07
| | | | | | | | | Problem: The insert-mode completion progress-message is in "running" state while the user is selecting an item. That is noisy and unwanted UX; it was only intended for the "Scanning..." task. Solution: End the progress-msg just after `ins_compl_show_statusmsg`.
* fix(messages): dangling progress-messages #41222Justin M. Keyes2026-08-07
| | | | | | | | | | Problem: Some builtin features emit progress-messages which never "complete". - On failure, `:write` does not complete the progress-msg it started. - ins-completion never ends its "Scanning..." message. Solution: - `buf_write()` emits "failed" status on failure. - `ins_compl_stop()` ends the completion one.
* fix(messages): :read starts a "bufwrite" progress #41219Justin M. Keyes2026-08-07
| | | | | | | | | | | Problem: filemess() treats an empty suffix as "a buffer write is starting", but readfile() calls it that way too. So ":read" (and ":edit", …) opens a `nvim.bufwrite "<file>"` progress that is never completed. Users of e.g. ghostty will see a stuck "progress" spinner. Solution: Only `buf_write()` starts the progress, via `filemess_progress()`.
* fix(bufwrite): coverity "uninitialized member" #41104Justin M. Keyes2026-08-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | CID 652079: (UNINIT) /src/nvim/bufwrite.c: 1413 in buf_write() 1407 // only makes sense at the start of the file. 1408 if (buf->b_p_bomb && !write_bin && (!append || perm < 0)) { 1409 write_info.bw_len = make_bom(buffer, fenc); 1410 if (write_info.bw_len > 0) { 1411 // don't convert 1412 write_info.bw_flags = FIO_NOCONVERT | wb_flags; >>> CID 652079: (UNINIT) >>> Using uninitialized value "write_info.bw_first" when calling "buf_write_bytes". 1413 if (buf_write_bytes(&write_info) == FAIL) { 1414 end = 0; 1415 } else { 1416 nchars += write_info.bw_len; 1417 } 1418 } /src/nvim/bufwrite.c: 1453 in buf_write() 1447 *s = c; 1448 } 1449 s++; 1450 if (++write_info.bw_len != bufsize) { 1451 continue; 1452 } >>> CID 652079: (UNINIT) >>> Using uninitialized value "write_info.bw_first" when calling "buf_write_bytes". 1453 if (buf_write_bytes(&write_info) == FAIL) { 1454 end = 0; // write error: break loop 1455 break; 1456 } 1457 nchars += bufsize - write_info.bw_len; 1458 s = buffer + write_info.bw_len;
* 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.
* 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(ctx): drop aucmd_prepbuf/aucmd_restbuf #40692Justin M. Keyes2026-07-11
|
* fix(bufwrite): cursor flicker on :writeJustin M. Keyes2026-07-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | PROBLEM: Cursor briefly flickers in cmdline when the "written" message is printed (very noticeable in Neovide with cursor animation). SOLUTION: - Mark UI "busy" (cursor hidden) while emitting the message, as done for the search message (cb2ca54331cd). - Note: ff68fd6b8a84 moved the message from `filemess()` into `buf_write..msg_progress`. - Fix a bug in `tui.c:flush_buf` which manifested after this change. See ANALYSIS below. https://github.com/libuv/libuv/issues/5182 ANALYSIS: After this change... ui_busy_start(); set_keep_msg(msg_progress(IObuff, msg_id, "success", 0, true, true), 0); ui_busy_stop(); ...ASAN analyzer fails on tui_spec.lua test "with non-tty (pipe) stdout/stderr": 2026-07-04T14:09:28.9521023Z = ==32405==ERROR: AddressSanitizer: ABRT on unknown address 0x03e900007e95 ... 4 0x7f5506a288fe in abort stdlib/abort.c:79:7 5 0x559afd7113a2 in uv__epoll_ctl_flush build/src/libuv/src/unix/linux.c:1335:7 6 0x559afd710a81 in uv__io_poll build/src/libuv/src/unix/linux.c:1448:9 7 0x559afd6f67a7 in uv_run build/src/libuv/src/unix/core.c:460:5 8 0x559afd2a72cc in flush_buf nvim/tui/tui.c:2642:5 9 0x559afd2bce9f in tui_flush nvim/tui/tui.c:1747:3 10 0x559afd2f39a0 in ui_client_event_flush nvim/auto/ui_events_client.generated.h:64:3 11 0x559afcb8e014 in parse_msgpack nvim/msgpack_rpc/channel.c:255:11 12 0x559afcb840e7 in receive_msgpack nvim/msgpack_rpc/channel.c:217:5 13 0x559afc53b2af in read_event nvim/event/rstream.c:180:23 14 0x559afc53ad52 in invoke_read_cb nvim/event/rstream.c:233:3 15 0x559afc5382d6 in read_cb nvim/event/rstream.c:135:3 16 0x559afd707b25 in uv__read build/src/libuv/src/unix/stream.c:1145:7 17 0x559afd70744a in uv__stream_io build/src/libuv/src/unix/stream.c:1208:5 18 0x559afd6f727e in uv__io_cb build/src/libuv/src/unix/core.c:930:5 19 0x559afd710d7a in uv__io_poll build/src/libuv/src/unix/linux.c:1546:11 20 0x559afd6f67a7 in uv_run build/src/libuv/src/unix/core.c:460:5 21 0x559afc526e2d in loop_uv_run nvim/event/loop.c:59:3 22 0x559afc526aa4 in loop_poll_events nvim/event/loop.c:80:26 23 0x559afd2fdbb7 in ui_client_run nvim/ui_client.c:172:5 24 0x559afc920d7b in main /home/runner/work/neovim/neovim/src/nvim/main.c:355:5 25 0x7f5506a2a1c9 in __libc_start_call_main main.h:58:16 26 0x7f5506a2a28a in __libc_start_main csu/../csu/libc-start.c:360:3 27 0x559afbd6d254 in _start The abort requires two rare conditions: 1. a `uv_write` whose buffer array *ends* in a zero-length buffer, which only happens by "flush while cursor-hidden". 2. an output fd that *epoll cannot watch*. The only CI test with such an fd is tui_spec.lua "with non-tty (pipe) stdout/stderr", which runs a TUI with `stdout > /dev/null`, then runs `:w testF`, which triggers the "written" message. Our change guarantees trailing-empty flushes (`:w` fires busy + `ui_flush()` while busy) in the only test that runs a TUI on `/dev/null`. 0. In a normal (non-busy) no-sync flush, post always contains `cursor_normal`. 1. Our change emits: ``` busy_start → msg_progress("…written") → ui_flush → busy_stop ``` 2. TUI flushes *while busy*, so `should_invisible() = true` and `flush_buf` skips the cursor-restore string (`bufs[2]` is zero-length). 3. libuv *cannot complete* a write whose tail is a zero-length buffer: EVERY trailing-empty write goes through epoll, even when every byte was already written. https://github.com/libuv/libuv/issues/5182 4. In `tui_spec.lua:3298`, the output fd is `/dev/null`, whose kernel `file_operations` has no `.poll` method (`drivers/char/mem.c`), so `EPOLL_CTL_ADD` fails with `EPERM`. Trailing empty buffers are semantically pointless, and libuv punishes them: forced async, one epoll round-trip *per trailing empty*, plus a 0-byte `write()` syscall. Helped-by: Shougo Matsushita <Shougo.Matsu@gmail.com> Helped-by: Fred Sundvik <fsundvik@gmail.com>
* refactor: simplify aucmd_restbuf usage #39879Justin M. Keyes2026-05-19
| | | | | | | | Problem: `aucmd_restbuf` must be guarded in case `aucmd_prepbuf` wasn't called. Solution: Update `aucmd_restbuf` to be a no-op if `aucmd_prepbuf` wasn't called. This requires `aco` to be zero-initialized.
* build: strncat warning in buf_write #39684phanium2026-05-08
| | | | | | | | | | | | | | | | | | | | | To make gcc happy ``` src/nvim/bufwrite.c: In function ‘buf_write’: src/nvim/bufwrite.c:1674:5: warning: ‘strncat’ specified bound depends on the length of the source argument [-Wstringop-overflow=] 1674 | strncat(msg_id + 14, IObuff, strlen(IObuff) - 1); | ^ src/nvim/bufwrite.c:1674:34: note: length computed here 1674 | strncat(msg_id + 14, IObuff, strlen(IObuff) - 1); | ^ src/nvim/fileio.c: In function ‘filemess’: src/nvim/fileio.c:137:5: warning: ‘strncat’ specified bound depends on the length of the source argument [-Wstringop-overflow=] 137 | strncat(msg_id + 14, IObuff, strlen(IObuff) - 1); | ^ src/nvim/fileio.c:137:34: note: length computed here 137 | strncat(msg_id + 14, IObuff, strlen(IObuff) - 1); | ^ ```
* fix(messages): disallow source="nvim" progress msg #39315luukvbaal2026-05-06
| | | | | | | | | Problem: Internal progress messages use the "nvim" source (since ff68fd6b), plugins shouldn't be allowed to set the progress message source to "nvim". The message ID used for internal progress messages is not identifiable as such. Solution: Disallow setting opts->source to "nvim" with nvim_echo(). Refactor msg_progress() and callees to bypass nvim_echo(). Prepend message id for internal progress messages with "nvim.".
* fix(messages): "progress" kind for busy messages #39280luukvbaal2026-04-21
| | | | | | | | | | Problem: The "Scanning:" completion, bufwrite, and indent (there may be more) messages which indicate progress can use the "progress" kind for their msg_show event. Indent message does not have a kind. Solution: Emit these messages with the "progress" kind. Set the message id to the replaced kind so that a UI knows to replace it (and to provide a migration path in case a UI was distinguishing these messages for whatever reason).
* build: update clang v21, fix warningsdundargoc2026-04-14
| | | | | - `src/nvim/ex_cmds_defs.h`: use "U" instead of "u" per `readability-uppercase-literal-suffix`
* fix: don't make path empty when truncating trailing slashes (#38844)zeertzjq2026-04-07
| | | | | | | | | | | | | | | | | | | | Fixes the following Coverity warning: *** CID 549779: Integer handling issues (INTEGER_OVERFLOW) /src/nvim/undo.c: 717 in u_get_undo_file_name() 711 dir_name[dir_len] = NUL; 712 713 // Remove trailing pathseps from directory name 714 char *p = &dir_name[dir_len - 1]; 715 while (vim_ispathsep(*p)) { 716 *p-- = NUL; >>> CID 549779: Integer handling issues (INTEGER_OVERFLOW) >>> Expression "dir_len--", where "dir_len" is known to be equal to 0, underflows the type of "dir_len--", which is type "size_t". 717 dir_len--; 718 } 719 720 bool has_directory = os_isdir(dir_name); 721 if (!has_directory && *dirp == NUL && !reading) { 722 // Last directory in the list does not exist, create it.
* fix(bufwrite.c): handle invalid byte sequences #37363Kevin Goodsell2026-02-12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: bw_rest was used as an extra buffer to save incomplete byte sequences between calls to buf_write_bytes. Besides being unnecessarily complicated, this introduced a number of issues: 1) The bytes stored in bw_rest could still be there at the end of writing the file, never having been written, thus losing some of the file content on write. 2) bw_rest was not cleared out after the "checking_conversion" phase, leaving them to affect the written file content during the writing phase, corrupting the file. 3) bw_rest could contain extra bytes that need to be written to the output buffer during a buf_write_convert call, potentially before any bytes are consumed. But some conversions are in-place, without a separate output buffer. Writing bytes from bw_rest to the "output" buffer actually overwrote bytes from the input buffer before they were read, corrupting the data to be written. 4) The extra bytes in bw_rest that need to be written to the conversion output buffer were not originally accounted for in the size calculation for the output buffer, causing a buffer overflow (previously fixed in Vim patch 9.1.2028). Solution: Rather than maintaining a separate buffer, the unconverted bytes at the end of the buffer can just be shifted to the beginning of the buffer, and the buffer size updated. This requires a bit of refactoring, and buf_write_convert and buf_write_convert_with_iconv need to report the number of bytes they consumed so that buf_write_bytes can handle the remaining bytes. Following conversion, bw_buf can be checked for any remaining bytes. Leftover bytes in this case result in a conversion error, which is better than silently dropping them. A short section of dead code was removed from buf_write_convert, for converting a non-UTF-8 buffer to UTF-8. Neovim buffers are always UTF-8. A few additional tests for iconv conversions have been added. Vim's iconv tests are disabled in Neovim because they use unsupported values for 'encoding'.
* refactor(fileio.c): avoid downcasting in {read,write}_eintr() (#37323)zeertzjq2026-01-09
|
* vim-patch:9.1.2028: [security]: Buffer-overflow with incomplete multi-byte ↵zeertzjq2025-12-28
| | | | | | | | | | | | | chars (#37133) Problem: Buffer overflow in buf_write() when converting incomplete multi-byte characters (Kevin Goodsell) Solution: Make the buffer slightly larger closes: vim/vim#19007 https://github.com/vim/vim/commit/f99de42a9fbc2caaac2741a275b6c25421582cf4 Co-authored-by: Christian Brabandt <cb@256bit.org>
* vim-patch:9.1.2024: 'fsync' option cannot be set per buffer (#37129)zeertzjq2025-12-28
| | | | | | | | | | | Problem: 'fsync' option cannot be set per buffer Solution: Make 'fsync' option global-local (glepnir) closes: vim/vim#19019 https://github.com/vim/vim/commit/4d5b30372663e8ea356b25fe94334558c6ae283f Co-authored-by: glepnir <glephunter@gmail.com>
* refactor(editor): extract backup name generation logic #37001yilisharcs2025-12-17
| | | | | | Problem: The logic for generating backup file names is duplicated in `buf_write_make_backup` and difficult to reuse. Solution: Extract name generation logic into `buf_get_backup_name`.
* vim-patch:8.1.1957: more code can be moved to evalvars.cJan Edmund Lazo2025-10-05
| | | | | | | | | | Problem: More code can be moved to evalvars.c. Solution: Move code to where it fits better. (Yegappan Lakshmanan, closes vim/vim#4883) https://github.com/vim/vim/commit/da6c03342117fb7f4a8110bd9e8627b612a05a64 Co-authored-by: Bram Moolenaar <Bram@vim.org>
* vim-patch:9.1.1688: potential buffer overrun in bufwrite.c (#35497)zeertzjq2025-08-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: potential buffer overrun in bufwrite.c Solution: Use a temporary variable (John Marriott) In my Windows 11 Pro 64-bit build MAXPATHL is 1024 and IOSIZE is 1025. In my Archlinux Linux 64-bit build MAXPATHL is 4096 and IOSIZE is 1025. In funuction buf_write(): There is a check (line 713) that makes sure the length of fname is less than MAXPATHL. There is a call to STRCPY() (line 1208) which copies the string at fname into IObuff (which has size IOSIZE). For Unix builds fname is set to sfname which may or may not be shorter. However, if sfname is NULL sfname is set to fname. Therefore, in builds where MAXPATHL > IOSIZE (eg in my linux build), it is theoretically possible for the STRCPY() call to exceed the bounds of IObuff. This PR addresses this by copying fname into a local variable that has the same maximum size as fname. In addition: Given that the filename is unconditionally overwritten in the for loop, only copy the directory portion of fname. Move variable i closer to where it is used. closes: vim/vim#18095 https://github.com/vim/vim/commit/a19b019b8745f1c91e42c2b9440bddebfa67a17a Co-authored-by: John Marriott <basilisk@internode.on.net>
* 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)!: 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.
* feat(ui)!: emit prompt "messages" as cmdline events #31525luukvbaal2025-01-02
| | | | | | | Problem: Prompts are emitted as messages events, where cmdline events are more appropriate. The user input is also emitted as message events in fast context, so cannot be displayed with vim.ui_attach(). Solution: Prompt for user input through cmdline prompts.
* refactor: iwyu #31637Justin M. Keyes2024-12-23
| | | Result of `make iwyu` (after some "fixups").
* fix(messages): no message kind for :write messages #31519Tomasz N2024-12-10
| | | | - Problem: cannot replace the initial bufwrite message (from `filemess`) by the final one (`"test.lua" [New] 0L, 0B written`), when using `vim.ui_attach`. - Solution: add kind to both messages.
* 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>
* refactor(highlight): make enum of builtin highlights start with 1bfredl2024-11-13
| | | | | This makes it possible to use HLF_ values directly as highlight id:s and avoids +1 adjustments especially around messages.
* refactor(message): propagate highlight id instead of attrsLuuk van Baal2