aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2025-02-05 23:09:29 +0000
committerJosh Rahm <joshuarahm@gmail.com>2025-02-05 23:09:29 +0000
commitd5f194ce780c95821a855aca3c19426576d28ae0 (patch)
treed45f461b19f9118ad2bb1f440a7a08973ad18832 /scripts
parentc5d770d311841ea5230426cc4c868e8db27300a8 (diff)
parent44740e561fc93afe3ebecfd3618bda2d2abeafb0 (diff)
downloadrneovim-rahm.tar.gz
rneovim-rahm.tar.bz2
rneovim-rahm.zip
Merge remote-tracking branch 'upstream/master' into mix_20240309HEADrahm
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/bump_deps.lua476
-rwxr-xr-xscripts/gen_eval_files.lua101
-rw-r--r--scripts/gen_help_html.lua7
-rwxr-xr-xscripts/gen_vimdoc.lua34
-rwxr-xr-xscripts/genappimage.sh33
-rw-r--r--scripts/luacats_grammar.lua4
-rw-r--r--scripts/luacats_parser.lua25
-rwxr-xr-xscripts/vimpatch.lua2
8 files changed, 254 insertions, 428 deletions
diff --git a/scripts/bump_deps.lua b/scripts/bump_deps.lua
index ad71da5150..a44e4a2d5e 100755
--- a/scripts/bump_deps.lua
+++ b/scripts/bump_deps.lua
@@ -3,44 +3,50 @@
-- Usage:
-- ./scripts/bump_deps.lua -h
-local M = {}
+assert(vim.fn.executable('gh') == 1)
+assert(vim.fn.executable('sed') == 1)
-local _trace = false
local required_branch_prefix = 'bump-'
local commit_prefix = 'build(deps): '
--- Print message
-local function p(s)
- vim.cmd('set verbose=1')
- vim.api.nvim_echo({ { s, '' } }, false, {})
- vim.cmd('set verbose=0')
-end
-
-local function die()
- p('')
+local repos = {
+ 'luajit/luajit',
+ 'libuv/libuv',
+ 'luvit/luv',
+ 'neovim/unibilium',
+ 'juliastrings/utf8proc',
+ 'tree-sitter/tree-sitter',
+ 'tree-sitter/tree-sitter-c',
+ 'tree-sitter-grammars/tree-sitter-lua',
+ 'tree-sitter-grammars/tree-sitter-vim',
+ 'neovim/tree-sitter-vimdoc',
+ 'tree-sitter-grammars/tree-sitter-query',
+ 'tree-sitter-grammars/tree-sitter-markdown',
+ 'bytecodealliance/wasmtime',
+ 'uncrustify/uncrustify',
+}
+
+local dependency_table = {} --- @type table<string, string>
+for _, repo in pairs(repos) do
+ dependency_table[vim.fs.basename(repo)] = repo
+end
+
+local function die(msg)
+ print(msg)
vim.cmd('cquit 1')
end
-- Executes and returns the output of `cmd`, or nil on failure.
-- if die_on_fail is true, process dies with die_msg on failure
---
--- Prints `cmd` if `trace` is enabled.
local function _run(cmd, die_on_fail, die_msg)
- if _trace then
- p('run: ' .. vim.inspect(cmd))
- end
- local rv = vim.trim(vim.fn.system(cmd)) or ''
- if vim.v.shell_error ~= 0 then
+ local rv = vim.system(cmd):wait()
+ if rv.code ~= 0 then
if die_on_fail then
- if _trace then
- p(rv)
- end
- p(die_msg)
- die()
+ die(die_msg)
end
return nil
end
- return rv
+ return vim.trim(rv.stdout)
end
-- Run a command, return nil on failure
@@ -53,108 +59,20 @@ local function run_die(cmd, err_msg)
return _run(cmd, true, err_msg)
end
-local function require_executable(cmd)
- local cmd_path = run_die({ 'sh', '-c', 'command -v ' .. cmd }, cmd .. ' not found!')
- run_die({ 'test', '-x', cmd_path }, cmd .. ' is not executable')
-end
-
-local function rm_file_if_present(path_to_file)
- run({ 'rm', '-f', path_to_file })
-end
-
-local nvim_src_dir = vim.fn.getcwd()
+local nvim_src_dir = run({ 'git', 'rev-parse', '--show-toplevel' })
local deps_file = nvim_src_dir .. '/' .. 'cmake.deps/deps.txt'
-local temp_dir = nvim_src_dir .. '/tmp'
-run({ 'mkdir', '-p', temp_dir })
-
-local function get_dependency(dependency_name)
- local dependency_table = {
- ['luajit'] = {
- repo = 'LuaJIT/LuaJIT',
- symbol = 'LUAJIT',
- },
- ['libuv'] = {
- repo = 'libuv/libuv',
- symbol = 'LIBUV',
- },
- ['luv'] = {
- repo = 'luvit/luv',
- symbol = 'LUV',
- },
- ['unibilium'] = {
- repo = 'neovim/unibilium',
- symbol = 'UNIBILIUM',
- },
- ['utf8proc'] = {
- repo = 'JuliaStrings/utf8proc',
- symbol = 'UTF8PROC',
- },
- ['tree-sitter'] = {
- repo = 'tree-sitter/tree-sitter',
- symbol = 'TREESITTER',
- },
- ['tree-sitter-c'] = {
- repo = 'tree-sitter/tree-sitter-c',
- symbol = 'TREESITTER_C',
- },
- ['tree-sitter-lua'] = {
- repo = 'tree-sitter-grammars/tree-sitter-lua',
- symbol = 'TREESITTER_LUA',
- },
- ['tree-sitter-vim'] = {
- repo = 'tree-sitter-grammars/tree-sitter-vim',
- symbol = 'TREESITTER_VIM',
- },
- ['tree-sitter-vimdoc'] = {
- repo = 'neovim/tree-sitter-vimdoc',
- symbol = 'TREESITTER_VIMDOC',
- },
- ['tree-sitter-query'] = {
- repo = 'tree-sitter-grammars/tree-sitter-query',
- symbol = 'TREESITTER_QUERY',
- },
- ['tree-sitter-markdown'] = {
- repo = 'tree-sitter-grammars/tree-sitter-markdown',
- symbol = 'TREESITTER_MARKDOWN',
- },
- ['wasmtime'] = {
- repo = 'bytecodealliance/wasmtime',
- symbol = 'WASMTIME',
- },
- ['uncrustify'] = {
- repo = 'uncrustify/uncrustify',
- symbol = 'UNCRUSTIFY',
- },
- }
- local dependency = dependency_table[dependency_name]
- if dependency == nil then
- p('Not a dependency: ' .. dependency_name)
- die()
- end
- dependency.name = dependency_name
- return dependency
-end
-
-local function get_gh_commit_sha(repo, ref)
- require_executable('gh')
-
- local sha = run_die(
- { 'gh', 'api', 'repos/' .. repo .. '/commits/' .. ref, '--jq', '.sha' },
- 'Failed to get commit hash from GitHub. Not a valid ref?'
- )
- return sha
-end
+--- @param repo string
+--- @param ref string
local function get_archive_info(repo, ref)
- require_executable('curl')
+ local temp_dir = os.getenv('TMPDIR') or os.getenv('TEMP')
local archive_name = ref .. '.tar.gz'
local archive_path = temp_dir .. '/' .. archive_name
local archive_url = 'https://github.com/' .. repo .. '/archive/' .. archive_name
- rm_file_if_present(archive_path)
run_die(
- { 'curl', '-sL', archive_url, '-o', archive_path },
+ { 'curl', '-sfL', archive_url, '-o', archive_path },
'Failed to download archive from GitHub'
)
@@ -166,9 +84,24 @@ local function get_archive_info(repo, ref)
return { url = archive_url, sha = archive_sha }
end
-local function write_cmakelists_line(symbol, kind, value)
- require_executable('sed')
+local function get_gh_commit_sha(repo, ref)
+ local full_repo = string.format('https://github.com/%s.git', repo)
+ local tag_exists = run_die({ 'git', 'ls-remote', full_repo, 'refs/tags/' .. ref }) ~= ''
+ -- We'd rather use the git tag over commit sha if possible
+ if tag_exists then
+ return ref
+ end
+
+ local sha = assert(
+ run_die(
+ { 'gh', 'api', 'repos/' .. repo .. '/commits/' .. ref, '--jq', '.sha' },
+ 'Failed to get commit hash from GitHub. Not a valid ref?'
+ )
+ )
+ return sha
+end
+local function update_deps_file(symbol, kind, value)
run_die({
'sed',
'-i',
@@ -178,290 +111,103 @@ local function write_cmakelists_line(symbol, kind, value)
}, 'Failed to write ' .. deps_file)
end
-local function explicit_create_branch(dep)
- require_executable('git')
+local function ref(name, _ref)
+ local repo = dependency_table[name]
+ local symbol = string.gsub(name, 'tree%-sitter', 'treesitter'):gsub('%-', '_'):upper()
- local checked_out_branch = run({ 'git', 'rev-parse', '--abbrev-ref', 'HEAD' })
- if checked_out_branch ~= 'master' then
- p('Not on master!')
- die()
- end
- run_die({ 'git', 'checkout', '-b', 'bump-' .. dep }, 'git failed to create branch')
-end
+ run_die(
+ { 'git', 'diff', '--quiet', 'HEAD', '--', deps_file },
+ deps_file .. ' has uncommitted changes'
+ )
-local function verify_branch(new_branch_suffix)
- require_executable('git')
+ _ref = get_gh_commit_sha(repo, _ref)
+
+ local archive = get_archive_info(repo, _ref)
+ local comment = string.sub(_ref, 1, 9)
local checked_out_branch = assert(run({ 'git', 'rev-parse', '--abbrev-ref', 'HEAD' }))
if not checked_out_branch:match('^' .. required_branch_prefix) then
- p(
+ print(
"Current branch '"
.. checked_out_branch
.. "' doesn't seem to start with "
.. required_branch_prefix
)
- p('Checking out to bump-' .. new_branch_suffix)
- explicit_create_branch(new_branch_suffix)
+ print('Checking out to bump-' .. name)
+ run_die({ 'git', 'checkout', '-b', 'bump-' .. name }, 'git failed to create branch')
end
-end
-
-local function update_cmakelists(dependency, archive, comment)
- require_executable('git')
- verify_branch(dependency.name)
-
- p('Updating ' .. dependency.name .. ' to ' .. archive.url .. '\n')
- write_cmakelists_line(dependency.symbol, 'URL', archive.url:gsub('/', '\\/'))
- write_cmakelists_line(dependency.symbol, 'SHA256', archive.sha)
+ print('Updating ' .. name .. ' to ' .. archive.url .. '\n')
+ update_deps_file(symbol, 'URL', archive.url:gsub('/', '\\/'))
+ update_deps_file(symbol, 'SHA256', archive.sha)
run_die({
'git',
'commit',
deps_file,
'-m',
- commit_prefix .. 'bump ' .. dependency.name .. ' to ' .. comment,
+ commit_prefix .. 'bump ' .. name .. ' to ' .. comment,
}, 'git failed to commit')
end
-local function verify_cmakelists_committed()
- require_executable('git')
-
- run_die(
- { 'git', 'diff', '--quiet', 'HEAD', '--', deps_file },
- deps_file .. ' has uncommitted changes'
- )
-end
-
-local function warn_luv_symbol()
- p('warning: ' .. get_dependency('Luv').symbol .. '_VERSION will not be updated')
-end
-
--- return first 9 chars of commit
-local function short_commit(commit)
- return string.sub(commit, 1, 9)
-end
-
--- TODO: remove hardcoded fork
-local function gh_pr(pr_title, pr_body)
- require_executable('gh')
-
- local pr_url = run_die({
- 'gh',
- 'pr',
- 'create',
- '--title',
- pr_title,
- '--body',
- pr_body,
- }, 'Failed to create PR')
- return pr_url
-end
-
-local function find_git_remote(fork)
- require_executable('git')
-
- local remotes = assert(run({ 'git', 'remote', '-v' }))
- local git_remote = ''
- for remote in remotes:gmatch('[^\r\n]+') do
- local words = {}
- for word in remote:gmatch('%w+') do
- table.insert(words, word)
- end
- local match = words[1]:match('/github.com[:/]neovim/neovim/')
- if fork == 'fork' then
- match = not match
- end
- if match and words[3] == '(fetch)' then
- git_remote = words[0]
- break
- end
- end
- if git_remote == '' then
- git_remote = 'origin'
- end
- return git_remote
-end
-
-local function create_pr(pr_title, pr_body)
- require_executable('git')
-
- local push_first = true
-
- local checked_out_branch = run({ 'git', 'rev-parse', '--abbrev-ref', 'HEAD' })
- if push_first then
- local push_remote =
- run({ 'git', 'config', '--get', 'branch.' .. checked_out_branch .. '.pushRemote' })
- if push_remote == nil then
- push_remote = run({ 'git', 'config', '--get', 'remote.pushDefault' })
- if push_remote == nil then
- push_remote =
- run({ 'git', 'config', '--get', 'branch.' .. checked_out_branch .. '.remote' })
- if push_remote == nil or push_remote == find_git_remote(nil) then
- push_remote = find_git_remote('fork')
- end
- end
- end
-
- p('Pushing to ' .. push_remote .. '/' .. checked_out_branch)
- run_die({ 'git', 'push', push_remote, checked_out_branch }, 'Git failed to push')
- end
-
- local pr_url = gh_pr(pr_title, pr_body)
- p('\nCreated PR: ' .. pr_url .. '\n')
-end
-
-function M.commit(dependency_name, commit)
- local dependency = assert(get_dependency(dependency_name))
- verify_cmakelists_committed()
- local commit_sha = get_gh_commit_sha(dependency.repo, commit)
- if commit_sha ~= commit then
- p('Not a commit: ' .. commit .. '. Did you mean version?')
- die()
- end
- local archive = get_archive_info(dependency.repo, commit)
- if dependency_name == 'Luv' then
- warn_luv_symbol()
- end
- update_cmakelists(dependency, archive, short_commit(commit))
-end
-
-function M.version(dependency_name, version)
- vim.validate('dependency_name', dependency_name, 'string')
- vim.validate('version', version, 'string')
- local dependency = assert(get_dependency(dependency_name))
- verify_cmakelists_committed()
- local commit_sha = get_gh_commit_sha(dependency.repo, version)
- if commit_sha == version then
- p('Not a version: ' .. version .. '. Did you mean commit?')
- die()
- end
- local archive = get_archive_info(dependency.repo, version)
- if dependency_name == 'Luv' then
- write_cmakelists_line(dependency.symbol, 'VERSION', version)
- end
- update_cmakelists(dependency, archive, version)
-end
-
-function M.head(dependency_name)
- local dependency = assert(get_dependency(dependency_name))
- verify_cmakelists_committed()
- local commit_sha = get_gh_commit_sha(dependency.repo, 'HEAD')
- local archive = get_archive_info(dependency.repo, commit_sha)
- if dependency_name == 'Luv' then
- warn_luv_symbol()
- end
- update_cmakelists(dependency, archive, 'HEAD - ' .. short_commit(commit_sha))
-end
-
-function M.create_branch(dep)
- explicit_create_branch(dep)
-end
-
-function M.submit_pr()
- require_executable('git')
-
- verify_branch('deps')
-
- local nvim_remote = find_git_remote(nil)
- local relevant_commit = assert(run_die({
- 'git',
- 'log',
- '--grep=' .. commit_prefix,
- '--reverse',
- "--format='%s'",
- nvim_remote .. '/master..HEAD',
- '-1',
- }, 'Failed to fetch commits'))
-
- local pr_title
- local pr_body
-
- if relevant_commit == '' then
- pr_title = commit_prefix .. 'bump some dependencies'
- pr_body = 'bump some dependencies'
- else
- relevant_commit = relevant_commit:gsub("'", '')
- pr_title = relevant_commit
- pr_body = relevant_commit:gsub(commit_prefix:gsub('%(', '%%('):gsub('%)', '%%)'), '')
- end
- pr_body = pr_body .. '\n\n(add explanations if needed)'
- p(pr_title .. '\n' .. pr_body .. '\n')
- create_pr(pr_title, pr_body)
-end
-
local function usage()
- local this_script = _G.arg[0]:match('[^/]*.lua$')
- print(([=[
+ local this_script = tostring(vim.fs.basename(_G.arg[0]))
+ local script_exe = './' .. this_script
+ local help = ([=[
Bump Nvim dependencies
- Usage: nvim -l %s [options]
- Bump to HEAD, tagged version, commit, or branch:
- nvim -l %s --dep Luv --head
- nvim -l %s --dep Luv --version 1.43.0-0
- nvim -l %s --dep Luv --commit abc123
- nvim -l %s --dep Luv --branch
- Create a PR:
- nvim -l %s --pr
+ Usage: %s [options]
+ Bump to HEAD, tagged version or commit:
+ %s luv --head
+ %s luv --ref 1.43.0-0
+ %s luv --ref abc123
Options:
- -h show this message and exit.
- --pr submit pr for bumping deps.
- --branch <dep> create a branch bump-<dep> from current branch.
- --dep <dependency> bump to a specific release or tag.
+ -h, --help show this message and exit.
+ --list list all dependencies
Dependency Options:
- --version <tag> bump to a specific release or tag.
- --commit <hash> bump to a specific commit.
- --HEAD bump to a current head.
+ --ref <ref> bump to a specific commit or tag.
+ --head bump to a current head.
+ ]=]):format(script_exe, script_exe, script_exe, script_exe)
+ print(help)
+end
- <dependency> is one of:
- "LuaJIT", "libuv", "Luv", "tree-sitter"
- ]=]):format(this_script, this_script, this_script, this_script, this_script, this_script))
+local function list_deps()
+ local l = 'Dependencies:\n'
+ for k in vim.spairs(dependency_table) do
+ l = string.format('%s\n%s%s', l, string.rep(' ', 2), k)
+ end
+ print(l)
end
-local function parseargs()
+do
local args = {}
- for i = 1, #_G.arg do
- if _G.arg[i] == '-h' then
+ local i = 1
+ while i <= #_G.arg do
+ if _G.arg[i] == '-h' or _G.arg[i] == '--help' then
args.h = true
- elseif _G.arg[i] == '--pr' then
- args.pr = true
- elseif _G.arg[i] == '--branch' then
- args.branch = _G.arg[i + 1]
- elseif _G.arg[i] == '--dep' then
- args.dep = _G.arg[i + 1]
- elseif _G.arg[i] == '--version' then
- args.version = _G.arg[i + 1]
- elseif _G.arg[i] == '--commit' then
- args.commit = _G.arg[i + 1]
+ elseif _G.arg[i] == '--list' then
+ args.list = true
+ elseif _G.arg[i] == '--ref' then
+ args.ref = _G.arg[i + 1]
+ i = i + 1
elseif _G.arg[i] == '--head' then
- args.head = true
+ args.ref = 'HEAD'
+ elseif vim.startswith(_G.arg[i], '--') then
+ die(string.format('Invalid argument %s\n', _G.arg[i]))
+ else
+ args.dep = _G.arg[i]
end
+ i = i + 1
end
- return args
-end
-
-local is_main = _G.arg[0]:match('bump_deps.lua')
-if is_main then
- local args = parseargs()
if args.h then
usage()
- elseif args.pr then
- M.submit_pr()
- elseif args.head then
- M.head(args.dep)
- elseif args.branch then
- M.create_branch(args.dep)
- elseif args.version then
- M.version(args.dep, args.version)
- elseif args.commit then
- M.commit(args.dep, args.commit)
- elseif args.pr then
- M.submit_pr()
+ elseif args.list then
+ list_deps()
+ elseif args.ref then
+ ref(args.dep, args.ref)
else
- print('missing required arg\n')
- os.exit(1)
+ die('missing required arg\n')
end
-else
- return M
end
diff --git a/scripts/gen_eval_files.lua b/scripts/gen_eval_files.lua
index a9431ae2e5..aaf76a0411 100755
--- a/scripts/gen_eval_files.lua
+++ b/scripts/gen_eval_files.lua
@@ -26,11 +26,11 @@ local LUA_API_RETURN_OVERRIDES = {
nvim_buf_get_command = 'table<string,vim.api.keyset.command_info>',
nvim_buf_get_extmark_by_id = 'vim.api.keyset.get_extmark_item_by_id',
nvim_buf_get_extmarks = 'vim.api.keyset.get_extmark_item[]',
- nvim_buf_get_keymap = 'vim.api.keyset.keymap[]',
+ nvim_buf_get_keymap = 'vim.api.keyset.get_keymap[]',
nvim_get_autocmds = 'vim.api.keyset.get_autocmds.ret[]',
nvim_get_color_map = 'table<string,integer>',
nvim_get_command = 'table<string,vim.api.keyset.command_info>',
- nvim_get_keymap = 'vim.api.keyset.keymap[]',
+ nvim_get_keymap = 'vim.api.keyset.get_keymap[]',
nvim_get_mark = 'vim.api.keyset.get_mark',
-- Can also return table<string,vim.api.keyset.get_hl_info>, however we need to
@@ -47,6 +47,18 @@ local LUA_API_RETURN_OVERRIDES = {
nvim_win_get_config = 'vim.api.keyset.win_config',
}
+local LUA_API_KEYSET_OVERRIDES = {
+ create_autocmd = {
+ callback = 'string|(fun(args: vim.api.keyset.create_autocmd.callback_args): boolean?)',
+ },
+}
+
+local LUA_API_PARAM_OVERRIDES = {
+ nvim_create_user_command = {
+ command = 'string|fun(args: vim.api.keyset.create_user_command.command_args)',
+ },
+}
+
local LUA_META_HEADER = {
'--- @meta _',
'-- THIS FILE IS GENERATED',
@@ -60,6 +72,10 @@ local LUA_API_META_HEADER = {
'-- DO NOT EDIT',
"error('Cannot require a meta file')",
'',
+ '--- This file embeds vimdoc as the function descriptions',
+ '--- so ignore any doc related errors.',
+ '--- @diagnostic disable: undefined-doc-name,luadoc-miss-symbol',
+ '',
'vim.api = {}',
}
@@ -118,10 +134,19 @@ local API_TYPES = {
LuaRef = 'function',
Dict = 'table<string,any>',
Float = 'number',
- HLGroupID = 'number|string',
+ HLGroupID = 'integer|string',
void = '',
}
+--- @param s string
+--- @return string
+local function luaescape(s)
+ if LUA_KEYWORDS[s] then
+ return s .. '_'
+ end
+ return s
+end
+
--- @param x string
--- @param sep? string
--- @return string[]
@@ -133,6 +158,10 @@ end
--- @param t string
--- @return string
local function api_type(t)
+ if vim.startswith(t, '*') then
+ return api_type(t:sub(2)) .. '?'
+ end
+
local as0 = t:match('^ArrayOf%((.*)%)')
if as0 then
local as = split(as0, ', ')
@@ -149,6 +178,33 @@ local function api_type(t)
return 'table<string,' .. api_type(d0) .. '>'
end
+ local u = t:match('^Union%((.*)%)')
+ if u then
+ local us = vim.split(u, ',%s*')
+ return table.concat(vim.tbl_map(api_type, us), '|')
+ end
+
+ local l = t:match('^LuaRefOf%((.*)%)')
+ if l then
+ --- @type string
+ l = l:gsub('%s+', ' ')
+ --- @type string?, string?
+ local as, r = l:match('%((.*)%),%s*(.*)')
+ if not as then
+ --- @type string
+ as = assert(l:match('%((.*)%)'))
+ end
+
+ local as1 = {} --- @type string[]
+ for a in vim.gsplit(as, ',%s') do
+ local a1 = vim.split(a, '%s+', { trimempty = true })
+ local nm = a1[2]:gsub('%*(.*)$', '%1?')
+ as1[#as1 + 1] = nm .. ': ' .. api_type(a1[1])
+ end
+
+ return ('fun(%s)%s'):format(table.concat(as1, ', '), r and ': ' .. api_type(r) or '')
+ end
+
return API_TYPES[t] or t
end
@@ -165,7 +221,7 @@ local function render_fun_sig(f, params)
--- @param v [string,string]
--- @return string
function(v)
- return v[1]
+ return luaescape(v[1])
end,
params
),
@@ -181,7 +237,6 @@ local function render_fun_sig(f, params)
end
--- Uniquify names
---- Fix any names that are lua keywords
--- @param params [string,string,string][]
--- @return [string,string,string][]
local function process_params(params)
@@ -189,9 +244,6 @@ local function process_params(params)
local sfx = 1
for _, p in ipairs(params) do
- if LUA_KEYWORDS[p[1]] then
- p[1] = p[1] .. '_'
- end
if seen[p[1]] then
p[1] = p[1] .. sfx
sfx = sfx + 1
@@ -251,11 +303,13 @@ local function get_api_meta()
sees[#sees + 1] = see.desc
end
+ local pty_overrides = LUA_API_PARAM_OVERRIDES[fun.name] or {}
+
local params = {} --- @type [string,string][]
for _, p in ipairs(fun.params) do
params[#params + 1] = {
p.name,
- api_type(p.type),
+ api_type(pty_overrides[p.name] or p.type),
not deprecated and p.desc or nil,
}
end
@@ -344,10 +398,10 @@ local function render_api_meta(_f, fun, write)
local param_names = {} --- @type string[]
local params = process_params(fun.params)
for _, p in ipairs(params) do
- param_names[#param_names + 1] = p[1]
- local pdesc = p[3]
+ local pname, ptype, pdesc = luaescape(p[1]), p[2], p[3]
+ param_names[#param_names + 1] = pname
if pdesc then
- local s = '--- @param ' .. p[1] .. ' ' .. p[2] .. ' '
+ local s = '--- @param ' .. pname .. ' ' .. ptype .. ' '
local pdesc_a = split(vim.trim(norm_text(pdesc)))
write(s .. pdesc_a[1])
for i = 2, #pdesc_a do
@@ -357,7 +411,7 @@ local function render_api_meta(_f, fun, write)
write('--- ' .. pdesc_a[i])
end
else
- write('--- @param ' .. p[1] .. ' ' .. p[2])
+ write('--- @param ' .. pname .. ' ' .. ptype)
end
end
@@ -382,9 +436,11 @@ local function get_api_keysets_meta()
local keysets = metadata.keysets
for _, k in ipairs(keysets) do
+ local pty_overrides = LUA_API_KEYSET_OVERRIDES[k.name] or {}
local params = {}
for _, key in ipairs(k.keys) do
- table.insert(params, { key .. '?', api_type(k.types[key] or 'any') })
+ local pty = pty_overrides[key] or k.types[key] or 'any'
+ table.insert(params, { key .. '?', api_type(pty) })
end
ret[k.name] = {
signature = 'NA',
@@ -444,10 +500,14 @@ local function render_eval_meta(f, fun, write)
end
end
+ for _, text in ipairs(vim.fn.reverse(fun.generics or {})) do
+ write(fmt('--- @generic %s', text))
+ end
+
local req_args = type(fun.args) == 'table' and fun.args[1] or fun.args or 0
for i, param in ipairs(params) do
- local pname, ptype = param[1], param[2]
+ local pname, ptype = luaescape(param[1]), param[2]
local optional = (pname ~= '...' and i > req_args) and '?' or ''
write(fmt('--- @param %s%s %s', pname, optional, ptype))
end
@@ -610,7 +670,16 @@ local function render_option_meta(_f, opt, write)
write('--- ' .. l)
end
- write('--- @type ' .. OPTION_TYPES[opt.type])
+ if opt.type == 'string' and not opt.list and opt.values then
+ local values = {} --- @type string[]
+ for _, e in ipairs(opt.values) do
+ values[#values + 1] = fmt("'%s'", e)
+ end
+ write('--- @type ' .. table.concat(values, '|'))
+ else
+ write('--- @type ' .. OPTION_TYPES[opt.type])
+ end
+
write('vim.o.' .. opt.full_name .. ' = ' .. render_option_default(opt.defaults))
if opt.abbreviation then
write('vim.o.' .. opt.abbreviation .. ' = vim.o.' .. opt.full_name)
diff --git a/scripts/gen_help_html.lua b/scripts/gen_help_html.lua
index b8f80e94be..53a65fd65f 100644
--- a/scripts/gen_help_html.lua
+++ b/scripts/gen_help_html.lua
@@ -48,7 +48,7 @@ local spell_dict = {
--- specify the list of keywords to ignore (i.e. allow), or true to disable spell check completely.
--- @type table<string, true|string[]>
local spell_ignore_files = {
- ['backers.txt'] = true,
+ ['credits.txt'] = { 'Neovim' },
['news.txt'] = { 'tree-sitter' }, -- in news, may refer to the upstream "tree-sitter" library
['news-0.10.txt'] = { 'tree-sitter' },
}
@@ -70,6 +70,8 @@ local new_layout = {
['dev_vimpatch.txt'] = true,
['editorconfig.txt'] = true,
['faq.txt'] = true,
+ ['gui.txt'] = true,
+ ['intro.txt'] = true,
['lua.txt'] = true,
['luaref.txt'] = true,
['news.txt'] = true,
@@ -84,6 +86,7 @@ local new_layout = {
-- Map of new:old pages, to redirect renamed pages.
local redirects = {
+ ['credits'] = 'backers',
['tui'] = 'term',
['terminal'] = 'nvim_terminal_emulator',
}
@@ -116,7 +119,7 @@ local exclude_invalid_urls = {
-- Deprecated, brain-damaged files that I don't care about.
local ignore_errors = {
['pi_netrw.txt'] = true,
- ['backers.txt'] = true,
+ ['credits.txt'] = true,
}
local function tofile(fname, text)
diff --git a/scripts/gen_vimdoc.lua b/scripts/gen_vimdoc.lua
index 9cd5b598da..d200050fe1 100755
--- a/scripts/gen_vimdoc.lua
+++ b/scripts/gen_vimdoc.lua
@@ -274,6 +274,7 @@ local config = {
'diagnostic.lua',
'codelens.lua',
'completion.lua',
+ 'folding_range.lua',
'inlay_hint.lua',
'tagfunc.lua',
'semantic_tokens.lua',
@@ -349,12 +350,14 @@ local config = {
helptag_fmt = function(name)
if name:lower() == 'treesitter' then
return 'lua-treesitter-core'
+ elseif name:lower() == 'query' then
+ return 'lua-treesitter-query'
elseif name:lower() == 'tstree' then
return { 'treesitter-tree', 'TSTree' }
elseif name:lower() == 'tsnode' then
return { 'treesitter-node', 'TSNode' }
end
- return 'lua-treesitter-' .. name:lower()
+ return 'treesitter-' .. name:lower()
end,
},
editorconfig = {
@@ -514,6 +517,8 @@ local function inline_type(obj, classes)
elseif desc == '' then
if ty_islist then
desc = desc .. 'A list of objects with the following fields:'
+ elseif cls.parent then
+ desc = desc .. fmt('Extends |%s| with the additional fields:', cls.parent)
else
desc = desc .. 'A table with the following fields:'
end
@@ -538,7 +543,8 @@ end
--- @param generics? table<string,string>
--- @param classes? table<string,nvim.luacats.parser.class>
--- @param exclude_types? true
-local function render_fields_or_params(xs, generics, classes, exclude_types)
+--- @param cfg nvim.gen_vimdoc.Config
+local function render_fields_or_params(xs, generics, classes, exclude_types, cfg)
local ret = {} --- @type string[]
xs = vim.tbl_filter(should_render_field_or_param, xs)
@@ -558,7 +564,9 @@ local function render_fields_or_params(xs, generics, classes, exclude_types)
p.desc = pdesc
inline_type(p, classes)
- local nm, ty, desc = p.name, p.type, p.desc
+ local nm, ty = p.name, p.type
+
+ local desc = p.classvar and string.format('See |%s|.', cfg.fn_helptag_fmt(p)) or p.desc
local fnm = p.kind == 'operator' and fmt('op(%s)', nm) or fmt_field_name(nm)
local pnm = fmt(' • %-' .. indent .. 's', fnm)
@@ -591,7 +599,8 @@ end
--- @param class nvim.luacats.parser.class
--- @param classes table<string,nvim.luacats.parser.class>
-local function render_class(class, classes)
+--- @param cfg nvim.gen_vimdoc.Config
+local function render_class(class, classes, cfg)
if class.access or class.nodoc or class.inlinedoc then
return
end
@@ -610,7 +619,7 @@ local function render_class(class, classes)
table.insert(ret, md_to_vimdoc(class.desc, INDENTATION, INDENTATION, TEXT_WIDTH))
end
- local fields_txt = render_fields_or_params(class.fields, nil, classes)
+ local fields_txt = render_fields_or_params(class.fields, nil, classes, nil, cfg)
if not fields_txt:match('^%s*$') then
table.insert(ret, '\n Fields: ~\n')
table.insert(ret, fields_txt)
@@ -621,11 +630,12 @@ local function render_class(class, classes)
end
--- @param classes table<string,nvim.luacats.parser.class>
-local function render_classes(classes)
+--- @param cfg nvim.gen_vimdoc.Config
+local function render_classes(classes, cfg)
local ret = {} --- @type string[]
for _, class in vim.spairs(classes) do
- ret[#ret + 1] = render_class(class, classes)
+ ret[#ret + 1] = render_class(class, classes, cfg)
end
return table.concat(ret)
@@ -656,10 +666,6 @@ local function render_fun_header(fun, cfg)
local proto = fun.table and nm or nm .. '(' .. table.concat(args, ', ') .. ')'
- if not cfg.fn_helptag_fmt then
- cfg.fn_helptag_fmt = fn_helptag_fmt_common
- end
-
local tag = '*' .. cfg.fn_helptag_fmt(fun) .. '*'
if #proto + #tag > TEXT_WIDTH - 8 then
@@ -774,7 +780,8 @@ local function render_fun(fun, classes, cfg)
end
if fun.params and #fun.params > 0 then
- local param_txt = render_fields_or_params(fun.params, fun.generics, classes, cfg.exclude_types)
+ local param_txt =
+ render_fields_or_params(fun.params, fun.generics, classes, cfg.exclude_types, cfg)
if not param_txt:match('^%s*$') then
table.insert(ret, '\n Parameters: ~\n')
ret[#ret + 1] = param_txt
@@ -957,6 +964,7 @@ end
--- @param cfg nvim.gen_vimdoc.Config
local function gen_target(cfg)
+ cfg.fn_helptag_fmt = cfg.fn_helptag_fmt or fn_helptag_fmt_common
print('Target:', cfg.filename)
local sections = {} --- @type table<string,nvim.gen_vimdoc.Section>
@@ -987,7 +995,7 @@ local function gen_target(cfg)
print(' Processing file:', f)
local funs_txt = render_funs(funs, all_classes, cfg)
if next(classes) then
- local classes_txt = render_classes(classes)
+ local classes_txt = render_classes(classes, cfg)
if vim.trim(classes_txt) ~= '' then
funs_txt = classes_txt .. '\n' .. funs_txt
end
diff --git a/scripts/genappimage.sh b/scripts/genappimage.sh
index e8aac42a9c..e683a9dcd1 100755
--- a/scripts/genappimage.sh
+++ b/scripts/genappimage.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/bash -e
########################################################################
# Package the binaries built as an AppImage
@@ -11,6 +11,7 @@ if [ -z "$ARCH" ]; then
ARCH="$(arch)"
export ARCH
fi
+ARCH_ORIGINAL=$ARCH
TAG=$1
@@ -40,16 +41,16 @@ export VERSION
cd "$APP_BUILD_DIR" || exit
# Only downloads linuxdeploy if the remote file is different from local
-if [ -e "$APP_BUILD_DIR"/linuxdeploy-x86_64.AppImage ]; then
- curl -Lo "$APP_BUILD_DIR"/linuxdeploy-x86_64.AppImage \
- -z "$APP_BUILD_DIR"/linuxdeploy-x86_64.AppImage \
- https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
+if [ -e "$APP_BUILD_DIR"/linuxdeploy-"$ARCH".AppImage ]; then
+ curl -Lo "$APP_BUILD_DIR"/linuxdeploy-"$ARCH".AppImage \
+ -z "$APP_BUILD_DIR"/linuxdeploy-"$ARCH".AppImage \
+ https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-"$ARCH".AppImage
else
- curl -Lo "$APP_BUILD_DIR"/linuxdeploy-x86_64.AppImage \
- https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
+ curl -Lo "$APP_BUILD_DIR"/linuxdeploy-"$ARCH".AppImage \
+ https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-"$ARCH".AppImage
fi
-chmod +x "$APP_BUILD_DIR"/linuxdeploy-x86_64.AppImage
+chmod +x "$APP_BUILD_DIR"/linuxdeploy-"$ARCH".AppImage
# metainfo is not packaged automatically by linuxdeploy
mkdir -p "$APP_DIR/usr/share/metainfo/"
@@ -75,24 +76,30 @@ chmod 755 AppRun
cd "$APP_BUILD_DIR" || exit # Get out of AppImage directory.
+# We want to be consistent, so always use arm64 over aarch64
+if [[ "$ARCH" == 'aarch64' ]]; then
+ ARCH="arm64"
+ export ARCH
+fi
+
# Set the name of the file generated by appimage
-export OUTPUT=nvim.appimage
+export OUTPUT=nvim-linux-"$ARCH".appimage
# If it's a release generate the zsync file
if [ -n "$TAG" ]; then
- export UPDATE_INFORMATION="gh-releases-zsync|neovim|neovim|$TAG|nvim.appimage.zsync"
+ export UPDATE_INFORMATION="gh-releases-zsync|neovim|neovim|$TAG|nvim-linux-$ARCH.appimage.zsync"
fi
# Generate AppImage.
# - Expects: $ARCH, $APP, $VERSION env vars
# - Expects: ./$APP.AppDir/ directory
-# - Produces: ./nvim.appimage
-./linuxdeploy-x86_64.AppImage --appdir $APP.AppDir -d "$ROOT_DIR"/runtime/nvim.desktop -i \
+# - Produces: ./nvim-linux-$ARCH.appimage
+./linuxdeploy-"$ARCH_ORIGINAL".AppImage --appdir $APP.AppDir -d "$ROOT_DIR"/runtime/nvim.desktop -i \
"$ROOT_DIR/runtime/nvim.png" --output appimage
# Moving the final executable to a different folder so it isn't in the
# way for a subsequent build.
-mv "$ROOT_DIR"/build/nvim.appimage* "$ROOT_DIR"/build/bin
+mv "$ROOT_DIR"/build/nvim-linux-"$ARCH".appimage* "$ROOT_DIR"/build/bin
echo 'genappimage.sh: finished'
diff --git a/scripts/luacats_grammar.lua b/scripts/luacats_grammar.lua
index 34c1470fea..b700bcf58f 100644
--- a/scripts/luacats_grammar.lua
+++ b/scripts/luacats_grammar.lua
@@ -160,9 +160,9 @@ local typedef = P({
return vim.trim(match):gsub('^%((.*)%)$', '%1'):gsub('%?+', '?')
end
-local opt_exact = opt(Cg(Pf('(exact)'), 'access'))
local access = P('private') + P('protected') + P('package')
local caccess = Cg(access, 'access')
+local cattr = Cg(comma(access + P('exact')), 'access')
local desc_delim = Sf '#:' + ws
local desc = Cg(rep(any), 'desc')
local opt_desc = opt(desc_delim * desc)
@@ -178,7 +178,7 @@ local grammar = P {
+ annot('type', comma1(Ct(v.ctype)) * opt_desc)
+ annot('cast', ty_name * ws * opt(Sf('+-')) * v.ctype)
+ annot('generic', ty_name * opt(colon * v.ctype))
- + annot('class', opt_exact * opt(paren(caccess)) * fill * ty_name * opt_parent)
+ + annot('class', opt(paren(cattr)) * fill * ty_name * opt_parent)
+ annot('field', opt(caccess * ws) * v.field_name * ws * v.ctype * opt_desc)
+ annot('operator', ty_name * opt(paren(Cg(v.ctype, 'argtype'))) * colon * v.ctype)
+ annot(access)
diff --git a/scripts/luacats_parser.lua b/scripts/luacats_parser.lua
index 9a763e4d7b..8a50077aa8 100644
--- a/scripts/luacats_parser.lua
+++ b/scripts/luacats_parser.lua
@@ -1,9 +1,6 @@
local luacats_grammar = require('scripts.luacats_grammar')
---- @class nvim.luacats.parser.param
---- @field name string
---- @field type string
---- @field desc string
+--- @class nvim.luacats.parser.param : nvim.luacats.Param
--- @class nvim.luacats.parser.return
--- @field name string
@@ -41,21 +38,14 @@ local luacats_grammar = require('scripts.luacats_grammar')
--- @field notes? nvim.luacats.parser.note[]
--- @field see? nvim.luacats.parser.note[]
---- @class nvim.luacats.parser.field
---- @field name string
---- @field type string
---- @field desc string
---- @field access? 'private'|'package'|'protected'
+--- @class nvim.luacats.parser.field : nvim.luacats.Field
+--- @field classvar? string
--- @field nodoc? true
---- @class nvim.luacats.parser.class
---- @field kind 'class'
---- @field parent? string
---- @field name string
---- @field desc string
+--- @class nvim.luacats.parser.class : nvim.luacats.Class
+--- @field desc? string
--- @field nodoc? true
--- @field inlinedoc? true
---- @field access? 'private'|'package'|'protected'
--- @field fields nvim.luacats.parser.field[]
--- @field notes? string[]
@@ -332,7 +322,10 @@ local function process_lua_line(line, state, classes, classvars, has_indent)
end
-- Add method as the field to the class
- table.insert(classes[class].fields, fun2field(cur_obj))
+ local cls = classes[class]
+ local field = fun2field(cur_obj)
+ field.classvar = cur_obj.classvar
+ table.insert(cls.fields, field)
return
end
diff --git a/scripts/vimpatch.lua b/scripts/vimpatch.lua
index cbec50fc17..5d8bea6a98 100755
--- a/scripts/vimpatch.lua
+++ b/scripts/vimpatch.lua
@@ -1,7 +1,7 @@
-- Updates version.c list of applied Vim patches.
--
-- Usage:
--- VIM_SOURCE_DIR=~/neovim/.vim-src/ nvim -V1 -es -i NONE +'luafile ./scripts/vimpatch.lua' +q
+-- VIM_SOURCE_DIR=~/neovim/.vim-src/ nvim -l ./scripts/vimpatch.lua
local nvim = vim.api