*dev_vimpatch.txt* Nvim NVIM REFERENCE MANUAL Merging patches from Vim *dev-vimpatch* Nvim was forked from Vim 7.4.160; it is kept up-to-date with relevant Vim patches in order to avoid duplicate work. Run `vim-patch.sh` to see the status of Vim patches: >bash ./scripts/vim-patch.sh -l < Everyone is welcome to create a |dev-vimpatch-pr| for relevant Vim patches, but some types of patches are |dev-vimpatch-na|. See |dev-vimpatch-quickstart| to get started immediately. Type |gO| to see the table of contents. ============================================================================== QUICKSTART *dev-vimpatch-quickstart* 1. Pull the Nvim source: >bash git clone https://github.com/neovim/neovim.git 2. Run `./scripts/vim-patch.sh -l` to see the list of missing Vim patches. 3. Choose a patch from the list (usually the oldest one), e.g. `8.0.0123`. - Check for open vim-patch PRs https://github.com/neovim/neovim/pulls?q=is%3Apr+is%3Aopen+label%3Avim-patch. 4. Run `./scripts/vim-patch.sh -p 8.0.0123` 5. Follow the instructions given by the script. NOTES - It's strongly recommended to work on the oldest missing patch, because later patches might depend on the changes. - Use `git log --grep` or `git log -G` to search the Nvim/Vim source history (even deleted code). E.g. to find `reset_option_was_set`: >bash git log -p -G reset_option_was_set < - Pass `git log` options like `--grep` and `-G` to `./scripts/vim-patch.sh -L` to filter unmerged Vim patches E.g. to find `+quickfix` patches: >bash ./scripts/vim-patch.sh -L --grep quickfix -- src < ============================================================================== PULL REQUESTS *dev-vimpatch-pr* Note: vim-patch.sh automates these steps for you. Use it! - Install `gh` (https://cli.github.com/) if you want to use `vim-patch.sh` to create PRs automatically - The pull request title should include `vim-patch:8.x.xxxx` (no whitespace) - The commit message https://github.com/neovim/neovim/commit/4ccf1125ff569eccfc34abc4ad794044c5ab7455 should include: - A token indicating the Vim patch number, formatted as follows: `vim-patch:8.0.0123` (no whitespace) - A URL pointing to the Vim commit: https://github.com/vim/vim/commit/c8020ee825b9d9196b1329c0e097424576fc9b3a - The original Vim commit message, including author Reviewers: hint for reviewing `runtime/` patches https://github.com/neovim/neovim/pull/1744#issuecomment-68202876 ============================================================================== NA (NOT APPLICABLE) PATCHES *dev-vimpatch-na* Most Vim patches are not applicable to Nvim. If you find NA patches, visit an the latest "version.c: update" pull request https://github.com/neovim/neovim/pulls?q=is%3Apr+author%3Aapp%2Fgithub-actions+version.c+is%3Aopen and mention the NA patches in a comment (please edit/update one comment, rather than adding a new comment for each patch). Or if there is no open `version.c: update` pull request, include NA patches in a commit message in this format: > vim-patch: vim-patch: ... < where `` is a valid Vim version (like `8.0.0123`) or commit-id (SHA). Each patch is on a separate line. Example: https://github.com/neovim/neovim/commit/00f60c2ce78fc1280e93d5a36bc7b2267d5f4ac6 ------------------------------------------------------------------------------ HOW TO DECIDE IF A VIM-PATCH IS WANTED Legacy Vim is becoming much less relevant to Nvim: we expect to decline the majority of their patches. Thus this is an "allow-list" instead of a "deny-list". Generally, only modules explicitly noted in the "OWNED BY VIM" list below, are in-scope; everything else should be marked "N/A". OWNED BY VIM - quickfix - regex - runtime files Everything else is owned by Nvim. Most of Vim's "bug fixes" for e.g. buffer/window behavior, or the events/autocmds subysytem, or "getchar" (input engine), just aren't relevant to Nvim anymore, because we've significantly enhanced and redesigned those subsystems to make them simpler. UNWANTED VIM-PATCHES - "channel" - "job" - "modelinestrict" https://github.com/neovim/neovim/issues/38985 - "tabpanel" - "terminal" - Vim9script features, and anything related to `:scriptversion`. (Nvim supports Vimscript version 1 only.) - Fixes for build warnings. - GUI-related changes. - Most new Vimscript functions or Ex commands (with rare exceptions). ============================================================================== VERSION.C *dev-vimpatch-version.c* The list of Vim patches in `src/nvim/version.c` is automatically updated https://github.com/neovim/neovim/pull/7780 based on the presence of `vim-patch:xxx` tokens in the Nvim git log. - Don't update `src/nvim/version.c` yourself. - `scripts/vim-patch.sh -p` intentionally omits `version.c` to avoid merge conflicts and save time when porting a patch. - The automation script (`scripts/vimpatch.lua`) only recognizes tokens like `vim-patch:8.0.1206`, not `vim-patch:`. ============================================================================== CODE DIFFERENCES *dev-vimpatch-diff* The following functions have been removed or deprecated in favor of newer alternatives. See `memory.c` https://github.com/neovim/neovim/blob/master/src/nvim/memory.c for more information. > ----------------------------------------------------------------------- Deprecated or removed Replacement ----------------------------------------------------------------------- vim_free xfree VIM_CLEAR(&foo) XFREE_CLEAR(foo) malloc alloc lalloc lalloc_id ALLOC_ONE xmalloc calloc lalloc_clear xcalloc realloc vim_realloc xrealloc mch_memmove memmove vim_memset copy_chars copy_spaces memset vim_strbyte strchr vim_strncpy strncpy xstrlcpy/xmemcpyz vim_strcat strncat xstrlcat VIM_ISWHITE ascii_iswhite IS_WHITE_OR_NUL ascii_iswhite_or_nul IS_WHITE_NL_OR_NUL ascii_iswhite_nl_or_nul vim_isalpha mb_isalpha vim_isNormalIDc ascii_isident vim_islower vim_isupper mb_islower mb_isupper vim_tolower vim_toupper mb_tolower mb_toupper mb_ptr2len utfc_ptr2len mb_ptr2len_len utfc_ptr2len_len mb_char2len utf_char2len mb_char2bytes utf_char2bytes mb_ptr2cells utf_ptr2cells mb_ptr2cells_len utf_ptr2cells_len mb_char2cells utf_char2cells mb_off2cells utf_off2cells mb_ptr2char utf_ptr2char mb_head_off utf_head_off mb_tail_off utf_cp_bounds mb_strnicmp2 utf_strnicmp MB_STRNICMP2 utf_strnicmp mb_lefthalve grid_lefthalve mb_fix_col grid_fix_col utf_off2cells grid_off2cells ml_get_curline get_cursor_line_ptr ml_get_cursor get_cursor_pos_ptr ml_get_curline_len get_cursor_line_len ml_get_cursor_len get_cursor_pos_len screen_char ui_line screen_line grid_put_linebuf screen_* (most functions) grid_* update_prepare, update_finish #9484 removed; use update_screen only ARRAY_LENGTH ARRAY_SIZE vim_strsave_escape_csi vim_strsave_escape_ks vim_unescape_csi vim_unescape_ks gettail path_tail mch_isFullName path_is_absolute script_do_profile profile_init ----------------------------------------------------------------------- < Make sure to note the difference between `utf_` and `utfc_` when replacing `mb_` functions. Also indirect call syntax `(*mb_ptr2len)(...)` should be replaced with an ordinary function call `utfc_ptr2len(...)`. > ----------------------------------------------------------------------- Data type Format (Vim source) Portable format (Nvim source) ------------ ----------------------- ---------------------------------- long long "%lld" "%" PRId64 size_t "%ld" "%zu" linenr_T "%ld" "%" PRIdLINENR ----------------------------------------------------------------------- < - See also: https://github.com/neovim/neovim/pull/1729#discussion_r22423779 - Vim's `ga_init2` was renamed to `ga_init` and the original `ga_init` is gone. - "Old style" Vim tests (`src/testdir/*.in`) should be converted to Lua tests (see #1286 https://github.com/neovim/neovim/issues/1286 and #1328 https://github.com/neovim/neovim/pull/1328). See Checklist for migrating legacy tests https://github.com/neovim/neovim/blob/master/test/README.md#checklist-for-migrating-legacy-tests. - However, please do not convert "new style" Vim tests (`src/testdir/*.vim`) to Lua. The "new style" Vim tests are faster than the old ones, and converting them takes time and effort better spent elsewhere. Just copy them to `test/old/testdir/*.vim`. - Conditions that check `enc_utf8` or `has_mbyte` are obsolete (only the "true" case is applicable). - `enc_utf8` and `has_mbyte` macros were removed in https://github.com/neovim/neovim/pull/13293 - Check for `CSI` in typeahead buffer is only necessary in Vim with `FEAT_GUI`. `CSI` does not have a special meaning in typeahead buffer in Nvim. (also see https://github.com/neovim/neovim/pull/16936) ============================================================================== LIST MANAGEMENT *dev-vimpatch-list-impl* Management of lists (types `list_T` and `listitem_T` from vim) was changed in https://github.com/neovim/neovim/pull/7708/. There is a lint against the "old" usage, but here are the most important changes. Declarations for the table - `list_T list`: a list - `listitem_T li`: an item of `list` - `int val` a value for `lv_copyID` > -------------------------------------------------------------------------------------- Old New Comment ------------------------------- ------------------------------------------------------ list->lv_first tv_list_first(list) list->lv_last tv_list_last(list) li->li_next TV_LIST_ITEM_NEXT(list, li) To be avoided if possible, must use list which li belongs to. li->li_prev TV_LIST_ITEM_PREV(list, li) To be avoided if possible, must use list which li belongs to. Suggestion by @ZyX-l: Use TV_LIST_ITER or indexing instead of the previous two calls. list->lv_len tv_list_len(list) list->lv_lock tv_list_locked(list) &li->li_tv TV_LIST_ITEM_TV(li) list->lv_refcount++ tv_list_ref(list) val = list->lv_copyID val = tv_list_copyid(list) list->lv_copyID = val tv_list_set_copyid(list, val) for (li = list->lv_first; TV_LIST_ITER_CONST(list, li, Use TV_LIST_ITER(...) if you need to li != NULL && another_cond; { if (another_cond) {break;} code}) modify list items (note: assigning copyID is also modification and this happens li = li->li_next) code always when recursively traversing a list). -------------------------------------------------------------------------------------- < For more details and some more advanced usage, see `typval.h` and `typval.c`. ============================================================================== DOCUMENTATION DIFFERENCES *dev-vimpatch-doc* The following should be removed from all imported documentation, and not be used in new documentation: - `{Only when compiled with ...}`: the vast majority of features have been made non-optional (see https://github.com/neovim/neovim/wiki/Introduction) ============================================================================== FILETYPE DETECTION *dev-vimpatch-filetype* Nvim's filetype detection behavior matches Vim, but is implemented as part of |vim.filetype| (see `$VIMRUNTIME/lua/vim/filetype.lua`). The logic is encoded in three tables, listed in order of precedence (the first match is returned): 1. `filename` for literal full path or basename lookup; 2. `pattern` for matching filenames or paths against |lua-pattern|s, optimized for fast lookup; 3. `extension` for literal extension lookup. Logic that requires checking file contents or buffer variables is implemented in `$VIMRUNTIME/lua/vim/filetype/detect.lua`. When porting filetype patches from Vim, keep the following in mind: Prefer explicit filenames or extensions over patterns, especially for case insensitive matches (see https://github.com/neovim/neovim/pull/29800): > "*[mM]akefile" regex -> "makefile", "Makefile" filenames "*.js\c" regex -> "js", "jS", "Js", "jS" extensions Pattern matching has several differences: - It is done using explicit Lua patterns without implicit anchoring instead of Vim regexes: > "*/debian/changelog" -> "/debian/changelog$" "*/bind/db.*" -> "/bind/db%." < - Filetype patterns are grouped by their parent pattern to improve matching performance: If the parent pattern does not match, skip testing all child patterns. Note that unlike leaf patterns, parent patterns do not have special matching behaviour if they contain a `/`. When adding a new filetype with pattern matching, consider the following: - If there is already a group with appropriate parent pattern, use it. - If there can be a fast and specific enough pattern to group at least 3 filetype patterns, add it as a separate grouped entry. New parent patterns should be - fast: rule of thumb is that it should be a short explicit string (i.e. no quantifiers or character sets); - specific: rules of thumb, in order: - full directory name (e.g., `"/etc/"`, `"/log/"`); - part of a rare enough directory name (e.g., `"/conf"`, `"git/"`); - string rarely used in real full paths (e.g., `"nginx"`). Example: - Filetype pattern: `".*/etc/a2ps/.*%.cfg"` - Good parents: `"/etc/"` or `"%.cfg$"` - Bad parents: `"%."` (fast but not specific) or `"/a2ps/.*%."` (specific but slow) When modifying an existing regular pattern, make sure that it still fits its group. vim:tw=78:ts=8:et:ft=help:norl: