Merging patches from Vim
Rustvim :help pages, generated
from source
using the tree-sitter-vimdoc parser.
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:./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.
QUICKSTART
Pull the Nvim source:
git clone https://github.com/neovim/neovim.git Run
./scripts/vim-patch.sh -l to see the list of missing Vim patches.
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.
Run
./scripts/vim-patch.sh -p 8.0.0123
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:
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:
./scripts/vim-patch.sh -L --grep quickfix -- src
PULL REQUESTS
Note: vim-patch.sh automates these steps for you. Use it!
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
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:<version-or-commit> vim-patch:<version-or-commit> ...
where
<version-or-commit> is a valid Vim version (like 8.0.0123) or
commit-id (SHA). Each patch is on a separate line.
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
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:<hash>.
CODE DIFFERENCES
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 -----------------------------------------------------------------------
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).
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
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
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
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):
filename for literal full path or basename lookup;
pattern for matching filenames or paths against lua-patterns, optimized
for fast lookup;
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" extensionsPattern 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.