mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 10:45:16 -07:00
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.
This commit is contained in:
parent
e5d7003b02
commit
517f0cc634
@ -3,4 +3,4 @@ line_endings = "Unix"
|
|||||||
indent_type = "Spaces"
|
indent_type = "Spaces"
|
||||||
indent_width = 2
|
indent_width = 2
|
||||||
quote_style = "AutoPreferSingle"
|
quote_style = "AutoPreferSingle"
|
||||||
call_parentheses = "Always"
|
call_parentheses = "Input"
|
||||||
|
@ -2,6 +2,5 @@
|
|||||||
/runtime/lua/coxpcall.lua
|
/runtime/lua/coxpcall.lua
|
||||||
/runtime/lua/vim/_meta
|
/runtime/lua/vim/_meta
|
||||||
/runtime/lua/vim/re.lua
|
/runtime/lua/vim/re.lua
|
||||||
/scripts
|
|
||||||
/src
|
/src
|
||||||
/test
|
/test
|
||||||
|
@ -233,7 +233,7 @@ add_glob_target(
|
|||||||
TARGET lintlua-stylua
|
TARGET lintlua-stylua
|
||||||
COMMAND ${STYLUA_PRG}
|
COMMAND ${STYLUA_PRG}
|
||||||
FLAGS --color=always --check --respect-ignores
|
FLAGS --color=always --check --respect-ignores
|
||||||
GLOB_DIRS runtime/
|
GLOB_DIRS runtime/ scripts/
|
||||||
GLOB_PAT *.lua
|
GLOB_PAT *.lua
|
||||||
TOUCH_STRATEGY SINGLE)
|
TOUCH_STRATEGY SINGLE)
|
||||||
|
|
||||||
@ -260,7 +260,7 @@ add_glob_target(
|
|||||||
TARGET formatlua
|
TARGET formatlua
|
||||||
COMMAND ${STYLUA_PRG}
|
COMMAND ${STYLUA_PRG}
|
||||||
FLAGS --respect-ignores
|
FLAGS --respect-ignores
|
||||||
GLOB_DIRS runtime
|
GLOB_DIRS runtime/ scripts/
|
||||||
GLOB_PAT *.lua)
|
GLOB_PAT *.lua)
|
||||||
|
|
||||||
add_custom_target(format)
|
add_custom_target(format)
|
||||||
|
@ -138,9 +138,10 @@ local function get_archive_info(repo, ref)
|
|||||||
'Failed to download archive from GitHub'
|
'Failed to download archive from GitHub'
|
||||||
)
|
)
|
||||||
|
|
||||||
local shacmd = (vim.fn.executable('sha256sum') == 1
|
local shacmd = (
|
||||||
and{ 'sha256sum', archive_path }
|
vim.fn.executable('sha256sum') == 1 and { 'sha256sum', archive_path }
|
||||||
or { 'shasum', '-a', '256', archive_path })
|
or { 'shasum', '-a', '256', archive_path }
|
||||||
|
)
|
||||||
local archive_sha = run(shacmd):gmatch('%w+')()
|
local archive_sha = run(shacmd):gmatch('%w+')()
|
||||||
return { url = archive_url, sha = archive_sha }
|
return { url = archive_url, sha = archive_sha }
|
||||||
end
|
end
|
||||||
@ -152,18 +153,7 @@ local function write_cmakelists_line(symbol, kind, value)
|
|||||||
'sed',
|
'sed',
|
||||||
'-i',
|
'-i',
|
||||||
'-e',
|
'-e',
|
||||||
's/'
|
's/' .. symbol .. '_' .. kind .. '.*$' .. '/' .. symbol .. '_' .. kind .. ' ' .. value .. '/',
|
||||||
.. symbol
|
|
||||||
.. '_'
|
|
||||||
.. kind
|
|
||||||
.. '.*$'
|
|
||||||
.. '/'
|
|
||||||
.. symbol
|
|
||||||
.. '_'
|
|
||||||
.. kind
|
|
||||||
.. ' '
|
|
||||||
.. value
|
|
||||||
.. '/',
|
|
||||||
deps_file,
|
deps_file,
|
||||||
}, 'Failed to write ' .. deps_file)
|
}, 'Failed to write ' .. deps_file)
|
||||||
end
|
end
|
||||||
@ -203,16 +193,13 @@ local function update_cmakelists(dependency, archive, comment)
|
|||||||
p('Updating ' .. dependency.name .. ' to ' .. archive.url .. '\n')
|
p('Updating ' .. dependency.name .. ' to ' .. archive.url .. '\n')
|
||||||
write_cmakelists_line(dependency.symbol, 'URL', archive.url:gsub('/', '\\/'))
|
write_cmakelists_line(dependency.symbol, 'URL', archive.url:gsub('/', '\\/'))
|
||||||
write_cmakelists_line(dependency.symbol, 'SHA256', archive.sha)
|
write_cmakelists_line(dependency.symbol, 'SHA256', archive.sha)
|
||||||
run_die(
|
run_die({
|
||||||
{
|
'git',
|
||||||
'git',
|
'commit',
|
||||||
'commit',
|
deps_file,
|
||||||
deps_file,
|
'-m',
|
||||||
'-m',
|
commit_prefix .. 'bump ' .. dependency.name .. ' to ' .. comment,
|
||||||
commit_prefix .. 'bump ' .. dependency.name .. ' to ' .. comment,
|
}, 'git failed to commit')
|
||||||
},
|
|
||||||
'git failed to commit'
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function verify_cmakelists_committed()
|
local function verify_cmakelists_committed()
|
||||||
@ -318,9 +305,9 @@ function M.commit(dependency_name, commit)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function M.version(dependency_name, version)
|
function M.version(dependency_name, version)
|
||||||
vim.validate{
|
vim.validate {
|
||||||
dependency_name={dependency_name,'s'},
|
dependency_name = { dependency_name, 's' },
|
||||||
version={version,'s'},
|
version = { version, 's' },
|
||||||
}
|
}
|
||||||
local dependency = assert(get_dependency(dependency_name))
|
local dependency = assert(get_dependency(dependency_name))
|
||||||
verify_cmakelists_committed()
|
verify_cmakelists_committed()
|
||||||
@ -384,7 +371,7 @@ function M.submit_pr()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function usage()
|
local function usage()
|
||||||
local this_script = _G.arg[0]:match("[^/]*.lua$")
|
local this_script = _G.arg[0]:match('[^/]*.lua$')
|
||||||
print(([=[
|
print(([=[
|
||||||
Bump Nvim dependencies
|
Bump Nvim dependencies
|
||||||
|
|
||||||
@ -421,13 +408,13 @@ local function parseargs()
|
|||||||
elseif _G.arg[i] == '--pr' then
|
elseif _G.arg[i] == '--pr' then
|
||||||
args.pr = true
|
args.pr = true
|
||||||
elseif _G.arg[i] == '--branch' then
|
elseif _G.arg[i] == '--branch' then
|
||||||
args.branch = _G.arg[i+1]
|
args.branch = _G.arg[i + 1]
|
||||||
elseif _G.arg[i] == '--dep' then
|
elseif _G.arg[i] == '--dep' then
|
||||||
args.dep = _G.arg[i+1]
|
args.dep = _G.arg[i + 1]
|
||||||
elseif _G.arg[i] == '--version' then
|
elseif _G.arg[i] == '--version' then
|
||||||
args.version = _G.arg[i+1]
|
args.version = _G.arg[i + 1]
|
||||||
elseif _G.arg[i] == '--commit' then
|
elseif _G.arg[i] == '--commit' then
|
||||||
args.commit = _G.arg[i+1]
|
args.commit = _G.arg[i + 1]
|
||||||
elseif _G.arg[i] == '--head' then
|
elseif _G.arg[i] == '--head' then
|
||||||
args.head = true
|
args.head = true
|
||||||
end
|
end
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
-- Generator for various vimdoc and Lua type files
|
-- Generator for various vimdoc and Lua type files
|
||||||
|
|
||||||
local DEP_API_METADATA = 'build/api_metadata.mpack'
|
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
|
--- @class vim.api.metadata
|
||||||
--- @field name string
|
--- @field name string
|
||||||
@ -302,7 +302,7 @@ local function get_api_keysets_meta()
|
|||||||
for _, k in ipairs(keysets) do
|
for _, k in ipairs(keysets) do
|
||||||
local params = {}
|
local params = {}
|
||||||
for _, key in ipairs(k.keys) do
|
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
|
end
|
||||||
ret[k.name] = {
|
ret[k.name] = {
|
||||||
signature = 'NA',
|
signature = 'NA',
|
||||||
@ -396,7 +396,7 @@ local function render_sig_and_tag(name, fun, write)
|
|||||||
|
|
||||||
local tag = table.concat(tags, ' ')
|
local tag = table.concat(tags, ' ')
|
||||||
local siglen = #fun.signature
|
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)
|
local tag_pad_len = math.max(1, 80 - #tag + conceal_offset)
|
||||||
|
|
||||||
if siglen + #tag > 80 then
|
if siglen + #tag > 80 then
|
||||||
@ -473,7 +473,7 @@ local function render_option_default(d, vimdoc)
|
|||||||
end
|
end
|
||||||
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
|
dt = d.meta
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -481,22 +481,22 @@ local function render_option_default(d, vimdoc)
|
|||||||
if not vimdoc then
|
if not vimdoc then
|
||||||
v = vim.inspect(dt) --[[@as string]]
|
v = vim.inspect(dt) --[[@as string]]
|
||||||
else
|
else
|
||||||
v = type(dt) == 'string' and '"'..dt..'"' or tostring(dt)
|
v = type(dt) == 'string' and '"' .. dt .. '"' or tostring(dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @type table<string, string|false>
|
--- @type table<string, string|false>
|
||||||
local envvars = {
|
local envvars = {
|
||||||
TMPDIR = false,
|
TMPDIR = false,
|
||||||
VIMRUNTIME = false,
|
VIMRUNTIME = false,
|
||||||
XDG_CONFIG_HOME = vim.env.HOME..'/.local/config',
|
XDG_CONFIG_HOME = vim.env.HOME .. '/.local/config',
|
||||||
XDG_DATA_HOME = vim.env.HOME..'/.local/share',
|
XDG_DATA_HOME = vim.env.HOME .. '/.local/share',
|
||||||
XDG_STATE_HOME = vim.env.HOME..'/.local/state',
|
XDG_STATE_HOME = vim.env.HOME .. '/.local/state',
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, default in pairs(envvars) do
|
for name, default in pairs(envvars) do
|
||||||
local value = vim.env[name] or default
|
local value = vim.env[name] or default
|
||||||
if value then
|
if value then
|
||||||
v = v:gsub(vim.pesc(value), '$'..name)
|
v = v:gsub(vim.pesc(value), '$' .. name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -509,26 +509,26 @@ end
|
|||||||
local function render_option_meta(_f, opt, write)
|
local function render_option_meta(_f, opt, write)
|
||||||
write('')
|
write('')
|
||||||
for _, l in ipairs(split(norm_text(opt.desc))) do
|
for _, l in ipairs(split(norm_text(opt.desc))) do
|
||||||
write('--- '..l)
|
write('--- ' .. l)
|
||||||
end
|
end
|
||||||
|
|
||||||
write('--- @type '..OPTION_TYPES[opt.type])
|
write('--- @type ' .. OPTION_TYPES[opt.type])
|
||||||
write('vim.o.'..opt.full_name..' = '..render_option_default(opt.defaults))
|
write('vim.o.' .. opt.full_name .. ' = ' .. render_option_default(opt.defaults))
|
||||||
if opt.abbreviation then
|
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
|
end
|
||||||
|
|
||||||
for _, s in pairs {
|
for _, s in pairs {
|
||||||
{'wo', 'window'},
|
{ 'wo', 'window' },
|
||||||
{'bo', 'buffer'},
|
{ 'bo', 'buffer' },
|
||||||
{'go', 'global'},
|
{ 'go', 'global' },
|
||||||
} do
|
} do
|
||||||
local id, scope = s[1], s[2]
|
local id, scope = s[1], s[2]
|
||||||
if vim.list_contains(opt.scope, scope) or (id == 'go' and #opt.scope > 1) then
|
if vim.list_contains(opt.scope, scope) or (id == 'go' and #opt.scope > 1) then
|
||||||
local pfx = 'vim.'..id..'.'
|
local pfx = 'vim.' .. id .. '.'
|
||||||
write(pfx..opt.full_name..' = vim.o.'..opt.full_name)
|
write(pfx .. opt.full_name .. ' = vim.o.' .. opt.full_name)
|
||||||
if opt.abbreviation then
|
if opt.abbreviation then
|
||||||
write(pfx..opt.abbreviation..' = '..pfx..opt.full_name)
|
write(pfx .. opt.abbreviation .. ' = ' .. pfx .. opt.full_name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -541,14 +541,14 @@ local function scope_to_doc(s)
|
|||||||
global = 'global',
|
global = 'global',
|
||||||
buffer = 'local to buffer',
|
buffer = 'local to buffer',
|
||||||
window = 'local to window',
|
window = 'local to window',
|
||||||
tab = 'local to tab page'
|
tab = 'local to tab page',
|
||||||
}
|
}
|
||||||
|
|
||||||
if #s == 1 then
|
if #s == 1 then
|
||||||
return m[s[1]]
|
return m[s[1]]
|
||||||
end
|
end
|
||||||
assert(s[1] == 'global')
|
assert(s[1] == 'global')
|
||||||
return 'global or '..m[s[2]]..' |global-local|'
|
return 'global or ' .. m[s[2]] .. ' |global-local|'
|
||||||
end
|
end
|
||||||
|
|
||||||
-- @param o vim.option_meta
|
-- @param o vim.option_meta
|
||||||
@ -602,23 +602,23 @@ local function build_option_tags(opt)
|
|||||||
--- @type string[]
|
--- @type string[]
|
||||||
local tags = { opt.full_name }
|
local tags = { opt.full_name }
|
||||||
|
|
||||||
tags[#tags+1] = opt.abbreviation
|
tags[#tags + 1] = opt.abbreviation
|
||||||
if opt.type == 'bool' then
|
if opt.type == 'bool' then
|
||||||
for i = 1, #tags do
|
for i = 1, #tags do
|
||||||
tags[#tags+1] = 'no'..tags[i]
|
tags[#tags + 1] = 'no' .. tags[i]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, t in ipairs(tags) do
|
for i, t in ipairs(tags) do
|
||||||
tags[i] = "'"..t.."'"
|
tags[i] = "'" .. t .. "'"
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, t in ipairs(opt.tags or {}) do
|
for _, t in ipairs(opt.tags or {}) do
|
||||||
tags[#tags+1] = t
|
tags[#tags + 1] = t
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, t in ipairs(tags) do
|
for i, t in ipairs(tags) do
|
||||||
tags[i] = "*"..t.."*"
|
tags[i] = '*' .. t .. '*'
|
||||||
end
|
end
|
||||||
|
|
||||||
return tags
|
return tags
|
||||||
@ -630,10 +630,10 @@ end
|
|||||||
local function render_option_doc(_f, opt, write)
|
local function render_option_doc(_f, opt, write)
|
||||||
local tags = build_option_tags(opt)
|
local tags = build_option_tags(opt)
|
||||||
local tag_str = table.concat(tags, ' ')
|
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 tag_pad = string.rep('\t', math.ceil((64 - #tag_str + conceal_offset) / 8))
|
||||||
-- local pad = string.rep(' ', 80 - #tag_str + conceal_offset)
|
-- local pad = string.rep(' ', 80 - #tag_str + conceal_offset)
|
||||||
write(tag_pad..tag_str)
|
write(tag_pad .. tag_str)
|
||||||
|
|
||||||
local name_str --- @type string
|
local name_str --- @type string
|
||||||
if opt.abbreviation then
|
if opt.abbreviation then
|
||||||
@ -649,19 +649,19 @@ local function render_option_doc(_f, opt, write)
|
|||||||
if opt.defaults.doc then
|
if opt.defaults.doc then
|
||||||
local deflen = #string.format('%s%s%s (', name_str, pad, otype)
|
local deflen = #string.format('%s%s%s (', name_str, pad, otype)
|
||||||
--- @type string
|
--- @type string
|
||||||
v = v:gsub('\n', '\n'..string.rep(' ', deflen - 2))
|
v = v:gsub('\n', '\n' .. string.rep(' ', deflen - 2))
|
||||||
end
|
end
|
||||||
write(string.format('%s%s%s\t(default %s)', name_str, pad, otype, v))
|
write(string.format('%s%s%s\t(default %s)', name_str, pad, otype, v))
|
||||||
else
|
else
|
||||||
write(string.format('%s\t%s', name_str, otype))
|
write(string.format('%s\t%s', name_str, otype))
|
||||||
end
|
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
|
for _, l in ipairs(split(opt.desc)) do
|
||||||
if l == '<' or l:match('^<%s') then
|
if l == '<' or l:match('^<%s') then
|
||||||
write(l)
|
write(l)
|
||||||
else
|
else
|
||||||
write('\t'..l:gsub('\\<', '<'))
|
write('\t' .. l:gsub('\\<', '<'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -751,21 +751,21 @@ local CONFIG = {
|
|||||||
header = { '' },
|
header = { '' },
|
||||||
from = 'A jump table for the options with a short description can be found at |Q_op|.',
|
from = 'A jump table for the options with a short description can be found at |Q_op|.',
|
||||||
footer = {
|
footer = {
|
||||||
' vim:tw=78:ts=8:noet:ft=help:norl:'
|
' vim:tw=78:ts=8:noet:ft=help:norl:',
|
||||||
},
|
},
|
||||||
funcs = get_option_meta,
|
funcs = get_option_meta,
|
||||||
render = render_option_doc,
|
render = render_option_doc,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- @param elem nvim.gen_eval_files.elem
|
--- @param elem nvim.gen_eval_files.elem
|
||||||
local function render(elem)
|
local function render(elem)
|
||||||
print('Rendering '..elem.path)
|
print('Rendering ' .. elem.path)
|
||||||
local from_lines = {} --- @type string[]
|
local from_lines = {} --- @type string[]
|
||||||
local from = elem.from
|
local from = elem.from
|
||||||
if from then
|
if from then
|
||||||
for line in io.lines(elem.path) do
|
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
|
if line:match(from) then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
@ -8,18 +8,18 @@ if do_not_run then
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local filetype_vim = "runtime/filetype.vim"
|
local filetype_vim = 'runtime/filetype.vim'
|
||||||
local filetype_lua = "runtime/lua/vim/filetype.lua"
|
local filetype_lua = 'runtime/lua/vim/filetype.lua'
|
||||||
|
|
||||||
local keywords = {
|
local keywords = {
|
||||||
["for"] = true,
|
['for'] = true,
|
||||||
["or"] = true,
|
['or'] = true,
|
||||||
["and"] = true,
|
['and'] = true,
|
||||||
["end"] = true,
|
['end'] = true,
|
||||||
["do"] = true,
|
['do'] = true,
|
||||||
["if"] = true,
|
['if'] = true,
|
||||||
["while"] = true,
|
['while'] = true,
|
||||||
["repeat"] = true,
|
['repeat'] = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
local sections = {
|
local sections = {
|
||||||
@ -28,42 +28,42 @@ local sections = {
|
|||||||
pattern = { str = {}, func = {} },
|
pattern = { str = {}, func = {} },
|
||||||
}
|
}
|
||||||
|
|
||||||
local specialchars = "%*%?\\%$%[%]%{%}"
|
local specialchars = '%*%?\\%$%[%]%{%}'
|
||||||
|
|
||||||
local function add_pattern(pat, ft)
|
local function add_pattern(pat, ft)
|
||||||
local ok = true
|
local ok = true
|
||||||
|
|
||||||
-- Patterns that start or end with { or } confuse splitting on commas and make parsing harder, so just skip those
|
-- 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
|
if not string.find(pat, '^%{') and not string.find(pat, '%}$') then
|
||||||
for part in string.gmatch(pat, "[^,]+") do
|
for part in string.gmatch(pat, '[^,]+') do
|
||||||
if not string.find(part, "[" .. specialchars .. "]") then
|
if not string.find(part, '[' .. specialchars .. ']') then
|
||||||
if type(ft) == "string" then
|
if type(ft) == 'string' then
|
||||||
sections.filename.str[part] = ft
|
sections.filename.str[part] = ft
|
||||||
else
|
else
|
||||||
sections.filename.func[part] = ft
|
sections.filename.func[part] = ft
|
||||||
end
|
end
|
||||||
elseif string.match(part, "^%*%.[^%./" .. specialchars .. "]+$") then
|
elseif string.match(part, '^%*%.[^%./' .. specialchars .. ']+$') then
|
||||||
if type(ft) == "string" then
|
if type(ft) == 'string' then
|
||||||
sections.extension.str[part:sub(3)] = ft
|
sections.extension.str[part:sub(3)] = ft
|
||||||
else
|
else
|
||||||
sections.extension.func[part:sub(3)] = ft
|
sections.extension.func[part:sub(3)] = ft
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if string.match(part, "^%*/[^" .. specialchars .. "]+$") then
|
if string.match(part, '^%*/[^' .. specialchars .. ']+$') then
|
||||||
-- For patterns matching */some/pattern we want to easily match files
|
-- For patterns matching */some/pattern we want to easily match files
|
||||||
-- with path /some/pattern, so include those in filename detection
|
-- 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
|
sections.filename.str[part:sub(2)] = ft
|
||||||
else
|
else
|
||||||
sections.filename.func[part:sub(2)] = ft
|
sections.filename.func[part:sub(2)] = ft
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if string.find(part, "^[%w-_.*?%[%]/]+$") then
|
if string.find(part, '^[%w-_.*?%[%]/]+$') then
|
||||||
local p = part:gsub("%.", "%%."):gsub("%*", ".*"):gsub("%?", ".")
|
local p = part:gsub('%.', '%%.'):gsub('%*', '.*'):gsub('%?', '.')
|
||||||
-- Insert into array to maintain order rather than setting
|
-- Insert into array to maintain order rather than setting
|
||||||
-- key-value directly
|
-- key-value directly
|
||||||
if type(ft) == "string" then
|
if type(ft) == 'string' then
|
||||||
sections.pattern.str[p] = ft
|
sections.pattern.str[p] = ft
|
||||||
else
|
else
|
||||||
sections.pattern.func[p] = ft
|
sections.pattern.func[p] = ft
|
||||||
@ -80,14 +80,16 @@ end
|
|||||||
|
|
||||||
local function parse_line(line)
|
local function parse_line(line)
|
||||||
local pat, ft
|
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
|
if pat then
|
||||||
return add_pattern(pat, ft)
|
return add_pattern(pat, ft)
|
||||||
else
|
else
|
||||||
local func
|
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
|
if pat then
|
||||||
return add_pattern(pat, function() return func end)
|
return add_pattern(pat, function()
|
||||||
|
return func
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -95,12 +97,12 @@ end
|
|||||||
local unparsed = {}
|
local unparsed = {}
|
||||||
local full_line
|
local full_line
|
||||||
for line in io.lines(filetype_vim) do
|
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
|
if cont then
|
||||||
full_line = full_line .. " " .. cont
|
full_line = full_line .. ' ' .. cont
|
||||||
else
|
else
|
||||||
if full_line then
|
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)
|
table.insert(unparsed, full_line)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -109,40 +111,46 @@ for line in io.lines(filetype_vim) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
if #unparsed > 0 then
|
if #unparsed > 0 then
|
||||||
print("Failed to parse the following patterns:")
|
print('Failed to parse the following patterns:')
|
||||||
for _, v in ipairs(unparsed) do
|
for _, v in ipairs(unparsed) do
|
||||||
print(v)
|
print(v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function add_item(indent, key, ft)
|
local function add_item(indent, key, ft)
|
||||||
if type(ft) == "string" then
|
if type(ft) == 'string' then
|
||||||
if string.find(key, "%A") or keywords[key] then
|
if string.find(key, '%A') or keywords[key] then
|
||||||
key = string.format("[\"%s\"]", key)
|
key = string.format('["%s"]', key)
|
||||||
end
|
end
|
||||||
return string.format([[%s%s = "%s",]], indent, key, ft)
|
return string.format([[%s%s = "%s",]], indent, key, ft)
|
||||||
elseif type(ft) == "function" then
|
elseif type(ft) == 'function' then
|
||||||
local func = ft()
|
local func = ft()
|
||||||
if string.find(key, "%A") or keywords[key] then
|
if string.find(key, '%A') or keywords[key] then
|
||||||
key = string.format("[\"%s\"]", key)
|
key = string.format('["%s"]', key)
|
||||||
end
|
end
|
||||||
-- Right now only a single argument is supported, which covers
|
-- Right now only a single argument is supported, which covers
|
||||||
-- everything in filetype.vim as of this writing
|
-- everything in filetype.vim as of this writing
|
||||||
local arg = string.match(func, "%((.*)%)$")
|
local arg = string.match(func, '%((.*)%)$')
|
||||||
func = string.gsub(func, "%(.*$", "")
|
func = string.gsub(func, '%(.*$', '')
|
||||||
if arg == "" then
|
if arg == '' then
|
||||||
-- Function with no arguments, call the function directly
|
-- Function with no arguments, call the function directly
|
||||||
return string.format([[%s%s = function() vim.fn["%s"]() end,]], indent, key, func)
|
return string.format([[%s%s = function() vim.fn["%s"]() end,]], indent, key, func)
|
||||||
elseif string.match(arg, [[^(["']).*%1$]]) then
|
elseif string.match(arg, [[^(["']).*%1$]]) then
|
||||||
-- String argument
|
-- String argument
|
||||||
if func == "s:StarSetf" then
|
if func == 's:StarSetf' then
|
||||||
return string.format([[%s%s = starsetf(%s),]], indent, key, arg)
|
return string.format([[%s%s = starsetf(%s),]], indent, key, arg)
|
||||||
else
|
else
|
||||||
return string.format([[%s%s = function() vim.fn["%s"](%s) end,]], indent, key, func, arg)
|
return string.format([[%s%s = function() vim.fn["%s"](%s) end,]], indent, key, func, arg)
|
||||||
end
|
end
|
||||||
elseif string.find(arg, "%(") then
|
elseif string.find(arg, '%(') then
|
||||||
-- Function argument
|
-- 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
|
else
|
||||||
assert(false, arg)
|
assert(false, arg)
|
||||||
end
|
end
|
||||||
@ -153,7 +161,7 @@ do
|
|||||||
local lines = {}
|
local lines = {}
|
||||||
local start = false
|
local start = false
|
||||||
for line in io.lines(filetype_lua) do
|
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
|
start = false
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -161,14 +169,14 @@ do
|
|||||||
table.insert(lines, line)
|
table.insert(lines, line)
|
||||||
end
|
end
|
||||||
|
|
||||||
local indent, section = line:match("^(%s+)-- BEGIN ([A-Z]+)$")
|
local indent, section = line:match('^(%s+)-- BEGIN ([A-Z]+)$')
|
||||||
if section then
|
if section then
|
||||||
start = true
|
start = true
|
||||||
local t = sections[string.lower(section)]
|
local t = sections[string.lower(section)]
|
||||||
|
|
||||||
local sorted = {}
|
local sorted = {}
|
||||||
for k, v in pairs(t.str) do
|
for k, v in pairs(t.str) do
|
||||||
table.insert(sorted, {[k] = v})
|
table.insert(sorted, { [k] = v })
|
||||||
end
|
end
|
||||||
|
|
||||||
table.sort(sorted, function(a, b)
|
table.sort(sorted, function(a, b)
|
||||||
@ -182,7 +190,7 @@ do
|
|||||||
|
|
||||||
sorted = {}
|
sorted = {}
|
||||||
for k, v in pairs(t.func) do
|
for k, v in pairs(t.func) do
|
||||||
table.insert(sorted, {[k] = v})
|
table.insert(sorted, { [k] = v })
|
||||||
end
|
end
|
||||||
|
|
||||||
table.sort(sorted, function(a, b)
|
table.sort(sorted, function(a, b)
|
||||||
@ -195,7 +203,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local f = io.open(filetype_lua, "w")
|
local f = io.open(filetype_lua, 'w')
|
||||||
f:write(table.concat(lines, "\n") .. "\n")
|
f:write(table.concat(lines, '\n') .. '\n')
|
||||||
f:close()
|
f:close()
|
||||||
end
|
end
|
||||||
|
@ -60,26 +60,26 @@ local new_layout = {
|
|||||||
|
|
||||||
-- TODO: These known invalid |links| require an update to the relevant docs.
|
-- TODO: These known invalid |links| require an update to the relevant docs.
|
||||||
local exclude_invalid = {
|
local exclude_invalid = {
|
||||||
["'string'"] = "eval.txt",
|
["'string'"] = 'eval.txt',
|
||||||
Query = 'treesitter.txt',
|
Query = 'treesitter.txt',
|
||||||
matchit = 'vim_diff.txt',
|
matchit = 'vim_diff.txt',
|
||||||
["set!"] = "treesitter.txt",
|
['set!'] = 'treesitter.txt',
|
||||||
}
|
}
|
||||||
|
|
||||||
-- False-positive "invalid URLs".
|
-- False-positive "invalid URLs".
|
||||||
local exclude_invalid_urls = {
|
local exclude_invalid_urls = {
|
||||||
["http://"] = "usr_23.txt",
|
['http://'] = 'usr_23.txt',
|
||||||
["http://."] = "usr_23.txt",
|
['http://.'] = 'usr_23.txt',
|
||||||
["http://aspell.net/man-html/Affix-Compression.html"] = "spell.txt",
|
['http://aspell.net/man-html/Affix-Compression.html'] = 'spell.txt',
|
||||||
["http://aspell.net/man-html/Phonetic-Code.html"] = "spell.txt",
|
['http://aspell.net/man-html/Phonetic-Code.html'] = 'spell.txt',
|
||||||
["http://canna.sourceforge.jp/"] = "mbyte.txt",
|
['http://canna.sourceforge.jp/'] = 'mbyte.txt',
|
||||||
["http://gnuada.sourceforge.net"] = "ft_ada.txt",
|
['http://gnuada.sourceforge.net'] = 'ft_ada.txt',
|
||||||
["http://lua-users.org/wiki/StringLibraryTutorial"] = "lua.txt",
|
['http://lua-users.org/wiki/StringLibraryTutorial'] = 'lua.txt',
|
||||||
["http://michael.toren.net/code/"] = "pi_tar.txt",
|
['http://michael.toren.net/code/'] = 'pi_tar.txt',
|
||||||
["http://papp.plan9.de"] = "syntax.txt",
|
['http://papp.plan9.de'] = 'syntax.txt',
|
||||||
["http://wiki.services.openoffice.org/wiki/Dictionaries"] = "spell.txt",
|
['http://wiki.services.openoffice.org/wiki/Dictionaries'] = 'spell.txt',
|
||||||
["http://www.adapower.com"] = "ft_ada.txt",
|
['http://www.adapower.com'] = 'ft_ada.txt',
|
||||||
["http://www.jclark.com/"] = "quickfix.txt",
|
['http://www.jclark.com/'] = 'quickfix.txt',
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Deprecated, brain-damaged files that I don't care about.
|
-- Deprecated, brain-damaged files that I don't care about.
|
||||||
@ -98,19 +98,18 @@ local function tofile(fname, text)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function html_esc(s)
|
local function html_esc(s)
|
||||||
return s:gsub(
|
return s:gsub('&', '&'):gsub('<', '<'):gsub('>', '>')
|
||||||
'&', '&'):gsub(
|
|
||||||
'<', '<'):gsub(
|
|
||||||
'>', '>')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function url_encode(s)
|
local function url_encode(s)
|
||||||
-- Credit: tpope / vim-unimpaired
|
-- Credit: tpope / vim-unimpaired
|
||||||
-- NOTE: these chars intentionally *not* escaped: ' ( )
|
-- 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()'_.~-]]=],
|
[=[[^A-Za-z0-9()'_.~-]]=],
|
||||||
[=[\="%".printf("%02X",char2nr(submatch(0)))]=],
|
[=[\="%".printf("%02X",char2nr(submatch(0)))]=],
|
||||||
'g')
|
'g'
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function expandtabs(s)
|
local function expandtabs(s)
|
||||||
@ -131,7 +130,7 @@ local function to_heading_tag(text)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function basename_noext(f)
|
local function basename_noext(f)
|
||||||
return vim.fs.basename(f:gsub('%.txt', ''))
|
return vim.fs.basename(f:gsub('%.txt', ''))
|
||||||
end
|
end
|
||||||
|
|
||||||
local function is_blank(s)
|
local function is_blank(s)
|
||||||
@ -151,7 +150,7 @@ local function fix_url(url)
|
|||||||
local removed_chars = ''
|
local removed_chars = ''
|
||||||
local fixed_url = url
|
local fixed_url = url
|
||||||
-- Remove up to one of each char from end of the URL, in this order.
|
-- 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
|
if fixed_url:sub(-1) == c then
|
||||||
removed_chars = c .. removed_chars
|
removed_chars = c .. removed_chars
|
||||||
fixed_url = fixed_url:sub(1, -2)
|
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.
|
--- Checks if a given line is a "noise" line that doesn't look good in HTML form.
|
||||||
local function is_noise(line, noise_lines)
|
local function is_noise(line, noise_lines)
|
||||||
if (
|
if
|
||||||
-- First line is always noise.
|
-- First line is always noise.
|
||||||
(noise_lines ~= nil and vim.tbl_count(noise_lines) == 0)
|
(noise_lines ~= nil and vim.tbl_count(noise_lines) == 0)
|
||||||
or line:find('Type .*gO.* to see the table of contents')
|
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?%:.*ft=help')
|
||||||
or line:find('^%s*vim?%:.*filetype=help')
|
or line:find('^%s*vim?%:.*filetype=help')
|
||||||
or line:find('[*>]local%-additions[*<]')
|
or line:find('[*>]local%-additions[*<]')
|
||||||
) then
|
then
|
||||||
-- table.insert(stats.noise_lines, getbuflinestr(root, opt.buf, 0))
|
-- table.insert(stats.noise_lines, getbuflinestr(root, opt.buf, 0))
|
||||||
table.insert(noise_lines or {}, line)
|
table.insert(noise_lines or {}, line)
|
||||||
return true
|
return true
|
||||||
@ -188,28 +187,32 @@ end
|
|||||||
--- Creates a github issue URL at neovim/tree-sitter-vimdoc with prefilled content.
|
--- 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 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 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+'
|
local bug_url = (
|
||||||
..vim.fs.basename(fname)
|
'https://github.com/neovim/tree-sitter-vimdoc/issues/new?labels=bug&title=parse+error%3A+'
|
||||||
..'+&body=Found+%60tree-sitter-vimdoc%60+parse+error+at%3A+'
|
.. vim.fs.basename(fname)
|
||||||
..this_url
|
.. '+&body=Found+%60tree-sitter-vimdoc%60+parse+error+at%3A+'
|
||||||
..'%0D%0DContext%3A%0D%0D%60%60%60%0D'
|
.. this_url
|
||||||
..url_encode(sample_text)
|
.. '%0D%0DContext%3A%0D%0D%60%60%60%0D'
|
||||||
..'%0D%60%60%60')
|
.. url_encode(sample_text)
|
||||||
|
.. '%0D%60%60%60'
|
||||||
|
)
|
||||||
return bug_url
|
return bug_url
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Creates a github issue URL at neovim/neovim with prefilled content.
|
--- 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 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 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+'
|
local bug_url = (
|
||||||
..vim.fs.basename(fname)
|
'https://github.com/neovim/neovim/issues/new?labels=bug&title=user+docs+HTML%3A+'
|
||||||
..'+&body=%60gen_help_html.lua%60+problem+at%3A+'
|
.. vim.fs.basename(fname)
|
||||||
..this_url
|
.. '+&body=%60gen_help_html.lua%60+problem+at%3A+'
|
||||||
..'%0D'
|
.. this_url
|
||||||
..(token_name and '+unhandled+token%3A+%60'..token_name..'%60' or '')
|
.. '%0D'
|
||||||
..'%0DContext%3A%0D%0D%60%60%60%0D'
|
.. (token_name and '+unhandled+token%3A+%60' .. token_name .. '%60' or '')
|
||||||
..url_encode(sample_text)
|
.. '%0DContext%3A%0D%0D%60%60%60%0D'
|
||||||
..'%0D%60%60%60')
|
.. url_encode(sample_text)
|
||||||
|
.. '%0D%60%60%60'
|
||||||
|
)
|
||||||
return bug_url
|
return bug_url
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -274,9 +277,11 @@ end
|
|||||||
|
|
||||||
local function get_tagname(node, bufnr)
|
local function get_tagname(node, bufnr)
|
||||||
local text = vim.treesitter.get_node_text(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 tag = (node:type() == 'optionlink' or node:parent():type() == 'optionlink')
|
||||||
local helpfile = vim.fs.basename(tagmap[tag]) or nil -- "api.txt"
|
and ("'%s'"):format(text)
|
||||||
local helppage = get_helppage(helpfile) -- "api.html"
|
or text
|
||||||
|
local helpfile = vim.fs.basename(tagmap[tag]) or nil -- "api.txt"
|
||||||
|
local helppage = get_helppage(helpfile) -- "api.html"
|
||||||
return helppage, tag
|
return helppage, tag
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -295,11 +300,9 @@ local function ignore_parse_error(fname, s)
|
|||||||
if ignore_errors[vim.fs.basename(fname)] then
|
if ignore_errors[vim.fs.basename(fname)] then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return (
|
-- Ignore parse errors for unclosed tag.
|
||||||
-- Ignore parse errors for unclosed tag.
|
-- This is common in vimdocs and is treated as plaintext by :help.
|
||||||
-- This is common in vimdocs and is treated as plaintext by :help.
|
return s:find("^[`'|*]")
|
||||||
s:find("^[`'|*]")
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function has_ancestor(node, ancestor_name)
|
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.
|
-- Flatten the sample text to a single, truncated line.
|
||||||
sample_text = vim.trim(sample_text):gsub('[\t\n]', ' '):sub(1, 80)
|
sample_text = vim.trim(sample_text):gsub('[\t\n]', ' '):sub(1, 80)
|
||||||
table.insert(stats.parse_errors, sample_text)
|
table.insert(stats.parse_errors, sample_text)
|
||||||
elseif (node_name == 'word' or node_name == 'uppercase_name')
|
elseif
|
||||||
and (not vim.tbl_contains({'codespan', 'taglink', 'tag'}, parent))
|
(node_name == 'word' or node_name == 'uppercase_name')
|
||||||
|
and (not vim.tbl_contains({ 'codespan', 'taglink', 'tag' }, parent))
|
||||||
then
|
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
|
if spell_dict[text_nopunct] then
|
||||||
invalid_spelling[text_nopunct] = invalid_spelling[text_nopunct] or {}
|
invalid_spelling[text_nopunct] = invalid_spelling[text_nopunct] or {}
|
||||||
invalid_spelling[text_nopunct][vim.fs.basename(opt.fname)] = node_text(root:parent())
|
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
|
-- 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
|
-- 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.
|
-- 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 .. ' '
|
text = text .. ' '
|
||||||
end
|
end
|
||||||
return text
|
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
|
local node_name = (root.named and root:named()) and root:type() or nil
|
||||||
-- Previous sibling kind (string).
|
-- 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).
|
-- 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).
|
-- Parent kind (string).
|
||||||
local parent = root:parent() and root:parent():type() or nil
|
local parent = root:parent() and root:parent():type() or nil
|
||||||
local text = ''
|
local text = ''
|
||||||
@ -450,7 +460,7 @@ local function visit_node(root, level, lang_tree, headings, opt, stats)
|
|||||||
trimmed = trim(text)
|
trimmed = trim(text)
|
||||||
end
|
end
|
||||||
|
|
||||||
if node_name == 'help_file' then -- root node
|
if node_name == 'help_file' then -- root node
|
||||||
return text
|
return text
|
||||||
elseif node_name == 'url' then
|
elseif node_name == 'url' then
|
||||||
local fixed_url, removed_chars = fix_url(trimmed)
|
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
|
return text
|
||||||
elseif node_name == 'h1' or node_name == 'h2' or node_name == 'h3' then
|
elseif node_name == 'h1' or node_name == 'h2' or node_name == 'h3' then
|
||||||
if is_noise(text, stats.noise_lines) then
|
if is_noise(text, stats.noise_lines) then
|
||||||
return '' -- Discard common "noise" lines.
|
return '' -- Discard common "noise" lines.
|
||||||
end
|
end
|
||||||
-- Remove "===" and tags from ToC text.
|
-- Remove "===" and tags from ToC text.
|
||||||
local hname = (node_text():gsub('%-%-%-%-+', ''):gsub('%=%=%=%=+', ''):gsub('%*.*%*', ''))
|
local hname = (node_text():gsub('%-%-%-%-+', ''):gsub('%=%=%=%=+', ''):gsub('%*.*%*', ''))
|
||||||
-- Use the first *tag* node as the heading anchor, if any.
|
-- Use the first *tag* node as the heading anchor, if any.
|
||||||
local tagnode = first(root, 'tag')
|
local tagnode = first(root, 'tag')
|
||||||
-- Use the *tag* as the heading anchor id, if possible.
|
-- 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
|
if node_name == 'h1' or #headings == 0 then
|
||||||
table.insert(headings, { name = hname, subheadings = {}, tag = tagname })
|
table.insert(headings, { name = hname, subheadings = {}, tag = tagname })
|
||||||
else
|
else
|
||||||
table.insert(headings[#headings].subheadings, { name = hname, subheadings = {}, tag = tagname })
|
table.insert(
|
||||||
|
headings[#headings].subheadings,
|
||||||
|
{ name = hname, subheadings = {}, tag = tagname }
|
||||||
|
)
|
||||||
end
|
end
|
||||||
local el = node_name == 'h1' and 'h2' or 'h3'
|
local el = node_name == 'h1' and 'h2' or 'h3'
|
||||||
return ('<%s id="%s" class="help-heading">%s</%s>\n'):format(el, tagname, text, el)
|
return ('<%s id="%s" class="help-heading">%s</%s>\n'):format(el, tagname, text, el)
|
||||||
@ -490,11 +504,16 @@ local function visit_node(root, level, lang_tree, headings, opt, stats)
|
|||||||
end
|
end
|
||||||
return string.format('<div class="help-para">\n%s\n</div>\n', text)
|
return string.format('<div class="help-para">\n%s\n</div>\n', text)
|
||||||
elseif node_name == 'line' then
|
elseif node_name == 'line' then
|
||||||
if (parent ~= 'codeblock' or parent ~= 'code') and (is_blank(text) or is_noise(text, stats.noise_lines)) then
|
if
|
||||||
return '' -- Discard common "noise" lines.
|
(parent ~= 'codeblock' or parent ~= 'code')
|
||||||
|
and (is_blank(text) or is_noise(text, stats.noise_lines))
|
||||||
|
then
|
||||||
|
return '' -- Discard common "noise" lines.
|
||||||
end
|
end
|
||||||
-- XXX: Avoid newlines (too much whitespace) after block elements in old (preformatted) layout.
|
-- 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')
|
return string.format('%s%s', div and trim(text) or text, div and '' or '\n')
|
||||||
elseif node_name == 'line_li' then
|
elseif node_name == 'line_li' then
|
||||||
local sib = root:prev_sibling()
|
local sib = root:prev_sibling()
|
||||||
@ -520,12 +539,17 @@ local function visit_node(root, level, lang_tree, headings, opt, stats)
|
|||||||
if ignored then
|
if ignored then
|
||||||
return text
|
return text
|
||||||
end
|
end
|
||||||
local s = ('%s<a href="%s#%s">%s</a>'):format(ws(), helppage, url_encode(tagname), html_esc(tagname))
|
local s = ('%s<a href="%s#%s">%s</a>'):format(
|
||||||
|
ws(),
|
||||||
|
helppage,
|
||||||
|
url_encode(tagname),
|
||||||
|
html_esc(tagname)
|
||||||
|
)
|
||||||
if opt.old and node_name == 'taglink' then
|
if opt.old and node_name == 'taglink' then
|
||||||
s = fix_tab_after_conceal(s, node_text(root:next_sibling()))
|
s = fix_tab_after_conceal(s, node_text(root:next_sibling()))
|
||||||
end
|
end
|
||||||
return s
|
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
|
if root:has_error() then
|
||||||
return text
|
return text
|
||||||
end
|
end
|
||||||
@ -541,24 +565,28 @@ local function visit_node(root, level, lang_tree, headings, opt, stats)
|
|||||||
elseif node_name == 'language' then
|
elseif node_name == 'language' then
|
||||||
language = node_text(root)
|
language = node_text(root)
|
||||||
return ''
|
return ''
|
||||||
elseif node_name == 'code' then -- Highlighted codeblock (child).
|
elseif node_name == 'code' then -- Highlighted codeblock (child).
|
||||||
if is_blank(text) then
|
if is_blank(text) then
|
||||||
return ''
|
return ''
|
||||||
end
|
end
|
||||||
local code
|
local code
|
||||||
if language then
|
if language then
|
||||||
code = ('<pre><code class="language-%s">%s</code></pre>'):format(language,trim(trim_indent(text), 2))
|
code = ('<pre><code class="language-%s">%s</code></pre>'):format(
|
||||||
|
language,
|
||||||
|
trim(trim_indent(text), 2)
|
||||||
|
)
|
||||||
language = nil
|
language = nil
|
||||||
else
|
else
|
||||||
code = ('<pre>%s</pre>'):format(trim(trim_indent(text), 2))
|
code = ('<pre>%s</pre>'):format(trim(trim_indent(text), 2))
|
||||||
end
|
end
|
||||||
return code
|
return code
|
||||||
elseif node_name == 'tag' then -- anchor
|
elseif node_name == 'tag' then -- anchor
|
||||||
if root:has_error() then
|
if root:has_error() then
|
||||||
return text
|
return text
|
||||||
end
|
end
|
||||||
local in_heading = vim.list_contains({'h1', 'h2', 'h3'}, parent)
|
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 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)
|
local tagname = node_text(root:child(1), false)
|
||||||
if vim.tbl_count(stats.first_tags) < 2 then
|
if vim.tbl_count(stats.first_tags) < 2 then
|
||||||
-- Force the first 2 tags in the doc to be anchored at the main heading.
|
-- 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
|
end
|
||||||
local el = in_heading and 'span' or 'code'
|
local el = in_heading and 'span' or 'code'
|
||||||
local encoded_tagname = url_encode(tagname)
|
local encoded_tagname = url_encode(tagname)
|
||||||
local s = ('%s<%s id="%s" class="%s"><a href="#%s">%s</a></%s>'):format(ws(), el, encoded_tagname, cssclass, encoded_tagname, trimmed, el)
|
local s = ('%s<%s id="%s" class="%s"><a href="#%s">%s</a></%s>'):format(
|
||||||
|
ws(),
|
||||||
|
el,
|
||||||
|
encoded_tagname,
|
||||||
|
cssclass,
|
||||||
|
encoded_tagname,
|
||||||
|
trimmed,
|
||||||
|
el
|
||||||
|
)
|
||||||
if opt.old then
|
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
|
end
|
||||||
|
|
||||||
if in_heading and prev ~= 'tag' then
|
if in_heading and prev ~= 'tag' then
|
||||||
-- Don't set "id", let the heading use the tag as its "id" (used by search engines).
|
-- Don't set "id", let the heading use the tag as its "id" (used by search engines).
|
||||||
s = ('%s<%s class="%s"><a href="#%s">%s</a></%s>'):format(ws(), el, cssclass, encoded_tagname, trimmed, el)
|
s = ('%s<%s class="%s"><a href="#%s">%s</a></%s>'):format(
|
||||||
|
ws(),
|
||||||
|
el,
|
||||||
|
cssclass,
|
||||||
|
encoded_tagname,
|
||||||
|
trimmed,
|
||||||
|
el
|
||||||
|
)
|
||||||
-- Start the <span> container for tags in a heading.
|
-- Start the <span> container for tags in a heading.
|
||||||
-- This makes "justify-content:space-between" right-align the tags.
|
-- This makes "justify-content:space-between" right-align the tags.
|
||||||
-- <h2>foo bar<span>tag1 tag2</span></h2>
|
-- <h2>foo bar<span>tag1 tag2</span></h2>
|
||||||
@ -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!]'
|
local sample_text = level > 0 and getbuflinestr(root, opt.buf, 3) or '[top level!]'
|
||||||
table.insert(stats.parse_errors, sample_text)
|
table.insert(stats.parse_errors, sample_text)
|
||||||
return ('<a class="parse-error" target="_blank" title="Report bug... (parse error)" href="%s">%s</a>'):format(
|
return ('<a class="parse-error" target="_blank" title="Report bug... (parse error)" href="%s">%s</a>'):format(
|
||||||
get_bug_url_vimdoc(opt.fname, opt.to_fname, sample_text), trimmed)
|
get_bug_url_vimdoc(opt.fname, opt.to_fname, sample_text),
|
||||||
else -- Unknown token.
|
trimmed
|
||||||
|
)
|
||||||
|
else -- Unknown token.
|
||||||
local sample_text = level > 0 and getbuflinestr(root, opt.buf, 3) or '[top level!]'
|
local sample_text = level > 0 and getbuflinestr(root, opt.buf, 3) or '[top level!]'
|
||||||
return ('<a class="unknown-token" target="_blank" title="Report bug... (unhandled token "%s")" href="%s">%s</a>'):format(
|
return ('<a class="unknown-token" target="_blank" title="Report bug... (unhandled token "%s")" href="%s">%s</a>'):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
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -605,9 +654,11 @@ local function get_helpfiles(include)
|
|||||||
local dir = './build/runtime/doc'
|
local dir = './build/runtime/doc'
|
||||||
local rv = {}
|
local rv = {}
|
||||||
for f, type in vim.fs.dir(dir) do
|
for f, type in vim.fs.dir(dir) do
|
||||||
if (vim.endswith(f, '.txt')
|
if
|
||||||
and type == 'file'
|
vim.endswith(f, '.txt')
|
||||||
and (not include or vim.list_contains(include, f))) then
|
and type == 'file'
|
||||||
|
and (not include or vim.list_contains(include, f))
|
||||||
|
then
|
||||||
local fullpath = vim.fn.fnamemodify(('%s/%s'):format(dir, f), ':p')
|
local fullpath = vim.fn.fnamemodify(('%s/%s'):format(dir, f), ':p')
|
||||||
table.insert(rv, fullpath)
|
table.insert(rv, fullpath)
|
||||||
end
|
end
|
||||||
@ -633,7 +684,7 @@ end
|
|||||||
--- Use the vimdoc parser defined in the build, not whatever happens to be installed on the system.
|
--- Use the vimdoc parser defined in the build, not whatever happens to be installed on the system.
|
||||||
local function ensure_runtimepath()
|
local function ensure_runtimepath()
|
||||||
if not vim.o.runtimepath:find('build/lib/nvim/') then
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -645,11 +696,11 @@ end
|
|||||||
local function parse_buf(fname, parser_path)
|
local function parse_buf(fname, parser_path)
|
||||||
local buf
|
local buf
|
||||||
if type(fname) == 'string' then
|
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()
|
buf = vim.api.nvim_get_current_buf()
|
||||||
else
|
else
|
||||||
buf = fname
|
buf = fname
|
||||||
vim.cmd('sbuffer '..tostring(fname)) -- Buffer number.
|
vim.cmd('sbuffer ' .. tostring(fname)) -- Buffer number.
|
||||||
end
|
end
|
||||||
if parser_path then
|
if parser_path then
|
||||||
vim.treesitter.language.add('vimdoc', { path = parser_path })
|
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)
|
local lang_tree, buf = parse_buf(fname, parser_path)
|
||||||
for _, tree in ipairs(lang_tree:trees()) do
|
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
|
end
|
||||||
lang_tree:destroy()
|
lang_tree:destroy()
|
||||||
vim.cmd.close()
|
vim.cmd.close()
|
||||||
@ -690,10 +741,10 @@ local function gen_one(fname, to_fname, old, commit, parser_path)
|
|||||||
local stats = {
|
local stats = {
|
||||||
noise_lines = {},
|
noise_lines = {},
|
||||||
parse_errors = {},
|
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 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 title = to_titlecase(basename_noext(fname))
|
||||||
|
|
||||||
local html = ([[
|
local html = ([[
|
||||||
@ -777,9 +828,17 @@ local function gen_one(fname, to_fname, old, commit, parser_path)
|
|||||||
|
|
||||||
local main = ''
|
local main = ''
|
||||||
for _, tree in ipairs(lang_tree:trees()) do
|
for _, tree in ipairs(lang_tree:trees()) do
|
||||||
main = main .. (visit_node(tree:root(), 0, tree, headings,
|
main = main
|
||||||
{ buf = buf, old = old, fname = fname, to_fname = to_fname, indent = 1, },
|
.. (
|
||||||
stats))
|
visit_node(
|
||||||
|
tree:root(),
|
||||||
|
0,
|
||||||
|
tree,
|
||||||
|
headings,
|
||||||
|
{ buf = buf, old = old, fname = fname, to_fname = to_fname, indent = 1 },
|
||||||
|
stats
|
||||||
|
)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
main = ([[
|
main = ([[
|
||||||
@ -809,7 +868,14 @@ local function gen_one(fname, to_fname, old, commit, parser_path)
|
|||||||
<hr/>
|
<hr/>
|
||||||
%s
|
%s
|
||||||
</div>
|
</div>
|
||||||
]]):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 = [[
|
local toc = [[
|
||||||
<div class="col-narrow toc">
|
<div class="col-narrow toc">
|
||||||
@ -819,13 +885,16 @@ local function gen_one(fname, to_fname, old, commit, parser_path)
|
|||||||
<hr/>
|
<hr/>
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local n = 0 -- Count of all headings + subheadings.
|
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
|
||||||
|
n = n + 1 + #h1.subheadings
|
||||||
|
end
|
||||||
for _, h1 in ipairs(headings) do
|
for _, h1 in ipairs(headings) do
|
||||||
toc = toc .. ('<div class="help-toc-h1"><a href="#%s">%s</a>\n'):format(h1.tag, h1.name)
|
toc = toc .. ('<div class="help-toc-h1"><a href="#%s">%s</a>\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
|
for _, h2 in ipairs(h1.subheadings) do
|
||||||
toc = toc .. ('<div class="help-toc-h2"><a href="#%s">%s</a></div>\n'):format(h2.tag, h2.name)
|
toc = toc
|
||||||
|
.. ('<div class="help-toc-h2"><a href="#%s">%s</a></div>\n'):format(h2.tag, h2.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
toc = toc .. '</div>'
|
toc = toc .. '</div>'
|
||||||
@ -859,11 +928,16 @@ local function gen_one(fname, to_fname, old, commit, parser_path)
|
|||||||
|
|
||||||
</footer>
|
</footer>
|
||||||
]]):format(
|
]]):format(
|
||||||
os.date('%Y-%m-%d %H:%M'), commit, commit:sub(1, 7), #stats.parse_errors, bug_link,
|
os.date('%Y-%m-%d %H:%M'),
|
||||||
html_esc(table.concat(stats.noise_lines, '\n')), #stats.noise_lines)
|
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</div>\n%s</body>\n</html>\n'):format(
|
html = ('%s%s%s</div>\n%s</body>\n</html>\n'):format(html, main, toc, footer)
|
||||||
html, main, toc, footer)
|
|
||||||
vim.cmd('q!')
|
vim.cmd('q!')
|
||||||
lang_tree:destroy()
|
lang_tree:destroy()
|
||||||
return html, stats
|
return html, stats
|
||||||
@ -1038,9 +1112,15 @@ function M._test()
|
|||||||
helpfiles = get_helpfiles()
|
helpfiles = get_helpfiles()
|
||||||
|
|
||||||
local function ok(cond, expected, actual)
|
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
|
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
|
else
|
||||||
return assert(cond)
|
return assert(cond)
|
||||||
end
|
end
|
||||||
@ -1050,7 +1130,11 @@ function M._test()
|
|||||||
end
|
end
|
||||||
|
|
||||||
ok(vim.tbl_count(tagmap) > 3000, '>3000', vim.tbl_count(tagmap))
|
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(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([[vim:tw=78:isk=!-~,^*,^\|,^\":ts=8:noet:ft=help:norl:]]))
|
||||||
ok(is_noise([[ NVIM REFERENCE MANUAL by Thiago de Arruda ]]))
|
ok(is_noise([[ NVIM REFERENCE MANUAL by Thiago de Arruda ]]))
|
||||||
@ -1060,7 +1144,10 @@ function M._test()
|
|||||||
eq(1, get_indent(' a'))
|
eq(1, get_indent(' a'))
|
||||||
eq(2, get_indent(' a\n b\n c\n'))
|
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(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).')
|
local fixed_url, removed_chars = fix_url('https://example.com).')
|
||||||
eq('https://example.com', fixed_url)
|
eq('https://example.com', fixed_url)
|
||||||
@ -1093,12 +1180,24 @@ end
|
|||||||
---
|
---
|
||||||
--- @returns info dict
|
--- @returns info dict
|
||||||
function M.gen(help_dir, to_dir, include, commit, parser_path)
|
function M.gen(help_dir, to_dir, include, commit, parser_path)
|
||||||
vim.validate{
|
vim.validate {
|
||||||
help_dir={help_dir, function(d) return vim.fn.isdirectory(vim.fn.expand(d)) == 1 end, 'valid directory'},
|
help_dir = {
|
||||||
to_dir={to_dir, 's'},
|
help_dir,
|
||||||
include={include, 't', true},
|
function(d)
|
||||||
commit={commit, 's', true},
|
return vim.fn.isdirectory(vim.fn.expand(d)) == 1
|
||||||
parser_path={parser_path, function(f) return f == nil or vim.fn.filereadable(vim.fn.expand(f)) == 1 end, 'valid vimdoc.{so,dll} filepath'},
|
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
|
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 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)
|
local html, stats = gen_one(f, to_fname, not new_layout[helpfile], commit or '?', parser_path)
|
||||||
tofile(to_fname, html)
|
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
|
err_count = err_count + #stats.parse_errors
|
||||||
end
|
end
|
||||||
print(('generated %d html pages'):format(#helpfiles))
|
print(('generated %d html pages'):format(#helpfiles))
|
||||||
@ -1139,10 +1244,22 @@ end
|
|||||||
--
|
--
|
||||||
-- @returns results dict
|
-- @returns results dict
|
||||||
function M.validate(help_dir, include, parser_path)
|
function M.validate(help_dir, include, parser_path)
|
||||||
vim.validate{
|
vim.validate {
|
||||||
help_dir={help_dir, function(d) return vim.fn.isdirectory(vim.fn.expand(d)) == 1 end, 'valid directory'},
|
help_dir = {
|
||||||
include={include, 't', true},
|
help_dir,
|
||||||
parser_path={parser_path, function(f) return f == nil or vim.fn.filereadable(vim.fn.expand(f)) == 1 end, 'valid vimdoc.{so,dll} filepath'},
|
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 err_count = 0
|
||||||
local files_to_errors = {}
|
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))
|
print(('validated (%-4s errors): %s'):format(#rv.parse_errors, helpfile))
|
||||||
if #rv.parse_errors > 0 then
|
if #rv.parse_errors > 0 then
|
||||||
files_to_errors[helpfile] = rv.parse_errors
|
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
|
end
|
||||||
err_count = err_count + #rv.parse_errors
|
err_count = err_count + #rv.parse_errors
|
||||||
end
|
end
|
||||||
|
@ -16,7 +16,7 @@ local _trace = false
|
|||||||
-- Print message
|
-- Print message
|
||||||
local function p(s)
|
local function p(s)
|
||||||
vim.cmd('set verbose=1')
|
vim.cmd('set verbose=1')
|
||||||
vim.api.nvim_echo({{s, ''}}, false, {})
|
vim.api.nvim_echo({ { s, '' } }, false, {})
|
||||||
vim.cmd('set verbose=0')
|
vim.cmd('set verbose=0')
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ end
|
|||||||
-- Prints `cmd` if `trace` is enabled.
|
-- Prints `cmd` if `trace` is enabled.
|
||||||
local function run(cmd, or_die)
|
local function run(cmd, or_die)
|
||||||
if _trace then
|
if _trace then
|
||||||
p('run: '..vim.inspect(cmd))
|
p('run: ' .. vim.inspect(cmd))
|
||||||
end
|
end
|
||||||
local rv = vim.trim(vim.fn.system(cmd)) or ''
|
local rv = vim.trim(vim.fn.system(cmd)) or ''
|
||||||
if vim.v.shell_error ~= 0 then
|
if vim.v.shell_error ~= 0 then
|
||||||
@ -43,14 +43,14 @@ end
|
|||||||
local function validate_commit(commit_message)
|
local function validate_commit(commit_message)
|
||||||
-- Return nil if the commit message starts with "fixup" as it signifies it's
|
-- Return nil if the commit message starts with "fixup" as it signifies it's
|
||||||
-- a work in progress and shouldn't be linted yet.
|
-- 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
|
return nil
|
||||||
end
|
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
|
-- Return nil if the type is vim-patch since most of the normal rules don't
|
||||||
-- apply.
|
-- apply.
|
||||||
if commit_split[1] == "vim-patch" then
|
if commit_split[1] == 'vim-patch' then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -81,32 +81,34 @@ local function validate_commit(commit_message)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Check if commit introduces a breaking change.
|
-- 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)
|
before_colon = before_colon:sub(1, -2)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if type is correct
|
-- Check if type is correct
|
||||||
local type = vim.split(before_colon, "(", {plain = true})[1]
|
local type = vim.split(before_colon, '(', { plain = true })[1]
|
||||||
local allowed_types = {'build', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'test', 'vim-patch'}
|
local allowed_types =
|
||||||
|
{ 'build', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'test', 'vim-patch' }
|
||||||
if not vim.tbl_contains(allowed_types, type) then
|
if not vim.tbl_contains(allowed_types, type) then
|
||||||
return string.format(
|
return string.format(
|
||||||
[[Invalid commit type "%s". Allowed types are:
|
[[Invalid commit type "%s". Allowed types are:
|
||||||
%s.
|
%s.
|
||||||
If none of these seem appropriate then use "fix"]],
|
If none of these seem appropriate then use "fix"]],
|
||||||
type,
|
type,
|
||||||
vim.inspect(allowed_types))
|
vim.inspect(allowed_types)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if scope is appropriate
|
-- Check if scope is appropriate
|
||||||
if before_colon:match("%(") then
|
if before_colon:match('%(') then
|
||||||
local scope = vim.trim(commit_message:match("%((.-)%)"))
|
local scope = vim.trim(commit_message:match('%((.-)%)'))
|
||||||
|
|
||||||
if scope == '' then
|
if scope == '' then
|
||||||
return [[Scope can't be empty]]
|
return [[Scope can't be empty]]
|
||||||
end
|
end
|
||||||
|
|
||||||
if vim.startswith(scope, "nvim_") then
|
if vim.startswith(scope, 'nvim_') then
|
||||||
return [[Scope should be "api" instead of "nvim_..."]]
|
return [[Scope should be "api" instead of "nvim_..."]]
|
||||||
end
|
end
|
||||||
|
|
||||||
local alternative_scope = {
|
local alternative_scope = {
|
||||||
@ -123,17 +125,17 @@ local function validate_commit(commit_message)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Check that description doesn't end with a period
|
-- 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 (".").]]
|
return [[Description ends with a period (".").]]
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check that description starts with a whitespace.
|
-- 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.]]
|
return [[There should be a whitespace after the colon.]]
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check that description doesn't start with multiple whitespaces.
|
-- 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.]]
|
return [[There should only be one whitespace after the colon.]]
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -143,7 +145,7 @@ local function validate_commit(commit_message)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Check that description isn't just whitespaces
|
-- 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.]]
|
return [[Description shouldn't be empty.]]
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -154,25 +156,25 @@ end
|
|||||||
function M.main(opt)
|
function M.main(opt)
|
||||||
_trace = not opt or not not opt.trace
|
_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
|
-- 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
|
if not ancestor then
|
||||||
ancestor = run({'git', 'merge-base', 'upstream/master', branch})
|
ancestor = run({ 'git', 'merge-base', 'upstream/master', branch })
|
||||||
end
|
end
|
||||||
local commits_str = run({'git', 'rev-list', ancestor..'..'..branch}, true)
|
local commits_str = run({ 'git', 'rev-list', ancestor .. '..' .. branch }, true)
|
||||||
assert(commits_str)
|
assert(commits_str)
|
||||||
|
|
||||||
local commits = {} --- @type string[]
|
local commits = {} --- @type string[]
|
||||||
for substring in commits_str:gmatch("%S+") do
|
for substring in commits_str:gmatch('%S+') do
|
||||||
table.insert(commits, substring)
|
table.insert(commits, substring)
|
||||||
end
|
end
|
||||||
|
|
||||||
local failed = 0
|
local failed = 0
|
||||||
for _, commit_id in ipairs(commits) do
|
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
|
if vim.v.shell_error ~= 0 then
|
||||||
p('Invalid commit-id: '..commit_id..'"')
|
p('Invalid commit-id: ' .. commit_id .. '"')
|
||||||
else
|
else
|
||||||
local invalid_msg = validate_commit(msg)
|
local invalid_msg = validate_commit(msg)
|
||||||
if invalid_msg then
|
if invalid_msg then
|
||||||
@ -183,20 +185,22 @@ function M.main(opt)
|
|||||||
p('\n')
|
p('\n')
|
||||||
end
|
end
|
||||||
|
|
||||||
p(string.format([[
|
p(string.format(
|
||||||
|
[[
|
||||||
Invalid commit message: "%s"
|
Invalid commit message: "%s"
|
||||||
Commit: %s
|
Commit: %s
|
||||||
%s
|
%s
|
||||||
]],
|
]],
|
||||||
msg,
|
msg,
|
||||||
commit_id,
|
commit_id,
|
||||||
invalid_msg))
|
invalid_msg
|
||||||
|
))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if failed > 0 then
|
if failed > 0 then
|
||||||
p([[
|
p([[
|
||||||
See also:
|
See also:
|
||||||
https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md#commit-messages
|
https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md#commit-messages
|
||||||
|
|
||||||
@ -259,7 +263,7 @@ function M._test()
|
|||||||
['feat(:grep/:make)'] = false,
|
['feat(:grep/:make)'] = false,
|
||||||
['feat(:grep'] = false,
|
['feat(:grep'] = false,
|
||||||
['feat(:grep/:make'] = 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
|
local failed = 0
|
||||||
@ -267,14 +271,15 @@ function M._test()
|
|||||||
local is_valid = (nil == validate_commit(message))
|
local is_valid = (nil == validate_commit(message))
|
||||||
if is_valid ~= expected then
|
if is_valid ~= expected then
|
||||||
failed = failed + 1
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
if failed > 0 then
|
if failed > 0 then
|
||||||
os.exit(1)
|
os.exit(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @class LintcommitOptions
|
--- @class LintcommitOptions
|
||||||
|
@ -59,9 +59,12 @@ local TAGGED_TYPES = { 'TSNode', 'LanguageTree' }
|
|||||||
|
|
||||||
-- Document these as 'table'
|
-- Document these as 'table'
|
||||||
local ALIAS_TYPES = {
|
local ALIAS_TYPES = {
|
||||||
'Range', 'Range4', 'Range6', 'TSMetadata',
|
'Range',
|
||||||
|
'Range4',
|
||||||
|
'Range6',
|
||||||
|
'TSMetadata',
|
||||||
'vim.filetype.add.filetypes',
|
'vim.filetype.add.filetypes',
|
||||||
'vim.filetype.match.args'
|
'vim.filetype.match.args',
|
||||||
}
|
}
|
||||||
|
|
||||||
local debug_outfile = nil --- @type string?
|
local debug_outfile = nil --- @type string?
|
||||||
@ -103,7 +106,7 @@ function StreamRead.new(filename)
|
|||||||
-- syphon lines to our table
|
-- syphon lines to our table
|
||||||
local filecontents = {} --- @type string[]
|
local filecontents = {} --- @type string[]
|
||||||
for line in io.lines(filename) do
|
for line in io.lines(filename) do
|
||||||
filecontents[#filecontents+1] = line
|
filecontents[#filecontents + 1] = line
|
||||||
end
|
end
|
||||||
|
|
||||||
return setmetatable({
|
return setmetatable({
|
||||||
@ -176,9 +179,15 @@ local function process_magic(line, generics)
|
|||||||
local magic_split = vim.split(magic, ' ', { plain = true })
|
local magic_split = vim.split(magic, ' ', { plain = true })
|
||||||
local directive = magic_split[1]
|
local directive = magic_split[1]
|
||||||
|
|
||||||
if vim.list_contains({
|
if
|
||||||
'cast', 'diagnostic', 'overload', 'meta', 'type'
|
vim.list_contains({
|
||||||
}, directive) then
|
'cast',
|
||||||
|
'diagnostic',
|
||||||
|
'overload',
|
||||||
|
'meta',
|
||||||
|
'type',
|
||||||
|
}, directive)
|
||||||
|
then
|
||||||
-- Ignore LSP directives
|
-- Ignore LSP directives
|
||||||
return '// gg:"' .. line .. '"'
|
return '// gg:"' .. line .. '"'
|
||||||
end
|
end
|
||||||
@ -202,8 +211,7 @@ local function process_magic(line, generics)
|
|||||||
if directive == 'param' then
|
if directive == 'param' then
|
||||||
for _, type in ipairs(TYPES) do
|
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 .. ')%)', 'param %1 %2')
|
||||||
magic =
|
magic = magic:gsub('^param%s+([a-zA-Z_?]+)%s+.*%((' .. type .. '|nil)%)', 'param %1 %2')
|
||||||
magic:gsub('^param%s+([a-zA-Z_?]+)%s+.*%((' .. type .. '|nil)%)', 'param %1 %2')
|
|
||||||
end
|
end
|
||||||
magic_split = vim.split(magic, ' ', { plain = true })
|
magic_split = vim.split(magic, ' ', { plain = true })
|
||||||
type_index = 3
|
type_index = 3
|
||||||
@ -225,7 +233,7 @@ local function process_magic(line, generics)
|
|||||||
-- fix optional parameters
|
-- fix optional parameters
|
||||||
if magic_split[2]:find('%?$') then
|
if magic_split[2]:find('%?$') then
|
||||||
if not ty:find('nil') then
|
if not ty:find('nil') then
|
||||||
ty = ty .. '|nil'
|
ty = ty .. '|nil'
|
||||||
end
|
end
|
||||||
magic_split[2] = magic_split[2]:sub(1, -2)
|
magic_split[2] = magic_split[2]:sub(1, -2)
|
||||||
end
|
end
|
||||||
@ -240,18 +248,15 @@ local function process_magic(line, generics)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for _, type in ipairs(ALIAS_TYPES) do
|
for _, type in ipairs(ALIAS_TYPES) do
|
||||||
ty = ty:gsub('^'..type..'$', 'table') --- @type string
|
ty = ty:gsub('^' .. type .. '$', 'table') --- @type string
|
||||||
end
|
end
|
||||||
|
|
||||||
-- surround some types by ()
|
-- surround some types by ()
|
||||||
for _, type in ipairs(TYPES) do
|
for _, type in ipairs(TYPES) do
|
||||||
ty = ty
|
ty = ty:gsub('^(' .. type .. '|nil):?$', '(%1)'):gsub('^(' .. type .. '):?$', '(%1)')
|
||||||
:gsub('^(' .. type .. '|nil):?$', '(%1)')
|
|
||||||
:gsub('^(' .. type .. '):?$', '(%1)')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
magic_split[type_index] = ty
|
magic_split[type_index] = ty
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
magic = table.concat(magic_split, ' ')
|
magic = table.concat(magic_split, ' ')
|
||||||
@ -281,7 +286,7 @@ local function process_block_comment(line, in_stream)
|
|||||||
-- easier to program
|
-- easier to program
|
||||||
in_stream:ungetLine(vim.trim(line:sub(closeSquare + 2)))
|
in_stream:ungetLine(vim.trim(line:sub(closeSquare + 2)))
|
||||||
end
|
end
|
||||||
comment_parts[#comment_parts+1] = thisComment
|
comment_parts[#comment_parts + 1] = thisComment
|
||||||
end
|
end
|
||||||
|
|
||||||
local comment = table.concat(comment_parts)
|
local comment = table.concat(comment_parts)
|
||||||
@ -303,7 +308,7 @@ local function process_function_header(line)
|
|||||||
|
|
||||||
if fn:sub(1, 1) == '(' then
|
if fn:sub(1, 1) == '(' then
|
||||||
-- it's an anonymous function
|
-- it's an anonymous function
|
||||||
return '// ZZ: '..line
|
return '// ZZ: ' .. line
|
||||||
end
|
end
|
||||||
-- fn has a name, so is interesting
|
-- fn has a name, so is interesting
|
||||||
|
|
||||||
@ -330,10 +335,7 @@ local function process_function_header(line)
|
|||||||
comma = ', '
|
comma = ', '
|
||||||
end
|
end
|
||||||
|
|
||||||
fn = fn:sub(1, paren_start)
|
fn = fn:sub(1, paren_start) .. 'self' .. comma .. fn:sub(paren_start + 1)
|
||||||
.. 'self'
|
|
||||||
.. comma
|
|
||||||
.. fn:sub(paren_start + 1)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if line:match('local') then
|
if line:match('local') then
|
||||||
@ -357,7 +359,7 @@ local function process_line(line, in_stream, generics)
|
|||||||
return process_magic(line:sub(4), generics)
|
return process_magic(line:sub(4), generics)
|
||||||
end
|
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)
|
return process_block_comment(line:sub(5), in_stream)
|
||||||
end
|
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+%=')
|
local v = line_raw:match('^([A-Za-z][.a-zA-Z_]*)%s+%=')
|
||||||
if v and v:match('%.') then
|
if v and v:match('%.') then
|
||||||
-- Special: this lets gen_vimdoc.py handle tables.
|
-- Special: this lets gen_vimdoc.py handle tables.
|
||||||
return 'table '..v..'() {}'
|
return 'table ' .. v .. '() {}'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -418,7 +420,7 @@ local TApp = {
|
|||||||
timestamp = os.date('%c %Z', os.time()),
|
timestamp = os.date('%c %Z', os.time()),
|
||||||
name = 'Lua2DoX',
|
name = 'Lua2DoX',
|
||||||
version = '0.2 20130128',
|
version = '0.2 20130128',
|
||||||
copyright = 'Copyright (c) Simon Dales 2012-13'
|
copyright = 'Copyright (c) Simon Dales 2012-13',
|
||||||
}
|
}
|
||||||
|
|
||||||
setmetatable(TApp, { __index = TApp })
|
setmetatable(TApp, { __index = TApp })
|
||||||
@ -447,12 +449,15 @@ if arg[1] == '--help' then
|
|||||||
elseif arg[1] == '--version' then
|
elseif arg[1] == '--version' then
|
||||||
writeln(TApp:getVersion())
|
writeln(TApp:getVersion())
|
||||||
writeln(TApp.copyright)
|
writeln(TApp.copyright)
|
||||||
else -- It's a filter.
|
else -- It's a filter.
|
||||||
local filename = arg[1]
|
local filename = arg[1]
|
||||||
|
|
||||||
if arg[2] == '--outdir' then
|
if arg[2] == '--outdir' then
|
||||||
local outdir = arg[3]
|
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)))
|
error(('invalid --outdir: "%s"'):format(tostring(outdir)))
|
||||||
end
|
end
|
||||||
vim.fn.mkdir(outdir, 'p')
|
vim.fn.mkdir(outdir, 'p')
|
||||||
|
@ -10,13 +10,13 @@ local function systemlist(...)
|
|||||||
local err = nvim.nvim_get_vvar('shell_error')
|
local err = nvim.nvim_get_vvar('shell_error')
|
||||||
local args_str = nvim.nvim_call_function('string', ...)
|
local args_str = nvim.nvim_call_function('string', ...)
|
||||||
if 0 ~= err then
|
if 0 ~= err then
|
||||||
error('command failed: '..args_str)
|
error('command failed: ' .. args_str)
|
||||||
end
|
end
|
||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
|
|
||||||
local function vimpatch_sh_list_numbers()
|
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
|
end
|
||||||
|
|
||||||
-- Generates the lines to be inserted into the src/version.c
|
-- 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')
|
nvim.nvim_command('silent normal! j0d/};\rk')
|
||||||
-- Insert the lines.
|
-- Insert the lines.
|
||||||
nvim.nvim_call_function('append', {
|
nvim.nvim_call_function('append', {
|
||||||
nvim.nvim_eval('line(".")'),
|
nvim.nvim_eval('line(".")'),
|
||||||
lines,
|
lines,
|
||||||
})
|
})
|
||||||
nvim.nvim_command('silent write')
|
nvim.nvim_command('silent write')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user