_init_packages.lua (3135B)
1 local pathtrails = {} --- @type table<string,true> ta 2 vim._so_trails = {} --- @type string[] 3 for s in (package.cpath .. ';'):gmatch('[^;]*;') do 4 s = s:sub(1, -2) -- Strip trailing semicolon 5 -- Find out path patterns. pathtrail should contain something like 6 -- /?.so, \?.dll. This allows not to bother determining what correct 7 -- suffixes are. 8 local pathtrail = s:match('[/\\][^/\\]*%?.*$') 9 if pathtrail and not pathtrails[pathtrail] then 10 pathtrails[pathtrail] = true 11 table.insert(vim._so_trails, pathtrail) 12 end 13 end 14 15 --- @param name string 16 function vim._load_package(name) 17 local basename = name:gsub('%.', '/') 18 local paths = { 'lua/' .. basename .. '.lua', 'lua/' .. basename .. '/init.lua' } 19 local found = vim.api.nvim__get_runtime(paths, false, { is_lua = true }) 20 if #found > 0 then 21 local f, err = loadfile(found[1]) 22 return f or error(err) 23 end 24 25 local so_paths = {} 26 for _, trail in ipairs(vim._so_trails) do 27 local path = 'lua' .. trail:gsub('?', basename) -- so_trails contains a leading slash 28 table.insert(so_paths, path) 29 end 30 31 found = vim.api.nvim__get_runtime(so_paths, false, { is_lua = true }) 32 if #found > 0 then 33 -- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is 34 -- a) strip prefix up to and including the first dash, if any 35 -- b) replace all dots by underscores 36 -- c) prepend "luaopen_" 37 -- So "foo-bar.baz" should result in "luaopen_bar_baz" 38 local dash = name:find('-', 1, true) 39 local modname = dash and name:sub(dash + 1) or name 40 local f, err = package.loadlib(found[1], 'luaopen_' .. modname:gsub('%.', '_')) 41 return f or error(err) 42 end 43 return nil 44 end 45 46 -- TODO(bfredl): dedicated state for this? 47 if vim.api then 48 -- Insert vim._load_package after the preloader at position 2 49 table.insert(package.loaders, 2, vim._load_package) 50 end 51 52 -- builtin functions which always should be available 53 require('vim._core.shared') 54 55 vim._submodules = { 56 inspect = true, 57 version = true, 58 fs = true, 59 glob = true, 60 iter = true, 61 re = true, 62 text = true, 63 provider = true, 64 } 65 66 -- These are for loading runtime modules in the vim namespace lazily. 67 setmetatable(vim, { 68 --- @param t table<any,any> 69 __index = function(t, key) 70 if vim._submodules[key] then 71 t[key] = require('vim.' .. key) 72 return t[key] 73 elseif key == 'inspect_pos' or key == 'show_pos' then 74 require('vim._inspector') 75 return t[key] 76 elseif vim.startswith(key, 'uri_') then 77 --- @type any? 78 local val = require('vim.uri')[key] 79 if val ~= nil then 80 -- Expose all `vim.uri` functions on the `vim` module. 81 t[key] = val 82 return t[key] 83 end 84 end 85 end, 86 }) 87 88 --- <Docs described in |vim.empty_dict()| > 89 ---@nodoc 90 --- TODO: should be in vim.shared when vim.shared always uses nvim-lua 91 --- @diagnostic disable-next-line:duplicate-set-field 92 function vim.empty_dict() 93 return setmetatable({}, vim._empty_dict_mt) 94 end 95 96 -- only on main thread: functions for interacting with editor state 97 if vim.api and not vim.is_thread() then 98 require('vim._core.editor') 99 require('vim._core.system') 100 end