aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/change.c
Commit message (Collapse)AuthorAge
* feat(multicursor): zq operator; cursor-local marks #42148Justin M. Keyes2026-09-29
| | | | | | | | | | | | | | | | | | Problem: - `[count]Q` and `{Visual}Q` are implemented as ad hoc utils, because `Q` is not an "operator". - `Q` always "toggles", it is not "idempotent". - Various *cursor-relative* marks (`'.`, `'[`) are not saved/restored per-cursor, so they don't work during cascade. - Insert cascade clobbers the primary's `'^` and changelist. Solution: - Introduce the `zq{motion}` operator, which places cursors at every reachable `{motion}`. - `{Visual}Q` is now an alias to `{Visual}zqj`. - Introduce `1Q` and `2Q` for idempotent cursor placement. - Drop `[count]Q`, it's redundant with `zqgn`. - Classify cursor-relative marks as `type=motion` instead of `type=jump`. Save/restore per-cursor during cascade.
* fix(ui2): retain substitute confirmation highlight with nohlsearch #41067debaditya2026-08-03
| | | | | | | Problem: ui2 clears the substitute confirmation match when it updates its prompt buffer with hlsearch disabled. Solution: Only invalidate the match highlight when the current buffer changes.
* 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>
* 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): invalid ruler items in other windows #40891Ondrej Balaz2026-07-22
| | | | | | | | | | | | | Problem: When buffer is open in multiple windows and its line count changes, any 'statusline' or 'rulerformat' items depending on it (e.g. %P) will become invalid in non-current windows because w_redr_status is only set on first change. Solution: Set w_redr_status on all windows with the buffer when the line count changes. Signed-off-by: Ondrej Balaz <blami@blami.net>
* 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
|
* vim-patch:8.2.4955: text property in wrong position after auto-indent (#40766)Jan Edmund Lazo2026-07-16
| | | | | | | | Problem: Text property in wrong position after auto-indent. Solution: Adjust text property columns. (closes vim/vim#10422, closes vim/vim#7719) https://github.com/vim/vim/commit/788c06a2492b546dd0824b119251cd8ea7da9cb5 Co-authored-by: LemonBoy <thatlemon@gmail.com>
* 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.
* refactor(insert): rename edit.c => insert.c #40705Justin M. Keyes2026-07-12
| | | | | | | | | | Problem: - `edit.c` is an unnecessarily misleading and less-discoverable name than `insert.c`. - Numerous insert-mode related things are named with a `ins_` prefix. - There is already a `insexpand.c` module... Solution: Rename `edit.c` => `insert.c`.
* vim-patch:9.2.0686: style: strcmp usage is inconsistent (#40353)zeertzjq2026-06-22
| | | | | | | | | | | Problem: style: strcmp usage is inconsistent. Solution: Always explicitly test the return value, matching the dominant style. closes: vim/vim#19101 https://github.com/vim/vim/commit/1a155327d830ac2df751b1b59d0639a0c3cfbf1e Co-authored-by: Doug Kearns <dougkearns@gmail.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.
* 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
* vim-patch:partial:9.2.0193: using copy_option_part() can be improved (#38369)zeertzjq2026-03-19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: using copy_option_part() can be improved Solution: Refactor and use the return value of copy_option_part() to avoid strlen() calls (John Marriott). In addition, this commit includes the following changes: memline.c: - In recover_names(): - Replace calls to vim_strsave() with vim_strnsave() for the literal strings - Use a string_T to store local variable dir_name. bufwrite.c: - In buf_write() - move variable wp to where it is used. help.c: - In fix_help_buffer(): - replace call to add_pathsep() with after_pathsep() optionstr.c: - In export_myvimdir(): - use a string_T to store local variable buf - replace call to add_pathsep() with after_pathsep() scriptfile.c: - In do_in_path(): - use a string_T to store local variable buf - measure the lengths of prefix and name once before the while loop - replace call to add_pathsep() with after_pathsep() - move some variables closer to where they are used spellfile.c: - In init_spellfile(): - use a string_T to store local variable buf closes: vim/vim#19725 https://github.com/vim/vim/commit/a74e5fc5b9cc3c1596f34df9d45e33f049162cfe Co-authored-by: John Marriott <basilisk@internode.on.net>
* fix(marks): make jumpoptions=view work with 'smoothscroll' (#38339)zeertzjq2026-03-17
| | | | | | Problem: 'jumpoptions' "view" doesn't remember skipcol and may lead to glitched display with 'smoothscroll'. Solution: Save skipcol in the mark view. Also make sure skipcol doesn't exceed line size.
* vim-patch:8.2.3159: cursor displayed in wrong position after deleting lineJan Edmund Lazo2026-01-01
| | | | | | | | | Problem: Cursor displayed in wrong position after deleting line. Solution: When deleting lines do not approximate botline. (fixes vim/vim#8559) https://github.com/vim/vim/commit/5bea41dea34bcc73c4efb1b554ad0a2018966ecc Co-authored-by: Bram Moolenaar <Bram@vim.org>
* vim-patch:9.1.0151: ml_get_buf_len() does not consider text properties (#37094)Jan Edmund Lazo2025-12-25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: ml_get_buf_len() does not consider text properties (zeertzj) Solution: Store text length excluding text properties length in addition in the memline related vim/vim#14123 closes: vim/vim#14133 https://github.com/vim/vim/commit/a72d1be5a9984709fc66f460b443ad4a38506113 -------- Replace ml_line_len with ml_line_textlen to be explicit that Nvim doesn't currently support Vim's text properties and Nvim doesn't support lines with "ambiguous" length. -------- vim-patch:9.1.0153: Text properties corrupted with fo+=aw and backspace Problem: Text properties corrupted with fo+=aw and backspace Solution: Allocate line and move text properties (zeertzjq) closes: vim/vim#14147 https://github.com/vim/vim/commit/7ac1145fbebb66dfee325dc5265309877d941c4e vim-patch:9.1.0163: Calling STRLEN() to compute ml_line_textlen when not needed Problem: Calling STRLEN() to compute ml_line_textlen when not needed. Solution: Use 0 when STRLEN() will be required and call STRLEN() later. (zeertzjq) closes: vim/vim#14155 https://github.com/vim/vim/commit/82e079df814f7372e9579450730062b205449efa Co-authored-by: Christian Brabandt <cb@256bit.org> Co-authored-by: zeertzjq <zeertzjq@outlook.com>
* refactor(messages): encapsulate msg_delay logicJustin M. Keyes2025-12-20
| | | | see also 9bbbeb60e355844780db0aef955e860d68ac0342
* test(messages): skip os_delay during testsJustin M. Keyes2025-12-20
| | | | | | | | | | | Problem: Tests that trigger `os_delay` messages may take 1-3 seconds, wasting build/CI time, since this serves no purpose in tests. Solution: - Introduce `msg_delay` for cases where `os_delay` is being used as a "UI feature". - Skip `msg_delay` in tests.
* 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>
* vim-patch:8.2.0853: ml_delete() often called with FALSE argumentJan Edmund Lazo2025-08-20
| | | | | | | | | Problem: ml_delete() often called with FALSE argument. Solution: Use ml_delete_flags(x, ML_DEL_MESSAGE) when argument is TRUE. https://github.com/vim/vim/commit/ca70c07b72c24aae3d141e67d08f50361f051af5 Co-authored-by: Bram Moolenaar <Bram@vim.org>
* 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.
* vim-patch:8.1.2127: the indent.c file is a bit bigJan Edmund Lazo2025-07-20
| | | | | | | | | | | Problem: The indent.c file is a bit big. Solution: Move C-indent code a a new cindent.c file. Move other indent-related code to indent.c. (Yegappan Lakshmanan, closes vim/vim#5031) https://github.com/vim/vim/commit/14c01f83487d5c53192297a710eda2b8a4ab17c9 Co-authored-by: Bram Moolenaar <Bram@vim.org>
* 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. - A/I in editable region works as usual. - i/a/A/I outside of editable region moves cursor to end of current prompt. - Support undo/redo in prompt buffer. - Support o/O in prompt buffer. - Expose prompt location as `':` mark.
* fix(terminal): remove condition that buf is curbuf (#33721)Gregory Anders2025-04-29
|
* feat(ui): no delay for errors with ext_messages (#33693)luukvbaal2025-04-29
| | | | | | | Problem: Delay for reading a message may be unwanted for ext_messages, and can be done by the implementation. Empty completion source error message is not distinguishable as such. Solution: Only delay without ext_messages enabled. Emit empty completion source message as an error.
* fix(marks): wrong display after inserting/deleting lines #33389luukvbaal2025-04-11
| | | | | | | | | | | | | | | Problem: Lines to/from which virt_lines or inline virt_text may have moved are left valid. Similarly the modified region may be too small to account for moved decorations after inserting or deleting lines. `redrawOneLine()` can be replaced with a call to `changed_lines_redraw_buf()`. Solution: Invalidate the line after a change if there is virt_lines, or inline virt_text in the buffer with 'wrap' enabled. Extend the modified region for inserted or deleted lines if there may be decorations in the buffer. Remove `redrawOneLine()`. Simplify the logic for `changed_lines_invalidate_win()`. Co-authored-by: zeertzjq <zeertzjq@outlook.com>
* vim-patch:9.1.1266: MS-Windows: type conversion warnings (#33264)zeertzjq2025-04-02
| | | | | | | | | | Problem: MS-Windows: type conversion warnings Solution: cast the variables (Yegappan Lakshmanan) closes: vim/vim#17027 https://github.com/vim/vim/commit/7b6add0b4a694d421a1eb9c9017698ccbedde41c Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
* vim-patch:9.1.1243: diff mode is lacking for changes within lineszeertzjq2025-03-28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Diff mode's inline highlighting is lackluster. It only performs a line-by-line comparison, and calculates a single shortest range within a line that could encompass all the changes. In lines with multiple changes, or those that span multiple lines, this approach tends to end up highlighting much more than necessary. Solution: Implement new inline highlighting modes by doing per-character or per-word diff within the diff block, and highlight only the relevant parts, add "inline:simple" to the defaults (which is the old behaviour) This change introduces a new diffopt option "inline:<type>". Setting to "none" will disable all inline highlighting, "simple" (the default) will use the old behavior, "char" / "word" will perform a character/word-wise diff of the texts within each diff block and only highlight the differences. The new char/word inline diff only use the internal xdiff, and will respect diff options such as algorithm choice, icase, and misc iwhite options. indent-heuristics is always on to perform better sliding. For character highlight, a post-process of the diff results is first applied before we show the highlight. This is because a naive diff will create a result with a lot of small diff chunks and gaps, due to the repetitive nature of individual characters. The post-process is a heuristic-based refinement that attempts to merge adjacent diff blocks if they are separated by a short gap (1-3 characters), and can be further tuned in the future for better results. This process results in more characters than necessary being highlighted but overall less visual noise. For word highlight, always use first buffer's iskeyword definition. Otherwise if each buffer has different iskeyword settings we would not be able to group words properly. The char/word diffing is always per-diff block, not per line, meaning that changes that span multiple lines will show up correctly. Added/removed newlines are not shown by default, but if the user has 'list' set (with "eol" listchar defined), the eol character will be be highlighted correctly for the specific newline characters. Also, add a new "DiffTextAdd" highlight group linked to "DiffText" by default. It allows color schemes to use different colors for texts that have been added within a line versus modified. This doesn't interact with linematch perfectly currently. The linematch feature splits up diff blocks into multiple smaller blocks for better visual matching, which makes inline highlight less useful especially for multi-line change (e.g. a line is broken into two lines). This could be addressed in the future. As a side change, this also removes the bounds checking introduced to diff_read() as they were added to mask existing logic bugs that were properly fixed in vim/vim#16768. closes: vim/vim#16881 https://github.com/vim/vim/commit/9943d4790e42721a6777da9e12637aa595ba4965 Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
* vim-patch:3495497: patch 9.1.1212: too many strlen() calls in edit.czeertzjq2025-03-18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: too many strlen() calls in edit.c Solution: refactor edit.c and remove strlen() calls (John Marriott) This commit attempts to make edit.c more efficient by: - in truncate_spaces() pass in the length of the string. - return a string_T from get_last_insert(), so that the length of the string is available to the caller. - refactor stuff_insert(): - replace calls to stuffReadbuff() (which calls STRLEN() on it's string argument) with stuffReadbuffLen() (which gets the length of it's string argument passed in). - replace call to vim_strrchr() which searches from the start of the string with a loop which searches from end of the string to find the last ESC character. - change get_last_insert_save() to call get_last_insert() to get the last_insert string (the logic is in one place). closes: vim/vim#16863 https://github.com/vim/vim/commit/34954972c27244a4a1fb4eeeae2aa4e021efd100 Co-authored-by: John Marriott <basilisk@internode.on.net>
* fix(marks): mark winline as invalid if change is in a concealed line (#32766)luukvbaal2025-03-07
| | | | Code that checks whether a `w_lines` entry has become invalid due to a change in a folded line should now also check for concealed lines.
* vim-patch:9.1.1176: wrong indent when expanding multiple lines (#32746)zeertzjq2025-03-06
| | | | | | | | | | Problem: wrong indentation of lastline when expanding multiple lines Solution: Check OPENLINE_FORCE_INDENT flag in open_line() (glepnir) closes: vim/vim#16786 https://github.com/vim/vim/commit/34a7d82aaed9836174f4ea84af047db3fdf6c8b3 Co-authored-by: glepnir <glephunter@gmail.com>
* feat(marks): add conceal_lines to nvim_buf_set_extmark()Luuk van Baal2025-02-25
| | | | Implement an extmark property that conceals lines vertically.
* vim-patch:9.1.1145: multi-line completion has wrong indentation for last ↵glepnir2025-02-25
| | | | | | | | | | | | line (#32625) Problem: When expanding omni completion items with newlines (e.g. `then\n\t\nend`), the end statement gets wrong indentation. Solution: Add OPENLINE_FORCE_INDENT flag to make open_line() use second_line_indent directly (glepnir) closes: vim/vim#16614 https://github.com/vim/vim/commit/5090a1fecb86c44be83d55e139ed79b7785fa090
* vim-patch:9.1.1137: ins_str() is inefficient by calling STRLEN() (#32591)zeertzjq2025-02-23
| | | | | | | | | | | | Problem: ins_str() is inefficient by calling STRLLEN() Solution: refactor ins_str() to take a length argument and let all callers provide the correct length when calling ins_str() (John Marriott) closes: vim/vim#16711 https://github.com/vim/vim/commit/f4b36417e893ff40296f1a5a264a4ecc6965f1d5 Co-authored-by: John Marriott <basilisk@internode.on.net>
* vim-patch:9.1.1108: 'smoothscroll' gets stuck with 'listchars' "eol" (#32434)zeertzjq2025-02-13
| | | | | | | | | | Problem: 'smoothscroll' gets stuck with 'listchars' "eol". Solution: Count size of 'listchars' "eol" in line size when scrolling. (zeertzjq) related: neovim/neovim#32405 closes: vim/vim#16627 https://github.com/vim/vim/commit/2c47ab8fcd7188fa87053c757ea86b0d846c06c1
* refactor: iwyu #31637Justin M. Keyes2024-12-23
| | | Result of `make iwyu` (after some "fixups").
* 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 Baal2024-11-08
| | | | | | | Problem: Highlight group id is not propagated to the end of the message call stack, where ext_messages are emitted. Solution: Refactor message functions to pass along highlight group id instead of attr id.
* fix(multibyte): handle backspace of wide clusters in replace modebfredl2024-09-06
| | | | | Make utf_head_off more robust against invalid sequences and embedded NUL chars
* 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.
* refactor: collapse statements in single assignmentsLewis Russell2024-07-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Variables are often assigned multiple places in common patterns. Solution: Replace these common patterns with different patterns that reduce the number of assignments. Use `MAX` and `MIN`: ```c if (x < y) { x = y; } // --> x = MAX(x, y); ``` ```c if (x > y) { x = y; } // --> x = MIN(x, y); ``` Use ternary: ```c int a; if (cond) { a = b; } els { a = c; } // --> int a = cond ? b : c; ```
* vim-patch:8.2.5047: CurSearch highlight is often wrongzeertzjq2024-06-19
| | | | | | | | | Problem: CurSearch highlight is often wrong. Solution: Remember the last highlighted position and redraw when needed. https://github.com/vim/vim/commit/368137aa525982984beed73940af481ac53a62af Co-authored-by: Bram Moolenaar <Bram@vim.org>
* refactor(memory): use builtin strcat() instead of STRCAT()bfredl2024-06-11
| | | | | | | | The latter was mostly relevant with the past char_u madness. NOTE: STRCAT also functioned as a counterfeit "NOLINT" for clint apparently. But NOLINT-ing every usecase is just the same as disabling the check entirely.
* refactor(change): check all tabpages in changed_lines_invalidate_buf() (#28666)zeertzjq2024-05-08
| | | | | This most likely doesn't matter as all windows are redrawn when switching tabpages and w_valid is reset is entering window, but still check all tabpages for consistency with changed_common().
*