lua.lua 2.5 KB

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