lua.lua 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. local fmt = string.format
  2. -- luacheck: ignore
  3. -- TODO: fix lint violations
  4. -- Iterator that splits a string o a given delimiter
  5. local function split(str, delim)
  6. delim = delim or "%s"
  7. return string.gmatch(str, fmt("[^%s]+", delim))
  8. end
  9. -- Find the proper directory separator depending
  10. -- on lua installation or OS.
  11. local function dir_separator()
  12. -- Look at package.config for directory separator string (it's the first line)
  13. if package.config then
  14. return string.match(package.config, "^[^\n]")
  15. elseif vim.fn.has "win32" == 1 then
  16. return "\\"
  17. else
  18. return "/"
  19. end
  20. end
  21. -- Search for lua traditional include paths.
  22. -- This mimics how require internally works.
  23. local function include_paths(fname, ext)
  24. ext = ext or "lua"
  25. local sep = dir_separator()
  26. local paths = string.gsub(package.path, "%?", fname)
  27. for path in split(paths, "%;") do
  28. if vim.fn.filereadable(path) == 1 then
  29. return path
  30. end
  31. end
  32. end
  33. -- Search for nvim lua include paths
  34. local function include_rtpaths(fname, ext)
  35. ext = ext or "lua"
  36. local sep = dir_separator()
  37. local rtpaths = vim.api.nvim_list_runtime_paths()
  38. local modfile, initfile = fmt("%s.%s", fname, ext), fmt("init.%s", ext)
  39. for _, path in ipairs(rtpaths) do
  40. -- Look on runtime path for 'lua/*.lua' files
  41. local path1 = table.concat({ path, ext, modfile }, sep)
  42. if vim.fn.filereadable(path1) == 1 then
  43. return path1
  44. end
  45. -- Look on runtime path for 'lua/*/init.lua' files
  46. local path2 = table.concat({ path, ext, fname, initfile }, sep)
  47. if vim.fn.filereadable(path2) == 1 then
  48. return path2
  49. end
  50. end
  51. end
  52. -- Global function that searches the path for the required file
  53. function find_required_path(module)
  54. -- Look at package.config for directory separator string (it's the first line)
  55. local sep = string.match(package.config, "^[^\n]")
  56. -- Properly change '.' to separator (probably '/' on *nix and '\' on Windows)
  57. local fname = vim.fn.substitute(module, "\\.", sep, "g")
  58. local f
  59. ---- First search for lua modules
  60. f = include_paths(fname, "lua")
  61. if f then
  62. return f
  63. end
  64. -- This part is just for nvim modules
  65. f = include_rtpaths(fname, "lua")
  66. if f then
  67. return f
  68. end
  69. ---- Now search for Fennel modules
  70. f = include_paths(fname, "fnl")
  71. if f then
  72. return f
  73. end
  74. -- This part is just for nvim modules
  75. f = include_rtpaths(fname, "fnl")
  76. if f then
  77. return f
  78. end
  79. end
  80. -- Set options to open require with gf
  81. vim.opt_local.include = [=[\v<((do|load)file|require)\s*\(?['"]\zs[^'"]+\ze['"]]=]
  82. vim.opt_local.includeexpr = "v:lua.find_required_path(v:fname)"