aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/buffer_defs.h
Commit message (Collapse)AuthorAge
* feat(multicursor): 'follow' option #42095Justin M. Keyes2026-09-27
| | | | | | | | Problem: - gQ does not restore follow-mode (q=). - Users/plugins have no way to check if follow-mode is enabled. Solution: Introduce buffer-local 'follow' option.
* refactor(charset)!: delete 'isprint' and cleanup 'iskeyword' and friendsbfredl2026-09-22
| | | | | | | | | | | | | In the `enc=utf-8` only world, the 'isprint' option is quite obsolete. The function is only consulted for decoded U+0080 to U+00FF chars whose printability is defined by the unicode charset, just like higher codepoints. Meanwhile, invalid `\x80` to `\xFF` bytes are always unprintable. Disentangle 'iskeyword', 'isfname' and 'isident' from each other by giving them all separate bitsets. Now these can be updated individually. These updaters can back out of errors gracefully, no need for extra panic logic in option[str].c to restore partially updated chartabs.
* fix(multicursor): selection by API/Lua from mapping #41999Justin M. Keyes2026-09-19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: A Visual selection produced by a Lua mapping is captured as the keys it fed (`:norm!`), so non-primary cursors get the wrong selection. Examples: - API cursor-moves around a fed "o" are lost. - `setpos("'<")` + "gv" reselects the primary's marks (treesitter `an`). - A mapping that feeds an absolute selection (`:norm! <Esc>`, then `norm! 3GV6G`). Solution: Classify fed keys as `lossy` if their produced selection differs from the selection at mapping-end, or fed-key-start: the mapping moved it by other means (API). Same idea as `composite.lossy` LHS-replay. Now the captured Visual session contains the mapping's own cmd (`<Cmd>…`, `:…`, or a Lua mapping-id) as one subatom, instead of the keys it fed. E.g. `v…<K_LUA id>` instead of `v…V…G`. Also affects dot-repeat ("."). A `:norm!` that ends a typed selection keeps the Visual session (`vatom`) open (instead of the usual `atom_visual_reset()` plus emit/stage), so the enclosing user frame (the mapping's `<Cmd>`/Lua, or a typed `:norm!`) can complete or replace it. - A child frame re-entering Visual does not restart it, so a later `norm! V` continues that session instead of a new `kVatomFed` one. - At end of the user (toplevel) frame, the fed subatoms are dropped in favor of the mapping's own atom: as a subatom if Visual is active, else as the session's closing suffix.
* vim-patch:9.2.1036: syntax highlighting is slower than necessary (#41644)zeertzjq2026-09-03
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: While advancing the syntax highlighting, store_current_state() calls syn_stack_find_entry() about once per parsed line, and that function rescans the state-cache list from its head every time. With the list capped at 1000 entries this linear rescan dominates the cost of highlighting a large file. Solution: Keep a cached position to the entry last located in the list and resume the scan from it when it is at or before the wanted line, advancing the finger as new states are stored (Julien Voisin). The list is sorted by line number, so when the remembered entry is at or before the wanted line the answer can only follow it, never precede it; resuming from there returns the same entry as a scan from the head. The "at or before" guard keeps this correct for any lookup order: a backward or random-access lookup whose remembered entry is past the wanted line falls back to a full scan. The pointer is cleared whenever an entry is freed, the array is reallocated or the block is freed, so it cannot dangle. Parsing the syntax of a 20000-line C file is about a third faster, a 5000-line file about a quarter faster, benchmarked via something like this: ``` call synID(1, 1, 1) " warm-up let s = reltime() for l in range(1, line('$')) | call synID(l, 1, 1) | endfor call writefile([reltimefloat(reltime(s))], $T) ``` closes: vim/vim#21166 https://github.com/vim/vim/commit/f1b454912996d6417acd0d738de0eb7b60902c56 Co-authored-by: Julien Voisin <julien.voisin@dustri.org>
* fix(multicursor): 'autocomplete' during insert-cascade raises E565 #41625Justin M. Keyes2026-09-02
| | | | | | | | | | Problem: With mcursors and 'autocomplete', a non-literal key (`<BS>`) during an active completion attempts to insert-cascade, which attempts a nested `edit()`, which refuses with E565. Solution: Defer the flush while completion is active; the pending keys will be handled later.
* fix(mappings): replaying a deleted Lua mapping is UBJustin M. Keyes2026-08-31
| | | | | | | | | | | | | | | | | | | | | | | | | Problem: Replaying a deleted Lua mapping, may call an arbitrary function. RHS of a Lua mapping embeds its LuaRef (`<K_LUA><ref><CR>`). The raw keys may outlive the ref (redobuff ".", CmdAtom `keys`). If the mapping is deleted, replaying it either (1) dereferences a freed registry slot, or (2) calls whatever callback reused the slot (autocmd, timer, other mapping). Solution: Assign a monotonic (never recycled) id to Lua mappings and encode the mapping keys as `<K_LUA><id><CR>`. Note: in the case of Vimscript, a deleted function raises E117, but if the function is redefined with the same name, the mapping will find it. Alternatives?: - Globally ensure `LuaRef` ids are not recycled. - Problem: could exhaust `int` in a long-lived Nvim session? Also, difficult to impl bc the "recycling" is done by `luaL_ref` itself. ref: 5ac2e47acc999472042df4f10f8f7b5ffa72ba3e
* feat(editor): `:bcd` changes buffer-local directorysaher2026-08-04
| | | | | | | | | | | | | | | | | | Problem: No way to set a buffer-local directory. Use-cases: - "Root dir" for LSP (and the "project" concept). - `:terminal` OSC 7 Solution: Add `:bcd` command. - Extend `getcwd()` to take a third arg; `getcwd(-1, -1, bunfr)` returns the buffer-local working directory. - Buffer-local directories have less priority than window-local ones, and more priority than tab-local ones. Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* 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>
* vim-patch:9.2.0869: buf_copy_options() can lose the P_INSECURE flag (#41040)zeertzjq2026-07-29
| | | | | | | | | | | | | | | | | | Problem: An insecurely-set 'indentexpr', 'formatexpr', 'includeexpr' or 'complete' value can end up evaluated outside the sandbox after buf_copy_options() and clears the flag. Solution: Copy the insecure flag alongside the value in buf_copy_options(), and make 'complete' a per-buffer insecure-flags field Supported by AI. closes: vim/vim#20861 https://github.com/vim/vim/commit/35f7fdfdfb036028cc8760d7c1556361bb85206a I'm a bit hesitant to port this, but it's a follow-up to #39452. Co-authored-by: Christian Brabandt <cb@256bit.org>
* docs: misc #40847Justin M. Keyes2026-07-25
| | | | Co-authored-by: Barrett Ruth <br@barrettruth.com> Co-authored-by: Nathan Zeng <nathan.j.zeng@gmail.com>
* refactor: 'previewpopup' #40945Justin M. Keyes2026-07-24
| | | | - drop w_maxwidth/w_maxheight, calculate them on-demand from 'previewpopup' (this is cheap bc of `opt_keyset`)
* feat(float): 'previewpopup' option #26799glepnir2026-07-23
| | | | | | | | Problem: The preview-window (:pedit, etc.) always uses a split, but it would be useful as a floatwin (or "popup"). Solution: Support Vim's 'previewpopup' option.
* refactor(window): extract w_kind for window role #40830glepnir2026-07-20
| | | | | | | | Problem: w_float_is_info conflates a window's role with its floating layout, which are orthogonal properties. Solution: Replace w_float_is_info with a w_kind enum for the window's role.
* refactor(globals): group Visual-mode globals in VisualState #40777Justin M. Keyes2026-07-16
|
* fix(filetype): trigger FileType after BufReadCmd #40679Barrett Ruth2026-07-13
| | | | | | | | | | | | | Problem: A successful `BufReadCmd` can leave an existing `filetype` without rerunning its `FileType` setup, so state cleared during reload may not be restored. This also causes `:edit`/reload syntax `directoryDirectory` groups to not be reapplied. Solution: After `BufReadCmd` handles a read, trigger `FileType` for the existing `filetype` if no `FileType` event fired during the read.
* refactor(core): group insert-mode globals in `InsState` #40712Justin M. Keyes2026-07-13
| | | | | | | | | Problem: Insert-mode globals are scattered. Solution: Group them into one struct. Besides improving readability and discoverability, this greatly helps with save/restore of an insert-mode session.
* vim-patch:9.2.0707: completion: popup misplaced when text before it is ↵zeertzjq2026-06-23
| | | | | | | | | | | | | | | | | | concealed (#40374) Problem: When the cursor line has concealed text before the start of the completion, the insert-mode completion popup is drawn at the wrong screen column and the cursor no longer lines up with the completed text. Solution: Record the concealed width before the cursor on its screen line in a new `win_T` field while `win_line()` draws it, subtract it in `pum_display()` to place the menu over the visible text, and redraw the cursor line so `win_line()` corrects the cursor too. closes: vim/vim#20539 https://github.com/vim/vim/commit/d167c50de4b954e5ddd97208187c5b3b77dd89cc Co-authored-by: Barrett Ruth <br@barrettruth.com>
* feat(column): per row click handlers for 'statuscolumn' (#40265)luukvbaal2026-06-20
| | | | | | | | | | | | | | Problem: - Current 'statuscolumn' click label caveat is restrictive. - v:virtnum is not unique to a line if it has both above and below virtual lines. - 'statuscolumn' click handler may expect v:virt/lnum to be set. Solution: - Store per-row click definitions for the statuscolumn in a (nested line/virt number) map. - Implement strategy that gives each 'statuscolumn' row a unique v:virtnum. - Set v:virt/lnum when determining which line is clicked.
* vim-patch:9.2.0635: checking the syntax contains/cluster list is slow (#40230)zeertzjq2026-06-14
| | | | | | | | | | | | | | | Problem: Deciding whether a group is in a "contains"/cluster list scans the list and expands clusters on every check, which is slow for syntaxes with large lists (e.g. plugins such as netrw). Solution: Resolve each list once into a sorted, cluster-expanded set of group IDs and use a binary search; cache it per syntax block and drop the cache when syntax definitions change (Hirohito Higashi). closes: vim/vim#20490 https://github.com/vim/vim/commit/48fbae4378ab9bb6e7fcbd2480544847eac10cd7 Co-authored-by: Hirohito Higashi <h.east.727@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(events)!: support `Optionset modified`, drop BufModifiedSet #35610glepnir2026-04-27
| | | | | | | | | Problem: BufModifiedSet autocmd only triggered for current buffer during redraw, causing delayed events when :wa writes non-current buffers. Solution: - Use the aucmd_defer approach to implement `Optionset modified`. - Drop BufModifiedSet.
* 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.0356: Cannot apply 'scrolloff' context lines at end of filezeertzjq2026-04-22
| | | | | | | | | | | | 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>
* vim-patch:9.2.0378: Using int as bool type in win_T struct (#39263)zeertzjq2026-04-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Several win_T fields are declared as "int" or "char" but are used strictly as boolean flags with TRUE/FALSE values. The integer types obscure the boolean intent and are wider than needed. Solution: Change the following win_T members to bool (stdbool.h) and update their assignments from TRUE/FALSE to true/false accordingly. The following conversions have been done: - int -> bool (10 members): w_set_curswant, w_botfill, w_old_botfill, w_do_win_fix_cursor, w_popup_fixed, w_border_highlight_isset, w_cline_folded, w_redr_status, w_arg_idx_invalid, w_has_scrollbar - char -> bool (4 members): w_topline_was_set, w_ru_empty, w_fold_manual, w_foldinvalid No existing code compares these members against TRUE/FALSE explicitly or uses ++/-- / bitwise ops on them, so only plain assignments are affected. Excluded: - w_locked (recursion counter with ++/--), - w_want_scrollbar (may hold -1 from dict_get_bool), - w_winbar_height (used in arithmetic and exposed as number via getwininfo()). related: vim/vim#20005 closes: vim/vim#20008 https://github.com/vim/vim/commit/146d5da0d16b7ea9c767a978cf02384d0831eb92 Co-authored-by: Hirohito Higashi <h.east.727@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(options): add 'winpinned' to pin a window #39157luukvbaal2026-04-19
| | | | | | | | | | | | | | 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>
* vim-patch:9.2.0254: w_locked can be bypassed when setting recursivelySean Dewar2026-03-29
| | | | | | | | | | | | | | | | 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>
* feat(prompt): prompt_appendbuf() appends to prompt buffer #37763Shadman2026-03-27
| | | | | | | | | | | Problem: Currently, we recommend always inserting text above prompt-line in prompt-buffer. This can be done using the `:` mark. However, although we recommend it this way it can sometimes get confusing how to do it best. Solution: Provide an api to append text to prompt buffer. This is a common use-case for things using prompt-buffer.
* vim-patch:9.2.0088: cannot display tabs for indentationzeertzjq2026-03-03
| | | | | | | | | | | | | Problem: cannot display tabs for indentation Solution: Add the "leadtab" value to the 'listchars' option to distinguish between tabs used for indentation and tabs used for alignment (HarshK97). closes: vim/vim#19094 https://github.com/vim/vim/commit/8526d32647245b3b623986949e7807b4b353e624 Co-authored-by: HarshK97 <harshkapse1234@gmail.com>
* fix(highlight): setting 'winhl' doesn't work with global ns (#37868)zeertzjq2026-02-15
| | | | | | Problem: Setting 'winhighlight' doesn't after setting global namespace using nvim_win_set_hl_ns(). Solution: Check if using another namespace when setting 'winhighlight' instead of disabling 'winhighlight' in nvim_win_set_hl_ns().
* vim-patch:9.1.2097: TabClosedPre may be triggered twice for the same tab pagezeertzjq2026-01-20
| | | | | | | | | | | | | | | 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
* 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>
* vim-patch:9.1.2001: cursor may end up in wrong window after :botright copen ↵zeertzjq2025-12-21
| | | | | | | | | | | | | | | | | | (#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>
* vim-patch:9.1.1933: completion: complete_match() is not useful (#36726)zeertzjq2025-11-28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: completion: complete_match() Vim script function and 'isexpand' option are not that useful and confusing (after v9.1.1341) Solution: Remove function and option and clean up code and documentation (Girish Palya). complete_match() and 'isexpand' add no real functionality to Vim. They duplicate what `strridx()` already does, yet pretend to be part of the completion system. They have nothing to do with the completion mechanism. * `f_complete_match()` in `insexpand.c` does not call any completion code. It’s just a `STRNCMP()` wrapper with fluff logic. * `'isexpand'` exists only as a proxy argument to that function. It does nothing on its own and amounts to misuse of a new option. The following Vim script function can be used to implement the same functionality: ```vim func CompleteMatch(triggers, sep=',') let line = getline('.')->strpart(0, col('.') - 1) let result = [] for trig in split(a:triggers, a:sep) let idx = strridx(line, trig) if l:idx >= 0 call add(result, [idx + 1, trig]) endif endfor return result endfunc ``` related: vim/vim#16716 fixes: vim/vim#18563 closes: vim/vim#18790 https://github.com/vim/vim/commit/cbcbff871224115c45bbd14582749a487c6fad30 Co-authored-by: Girish Palya <girishji@gmail.com>
* fix(statusline): redraw if Visual selection other end changes (#36281)zeertzjq2025-10-23
|
* vim-patch:9.1.1819: Cannot configure the inner foldlevel indicator (#36010)zeertzjq2025-10-03
| | | | | | | | | | | | Problem: Cannot configure the inner foldlevel indicator for the foldcolumn Solution: Add "foldinner" suboption value to the 'fillchar' option (Maria José Solano). closes: vim/vim#18365 https://github.com/vim/vim/commit/1a691afd2717732c6f42dfe3278a9540db0d8110 Co-authored-by: Maria José Solano <majosolano99@gmail.com>
* vim-patch:9.1.1808: Option insecure flags not copied when splitting windowzeertzjq2025-09-30
| | | | | | | | | | Problem: Option insecure flags not copied when splitting window. Solution: Move window-local insecure flags to winopt_T and copy them properly (zeertzjq). closes: vim/vim#18434 https://github.com/vim/vim/commit/b3740f4b00a78701637a49445adeb20b13e6edf6
* vim-patch:9.1.1802: 'nowrap' in a modeline may hide malicious code (#35946)zeertzjq2025-09-29
| | | | | | | | | | | | | | | | Problem: 'nowrap' in a modeline may hide malicious code. Solution: Forcibly use '>' as 'listchars' "extends" if 'nowrap' was set from a modeline (zeertzjq). Manual `:setlocal nowrap` disables this behavior. There is a separate problem with `:set nowrap` that also applies to some other options. related: vim/vim#18214 related: vim/vim#18399 closes: vim/vim#18425 https://github.com/vim/vim/commit/9d5208a9313dd8b0d62c97af5485f1715af98a1c Cherry-pick some test_modeline.vim changes from patches 9.0.{0363,0626}.
* vim-patch:9.1.1779: completion: 'autocomplete' cannot be enabled per buffer ↵zeertzjq2025-09-21
| | | | | | | | | | | | | | (#35853) Problem: completion: 'autocomplete' cannot be enabled per buffer (Tomasz N) Solution: Make 'autocomplete' global or local to buffer (Girish Palya) fixes: vim/vim#18320 closes: vim/vim#18333 https://github.com/vim/vim/commit/0208b3e80a080740ff77a5661d0f65090e317d90 Co-authored-by: Girish Palya <girishji@gmail.com>
* fix(terminal): don't trigger TextChangedT for unrelated redrawsSean Dewar2025-08-26
| | | | | | | | | | | | | | | | | | | | | | | | Problem: TextChangedT fires depending on whether Nvim needs to update_screen while in terminal mode. This makes little sense as redraws can be completely unrelated to the terminal. Also, TextChanged could be fired from changes in terminal mode after returning to normal mode. Solution: trigger it when b:changedtick changes, like other such events. Happens when invalid cells are refreshed, though is no longer affected by cursor changes. Don't fire TextChanged from changes in terminal mode after leaving. Unlike the other TextChanged* events, I've elected to not have it be influenced by typeahead. Plus, unlike when leaving insert mode when no TextChangedI events are defined, I don't trigger TextChanged when returning to normal mode from changes in terminal mode (is that a Vim bug?) Curiously, Vim's TextChangedT is different; it's tied to its terminal cursor redraws, which triggers pretty eagerly (but is unaffected by unrelated redraws) - usually *twice* when data is sent to the terminal (regardless of whether it causes any visible changes, like incomplete escape codes; wasn't true for Nvim). Not clear to me how this event was actually intended to work, but this seems to make the most sense to me.
* vim-patch:9.1.1603: completion: cannot use autoloaded funcs in 'complete' ↵zeertzjq2025-08-09
| | | | | | | | | | | | | | | | | F{func} Problem: completion: cannot use autoloaded funcs in 'complete' F{func} (Maxim Kim) Solution: Make it work (Girish Palya) fixes: vim/vim#17869 closes: vim/vim#17885 https://github.com/vim/vim/commit/1bfe86a7d37ea849078255f16f99ed69fbf205dc Cherry-pick Test_omni_autoload() from patch 8.2.3223. Co-authored-by: Girish Palya <girishji@gmail.com>
* vim-patch:9.1.1557: not possible to anchor specific lines in diff mode (#34967)zeertzjq2025-07-18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: not possible to anchor specific lines in diff mode Solution: Add support for the anchoring lines in diff mode using the 'diffanchor' option (Yee Cheng Chin). Adds support for anchoring specific lines to each other while viewing a diff. While lines are anchored, they are guaranteed to be aligned to each other in a diff view, allowing the user to control and inform the diff algorithm what the desired alignment is. Internally, this is done by splitting up the buffer at each anchor and run the diff algorithm on each split section separately, and then merge the results back for a logically consistent diff result. To do this, add a new "diffanchors" option that takes a list of `{address}`, and a new "diffopt" option value "anchor". Each address specified will be an anchor, and the user can choose to use any type of address, including marks, line numbers, or pattern search. Anchors are sorted by line number in each file, and it's possible to have multiple anchors on the same line (this is useful when doing multi-buffer diff). Update documentation to provide examples. This is similar to Git diff's `--anchored` flag. Other diff tools like Meld/Araxis Merge also have similar features (called "synchronization points" or "synchronization links"). We are not using Git/Xdiff's `--anchored` implementation here because it has a very limited API (it requires usage of the Patience algorithm, and can only anchor unique lines that are the same across both files). Because the user could anchor anywhere, diff anchors could result in adjacent diff blocks (one block is directly touching another without a gap), if there is a change right above the anchor point. We don't want to merge these diff blocks because we want to line up the change at the anchor. Adjacent diff blocks were first allowed when linematch was added, but the existing code had a lot of branched paths where line-matched diff blocks were handled differently. As a part of this change, refactor them to have a more unified code path that is generalized enough to handle adjacent diff blocks correctly and without needing to carve in exceptions all over the place. closes: vim/vim#17615 https://github.com/vim/vim/commit/0d9160e11ce4b921adff1e5621dd989ce96fb0f3 Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
* feat(options): per-buffer 'busy' status #34493Shadman2025-07-06
| | | | | | | | Problem: Plugins cannot mark a buffer as "busy". Solution: - Add a buffer-local 'busy' option. - Show a busy indicator in the default 'statusline'.
* feat(prompt): multiline prompt input #33371Shadman2025-06-17
| | | | | | | | | | | | | | Problem: Cannot enter multiline prompts in a buftype=prompt buffer. Solution: - Support shift+enter (`<s-enter>`) to start a new line in the prompt. - Pasting multiline text via OS paste, clipboard, "xp, etc.