mirror of
https://github.com/neovim/neovim.git
synced 2025-12-12 01:22:41 +00:00
feat(version): support multiple Vim versions
Group up to 15 vimpatch numbers in 1 line to guard against 'make formatc'. 1-liner for vim_versions, num_patches. Automate '*Version' to remove version.h macros. '-V1 -v' lists merged Vim versions.
This commit is contained in:
@@ -19,58 +19,105 @@ local function vimpatch_sh_list_tokens()
|
||||
return systemlist({ { 'bash', '-c', 'scripts/vim-patch.sh -M' } })
|
||||
end
|
||||
|
||||
-- Generates the lines to be inserted into the src/nvim/version.c
|
||||
-- `included_patches[]` definition.
|
||||
-- Generate the data,lines to update src/nvim/version.c.
|
||||
-- - `vim_versions[]`
|
||||
-- - `Versions[]`
|
||||
-- - `num_patches[]`
|
||||
-- - `included_patchsets[]`
|
||||
local function gen_version_c_lines()
|
||||
-- Sets of merged Vim x.y.zzzz patch numbers.
|
||||
local merged_patch_sets = {}
|
||||
-- List of version sets where each set contains:
|
||||
-- 1. major_minor_version (int)
|
||||
-- 2. major_minor_version (string)
|
||||
-- 3. set of merged patch numbers
|
||||
local merged_version_list = {}
|
||||
for _, token in ipairs(vimpatch_sh_list_tokens()) do
|
||||
local major_version, minor_version, patch_num = string.match(token, '^(%d+).(%d+).(%d+)$')
|
||||
local n = tonumber(patch_num)
|
||||
-- TODO(@janlazo): Allow multiple Vim versions
|
||||
-- if n then
|
||||
if n and major_version == '8' and minor_version == '1' then
|
||||
if n then
|
||||
local major_minor_version = major_version * 100 + minor_version
|
||||
merged_patch_sets[major_minor_version] = merged_patch_sets[major_minor_version] or {}
|
||||
table.insert(merged_patch_sets[major_minor_version], n)
|
||||
end
|
||||
end
|
||||
|
||||
local sorted_versions = {}
|
||||
for k, _ in pairs(merged_patch_sets) do
|
||||
table.insert(sorted_versions, k)
|
||||
end
|
||||
table.sort(sorted_versions)
|
||||
local lines = {}
|
||||
for _, major_minor_version in ipairs(sorted_versions) do
|
||||
-- table.insert(lines, string.format(' // major minor version: %s', major_minor_version))
|
||||
local patch_set = merged_patch_sets[major_minor_version]
|
||||
for i = #patch_set, 1, -1 do
|
||||
local patch = patch_set[i]
|
||||
table.insert(lines, string.format(' %s,', patch))
|
||||
if patch > 0 then
|
||||
local oldest_unmerged_patch = patch_set[i - 1] and (patch_set[i - 1] + 1) or 0
|
||||
for unmerged_patch = patch -1, oldest_unmerged_patch, -1 do
|
||||
table.insert(lines, string.format(' // %s,', unmerged_patch))
|
||||
end
|
||||
local len = #merged_version_list
|
||||
if len == 0 or merged_version_list[len][1] ~= major_minor_version then
|
||||
local vstr = '"' .. major_version .. '.' .. minor_version .. '"'
|
||||
table.insert(merged_version_list, { major_minor_version, vstr, { n } })
|
||||
else
|
||||
table.insert(merged_version_list[len][3], n)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return lines
|
||||
local major_vim_versions = {}
|
||||
local major_vim_versions_str = {}
|
||||
local num_patches = {}
|
||||
local patch_lines = {}
|
||||
for _, version_set in ipairs(merged_version_list) do
|
||||
local major_minor_version, major_minor_version_str, patch_set = unpack(version_set)
|
||||
table.insert(major_vim_versions, major_minor_version)
|
||||
table.insert(major_vim_versions_str, major_minor_version_str)
|
||||
table.insert(num_patches, #patch_set)
|
||||
table.insert(patch_lines, ' (const int[]) { // ' .. major_minor_version)
|
||||
|
||||
local patchset_set = {}
|
||||
for i = #patch_set, 1, -1 do
|
||||
local patch = patch_set[i]
|
||||
local next_patch = patch_set[i - 1]
|
||||
local patch_diff = patch - (next_patch or 0)
|
||||
table.insert(patchset_set, patch)
|
||||
|
||||
-- guard against last patch or `make formatc`
|
||||
if #patchset_set > 15 or i == 1 or patch_diff > 1 then
|
||||
table.insert(patch_lines, ' ' .. table.concat(patchset_set, ', ') .. ',')
|
||||
patchset_set = {}
|
||||
end
|
||||
if i == 1 and patch > 0 then
|
||||
local line = ' // 0'
|
||||
if patch > 1 then
|
||||
line = line .. '-' .. (patch - 1)
|
||||
end
|
||||
table.insert(patch_lines, line)
|
||||
elseif patch_diff > 1 then
|
||||
local line = ' // ' .. (next_patch + 1)
|
||||
if patch_diff > 2 then
|
||||
line = line .. '-' .. (patch - 1)
|
||||
end
|
||||
table.insert(patch_lines, line)
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(patch_lines, ' },')
|
||||
end
|
||||
|
||||
return major_vim_versions, major_vim_versions_str, num_patches, patch_lines
|
||||
end
|
||||
|
||||
local function patch_version_c()
|
||||
local lines = gen_version_c_lines()
|
||||
local major_vim_versions, major_vim_versions_str, num_patches, patch_lines = gen_version_c_lines()
|
||||
|
||||
nvim.nvim_command('silent noswapfile noautocmd edit src/nvim/version.c')
|
||||
nvim.nvim_command('/static const int included_patches')
|
||||
nvim.nvim_command([[/^char \*Versions]])
|
||||
-- Replace the line.
|
||||
nvim.nvim_call_function('setline', {
|
||||
nvim.nvim_eval('line(".")'),
|
||||
'char *Versions[] = { ' .. table.concat(major_vim_versions_str, ', ') .. ' };',
|
||||
})
|
||||
nvim.nvim_command([[/^static const int vim_versions]])
|
||||
-- Replace the line.
|
||||
nvim.nvim_call_function('setline', {
|
||||
nvim.nvim_eval('line(".")'),
|
||||
'static const int vim_versions[] = { ' .. table.concat(major_vim_versions, ', ') .. ' };',
|
||||
})
|
||||
nvim.nvim_command([[/^static const int num_patches]])
|
||||
-- Replace the line.
|
||||
nvim.nvim_call_function('setline', {
|
||||
nvim.nvim_eval('line(".")'),
|
||||
'static const int num_patches[] = { ' .. table.concat(num_patches, ', ') .. ' };',
|
||||
})
|
||||
nvim.nvim_command([[/^static const int \*included_patchsets]])
|
||||
-- Delete the existing lines.
|
||||
nvim.nvim_command('silent normal! j0d/};\rk')
|
||||
-- Insert the lines.
|
||||
nvim.nvim_call_function('append', {
|
||||
nvim.nvim_eval('line(".")'),
|
||||
lines,
|
||||
patch_lines,
|
||||
})
|
||||
nvim.nvim_command('silent write')
|
||||
end
|
||||
|
||||
@@ -3800,14 +3800,15 @@ static int chk_modeline(linenr_T lnum, int flags)
|
||||
continue;
|
||||
}
|
||||
|
||||
const int vim_version = min_vim_version();
|
||||
if (*e == ':'
|
||||
&& (s[0] != 'V'
|
||||
|| strncmp(skipwhite(e + 1), "set", 3) == 0)
|
||||
&& (s[3] == ':'
|
||||
|| (VIM_VERSION_100 >= vers && isdigit((uint8_t)s[3]))
|
||||
|| (VIM_VERSION_100 < vers && s[3] == '<')
|
||||
|| (VIM_VERSION_100 > vers && s[3] == '>')
|
||||
|| (VIM_VERSION_100 == vers && s[3] == '='))) {
|
||||
|| (vim_version >= vers && isdigit((uint8_t)s[3]))
|
||||
|| (vim_version < vers && s[3] == '<')
|
||||
|| (vim_version > vers && s[3] == '>')
|
||||
|| (vim_version == vers && s[3] == '='))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2812,14 +2812,10 @@ static void f_has(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
int minor = atoi(end + 1);
|
||||
|
||||
// Expect "patch-9.9.01234".
|
||||
n = (major < VIM_VERSION_MAJOR
|
||||
|| (major == VIM_VERSION_MAJOR
|
||||
&& (minor < VIM_VERSION_MINOR
|
||||
|| (minor == VIM_VERSION_MINOR
|
||||
&& has_vim_patch(atoi(end + 3))))));
|
||||
n = has_vim_patch(atoi(end + 3), major * 100 + minor);
|
||||
}
|
||||
} else if (ascii_isdigit(name[5])) {
|
||||
n = has_vim_patch(atoi(name + 5));
|
||||
n = has_vim_patch(atoi(name + 5), 0);
|
||||
}
|
||||
} else if (STRNICMP(name, "nvim-", 5) == 0) {
|
||||
// Expect "nvim-x.y.z"
|
||||
|
||||
@@ -281,8 +281,9 @@ void evalvars_init(void)
|
||||
hash_add(&compat_hashtab, p->vv_di.di_key);
|
||||
}
|
||||
}
|
||||
set_vim_var_nr(VV_VERSION, VIM_VERSION_100);
|
||||
set_vim_var_nr(VV_VERSIONLONG, VIM_VERSION_100 * 10000 + highest_patch());
|
||||
const int vim_version = min_vim_version();
|
||||
set_vim_var_nr(VV_VERSION, vim_version);
|
||||
set_vim_var_nr(VV_VERSIONLONG, vim_version * 10000 + highest_patch());
|
||||
|
||||
dict_T *const msgpack_types_dict = tv_dict_alloc();
|
||||
for (size_t i = 0; i < ARRAY_SIZE(msgpack_type_names); i++) {
|
||||
|
||||
@@ -330,7 +330,7 @@ int ml_open(buf_T *buf)
|
||||
b0p->b0_magic_int = B0_MAGIC_INT;
|
||||
b0p->b0_magic_short = (int16_t)B0_MAGIC_SHORT;
|
||||
b0p->b0_magic_char = B0_MAGIC_CHAR;
|
||||
xstrlcpy(xstpcpy(b0p->b0_version, "VIM "), Version, 6);
|
||||
xstrlcpy(xstpcpy(b0p->b0_version, "VIM "), Versions[0], 6);
|
||||
long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);
|
||||
|
||||
if (!buf->b_spell) {
|
||||
|
||||
6678
src/nvim/version.c
6678
src/nvim/version.c
File diff suppressed because it is too large
Load Diff
@@ -5,26 +5,10 @@
|
||||
#include "nvim/macros_defs.h"
|
||||
|
||||
// defined in version.c
|
||||
extern char *Version;
|
||||
extern char *Versions[];
|
||||
extern char *longVersion;
|
||||
#ifndef NDEBUG
|
||||
extern char *version_cflags;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Vim version number, name, etc. Patchlevel is defined in version.c.
|
||||
//
|
||||
|
||||
// Values that change for a new release
|
||||
#define VIM_VERSION_MAJOR 8
|
||||
#define VIM_VERSION_MINOR 1
|
||||
|
||||
// Values based on the above
|
||||
#define VIM_VERSION_MAJOR_STR STR(VIM_VERSION_MAJOR)
|
||||
#define VIM_VERSION_MINOR_STR STR(VIM_VERSION_MINOR)
|
||||
#define VIM_VERSION_100 (VIM_VERSION_MAJOR * 100 + VIM_VERSION_MINOR)
|
||||
|
||||
// swap file compatibility (max. length is 6 chars)
|
||||
#define VIM_VERSION_SHORT VIM_VERSION_MAJOR_STR "." VIM_VERSION_MINOR_STR
|
||||
|
||||
#include "version.h.generated.h"
|
||||
|
||||
@@ -104,4 +104,39 @@ describe('has()', function()
|
||||
fn.has('python3') -- use a call whose implementation shells out
|
||||
eq(73, fn.eval('v:shell_error'))
|
||||
end)
|
||||
|
||||
it('"patch[0-9]\\+"', function()
|
||||
eq(1, fn.has('patch0'))
|
||||
eq(1, fn.has('patch1'))
|
||||
end)
|
||||
|
||||
it('"patch-x.y.z"', function()
|
||||
-- versions older than current v:version always succeed
|
||||
-- unless minor version has 2+ digits
|
||||
eq(1, fn.has('patch-7.4.0'))
|
||||
eq(0, fn.has('patch-7.40.0'))
|
||||
eq(1, fn.has('patch-8.0.0'))
|
||||
eq(0, fn.has('patch-8.00.0'))
|
||||
|
||||
eq(1, fn.has('patch-8.1.0'))
|
||||
eq(1, fn.has('patch-8.1.1'))
|
||||
eq(1, fn.has('patch-8.1.0001'))
|
||||
eq(1, fn.has('patch-8.1.1939'))
|
||||
eq(1, fn.has('patch-8.1.2424'))
|
||||
|
||||
eq(0, fn.has('patch-8.2.0'))
|
||||
eq(1, fn.has('patch-8.2.1'))
|
||||
eq(1, fn.has('patch-8.2.2999'))
|
||||
eq(1, fn.has('patch-8.2.5171'))
|
||||
|
||||
eq(0, fn.has('patch-9.0.0'))
|
||||
eq(1, fn.has('patch-9.0.1'))
|
||||
eq(1, fn.has('patch-9.0.998'))
|
||||
eq(1, fn.has('patch-9.0.2190'))
|
||||
|
||||
eq(0, fn.has('patch-9.1.0'))
|
||||
eq(1, fn.has('patch-9.1.1'))
|
||||
eq(1, fn.has('patch-9.1.690'))
|
||||
eq(1, fn.has('patch-9.1.1934'))
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user