mirror of
https://github.com/neovim/neovim.git
synced 2026-08-26 17:11:48 +00:00
feat(help): generate :helptags using Treesitter
Problem: Tags are manually parsed in C which is not flexible and prone to errors. Extending the help system to allow for other formats (e.g. Markdown) would require a large rewrite in the C core, while with Treesitter it only needs a query update. Solution: Use the power of treesitter to extract the tags from helpfiles. - build: set `$VIMRUNTIME` when generating helptags, like `cmake/Util.cmake` already does for other generators. - fix(help): only accept tags delimited by whitespace. The old C parser only accepted a `*tag*` preceded by start-of-line or whitespace and followed by whitespace or end-of-line. The vimdoc parser also captures tags followed by other text, e.g. `*$XDG_STATE_HOME*/.../logs` in starting.txt, which caused an E154 duplicate tag error for docs that were previously fine.
This commit is contained in:
committed by
Justin M. Keyes
parent
a1de07418b
commit
b36b3d7f3a
@@ -1,11 +1,12 @@
|
||||
local t = require('test.testutil')
|
||||
local n = require('test.functional.testnvim')()
|
||||
|
||||
local describe, it, before_each, finally = t.describe, t.it, t.before_each, t.finally
|
||||
local describe, it, before_each, after_each, finally =
|
||||
t.describe, t.it, t.before_each, t.after_each, t.finally
|
||||
local clear = n.clear
|
||||
local eval = n.eval
|
||||
local command = n.command
|
||||
local eq = t.eq
|
||||
local pcall_err = t.pcall_err
|
||||
local fn = n.fn
|
||||
local api = n.api
|
||||
local mkdir = t.mkdir
|
||||
@@ -324,3 +325,83 @@ describe(':help', function()
|
||||
eq('*…*', api.nvim_get_current_line())
|
||||
end)
|
||||
end)
|
||||
|
||||
describe(':helptags', function()
|
||||
before_each(function()
|
||||
for _, sfx in ipairs({ '', '2' }) do
|
||||
fn.mkdir(('Xhelptags%s/doc'):format(sfx), 'p')
|
||||
for _, tag in ipairs({ 'Xa', 'Xb' }) do
|
||||
write_file(('Xhelptags%s/doc/%s%s.txt'):format(sfx, tag, sfx), ('*%s%s*'):format(tag, sfx))
|
||||
end
|
||||
end
|
||||
|
||||
clear()
|
||||
command('set rtp+=Xhelptags,Xhelptags2')
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
rmdir('Xhelptags')
|
||||
rmdir('Xhelptags2')
|
||||
end)
|
||||
|
||||
it('requires an argument', function()
|
||||
local msg = t.pcall_err(command, 'helptags')
|
||||
eq(true, msg:find('E471') ~= nil)
|
||||
end)
|
||||
|
||||
it('{dir}', function()
|
||||
command('helptags Xhelptags/doc')
|
||||
|
||||
eq(eval("['Xa Xa.txt /*Xa*','Xb Xb.txt /*Xb*']"), eval("readfile('Xhelptags/doc/tags')"))
|
||||
|
||||
command('help Xa')
|
||||
eq('*Xa*', api.nvim_get_current_line())
|
||||
end)
|
||||
|
||||
it('ALL', function()
|
||||
command('helptags ALL')
|
||||
|
||||
eq(eval("['Xa Xa.txt /*Xa*','Xb Xb.txt /*Xb*']"), eval("readfile('Xhelptags/doc/tags')"))
|
||||
eq(eval("['Xa2 Xa2.txt /*Xa2*','Xb2 Xb2.txt /*Xb2*']"), eval("readfile('Xhelptags2/doc/tags')"))
|
||||
|
||||
command('help Xa2')
|
||||
eq('*Xa2*', api.nvim_get_current_line())
|
||||
end)
|
||||
|
||||
it('++t', function()
|
||||
command('helptags ++t Xhelptags/doc')
|
||||
eq('help-tags tags 1', eval("readfile('Xhelptags/doc/tags')[-1]"))
|
||||
end)
|
||||
|
||||
it('generates help-tag tag for VIMRUNTIME', function()
|
||||
command('let $VIMRUNTIME="Xhelptags"')
|
||||
command('helptags Xhelptags/doc')
|
||||
eq('help-tags tags 1', eval("readfile('Xhelptags/doc/tags')[-1]"))
|
||||
end)
|
||||
|
||||
it('errors on duplicate tags', function()
|
||||
-- duplicate tags in different files
|
||||
write_file('Xhelptags/doc/Xd.txt', '*Xa*', nil, true)
|
||||
local msg = t.pcall_err(command, 'helptags Xhelptags/doc')
|
||||
eq(true, msg:find('E154') ~= nil)
|
||||
|
||||
-- tags file should still be generated
|
||||
eq(1, eval("filereadable('Xhelptags/doc/tags')"))
|
||||
|
||||
os.remove('Xhelptags/doc/Xd.txt')
|
||||
|
||||
-- duplicate tags in same file
|
||||
write_file('Xhelptags/doc/Xa.txt', '\n*Xa*', nil, true)
|
||||
|
||||
msg = t.pcall_err(command, 'helptags Xhelptags/doc')
|
||||
eq(true, msg:find('E154') ~= nil)
|
||||
|
||||
eq(1, eval("filereadable('Xhelptags/doc/tags')"))
|
||||
end)
|
||||
|
||||
it('with translated help files', function()
|
||||
write_file('Xhelptags/doc/Xa.nlx', '*Xa*', nil, true)
|
||||
command('helptags Xhelptags/doc')
|
||||
eq(1, eval("filereadable('Xhelptags/doc/tags-nl')"))
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user