bootstrap.lua 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. config_dir = self.config_dir,
  98. }
  99. local config = require "lvim.config"
  100. config:init {
  101. user_config = join_paths(self.config_dir, "config.lua"),
  102. }
  103. require("lvim.plugin-loader"):init {
  104. package_root = self.pack_dir,
  105. install_path = self.packer_install_dir,
  106. }
  107. return self
  108. end
  109. ---Update LunarVim
  110. ---pulls the latest changes from github and, resets the startup cache
  111. function M:update()
  112. hooks.run_pre_update()
  113. M:update_repo()
  114. hooks.run_post_update()
  115. end
  116. local function git_cmd(subcmd)
  117. local Job = require "plenary.job"
  118. local Log = require "lvim.core.log"
  119. local args = { "-C", get_install_path() }
  120. vim.list_extend(args, subcmd)
  121. local stderr = {}
  122. local stdout, ret = Job
  123. :new({
  124. command = "git",
  125. args = args,
  126. cwd = get_install_path(),
  127. on_stderr = function(_, data)
  128. table.insert(stderr, data)
  129. end,
  130. })
  131. :sync()
  132. if not vim.tbl_isempty(stderr) then
  133. Log:debug(stderr)
  134. end
  135. if not vim.tbl_isempty(stdout) then
  136. Log:debug(stdout)
  137. end
  138. return ret
  139. end
  140. ---pulls the latest changes from github
  141. function M:update_repo()
  142. local Log = require "lvim.core.log"
  143. local sub_commands = {
  144. fetch = { "fetch" },
  145. diff = { "diff", "--quiet", "@{upstream}" },
  146. merge = { "merge", "--ff-only", "--progress" },
  147. }
  148. Log:info "Checking for updates"
  149. local ret = git_cmd(sub_commands.fetch)
  150. if ret ~= 0 then
  151. Log:error "Update failed! Check the log for further information"
  152. return
  153. end
  154. ret = git_cmd(sub_commands.diff)
  155. if ret == 0 then
  156. Log:info "LunarVim is already up-to-date"
  157. return
  158. end
  159. ret = git_cmd(sub_commands.merge)
  160. if ret ~= 0 then
  161. Log:error "Update failed! Please pull the changes manually instead."
  162. return
  163. end
  164. end
  165. return M