feat(runtime): Lua ftplugin 'includeexpr' #32719

Problem:
Current `'includeexpr'` in runtime/ftplugin/lua.vim doesn't work with Nvim Lua.

Solution:
Provide an improved 'includeexpr' for Lua in "ftplugin/lua.lua".

Closes: https://github.com/neovim/neovim/issues/32490
This commit is contained in:
Phạm Bình An
2025-03-18 05:41:07 +07:00
committed by GitHub
parent 063b69bab4
commit 08c328b8b0
4 changed files with 115 additions and 1 deletions

View File

@ -326,6 +326,8 @@ LUA
`vim.o`, `vim.wo`, `vim.bo`, `vim.opt`, `vim.opt_local`, `vim.opt_global`,
and `vim.fn`.
• Documentation for |lua-bit|.
• |gf| in Lua buffers can go to module in same repo, |runtime-search-path| and
|package.path|.
• |vim.fs.rm()| can delete files and directories.
• |vim.validate()| now has a new signature which uses less tables,
is more performant and easier to read.

View File

@ -1,9 +1,10 @@
-- use treesitter over syntax
vim.treesitter.start()
vim.bo.includeexpr = 'v:lua.require"vim._ftplugin.lua".includeexpr()'
vim.bo.omnifunc = 'v:lua.vim.lua_omnifunc'
vim.wo[0][0].foldexpr = 'v:lua.vim.treesitter.foldexpr()'
vim.b.undo_ftplugin = (vim.b.undo_ftplugin or '')
.. '\n call v:lua.vim.treesitter.stop()'
.. '\n setl omnifunc< foldexpr<'
.. '\n setl omnifunc< foldexpr< includeexpr<'

View File

@ -0,0 +1,26 @@
local M = {}
--- @param module string
---@return string
function M.includeexpr(module)
---@param fname string
---@return boolean
local function filereadable(fname)
return vim.fn.filereadable(fname) == 1
end
local fname = module:gsub('%.', '/')
local root = vim.fs.root(vim.api.nvim_buf_get_name(0), 'lua') or vim.fn.getcwd()
for _, suf in ipairs { '.lua', '/init.lua' } do
local path = vim.fs.joinpath(root, 'lua', fname .. suf)
if filereadable(path) then
return path
end
end
local modInfo = vim.loader.find(module)[1]
return modInfo and modInfo.modpath or module
end
return M

View File

@ -0,0 +1,85 @@
local t = require('test.testutil')
local n = require('test.functional.testnvim')()
local exec_lua = n.exec_lua
local command = n.command
local eq = t.eq
---@param type string
---@return string
local function stdpath(type)
return exec_lua(([[return vim.fs.normalize(vim.fn.stdpath("%s"))]]):format(type))
end
---@return string
local function vimruntime()
return exec_lua [[ return vim.fs.normalize(vim.env.VIMRUNTIME) ]]
end
---@param module string
---@return string
local function lua_includeexpr(module)
return exec_lua(([[return require('vim._ftplugin.lua').includeexpr("%s")]]):format(module))
end
local root = exec_lua [[ return vim.fs.normalize(vim.fn.getcwd()) ]]
describe("Lua 'includeexpr'", function()
setup(n.clear)
local temp_dir = t.tmpname(false)
before_each(function()
command(([[
edit `=stdpath('config') .. '/lua/user-foo/init.lua'`
write ++p
edit `=stdpath('config') .. '/lua/user-foo/bar.lua'`
write ++p
edit `=stdpath('data') .. '/site/pack/packer/start/plugin-foo/lua/plugin-foo/init.lua'`
write ++p
edit `=stdpath('data') .. '/site/pack/packer/start/plugin-foo/lua/plugin-foo/bar.lua'`
write ++p
edit runtime/lua/foo/init.lua
write ++p
edit runtime/lua/foo/bar/init.lua
write ++p
edit %s/lua/runtime-foo/init.lua
write ++p
edit %s/lua/runtime-foo/bar.lua
write ++p
]]):format(temp_dir, temp_dir))
end)
it('finds module in current repo', function()
command [[ edit runtime/lua/vim/_ftplugin/lua.lua ]]
eq(root .. '/runtime/lua/vim/_ftplugin/lua.lua', lua_includeexpr('vim._ftplugin.lua'))
eq(root .. '/runtime/lua/editorconfig.lua', lua_includeexpr('editorconfig'))
eq(root .. '/runtime/lua/foo/init.lua', lua_includeexpr('foo'))
eq(root .. '/runtime/lua/foo/bar/init.lua', lua_includeexpr('foo.bar'))
end)
it('find module in packpath/start', function()
eq(
stdpath('data') .. '/site/pack/packer/start/plugin-foo/lua/plugin-foo/init.lua',
lua_includeexpr('plugin-foo')
)
eq(
stdpath('data') .. '/site/pack/packer/start/plugin-foo/lua/plugin-foo/bar.lua',
lua_includeexpr('plugin-foo.bar')
)
end)
it('finds module in $VIMRUNTIME', function()
command('edit ' .. root)
eq(vimruntime() .. '/lua/vim/_ftplugin/lua.lua', lua_includeexpr('vim._ftplugin.lua'))
eq(vimruntime() .. '/lua/editorconfig.lua', lua_includeexpr('editorconfig'))
end)
it('find module in runtimepath', function()
eq(stdpath('config') .. '/lua/user-foo/init.lua', lua_includeexpr('user-foo'))
eq(stdpath('config') .. '/lua/user-foo/bar.lua', lua_includeexpr('user-foo.bar'))
command('set rtp+=' .. temp_dir)
eq(temp_dir .. '/lua/runtime-foo/init.lua', lua_includeexpr('runtime-foo'))
eq(temp_dir .. '/lua/runtime-foo/bar.lua', lua_includeexpr('runtime-foo.bar'))
end)
end)