From 517f0cc634b985057da5b95cf4ad659ee456a77e Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 4 Dec 2023 12:38:31 -0800 Subject: [PATCH] build: enable lintlua for scripts/ dir #26391 Problem: We don't enable stylua for many Lua scripts. Automating code-style is an important tool for reducing time spent on accidental (non-essential) complexity. Solution: - Enable lintlua for `scripts/` directory. - Specify `call_parentheses = "Input"`, we should allow kwargs-style function invocations. --- .stylua.toml | 2 +- .styluaignore | 1 - CMakeLists.txt | 4 +- scripts/bump_deps.lua | 53 +++--- scripts/gen_eval_files.lua | 72 ++++---- scripts/gen_filetype.lua | 102 ++++++----- scripts/gen_help_html.lua | 341 +++++++++++++++++++++++++------------ scripts/lintcommit.lua | 67 ++++---- scripts/lua2dox.lua | 55 +++--- scripts/vimpatch.lua | 10 +- 10 files changed, 415 insertions(+), 292 deletions(-) diff --git a/.stylua.toml b/.stylua.toml index a2b3447506..22d6d3e6fc 100644 --- a/.stylua.toml +++ b/.stylua.toml @@ -3,4 +3,4 @@ line_endings = "Unix" indent_type = "Spaces" indent_width = 2 quote_style = "AutoPreferSingle" -call_parentheses = "Always" +call_parentheses = "Input" diff --git a/.styluaignore b/.styluaignore index c9303e07ce..c720c00f7e 100644 --- a/.styluaignore +++ b/.styluaignore @@ -2,6 +2,5 @@ /runtime/lua/coxpcall.lua /runtime/lua/vim/_meta /runtime/lua/vim/re.lua -/scripts /src /test diff --git a/CMakeLists.txt b/CMakeLists.txt index 6701b0211b..2bae668e51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -233,7 +233,7 @@ add_glob_target( TARGET lintlua-stylua COMMAND ${STYLUA_PRG} FLAGS --color=always --check --respect-ignores - GLOB_DIRS runtime/ + GLOB_DIRS runtime/ scripts/ GLOB_PAT *.lua TOUCH_STRATEGY SINGLE) @@ -260,7 +260,7 @@ add_glob_target( TARGET formatlua COMMAND ${STYLUA_PRG} FLAGS --respect-ignores - GLOB_DIRS runtime + GLOB_DIRS runtime/ scripts/ GLOB_PAT *.lua) add_custom_target(format) diff --git a/scripts/bump_deps.lua b/scripts/bump_deps.lua index 076ad374cf..c5294893e0 100755 --- a/scripts/bump_deps.lua +++ b/scripts/bump_deps.lua @@ -138,9 +138,10 @@ local function get_archive_info(repo, ref) 'Failed to download archive from GitHub' ) - local shacmd = (vim.fn.executable('sha256sum') == 1 - and{ 'sha256sum', archive_path } - or { 'shasum', '-a', '256', archive_path }) + local shacmd = ( + vim.fn.executable('sha256sum') == 1 and { 'sha256sum', archive_path } + or { 'shasum', '-a', '256', archive_path } + ) local archive_sha = run(shacmd):gmatch('%w+')() return { url = archive_url, sha = archive_sha } end @@ -152,18 +153,7 @@ local function write_cmakelists_line(symbol, kind, value) 'sed', '-i', '-e', - 's/' - .. symbol - .. '_' - .. kind - .. '.*$' - .. '/' - .. symbol - .. '_' - .. kind - .. ' ' - .. value - .. '/', + 's/' .. symbol .. '_' .. kind .. '.*$' .. '/' .. symbol .. '_' .. kind .. ' ' .. value .. '/', deps_file, }, 'Failed to write ' .. deps_file) end @@ -203,16 +193,13 @@ local function update_cmakelists(dependency, archive, comment) 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) - run_die( - { - 'git', - 'commit', - deps_file, - '-m', - commit_prefix .. 'bump ' .. dependency.name .. ' to ' .. comment, - }, - 'git failed to commit' - ) + run_die({ + 'git', + 'commit', + deps_file, + '-m', + commit_prefix .. 'bump ' .. dependency.name .. ' to ' .. comment, + }, 'git failed to commit') end local function verify_cmakelists_committed() @@ -318,9 +305,9 @@ function M.commit(dependency_name, commit) end function M.version(dependency_name, version) - vim.validate{ - dependency_name={dependency_name,'s'}, - version={version,'s'}, + vim.validate { + dependency_name = { dependency_name, 's' }, + version = { version, 's' }, } local dependency = assert(get_dependency(dependency_name)) verify_cmakelists_committed() @@ -384,7 +371,7 @@ function M.submit_pr() end local function usage() - local this_script = _G.arg[0]:match("[^/]*.lua$") + local this_script = _G.arg[0]:match('[^/]*.lua$') print(([=[ Bump Nvim dependencies @@ -421,13 +408,13 @@ local function parseargs() elseif _G.arg[i] == '--pr' then args.pr = true elseif _G.arg[i] == '--branch' then - args.branch = _G.arg[i+1] + args.branch = _G.arg[i + 1] elseif _G.arg[i] == '--dep' then - args.dep = _G.arg[i+1] + args.dep = _G.arg[i + 1] elseif _G.arg[i] == '--version' then - args.version = _G.arg[i+1] + args.version = _G.arg[i + 1] elseif _G.arg[i] == '--commit' then - args.commit = _G.arg[i+1] + args.commit = _G.arg[i + 1] elseif _G.arg[i] == '--head' then args.head = true end diff --git a/scripts/gen_eval_files.lua b/scripts/gen_eval_files.lua index e331dd996e..dddc7d000c 100755 --- a/scripts/gen_eval_files.lua +++ b/scripts/gen_eval_files.lua @@ -1,7 +1,7 @@ -- Generator for various vimdoc and Lua type files local DEP_API_METADATA = 'build/api_metadata.mpack' -local DEP_API_DOC = 'runtime/doc/api.mpack' +local DEP_API_DOC = 'runtime/doc/api.mpack' --- @class vim.api.metadata --- @field name string @@ -302,7 +302,7 @@ local function get_api_keysets_meta() for _, k in ipairs(keysets) do local params = {} for _, key in ipairs(k.keys) do - table.insert(params, {key..'?', api_type(k.types[key] or 'any')}) + table.insert(params, { key .. '?', api_type(k.types[key] or 'any') }) end ret[k.name] = { signature = 'NA', @@ -396,7 +396,7 @@ local function render_sig_and_tag(name, fun, write) local tag = table.concat(tags, ' ') local siglen = #fun.signature - local conceal_offset = 2*(#tags - 1) + local conceal_offset = 2 * (#tags - 1) local tag_pad_len = math.max(1, 80 - #tag + conceal_offset) if siglen + #tag > 80 then @@ -473,7 +473,7 @@ local function render_option_default(d, vimdoc) end end - if dt == "" or dt == nil or type(dt) == 'function' then + if dt == '' or dt == nil or type(dt) == 'function' then dt = d.meta end @@ -481,22 +481,22 @@ local function render_option_default(d, vimdoc) if not vimdoc then v = vim.inspect(dt) --[[@as string]] else - v = type(dt) == 'string' and '"'..dt..'"' or tostring(dt) + v = type(dt) == 'string' and '"' .. dt .. '"' or tostring(dt) end --- @type table local envvars = { TMPDIR = false, VIMRUNTIME = false, - XDG_CONFIG_HOME = vim.env.HOME..'/.local/config', - XDG_DATA_HOME = vim.env.HOME..'/.local/share', - XDG_STATE_HOME = vim.env.HOME..'/.local/state', + XDG_CONFIG_HOME = vim.env.HOME .. '/.local/config', + XDG_DATA_HOME = vim.env.HOME .. '/.local/share', + XDG_STATE_HOME = vim.env.HOME .. '/.local/state', } for name, default in pairs(envvars) do local value = vim.env[name] or default if value then - v = v:gsub(vim.pesc(value), '$'..name) + v = v:gsub(vim.pesc(value), '$' .. name) end end @@ -509,26 +509,26 @@ end local function render_option_meta(_f, opt, write) write('') for _, l in ipairs(split(norm_text(opt.desc))) do - write('--- '..l) + write('--- ' .. l) end - write('--- @type '..OPTION_TYPES[opt.type]) - write('vim.o.'..opt.full_name..' = '..render_option_default(opt.defaults)) + write('--- @type ' .. OPTION_TYPES[opt.type]) + 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) + write('vim.o.' .. opt.abbreviation .. ' = vim.o.' .. opt.full_name) end for _, s in pairs { - {'wo', 'window'}, - {'bo', 'buffer'}, - {'go', 'global'}, + { 'wo', 'window' }, + { 'bo', 'buffer' }, + { 'go', 'global' }, } do local id, scope = s[1], s[2] if vim.list_contains(opt.scope, scope) or (id == 'go' and #opt.scope > 1) then - local pfx = 'vim.'..id..'.' - write(pfx..opt.full_name..' = vim.o.'..opt.full_name) + local pfx = 'vim.' .. id .. '.' + write(pfx .. opt.full_name .. ' = vim.o.' .. opt.full_name) if opt.abbreviation then - write(pfx..opt.abbreviation..' = '..pfx..opt.full_name) + write(pfx .. opt.abbreviation .. ' = ' .. pfx .. opt.full_name) end end end @@ -541,14 +541,14 @@ local function scope_to_doc(s) global = 'global', buffer = 'local to buffer', window = 'local to window', - tab = 'local to tab page' + tab = 'local to tab page', } if #s == 1 then return m[s[1]] end assert(s[1] == 'global') - return 'global or '..m[s[2]]..' |global-local|' + return 'global or ' .. m[s[2]] .. ' |global-local|' end -- @param o vim.option_meta @@ -602,23 +602,23 @@ local function build_option_tags(opt) --- @type string[] local tags = { opt.full_name } - tags[#tags+1] = opt.abbreviation + tags[#tags + 1] = opt.abbreviation if opt.type == 'bool' then for i = 1, #tags do - tags[#tags+1] = 'no'..tags[i] + tags[#tags + 1] = 'no' .. tags[i] end end for i, t in ipairs(tags) do - tags[i] = "'"..t.."'" + tags[i] = "'" .. t .. "'" end for _, t in ipairs(opt.tags or {}) do - tags[#tags+1] = t + tags[#tags + 1] = t end for i, t in ipairs(tags) do - tags[i] = "*"..t.."*" + tags[i] = '*' .. t .. '*' end return tags @@ -630,10 +630,10 @@ end local function render_option_doc(_f, opt, write) local tags = build_option_tags(opt) local tag_str = table.concat(tags, ' ') - local conceal_offset = 2*(#tags - 1) + local conceal_offset = 2 * (#tags - 1) local tag_pad = string.rep('\t', math.ceil((64 - #tag_str + conceal_offset) / 8)) -- local pad = string.rep(' ', 80 - #tag_str + conceal_offset) - write(tag_pad..tag_str) + write(tag_pad .. tag_str) local name_str --- @type string if opt.abbreviation then @@ -649,19 +649,19 @@ local function render_option_doc(_f, opt, write) if opt.defaults.doc then local deflen = #string.format('%s%s%s (', name_str, pad, otype) --- @type string - v = v:gsub('\n', '\n'..string.rep(' ', deflen - 2)) + v = v:gsub('\n', '\n' .. string.rep(' ', deflen - 2)) end write(string.format('%s%s%s\t(default %s)', name_str, pad, otype, v)) else write(string.format('%s\t%s', name_str, otype)) end - write('\t\t\t'..scope_to_doc(opt.scope)..scope_more_doc(opt)) + write('\t\t\t' .. scope_to_doc(opt.scope) .. scope_more_doc(opt)) for _, l in ipairs(split(opt.desc)) do if l == '<' or l:match('^<%s') then write(l) else - write('\t'..l:gsub('\\<', '<')) + write('\t' .. l:gsub('\\<', '<')) end end end @@ -751,21 +751,21 @@ local CONFIG = { header = { '' }, from = 'A jump table for the options with a short description can be found at |Q_op|.', footer = { - ' vim:tw=78:ts=8:noet:ft=help:norl:' + ' vim:tw=78:ts=8:noet:ft=help:norl:', }, funcs = get_option_meta, render = render_option_doc, - } + }, } --- @param elem nvim.gen_eval_files.elem local function render(elem) - print('Rendering '..elem.path) - local from_lines = {} --- @type string[] + print('Rendering ' .. elem.path) + local from_lines = {} --- @type string[] local from = elem.from if from then for line in io.lines(elem.path) do - from_lines[#from_lines+1] = line + from_lines[#from_lines + 1] = line if line:match(from) then break end diff --git a/scripts/gen_filetype.lua b/scripts/gen_filetype.lua index 42478a1082..18b53f1ea4 100644 --- a/scripts/gen_filetype.lua +++ b/scripts/gen_filetype.lua @@ -8,18 +8,18 @@ if do_not_run then return end -local filetype_vim = "runtime/filetype.vim" -local filetype_lua = "runtime/lua/vim/filetype.lua" +local filetype_vim = 'runtime/filetype.vim' +local filetype_lua = 'runtime/lua/vim/filetype.lua' local keywords = { - ["for"] = true, - ["or"] = true, - ["and"] = true, - ["end"] = true, - ["do"] = true, - ["if"] = true, - ["while"] = true, - ["repeat"] = true, + ['for'] = true, + ['or'] = true, + ['and'] = true, + ['end'] = true, + ['do'] = true, + ['if'] = true, + ['while'] = true, + ['repeat'] = true, } local sections = { @@ -28,42 +28,42 @@ local sections = { pattern = { str = {}, func = {} }, } -local specialchars = "%*%?\\%$%[%]%{%}" +local specialchars = '%*%?\\%$%[%]%{%}' local function add_pattern(pat, ft) local ok = true -- Patterns that start or end with { or } confuse splitting on commas and make parsing harder, so just skip those - if not string.find(pat, "^%{") and not string.find(pat, "%}$") then - for part in string.gmatch(pat, "[^,]+") do - if not string.find(part, "[" .. specialchars .. "]") then - if type(ft) == "string" then + if not string.find(pat, '^%{') and not string.find(pat, '%}$') then + for part in string.gmatch(pat, '[^,]+') do + if not string.find(part, '[' .. specialchars .. ']') then + if type(ft) == 'string' then sections.filename.str[part] = ft else sections.filename.func[part] = ft end - elseif string.match(part, "^%*%.[^%./" .. specialchars .. "]+$") then - if type(ft) == "string" then + elseif string.match(part, '^%*%.[^%./' .. specialchars .. ']+$') then + if type(ft) == 'string' then sections.extension.str[part:sub(3)] = ft else sections.extension.func[part:sub(3)] = ft end else - if string.match(part, "^%*/[^" .. specialchars .. "]+$") then + if string.match(part, '^%*/[^' .. specialchars .. ']+$') then -- For patterns matching */some/pattern we want to easily match files -- with path /some/pattern, so include those in filename detection - if type(ft) == "string" then + if type(ft) == 'string' then sections.filename.str[part:sub(2)] = ft else sections.filename.func[part:sub(2)] = ft end end - if string.find(part, "^[%w-_.*?%[%]/]+$") then - local p = part:gsub("%.", "%%."):gsub("%*", ".*"):gsub("%?", ".") + if string.find(part, '^[%w-_.*?%[%]/]+$') then + local p = part:gsub('%.', '%%.'):gsub('%*', '.*'):gsub('%?', '.') -- Insert into array to maintain order rather than setting -- key-value directly - if type(ft) == "string" then + if type(ft) == 'string' then sections.pattern.str[p] = ft else sections.pattern.func[p] = ft @@ -80,14 +80,16 @@ end local function parse_line(line) local pat, ft - pat, ft = line:match("^%s*au%a* Buf[%a,]+%s+(%S+)%s+setf%s+(%S+)") + pat, ft = line:match('^%s*au%a* Buf[%a,]+%s+(%S+)%s+setf%s+(%S+)') if pat then return add_pattern(pat, ft) else local func - pat, func = line:match("^%s*au%a* Buf[%a,]+%s+(%S+)%s+call%s+(%S+)") + pat, func = line:match('^%s*au%a* Buf[%a,]+%s+(%S+)%s+call%s+(%S+)') if pat then - return add_pattern(pat, function() return func end) + return add_pattern(pat, function() + return func + end) end end end @@ -95,12 +97,12 @@ end local unparsed = {} local full_line for line in io.lines(filetype_vim) do - local cont = string.match(line, "^%s*\\%s*(.*)$") + local cont = string.match(line, '^%s*\\%s*(.*)$') if cont then - full_line = full_line .. " " .. cont + full_line = full_line .. ' ' .. cont else if full_line then - if not parse_line(full_line) and string.find(full_line, "^%s*au%a* Buf") then + if not parse_line(full_line) and string.find(full_line, '^%s*au%a* Buf') then table.insert(unparsed, full_line) end end @@ -109,40 +111,46 @@ for line in io.lines(filetype_vim) do end if #unparsed > 0 then - print("Failed to parse the following patterns:") + print('Failed to parse the following patterns:') for _, v in ipairs(unparsed) do print(v) end end local function add_item(indent, key, ft) - if type(ft) == "string" then - if string.find(key, "%A") or keywords[key] then - key = string.format("[\"%s\"]", key) + if type(ft) == 'string' then + if string.find(key, '%A') or keywords[key] then + key = string.format('["%s"]', key) end return string.format([[%s%s = "%s",]], indent, key, ft) - elseif type(ft) == "function" then + elseif type(ft) == 'function' then local func = ft() - if string.find(key, "%A") or keywords[key] then - key = string.format("[\"%s\"]", key) + if string.find(key, '%A') or keywords[key] then + key = string.format('["%s"]', key) end -- Right now only a single argument is supported, which covers -- everything in filetype.vim as of this writing - local arg = string.match(func, "%((.*)%)$") - func = string.gsub(func, "%(.*$", "") - if arg == "" then + local arg = string.match(func, '%((.*)%)$') + func = string.gsub(func, '%(.*$', '') + if arg == '' then -- Function with no arguments, call the function directly return string.format([[%s%s = function() vim.fn["%s"]() end,]], indent, key, func) elseif string.match(arg, [[^(["']).*%1$]]) then -- String argument - if func == "s:StarSetf" then + if func == 's:StarSetf' then return string.format([[%s%s = starsetf(%s),]], indent, key, arg) else return string.format([[%s%s = function() vim.fn["%s"](%s) end,]], indent, key, func, arg) end - elseif string.find(arg, "%(") then + elseif string.find(arg, '%(') then -- Function argument - return string.format([[%s%s = function() vim.fn["%s"](vim.fn.%s) end,]], indent, key, func, arg) + return string.format( + [[%s%s = function() vim.fn["%s"](vim.fn.%s) end,]], + indent, + key, + func, + arg + ) else assert(false, arg) end @@ -153,7 +161,7 @@ do local lines = {} local start = false for line in io.lines(filetype_lua) do - if line:match("^%s+-- END [A-Z]+$") then + if line:match('^%s+-- END [A-Z]+$') then start = false end @@ -161,14 +169,14 @@ do table.insert(lines, line) end - local indent, section = line:match("^(%s+)-- BEGIN ([A-Z]+)$") + local indent, section = line:match('^(%s+)-- BEGIN ([A-Z]+)$') if section then start = true local t = sections[string.lower(section)] local sorted = {} for k, v in pairs(t.str) do - table.insert(sorted, {[k] = v}) + table.insert(sorted, { [k] = v }) end table.sort(sorted, function(a, b) @@ -182,7 +190,7 @@ do sorted = {} for k, v in pairs(t.func) do - table.insert(sorted, {[k] = v}) + table.insert(sorted, { [k] = v }) end table.sort(sorted, function(a, b) @@ -195,7 +203,7 @@ do end end end - local f = io.open(filetype_lua, "w") - f:write(table.concat(lines, "\n") .. "\n") + local f = io.open(filetype_lua, 'w') + f:write(table.concat(lines, '\n') .. '\n') f:close() end diff --git a/scripts/gen_help_html.lua b/scripts/gen_help_html.lua index 633207e018..9369711b0f 100644 --- a/scripts/gen_help_html.lua +++ b/scripts/gen_help_html.lua @@ -60,26 +60,26 @@ local new_layout = { -- TODO: These known invalid |links| require an update to the relevant docs. local exclude_invalid = { - ["'string'"] = "eval.txt", + ["'string'"] = 'eval.txt', Query = 'treesitter.txt', matchit = 'vim_diff.txt', - ["set!"] = "treesitter.txt", + ['set!'] = 'treesitter.txt', } -- False-positive "invalid URLs". local exclude_invalid_urls = { - ["http://"] = "usr_23.txt", - ["http://."] = "usr_23.txt", - ["http://aspell.net/man-html/Affix-Compression.html"] = "spell.txt", - ["http://aspell.net/man-html/Phonetic-Code.html"] = "spell.txt", - ["http://canna.sourceforge.jp/"] = "mbyte.txt", - ["http://gnuada.sourceforge.net"] = "ft_ada.txt", - ["http://lua-users.org/wiki/StringLibraryTutorial"] = "lua.txt", - ["http://michael.toren.net/code/"] = "pi_tar.txt", - ["http://papp.plan9.de"] = "syntax.txt", - ["http://wiki.services.openoffice.org/wiki/Dictionaries"] = "spell.txt", - ["http://www.adapower.com"] = "ft_ada.txt", - ["http://www.jclark.com/"] = "quickfix.txt", + ['http://'] = 'usr_23.txt', + ['http://.'] = 'usr_23.txt', + ['http://aspell.net/man-html/Affix-Compression.html'] = 'spell.txt', + ['http://aspell.net/man-html/Phonetic-Code.html'] = 'spell.txt', + ['http://canna.sourceforge.jp/'] = 'mbyte.txt', + ['http://gnuada.sourceforge.net'] = 'ft_ada.txt', + ['http://lua-users.org/wiki/StringLibraryTutorial'] = 'lua.txt', + ['http://michael.toren.net/code/'] = 'pi_tar.txt', + ['http://papp.plan9.de'] = 'syntax.txt', + ['http://wiki.services.openoffice.org/wiki/Dictionaries'] = 'spell.txt', + ['http://www.adapower.com'] = 'ft_ada.txt', + ['http://www.jclark.com/'] = 'quickfix.txt', } -- Deprecated, brain-damaged files that I don't care about. @@ -98,19 +98,18 @@ local function tofile(fname, text) end local function html_esc(s) - return s:gsub( - '&', '&'):gsub( - '<', '<'):gsub( - '>', '>') + return s:gsub('&', '&'):gsub('<', '<'):gsub('>', '>') end local function url_encode(s) -- Credit: tpope / vim-unimpaired -- NOTE: these chars intentionally *not* escaped: ' ( ) - return vim.fn.substitute(vim.fn.iconv(s, 'latin1', 'utf-8'), + return vim.fn.substitute( + vim.fn.iconv(s, 'latin1', 'utf-8'), [=[[^A-Za-z0-9()'_.~-]]=], [=[\="%".printf("%02X",char2nr(submatch(0)))]=], - 'g') + 'g' + ) end local function expandtabs(s) @@ -131,7 +130,7 @@ local function to_heading_tag(text) end local function basename_noext(f) - return vim.fs.basename(f:gsub('%.txt', '')) + return vim.fs.basename(f:gsub('%.txt', '')) end local function is_blank(s) @@ -151,7 +150,7 @@ local function fix_url(url) local removed_chars = '' local fixed_url = url -- Remove up to one of each char from end of the URL, in this order. - for _, c in ipairs({ '.', ')', }) do + for _, c in ipairs({ '.', ')' }) do if fixed_url:sub(-1) == c then removed_chars = c .. removed_chars fixed_url = fixed_url:sub(1, -2) @@ -162,7 +161,7 @@ end --- Checks if a given line is a "noise" line that doesn't look good in HTML form. local function is_noise(line, noise_lines) - if ( + if -- First line is always noise. (noise_lines ~= nil and vim.tbl_count(noise_lines) == 0) or line:find('Type .*gO.* to see the table of contents') @@ -177,7 +176,7 @@ local function is_noise(line, noise_lines) or line:find('^%s*vim?%:.*ft=help') or line:find('^%s*vim?%:.*filetype=help') or line:find('[*>]local%-additions[*<]') - ) then + then -- table.insert(stats.noise_lines, getbuflinestr(root, opt.buf, 0)) table.insert(noise_lines or {}, line) return true @@ -188,28 +187,32 @@ end --- Creates a github issue URL at neovim/tree-sitter-vimdoc with prefilled content. local function get_bug_url_vimdoc(fname, to_fname, sample_text) local this_url = string.format('https://neovim.io/doc/user/%s', vim.fs.basename(to_fname)) - local bug_url = ('https://github.com/neovim/tree-sitter-vimdoc/issues/new?labels=bug&title=parse+error%3A+' - ..vim.fs.basename(fname) - ..'+&body=Found+%60tree-sitter-vimdoc%60+parse+error+at%3A+' - ..this_url - ..'%0D%0DContext%3A%0D%0D%60%60%60%0D' - ..url_encode(sample_text) - ..'%0D%60%60%60') + local bug_url = ( + 'https://github.com/neovim/tree-sitter-vimdoc/issues/new?labels=bug&title=parse+error%3A+' + .. vim.fs.basename(fname) + .. '+&body=Found+%60tree-sitter-vimdoc%60+parse+error+at%3A+' + .. this_url + .. '%0D%0DContext%3A%0D%0D%60%60%60%0D' + .. url_encode(sample_text) + .. '%0D%60%60%60' + ) return bug_url end --- Creates a github issue URL at neovim/neovim with prefilled content. local function get_bug_url_nvim(fname, to_fname, sample_text, token_name) local this_url = string.format('https://neovim.io/doc/user/%s', vim.fs.basename(to_fname)) - local bug_url = ('https://github.com/neovim/neovim/issues/new?labels=bug&title=user+docs+HTML%3A+' - ..vim.fs.basename(fname) - ..'+&body=%60gen_help_html.lua%60+problem+at%3A+' - ..this_url - ..'%0D' - ..(token_name and '+unhandled+token%3A+%60'..token_name..'%60' or '') - ..'%0DContext%3A%0D%0D%60%60%60%0D' - ..url_encode(sample_text) - ..'%0D%60%60%60') + local bug_url = ( + 'https://github.com/neovim/neovim/issues/new?labels=bug&title=user+docs+HTML%3A+' + .. vim.fs.basename(fname) + .. '+&body=%60gen_help_html.lua%60+problem+at%3A+' + .. this_url + .. '%0D' + .. (token_name and '+unhandled+token%3A+%60' .. token_name .. '%60' or '') + .. '%0DContext%3A%0D%0D%60%60%60%0D' + .. url_encode(sample_text) + .. '%0D%60%60%60' + ) return bug_url end @@ -274,9 +277,11 @@ end local function get_tagname(node, bufnr) local text = vim.treesitter.get_node_text(node, bufnr) - local tag = (node:type() == 'optionlink' or node:parent():type() == 'optionlink') and ("'%s'"):format(text) or text - local helpfile = vim.fs.basename(tagmap[tag]) or nil -- "api.txt" - local helppage = get_helppage(helpfile) -- "api.html" + local tag = (node:type() == 'optionlink' or node:parent():type() == 'optionlink') + and ("'%s'"):format(text) + or text + local helpfile = vim.fs.basename(tagmap[tag]) or nil -- "api.txt" + local helppage = get_helppage(helpfile) -- "api.html" return helppage, tag end @@ -295,11 +300,9 @@ local function ignore_parse_error(fname, s) if ignore_errors[vim.fs.basename(fname)] then return true end - return ( - -- Ignore parse errors for unclosed tag. - -- This is common in vimdocs and is treated as plaintext by :help. - s:find("^[`'|*]") - ) + -- Ignore parse errors for unclosed tag. + -- This is common in vimdocs and is treated as plaintext by :help. + return s:find("^[`'|*]") end local function has_ancestor(node, ancestor_name) @@ -377,10 +380,11 @@ local function visit_validate(root, level, lang_tree, opt, stats) -- Flatten the sample text to a single, truncated line. sample_text = vim.trim(sample_text):gsub('[\t\n]', ' '):sub(1, 80) table.insert(stats.parse_errors, sample_text) - elseif (node_name == 'word' or node_name == 'uppercase_name') - and (not vim.tbl_contains({'codespan', 'taglink', 'tag'}, parent)) + elseif + (node_name == 'word' or node_name == 'uppercase_name') + and (not vim.tbl_contains({ 'codespan', 'taglink', 'tag' }, parent)) then - local text_nopunct = vim.fn.trim(text, '.,', 0) -- Ignore some punctuation. + local text_nopunct = vim.fn.trim(text, '.,', 0) -- Ignore some punctuation. if spell_dict[text_nopunct] then invalid_spelling[text_nopunct] = invalid_spelling[text_nopunct] or {} invalid_spelling[text_nopunct][vim.fs.basename(opt.fname)] = node_text(root:parent()) @@ -399,7 +403,7 @@ local function fix_tab_after_conceal(text, next_node_text) -- Vim tabs take into account the two concealed characters even though they -- are invisible, so we need to add back in the two spaces if this is -- followed by a tab to make the tab alignment to match Vim's behavior. - if string.sub(next_node_text,1,1) == '\t' then + if string.sub(next_node_text, 1, 1) == '\t' then text = text .. ' ' end return text @@ -411,9 +415,15 @@ local function visit_node(root, level, lang_tree, headings, opt, stats) local node_name = (root.named and root:named()) and root:type() or nil -- Previous sibling kind (string). - local prev = root:prev_sibling() and (root:prev_sibling().named and root:prev_sibling():named()) and root:prev_sibling():type() or nil + local prev = root:prev_sibling() + and (root:prev_sibling().named and root:prev_sibling():named()) + and root:prev_sibling():type() + or nil -- Next sibling kind (string). - local next_ = root:next_sibling() and (root:next_sibling().named and root:next_sibling():named()) and root:next_sibling():type() or nil + local next_ = root:next_sibling() + and (root:next_sibling().named and root:next_sibling():named()) + and root:next_sibling():type() + or nil -- Parent kind (string). local parent = root:parent() and root:parent():type() or nil local text = '' @@ -450,7 +460,7 @@ local function visit_node(root, level, lang_tree, headings, opt, stats) trimmed = trim(text) end - if node_name == 'help_file' then -- root node + if node_name == 'help_file' then -- root node return text elseif node_name == 'url' then local fixed_url, removed_chars = fix_url(trimmed) @@ -459,18 +469,22 @@ local function visit_node(root, level, lang_tree, headings, opt, stats) return text elseif node_name == 'h1' or node_name == 'h2' or node_name == 'h3' then if is_noise(text, stats.noise_lines) then - return '' -- Discard common "noise" lines. + return '' -- Discard common "noise" lines. end -- Remove "===" and tags from ToC text. local hname = (node_text():gsub('%-%-%-%-+', ''):gsub('%=%=%=%=+', ''):gsub('%*.*%*', '')) -- Use the first *tag* node as the heading anchor, if any. local tagnode = first(root, 'tag') -- Use the *tag* as the heading anchor id, if possible. - local tagname = tagnode and url_encode(node_text(tagnode:child(1), false)) or to_heading_tag(hname) + local tagname = tagnode and url_encode(node_text(tagnode:child(1), false)) + or to_heading_tag(hname) if node_name == 'h1' or #headings == 0 then table.insert(headings, { name = hname, subheadings = {}, tag = tagname }) else - table.insert(headings[#headings].subheadings, { name = hname, subheadings = {}, tag = tagname }) + table.insert( + headings[#headings].subheadings, + { name = hname, subheadings = {}, tag = tagname } + ) end local el = node_name == 'h1' and 'h2' or 'h3' return ('<%s id="%s" class="help-heading">%s\n'):format(el, tagname, text, el) @@ -490,11 +504,16 @@ local function visit_node(root, level, lang_tree, headings, opt, stats) end return string.format('
\n%s\n
\n', text) elseif node_name == 'line' then - if (parent ~= 'codeblock' or parent ~= 'code') and (is_blank(text) or is_noise(text, stats.noise_lines)) then - return '' -- Discard common "noise" lines. + if + (parent ~= 'codeblock' or parent ~= 'code') + and (is_blank(text) or is_noise(text, stats.noise_lines)) + then + return '' -- Discard common "noise" lines. end -- XXX: Avoid newlines (too much whitespace) after block elements in old (preformatted) layout. - local div = opt.old and root:child(0) and vim.list_contains({'column_heading', 'h1', 'h2', 'h3'}, root:child(0):type()) + local div = opt.old + and root:child(0) + and vim.list_contains({ 'column_heading', 'h1', 'h2', 'h3' }, root:child(0):type()) return string.format('%s%s', div and trim(text) or text, div and '' or '\n') elseif node_name == 'line_li' then local sib = root:prev_sibling() @@ -520,12 +539,17 @@ local function visit_node(root, level, lang_tree, headings, opt, stats) if ignored then return text end - local s = ('%s%s'):format(ws(), helppage, url_encode(tagname), html_esc(tagname)) + local s = ('%s%s'):format( + ws(), + helppage, + url_encode(tagname), + html_esc(tagname) + ) if opt.old and node_name == 'taglink' then s = fix_tab_after_conceal(s, node_text(root:next_sibling())) end return s - elseif vim.list_contains({'codespan', 'keycode'}, node_name) then + elseif vim.list_contains({ 'codespan', 'keycode' }, node_name) then if root:has_error() then return text end @@ -541,24 +565,28 @@ local function visit_node(root, level, lang_tree, headings, opt, stats) elseif node_name == 'language' then language = node_text(root) return '' - elseif node_name == 'code' then -- Highlighted codeblock (child). + elseif node_name == 'code' then -- Highlighted codeblock (child). if is_blank(text) then return '' end local code if language then - code = ('
%s
'):format(language,trim(trim_indent(text), 2)) + code = ('
%s
'):format( + language, + trim(trim_indent(text), 2) + ) language = nil else code = ('
%s
'):format(trim(trim_indent(text), 2)) end return code - elseif node_name == 'tag' then -- anchor + elseif node_name == 'tag' then -- anchor if root:has_error() then return text end - local in_heading = vim.list_contains({'h1', 'h2', 'h3'}, parent) - local cssclass = (not in_heading and get_indent(node_text()) > 8) and 'help-tag-right' or 'help-tag' + local in_heading = vim.list_contains({ 'h1', 'h2', 'h3' }, parent) + local cssclass = (not in_heading and get_indent(node_text()) > 8) and 'help-tag-right' + or 'help-tag' local tagname = node_text(root:child(1), false) if vim.tbl_count(stats.first_tags) < 2 then -- Force the first 2 tags in the doc to be anchored at the main heading. @@ -567,14 +595,29 @@ local function visit_node(root, level, lang_tree, headings, opt, stats) end local el = in_heading and 'span' or 'code' local encoded_tagname = url_encode(tagname) - local s = ('%s<%s id="%s" class="%s">%s'):format(ws(), el, encoded_tagname, cssclass, encoded_tagname, trimmed, el) + local s = ('%s<%s id="%s" class="%s">%s'):format( + ws(), + el, + encoded_tagname, + cssclass, + encoded_tagname, + trimmed, + el + ) if opt.old then - s = fix_tab_after_conceal(s, node_text(root:next_sibling())) + s = fix_tab_after_conceal(s, node_text(root:next_sibling())) end if in_heading and prev ~= 'tag' then -- Don't set "id", let the heading use the tag as its "id" (used by search engines). - s = ('%s<%s class="%s">%s'):format(ws(), el, cssclass, encoded_tagname, trimmed, el) + s = ('%s<%s class="%s">%s'):format( + ws(), + el, + cssclass, + encoded_tagname, + trimmed, + el + ) -- Start the container for tags in a heading. -- This makes "justify-content:space-between" right-align the tags. --

foo bartag1 tag2

@@ -593,11 +636,17 @@ local function visit_node(root, level, lang_tree, headings, opt, stats) local sample_text = level > 0 and getbuflinestr(root, opt.buf, 3) or '[top level!]' table.insert(stats.parse_errors, sample_text) return ('%s'):format( - get_bug_url_vimdoc(opt.fname, opt.to_fname, sample_text), trimmed) - else -- Unknown token. + get_bug_url_vimdoc(opt.fname, opt.to_fname, sample_text), + trimmed + ) + else -- Unknown token. local sample_text = level > 0 and getbuflinestr(root, opt.buf, 3) or '[top level!]' return ('%s'):format( - node_name, get_bug_url_nvim(opt.fname, opt.to_fname, sample_text, node_name), trimmed), ('unknown-token:"%s"'):format(node_name) + node_name, + get_bug_url_nvim(opt.fname, opt.to_fname, sample_text, node_name), + trimmed + ), + ('unknown-token:"%s"'):format(node_name) end end @@ -605,9 +654,11 @@ local function get_helpfiles(include) local dir = './build/runtime/doc' local rv = {} for f, type in vim.fs.dir(dir) do - if (vim.endswith(f, '.txt') - and type == 'file' - and (not include or vim.list_contains(include, f))) then + if + vim.endswith(f, '.txt') + and type == 'file' + and (not include or vim.list_contains(include, f)) + then local fullpath = vim.fn.fnamemodify(('%s/%s'):format(dir, f), ':p') table.insert(rv, fullpath) end @@ -633,7 +684,7 @@ end --- Use the vimdoc parser defined in the build, not whatever happens to be installed on the system. local function ensure_runtimepath() if not vim.o.runtimepath:find('build/lib/nvim/') then - vim.cmd[[set runtimepath^=./build/lib/nvim/]] + vim.cmd [[set runtimepath^=./build/lib/nvim/]] end end @@ -645,11 +696,11 @@ end local function parse_buf(fname, parser_path) local buf if type(fname) == 'string' then - vim.cmd('split '..vim.fn.fnameescape(fname)) -- Filename. + vim.cmd('split ' .. vim.fn.fnameescape(fname)) -- Filename. buf = vim.api.nvim_get_current_buf() else buf = fname - vim.cmd('sbuffer '..tostring(fname)) -- Buffer number. + vim.cmd('sbuffer ' .. tostring(fname)) -- Buffer number. end if parser_path then vim.treesitter.language.add('vimdoc', { path = parser_path }) @@ -671,7 +722,7 @@ local function validate_one(fname, parser_path) } local lang_tree, buf = parse_buf(fname, parser_path) for _, tree in ipairs(lang_tree:trees()) do - visit_validate(tree:root(), 0, tree, { buf = buf, fname = fname, }, stats) + visit_validate(tree:root(), 0, tree, { buf = buf, fname = fname }, stats) end lang_tree:destroy() vim.cmd.close() @@ -690,10 +741,10 @@ local function gen_one(fname, to_fname, old, commit, parser_path) local stats = { noise_lines = {}, parse_errors = {}, - first_tags = {}, -- Track the first few tags in doc. + first_tags = {}, -- Track the first few tags in doc. } local lang_tree, buf = parse_buf(fname, parser_path) - local headings = {} -- Headings (for ToC). 2-dimensional: h1 contains h2/h3. + local headings = {} -- Headings (for ToC). 2-dimensional: h1 contains h2/h3. local title = to_titlecase(basename_noext(fname)) local html = ([[ @@ -777,9 +828,17 @@ local function gen_one(fname, to_fname, old, commit, parser_path) local main = '' for _, tree in ipairs(lang_tree:trees()) do - main = main .. (visit_node(tree:root(), 0, tree, headings, - { buf = buf, old = old, fname = fname, to_fname = to_fname, indent = 1, }, - stats)) + main = main + .. ( + visit_node( + tree:root(), + 0, + tree, + headings, + { buf = buf, old = old, fname = fname, to_fname = to_fname, indent = 1 }, + stats + ) + ) end main = ([[ @@ -809,7 +868,14 @@ local function gen_one(fname, to_fname, old, commit, parser_path)
%s - ]]):format(logo_svg, stats.first_tags[2] or '', stats.first_tags[1] or '', title, vim.fs.basename(fname), main) + ]]):format( + logo_svg, + stats.first_tags[2] or '', + stats.first_tags[1] or '', + title, + vim.fs.basename(fname), + main + ) local toc = [[
@@ -819,13 +885,16 @@ local function gen_one(fname, to_fname, old, commit, parser_path)
]] - local n = 0 -- Count of all headings + subheadings. - for _, h1 in ipairs(headings) do n = n + 1 + #h1.subheadings end + local n = 0 -- Count of all headings + subheadings. + for _, h1 in ipairs(headings) do + n = n + 1 + #h1.subheadings + end for _, h1 in ipairs(headings) do toc = toc .. ('
%s\n'):format(h1.tag, h1.name) - if n < 30 or #headings < 10 then -- Show subheadings only if there aren't too many. + if n < 30 or #headings < 10 then -- Show subheadings only if there aren't too many. for _, h2 in ipairs(h1.subheadings) do - toc = toc .. ('\n'):format(h2.tag, h2.name) + toc = toc + .. ('\n'):format(h2.tag, h2.name) end end toc = toc .. '
' @@ -859,11 +928,16 @@ local function gen_one(fname, to_fname, old, commit, parser_path) ]]):format( - os.date('%Y-%m-%d %H:%M'), commit, commit:sub(1, 7), #stats.parse_errors, bug_link, - html_esc(table.concat(stats.noise_lines, '\n')), #stats.noise_lines) + os.date('%Y-%m-%d %H:%M'), + commit, + commit:sub(1, 7), + #stats.parse_errors, + bug_link, + html_esc(table.concat(stats.noise_lines, '\n')), + #stats.noise_lines + ) - html = ('%s%s%s
\n%s\n\n'):format( - html, main, toc, footer) + html = ('%s%s%s\n%s\n\n'):format(html, main, toc, footer) vim.cmd('q!') lang_tree:destroy() return html, stats @@ -1038,9 +1112,15 @@ function M._test() helpfiles = get_helpfiles() local function ok(cond, expected, actual) - assert((not expected and not actual) or (expected and actual), 'if "expected" is given, "actual" is also required') + assert( + (not expected and not actual) or (expected and actual), + 'if "expected" is given, "actual" is also required' + ) if expected then - return assert(cond, ('expected %s, got: %s'):format(vim.inspect(expected), vim.inspect(actual))) + return assert( + cond, + ('expected %s, got: %s'):format(vim.inspect(expected), vim.inspect(actual)) + ) else return assert(cond) end @@ -1050,7 +1130,11 @@ function M._test() end ok(vim.tbl_count(tagmap) > 3000, '>3000', vim.tbl_count(tagmap)) - ok(vim.endswith(tagmap['vim.diagnostic.set()'], 'diagnostic.txt'), tagmap['vim.diagnostic.set()'], 'diagnostic.txt') + ok( + vim.endswith(tagmap['vim.diagnostic.set()'], 'diagnostic.txt'), + tagmap['vim.diagnostic.set()'], + 'diagnostic.txt' + ) ok(vim.endswith(tagmap['%:s'], 'cmdline.txt'), tagmap['%:s'], 'cmdline.txt') ok(is_noise([[vim:tw=78:isk=!-~,^*,^\|,^\":ts=8:noet:ft=help:norl:]])) ok(is_noise([[ NVIM REFERENCE MANUAL by Thiago de Arruda ]])) @@ -1060,7 +1144,10 @@ function M._test() eq(1, get_indent(' a')) eq(2, get_indent(' a\n b\n c\n')) eq(5, get_indent(' a\n \n b\n c\n d\n e\n')) - eq('a\n \n b\n c\n d\n e\n', trim_indent(' a\n \n b\n c\n d\n e\n')) + eq( + 'a\n \n b\n c\n d\n e\n', + trim_indent(' a\n \n b\n c\n d\n e\n') + ) local fixed_url, removed_chars = fix_url('https://example.com).') eq('https://example.com', fixed_url) @@ -1093,12 +1180,24 @@ end --- --- @returns info dict function M.gen(help_dir, to_dir, include, commit, parser_path) - vim.validate{ - help_dir={help_dir, function(d) return vim.fn.isdirectory(vim.fn.expand(d)) == 1 end, 'valid directory'}, - to_dir={to_dir, 's'}, - include={include, 't', true}, - commit={commit, 's', true}, - parser_path={parser_path, function(f) return f == nil or vim.fn.filereadable(vim.fn.expand(f)) == 1 end, 'valid vimdoc.{so,dll} filepath'}, + vim.validate { + help_dir = { + help_dir, + function(d) + return vim.fn.isdirectory(vim.fn.expand(d)) == 1 + end, + 'valid directory', + }, + to_dir = { to_dir, 's' }, + include = { include, 't', true }, + commit = { commit, 's', true }, + parser_path = { + parser_path, + function(f) + return f == nil or vim.fn.filereadable(vim.fn.expand(f)) == 1 + end, + 'valid vimdoc.{so,dll} filepath', + }, } local err_count = 0 @@ -1117,7 +1216,13 @@ function M.gen(help_dir, to_dir, include, commit, parser_path) local to_fname = ('%s/%s'):format(to_dir, get_helppage(helpfile)) local html, stats = gen_one(f, to_fname, not new_layout[helpfile], commit or '?', parser_path) tofile(to_fname, html) - print(('generated (%-4s errors): %-15s => %s'):format(#stats.parse_errors, helpfile, vim.fs.basename(to_fname))) + print( + ('generated (%-4s errors): %-15s => %s'):format( + #stats.parse_errors, + helpfile, + vim.fs.basename(to_fname) + ) + ) err_count = err_count + #stats.parse_errors end print(('generated %d html pages'):format(#helpfiles)) @@ -1139,10 +1244,22 @@ end -- -- @returns results dict function M.validate(help_dir, include, parser_path) - vim.validate{ - help_dir={help_dir, function(d) return vim.fn.isdirectory(vim.fn.expand(d)) == 1 end, 'valid directory'}, - include={include, 't', true}, - parser_path={parser_path, function(f) return f == nil or vim.fn.filereadable(vim.fn.expand(f)) == 1 end, 'valid vimdoc.{so,dll} filepath'}, + vim.validate { + help_dir = { + help_dir, + function(d) + return vim.fn.isdirectory(vim.fn.expand(d)) == 1 + end, + 'valid directory', + }, + include = { include, 't', true }, + parser_path = { + parser_path, + function(f) + return f == nil or vim.fn.filereadable(vim.fn.expand(f)) == 1 + end, + 'valid vimdoc.{so,dll} filepath', + }, } local err_count = 0 local files_to_errors = {} @@ -1157,7 +1274,9 @@ function M.validate(help_dir, include, parser_path) print(('validated (%-4s errors): %s'):format(#rv.parse_errors, helpfile)) if #rv.parse_errors > 0 then files_to_errors[helpfile] = rv.parse_errors - vim.print(('%s'):format(vim.iter(rv.parse_errors):fold('', function(s, v) return s..'\n '..v end))) + vim.print(('%s'):format(vim.iter(rv.parse_errors):fold('', function(s, v) + return s .. '\n ' .. v + end))) end err_count = err_count + #rv.parse_errors end diff --git a/scripts/lintcommit.lua b/scripts/lintcommit.lua index a3ad4657e9..96f6304247 100644 --- a/scripts/lintcommit.lua +++ b/scripts/lintcommit.lua @@ -16,7 +16,7 @@ local _trace = false -- Print message local function p(s) vim.cmd('set verbose=1') - vim.api.nvim_echo({{s, ''}}, false, {}) + vim.api.nvim_echo({ { s, '' } }, false, {}) vim.cmd('set verbose=0') end @@ -25,7 +25,7 @@ end -- Prints `cmd` if `trace` is enabled. local function run(cmd, or_die) if _trace then - p('run: '..vim.inspect(cmd)) + p('run: ' .. vim.inspect(cmd)) end local rv = vim.trim(vim.fn.system(cmd)) or '' if vim.v.shell_error ~= 0 then @@ -43,14 +43,14 @@ end local function validate_commit(commit_message) -- Return nil if the commit message starts with "fixup" as it signifies it's -- a work in progress and shouldn't be linted yet. - if vim.startswith(commit_message, "fixup") then + if vim.startswith(commit_message, 'fixup') then return nil end - local commit_split = vim.split(commit_message, ":", {plain = true}) + local commit_split = vim.split(commit_message, ':', { plain = true }) -- Return nil if the type is vim-patch since most of the normal rules don't -- apply. - if commit_split[1] == "vim-patch" then + if commit_split[1] == 'vim-patch' then return nil end @@ -81,32 +81,34 @@ local function validate_commit(commit_message) end -- Check if commit introduces a breaking change. - if vim.endswith(before_colon, "!") then + if vim.endswith(before_colon, '!') then before_colon = before_colon:sub(1, -2) end -- Check if type is correct - local type = vim.split(before_colon, "(", {plain = true})[1] - local allowed_types = {'build', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'test', 'vim-patch'} + local type = vim.split(before_colon, '(', { plain = true })[1] + local allowed_types = + { 'build', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'test', 'vim-patch' } if not vim.tbl_contains(allowed_types, type) then return string.format( [[Invalid commit type "%s". Allowed types are: %s. If none of these seem appropriate then use "fix"]], type, - vim.inspect(allowed_types)) + vim.inspect(allowed_types) + ) end -- Check if scope is appropriate - if before_colon:match("%(") then - local scope = vim.trim(commit_message:match("%((.-)%)")) + if before_colon:match('%(') then + local scope = vim.trim(commit_message:match('%((.-)%)')) if scope == '' then return [[Scope can't be empty]] end - if vim.startswith(scope, "nvim_") then - return [[Scope should be "api" instead of "nvim_..."]] + if vim.startswith(scope, 'nvim_') then + return [[Scope should be "api" instead of "nvim_..."]] end local alternative_scope = { @@ -123,17 +125,17 @@ local function validate_commit(commit_message) end -- Check that description doesn't end with a period - if vim.endswith(after_colon, ".") then + if vim.endswith(after_colon, '.') then return [[Description ends with a period (".").]] end -- Check that description starts with a whitespace. - if after_colon:sub(1,1) ~= " " then + if after_colon:sub(1, 1) ~= ' ' then return [[There should be a whitespace after the colon.]] end -- Check that description doesn't start with multiple whitespaces. - if after_colon:sub(1,2) == " " then + if after_colon:sub(1, 2) == ' ' then return [[There should only be one whitespace after the colon.]] end @@ -143,7 +145,7 @@ local function validate_commit(commit_message) end -- Check that description isn't just whitespaces - if vim.trim(after_colon) == "" then + if vim.trim(after_colon) == '' then return [[Description shouldn't be empty.]] end @@ -154,25 +156,25 @@ end function M.main(opt) _trace = not opt or not not opt.trace - local branch = run({'git', 'rev-parse', '--abbrev-ref', 'HEAD'}, true) + local branch = run({ 'git', 'rev-parse', '--abbrev-ref', 'HEAD' }, true) -- TODO(justinmk): check $GITHUB_REF - local ancestor = run({'git', 'merge-base', 'origin/master', branch}) + local ancestor = run({ 'git', 'merge-base', 'origin/master', branch }) if not ancestor then - ancestor = run({'git', 'merge-base', 'upstream/master', branch}) + ancestor = run({ 'git', 'merge-base', 'upstream/master', branch }) end - local commits_str = run({'git', 'rev-list', ancestor..'..'..branch}, true) + local commits_str = run({ 'git', 'rev-list', ancestor .. '..' .. branch }, true) assert(commits_str) local commits = {} --- @type string[] - for substring in commits_str:gmatch("%S+") do - table.insert(commits, substring) + for substring in commits_str:gmatch('%S+') do + table.insert(commits, substring) end local failed = 0 for _, commit_id in ipairs(commits) do - local msg = run({'git', 'show', '-s', '--format=%s' , commit_id}) + local msg = run({ 'git', 'show', '-s', '--format=%s', commit_id }) if vim.v.shell_error ~= 0 then - p('Invalid commit-id: '..commit_id..'"') + p('Invalid commit-id: ' .. commit_id .. '"') else local invalid_msg = validate_commit(msg) if invalid_msg then @@ -183,20 +185,22 @@ function M.main(opt) p('\n') end - p(string.format([[ + p(string.format( + [[ Invalid commit message: "%s" Commit: %s %s ]], msg, commit_id, - invalid_msg)) + invalid_msg + )) end end end if failed > 0 then - p([[ + p([[ See also: https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md#commit-messages @@ -259,7 +263,7 @@ function M._test() ['feat(:grep/:make)'] = false, ['feat(:grep'] = false, ['feat(:grep/:make'] = false, - ['ci: you\'re saying this commit message just goes on and on and on and on and on and on for way too long?'] = false, + ["ci: you're saying this commit message just goes on and on and on and on and on and on for way too long?"] = false, } local failed = 0 @@ -267,14 +271,15 @@ function M._test() local is_valid = (nil == validate_commit(message)) if is_valid ~= expected then failed = failed + 1 - p(string.format('[ FAIL ]: expected=%s, got=%s\n input: "%s"', expected, is_valid, message)) + p( + string.format('[ FAIL ]: expected=%s, got=%s\n input: "%s"', expected, is_valid, message) + ) end end if failed > 0 then os.exit(1) end - end --- @class LintcommitOptions diff --git a/scripts/lua2dox.lua b/scripts/lua2dox.lua index 1c8bc5a3cb..c4ad7fbb03 100644 --- a/scripts/lua2dox.lua +++ b/scripts/lua2dox.lua @@ -59,9 +59,12 @@ local TAGGED_TYPES = { 'TSNode', 'LanguageTree' } -- Document these as 'table' local ALIAS_TYPES = { - 'Range', 'Range4', 'Range6', 'TSMetadata', + 'Range', + 'Range4', + 'Range6', + 'TSMetadata', 'vim.filetype.add.filetypes', - 'vim.filetype.match.args' + 'vim.filetype.match.args', } local debug_outfile = nil --- @type string? @@ -103,7 +106,7 @@ function StreamRead.new(filename) -- syphon lines to our table local filecontents = {} --- @type string[] for line in io.lines(filename) do - filecontents[#filecontents+1] = line + filecontents[#filecontents + 1] = line end return setmetatable({ @@ -176,9 +179,15 @@ local function process_magic(line, generics) local magic_split = vim.split(magic, ' ', { plain = true }) local directive = magic_split[1] - if vim.list_contains({ - 'cast', 'diagnostic', 'overload', 'meta', 'type' - }, directive) then + if + vim.list_contains({ + 'cast', + 'diagnostic', + 'overload', + 'meta', + 'type', + }, directive) + then -- Ignore LSP directives return '// gg:"' .. line .. '"' end @@ -202,8 +211,7 @@ local function process_magic(line, generics) if directive == 'param' then for _, type in ipairs(TYPES) do magic = magic:gsub('^param%s+([a-zA-Z_?]+)%s+.*%((' .. type .. ')%)', 'param %1 %2') - magic = - magic:gsub('^param%s+([a-zA-Z_?]+)%s+.*%((' .. type .. '|nil)%)', 'param %1 %2') + magic = magic:gsub('^param%s+([a-zA-Z_?]+)%s+.*%((' .. type .. '|nil)%)', 'param %1 %2') end magic_split = vim.split(magic, ' ', { plain = true }) type_index = 3 @@ -225,7 +233,7 @@ local function process_magic(line, generics) -- fix optional parameters if magic_split[2]:find('%?$') then if not ty:find('nil') then - ty = ty .. '|nil' + ty = ty .. '|nil' end magic_split[2] = magic_split[2]:sub(1, -2) end @@ -240,18 +248,15 @@ local function process_magic(line, generics) end for _, type in ipairs(ALIAS_TYPES) do - ty = ty:gsub('^'..type..'$', 'table') --- @type string + ty = ty:gsub('^' .. type .. '$', 'table') --- @type string end -- surround some types by () for _, type in ipairs(TYPES) do - ty = ty - :gsub('^(' .. type .. '|nil):?$', '(%1)') - :gsub('^(' .. type .. '):?$', '(%1)') + ty = ty:gsub('^(' .. type .. '|nil):?$', '(%1)'):gsub('^(' .. type .. '):?$', '(%1)') end magic_split[type_index] = ty - end magic = table.concat(magic_split, ' ') @@ -281,7 +286,7 @@ local function process_block_comment(line, in_stream) -- easier to program in_stream:ungetLine(vim.trim(line:sub(closeSquare + 2))) end - comment_parts[#comment_parts+1] = thisComment + comment_parts[#comment_parts + 1] = thisComment end local comment = table.concat(comment_parts) @@ -303,7 +308,7 @@ local function process_function_header(line) if fn:sub(1, 1) == '(' then -- it's an anonymous function - return '// ZZ: '..line + return '// ZZ: ' .. line end -- fn has a name, so is interesting @@ -330,10 +335,7 @@ local function process_function_header(line) comma = ', ' end - fn = fn:sub(1, paren_start) - .. 'self' - .. comma - .. fn:sub(paren_start + 1) + fn = fn:sub(1, paren_start) .. 'self' .. comma .. fn:sub(paren_start + 1) end if line:match('local') then @@ -357,7 +359,7 @@ local function process_line(line, in_stream, generics) return process_magic(line:sub(4), generics) end - if vim.startswith(line, '--'..'[[') then -- it's a long comment + if vim.startswith(line, '--' .. '[[') then -- it's a long comment return process_block_comment(line:sub(5), in_stream) end @@ -375,7 +377,7 @@ local function process_line(line, in_stream, generics) local v = line_raw:match('^([A-Za-z][.a-zA-Z_]*)%s+%=') if v and v:match('%.') then -- Special: this lets gen_vimdoc.py handle tables. - return 'table '..v..'() {}' + return 'table ' .. v .. '() {}' end end @@ -418,7 +420,7 @@ local TApp = { timestamp = os.date('%c %Z', os.time()), name = 'Lua2DoX', version = '0.2 20130128', - copyright = 'Copyright (c) Simon Dales 2012-13' + copyright = 'Copyright (c) Simon Dales 2012-13', } setmetatable(TApp, { __index = TApp }) @@ -447,12 +449,15 @@ if arg[1] == '--help' then elseif arg[1] == '--version' then writeln(TApp:getVersion()) writeln(TApp.copyright) -else -- It's a filter. +else -- It's a filter. local filename = arg[1] if arg[2] == '--outdir' then local outdir = arg[3] - if type(outdir) ~= 'string' or (0 ~= vim.fn.filereadable(outdir) and 0 == vim.fn.isdirectory(outdir)) then + if + type(outdir) ~= 'string' + or (0 ~= vim.fn.filereadable(outdir) and 0 == vim.fn.isdirectory(outdir)) + then error(('invalid --outdir: "%s"'):format(tostring(outdir))) end vim.fn.mkdir(outdir, 'p') diff --git a/scripts/vimpatch.lua b/scripts/vimpatch.lua index 836f672f6e..cbec50fc17 100755 --- a/scripts/vimpatch.lua +++ b/scripts/vimpatch.lua @@ -10,13 +10,13 @@ local function systemlist(...) local err = nvim.nvim_get_vvar('shell_error') local args_str = nvim.nvim_call_function('string', ...) if 0 ~= err then - error('command failed: '..args_str) + error('command failed: ' .. args_str) end return rv end local function vimpatch_sh_list_numbers() - return systemlist( { { 'bash', '-c', 'scripts/vim-patch.sh -M', } } ) + return systemlist({ { 'bash', '-c', 'scripts/vim-patch.sh -M' } }) end -- Generates the lines to be inserted into the src/version.c @@ -55,9 +55,9 @@ local function patch_version_c() nvim.nvim_command('silent normal! j0d/};\rk') -- Insert the lines. nvim.nvim_call_function('append', { - nvim.nvim_eval('line(".")'), - lines, - }) + nvim.nvim_eval('line(".")'), + lines, + }) nvim.nvim_command('silent write') end