bootstrap.lua 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. local M = {}
  2. package.loaded["lvim.utils.hooks"] = nil
  3. local _, hooks = pcall(require, "lvim.utils.hooks")
  4. ---Join path segments that were passed as input
  5. ---@return string
  6. function _G.join_paths(...)
  7. local uv = vim.loop
  8. local path_sep = uv.os_uname().version:match "Windows" and "\\" or "/"
  9. local result = table.concat({ ... }, path_sep)
  10. return result
  11. end
  12. ---Get the full path to `$LUNARVIM_RUNTIME_DIR`
  13. ---@return string
  14. function _G.get_runtime_dir()
  15. local lvim_runtime_dir = os.getenv "LUNARVIM_RUNTIME_DIR"
  16. if not lvim_runtime_dir then
  17. -- when nvim is used directly
  18. return vim.fn.stdpath "config"
  19. end
  20. return lvim_runtime_dir
  21. end
  22. ---Get the full path to `$LUNARVIM_CONFIG_DIR`
  23. ---@return string
  24. function _G.get_config_dir()
  25. local lvim_config_dir = os.getenv "LUNARVIM_CONFIG_DIR"
  26. if not lvim_config_dir then
  27. return vim.fn.stdpath "config"
  28. end
  29. return lvim_config_dir
  30. end
  31. ---Get the full path to `$LUNARVIM_CACHE_DIR`
  32. ---@return string
  33. function _G.get_cache_dir()
  34. local lvim_cache_dir = os.getenv "LUNARVIM_CACHE_DIR"
  35. if not lvim_cache_dir then
  36. return vim.fn.stdpath "cache"
  37. end
  38. return lvim_cache_dir
  39. end
  40. ---Get the full path to the currently installed lunarvim repo
  41. ---@return string
  42. local function get_install_path()
  43. local lvim_runtime_dir = os.getenv "LUNARVIM_RUNTIME_DIR"
  44. if not lvim_runtime_dir then
  45. -- when nvim is used directly
  46. return vim.fn.stdpath "config"
  47. end
  48. return join_paths(lvim_runtime_dir, "lvim")
  49. end
  50. ---Get currently installed version of LunarVim
  51. ---@param type string can be "short"
  52. ---@return string
  53. function _G.get_version(type)
  54. type = type or ""
  55. local lvim_full_ver = vim.fn.system("git -C " .. get_install_path() .. " describe --tags")
  56. if string.match(lvim_full_ver, "%d") == nil then
  57. return nil
  58. end
  59. if type == "short" then
  60. return vim.fn.split(lvim_full_ver, "-")[1]
  61. else
  62. return string.sub(lvim_full_ver, 1, #lvim_full_ver - 1)
  63. end
  64. end
  65. ---Initialize the `&runtimepath` variables and prepare for startup
  66. ---@return table
  67. function M:init()
  68. self.runtime_dir = get_runtime_dir()
  69. self.config_dir = get_config_dir()
  70. self.cache_path = get_cache_dir()
  71. self.install_path = get_install_path()
  72. self.pack_dir = join_paths(self.runtime_dir, "site", "pack")
  73. self.packer_install_dir = join_paths(self.runtime_dir, "site", "pack", "packer", "start", "packer.nvim")
  74. self.packer_cache_path = join_paths(self.config_dir, "plugin", "packer_compiled.lua")
  75. if os.getenv "LUNARVIM_RUNTIME_DIR" then
  76. vim.opt.rtp:remove(join_paths(vim.fn.stdpath "data", "site"))
  77. vim.opt.rtp:remove(join_paths(vim.fn.stdpath "data", "site", "after"))
  78. vim.opt.rtp:prepend(join_paths(self.runtime_dir, "site"))
  79. vim.opt.rtp:append(join_paths(self.runtime_dir, "site", "after"))
  80. vim.opt.rtp:remove(vim.fn.stdpath "config")
  81. vim.opt.rtp:remove(join_paths(vim.fn.stdpath "config", "after"))
  82. vim.opt.rtp:prepend(self.config_dir)
  83. vim.opt.rtp:append(join_paths(self.config_dir, "after"))
  84. -- TODO: we need something like this: vim.opt.packpath = vim.opt.rtp
  85. vim.cmd [[let &packpath = &runtimepath]]
  86. vim.cmd("set spellfile=" .. join_paths(self.config_dir, "spell", "en.utf-8.add"))
  87. end
  88. vim.fn.mkdir(get_cache_dir(), "p")
  89. -- FIXME: currently unreliable in unit-tests
  90. if not os.getenv "LVIM_TEST_ENV" then
  91. require("lvim.impatient").setup {
  92. path = vim.fn.stdpath "cache" .. "/lvim_cache",
  93. enable_profiling = true,
  94. }
  95. end
  96. require("lvim.config"):init()
  97. require("lvim.plugin-loader"):init {
  98. package_root = self.pack_dir,
  99. install_path = self.packer_install_dir,
  100. }
  101. return self
  102. end
  103. ---Update LunarVim
  104. ---pulls the latest changes from github and, resets the startup cache
  105. function M:update()
  106. hooks.run_pre_update()
  107. M:update_repo()
  108. hooks.run_post_update()
  109. end
  110. local function git_cmd(subcmd)
  111. local Job = require "plenary.job"
  112. local Log = require "lvim.core.log"
  113. local args = { "-C", get_install_path() }
  114. vim.list_extend(args, subcmd)
  115. local stderr = {}
  116. local stdout, ret = Job
  117. :new({
  118. command = "git",
  119. args = args,
  120. cwd = get_install_path(),
  121. on_stderr = function(_, data)
  122. table.insert(stderr, data)
  123. end,
  124. })
  125. :sync()
  126. if not vim.tbl_isempty(stderr) then
  127. Log:debug(stderr)
  128. end
  129. if not vim.tbl_isempty(stdout) then
  130. Log:debug(stdout)
  131. end
  132. return ret
  133. end
  134. ---pulls the latest changes from github
  135. function M:update_repo()
  136. local Log = require "lvim.core.log"
  137. local sub_commands = {
  138. fetch = { "fetch" },
  139. diff = { "diff", "--quiet", "@{upstream}" },
  140. merge = { "merge", "--ff-only", "--progress" },
  141. }
  142. Log:info "Checking for updates"
  143. local ret = git_cmd(sub_commands.fetch)
  144. if ret ~= 0 then
  145. Log:error "Update failed! Check the log for further information"
  146. return
  147. end
  148. ret = git_cmd(sub_commands.diff)
  149. if ret == 0 then
  150. Log:info "LunarVim is already up-to-date"
  151. return
  152. end
  153. ret = git_cmd(sub_commands.merge)
  154. if ret ~= 0 then
  155. Log:error "Update failed! Please pull the changes manually instead."
  156. return
  157. end
  158. end
  159. return M