فهرست منبع

Merge remote-tracking branch 'origin/rolling'

kylo252 3 سال پیش
والد
کامیت
30de3736ba
75فایلهای تغییر یافته به همراه1137 افزوده شده و 835 حذف شده
  1. 1 0
      .github/workflows/commitlint.config.js
  2. 1 0
      .luacheckrc
  3. 13 13
      init.lua
  4. 0 129
      lua/core/autocmds.lua
  5. 0 28
      lua/core/builtins/init.lua
  6. 0 31
      lua/core/comment.lua
  7. 0 60
      lua/core/log.lua
  8. 0 194
      lua/core/telescope.lua
  9. 50 52
      lua/lvim/bootstrap.lua
  10. 9 12
      lua/lvim/config/defaults.lua
  11. 62 29
      lua/lvim/config/init.lua
  12. 1 1
      lua/lvim/config/settings.lua
  13. 88 0
      lua/lvim/core/autocmds.lua
  14. 0 0
      lua/lvim/core/autopairs.lua
  15. 1 1
      lua/lvim/core/bufferline.lua
  16. 28 0
      lua/lvim/core/builtins/init.lua
  17. 22 15
      lua/lvim/core/cmp.lua
  18. 3 3
      lua/lvim/core/commands.lua
  19. 71 0
      lua/lvim/core/comment.lua
  20. 0 0
      lua/lvim/core/dap.lua
  21. 5 5
      lua/lvim/core/dashboard.lua
  22. 0 0
      lua/lvim/core/gitsigns.lua
  23. 62 66
      lua/lvim/core/info.lua
  24. 161 0
      lua/lvim/core/log.lua
  25. 0 0
      lua/lvim/core/lualine/colors.lua
  26. 7 7
      lua/lvim/core/lualine/components.lua
  27. 0 0
      lua/lvim/core/lualine/conditions.lua
  28. 2 2
      lua/lvim/core/lualine/init.lua
  29. 2 2
      lua/lvim/core/lualine/styles.lua
  30. 0 0
      lua/lvim/core/lualine/utils.lua
  31. 19 11
      lua/lvim/core/nvimtree.lua
  32. 0 0
      lua/lvim/core/project.lua
  33. 134 0
      lua/lvim/core/telescope.lua
  34. 80 0
      lua/lvim/core/telescope/custom-finders.lua
  35. 3 3
      lua/lvim/core/terminal.lua
  36. 1 1
      lua/lvim/core/treesitter.lua
  37. 21 18
      lua/lvim/core/which-key.lua
  38. 2 2
      lua/lvim/impatient.lua
  39. 0 0
      lua/lvim/impatient/profile.lua
  40. 0 0
      lua/lvim/interface/popup.lua
  41. 0 0
      lua/lvim/interface/text.lua
  42. 1 5
      lua/lvim/keymappings.lua
  43. 2 2
      lua/lvim/lsp/config.lua
  44. 0 0
      lua/lvim/lsp/handlers.lua
  45. 9 10
      lua/lvim/lsp/init.lua
  46. 6 6
      lua/lvim/lsp/manager.lua
  47. 4 4
      lua/lvim/lsp/null-ls/formatters.lua
  48. 9 3
      lua/lvim/lsp/null-ls/init.lua
  49. 4 4
      lua/lvim/lsp/null-ls/linters.lua
  50. 1 1
      lua/lvim/lsp/null-ls/services.lua
  51. 1 1
      lua/lvim/lsp/peek.lua
  52. 0 0
      lua/lvim/lsp/providers/jsonls.lua
  53. 1 1
      lua/lvim/lsp/providers/sumneko_lua.lua
  54. 1 1
      lua/lvim/lsp/providers/vuels.lua
  55. 0 0
      lua/lvim/lsp/providers/yamlls.lua
  56. 4 4
      lua/lvim/lsp/templates.lua
  57. 1 1
      lua/lvim/lsp/utils.lua
  58. 0 0
      lua/lvim/lualine/themes/onedarker.lua
  59. 2 2
      lua/lvim/plugin-loader.lua
  60. 26 18
      lua/lvim/plugins.lua
  61. 0 0
      lua/lvim/utils/ft.lua
  62. 7 5
      lua/lvim/utils/hooks.lua
  63. 3 35
      lua/lvim/utils/init.lua
  64. 0 0
      lua/lvim/utils/table.lua
  65. 1 1
      tests/bootstrap_spec.lua
  66. 37 0
      tests/config_loader_spec.lua
  67. 11 11
      tests/lsp_spec.lua
  68. 1 5
      tests/minimal_init.lua
  69. 107 0
      tests/minimal_lsp.lua
  70. 6 5
      tests/plugins_load_spec.lua
  71. 2 2
      utils/bin/lvim.ps1
  72. 14 9
      utils/installer/config.example-no-ts.lua
  73. 14 9
      utils/installer/config.example.lua
  74. 2 3
      utils/installer/install.ps1
  75. 11 2
      utils/installer/install.sh

+ 1 - 0
.github/workflows/commitlint.config.js

@@ -20,6 +20,7 @@ module.exports = {
       "always",
       [
         "build",
+        "chore",
         "ci",
         "docs",
         "feat",

+ 1 - 0
.luacheckrc

@@ -22,6 +22,7 @@ stds.nvim = {
     "get_runtime_dir",
     "get_config_dir",
     "get_cache_dir",
+    "get_lvim_base_dir",
     "get_version",
     -- vim = { fields = { "cmd", "api", "fn", "o" } },
   },

+ 13 - 13
init.lua

@@ -1,26 +1,26 @@
-if os.getenv "LUNARVIM_RUNTIME_DIR" then
-  local path_sep = vim.loop.os_uname().version:match "Windows" and "\\" or "/"
-  vim.opt.rtp:append(os.getenv "LUNARVIM_RUNTIME_DIR" .. path_sep .. "lvim")
+local init_path = debug.getinfo(1, "S").source:sub(2)
+local base_dir = init_path:match("(.*[/\\])"):sub(1, -2)
+
+if not vim.tbl_contains(vim.opt.rtp:get(), base_dir) then
+  vim.opt.rtp:append(base_dir)
 end
 
-require("bootstrap"):init()
+require("lvim.bootstrap"):init(base_dir)
 
-local config = require "config"
--- config:init()
-config:load()
+require("lvim.config"):load()
 
-local plugins = require "plugins"
-require("plugin-loader"):load { plugins, lvim.plugins }
+local plugins = require "lvim.plugins"
+require("lvim.plugin-loader"):load { plugins, lvim.plugins }
 
-local Log = require "core.log"
+local Log = require "lvim.core.log"
 Log:debug "Starting LunarVim"
 
 vim.g.colors_name = lvim.colorscheme -- Colorscheme must get called after plugins are loaded or it will break new installs.
 vim.cmd("colorscheme " .. lvim.colorscheme)
 
-local commands = require "core.commands"
+local commands = require "lvim.core.commands"
 commands.load(commands.defaults)
 
-require("keymappings").setup()
+require("lvim.keymappings").setup()
 
-require("lsp").setup()
+require("lvim.lsp").setup()

+ 0 - 129
lua/core/autocmds.lua

@@ -1,129 +0,0 @@
-local autocommands = {}
-local config = require "config"
-
-lvim.autocommands = {
-  _general_settings = {
-    {
-      "Filetype",
-      "*",
-      "lua require('utils.ft').do_filetype(vim.fn.expand(\"<amatch>\"))",
-    },
-    {
-      "FileType",
-      "qf",
-      "nnoremap <silent> <buffer> q :q<CR>",
-    },
-    {
-      "FileType",
-      "lsp-installer",
-      "nnoremap <silent> <buffer> q :q<CR>",
-    },
-    {
-      "TextYankPost",
-      "*",
-      "lua require('vim.highlight').on_yank({higroup = 'Search', timeout = 200})",
-    },
-    {
-      "BufWinEnter",
-      "*",
-      "setlocal formatoptions-=c formatoptions-=r formatoptions-=o",
-    },
-    {
-      "BufWinEnter",
-      "dashboard",
-      "setlocal cursorline signcolumn=yes cursorcolumn number",
-    },
-    {
-      "BufRead",
-      "*",
-      "setlocal formatoptions-=c formatoptions-=r formatoptions-=o",
-    },
-    {
-      "BufNewFile",
-      "*",
-      "setlocal formatoptions-=c formatoptions-=r formatoptions-=o",
-    },
-    { "BufWritePost", config.path, "lua require('utils').reload_lv_config()" },
-    {
-      "FileType",
-      "qf",
-      "set nobuflisted",
-    },
-    -- { "VimLeavePre", "*", "set title set titleold=" },
-  },
-  _filetypechanges = {
-    { "BufWinEnter", ".tf", "setlocal filetype=terraform" },
-    { "BufRead", "*.tf", "setlocal filetype=terraform" },
-    { "BufNewFile", "*.tf", "setlocal filetype=terraform" },
-    { "BufWinEnter", ".zsh", "setlocal filetype=sh" },
-    { "BufRead", "*.zsh", "setlocal filetype=sh" },
-    { "BufNewFile", "*.zsh", "setlocal filetype=sh" },
-  },
-  -- _solidity = {
-  --     {'BufWinEnter', '.sol', 'setlocal filetype=solidity'}, {'BufRead', '*.sol', 'setlocal filetype=solidity'},
-  --     {'BufNewFile', '*.sol', 'setlocal filetype=solidity'}
-  -- },
-  -- _gemini = {
-  --     {'BufWinEnter', '.gmi', 'setlocal filetype=markdown'}, {'BufRead', '*.gmi', 'setlocal filetype=markdown'},
-  --     {'BufNewFile', '*.gmi', 'setlocal filetype=markdown'}
-  -- },
-  _git = {
-    { "FileType", "gitcommit", "setlocal wrap" },
-    { "FileType", "gitcommit", "setlocal spell" },
-  },
-  _markdown = {
-    { "FileType", "markdown", "setlocal wrap" },
-    { "FileType", "markdown", "setlocal spell" },
-  },
-  _buffer_bindings = {
-    { "FileType", "floaterm", "nnoremap <silent> <buffer> q :q<CR>" },
-  },
-  _auto_resize = {
-    -- will cause split windows to be resized evenly if main window is resized
-    { "VimResized", "*", "wincmd =" },
-  },
-  _packer_compile = {
-    -- will run PackerCompile after writing plugins.lua
-    { "BufWritePost", "plugins.lua", "PackerCompile" },
-  },
-  _general_lsp = {
-    { "FileType", "lspinfo", "nnoremap <silent> <buffer> q :q<CR>" },
-  },
-
-  -- _fterm_lazygit = {
-  --   -- will cause esc key to exit lazy git
-  --   {"TermEnter", "*", "call LazyGitNativation()"}
-  -- },
-  -- _mode_switching = {
-  --   -- will switch between absolute and relative line numbers depending on mode
-  --   {'InsertEnter', '*', 'if &relativenumber | let g:ms_relativenumberoff = 1 | setlocal number norelativenumber | endif'},
-  --   {'InsertLeave', '*', 'if exists("g:ms_relativenumberoff") | setlocal relativenumber | endif'},
-  --   {'InsertEnter', '*', 'if &cursorline | let g:ms_cursorlineoff = 1 | setlocal nocursorline | endif'},
-  --   {'InsertLeave', '*', 'if exists("g:ms_cursorlineoff") | setlocal cursorline | endif'},
-  -- },
-  custom_groups = {},
-}
-
-function autocommands.define_augroups(definitions) -- {{{1
-  -- Create autocommand groups based on the passed definitions
-  --
-  -- The key will be the name of the group, and each definition
-  -- within the group should have:
-  --    1. Trigger
-  --    2. Pattern
-  --    3. Text
-  -- just like how they would normally be defined from Vim itself
-  for group_name, definition in pairs(definitions) do
-    vim.cmd("augroup " .. group_name)
-    vim.cmd "autocmd!"
-
-    for _, def in pairs(definition) do
-      local command = table.concat(vim.tbl_flatten { "autocmd", def }, " ")
-      vim.cmd(command)
-    end
-
-    vim.cmd "augroup END"
-  end
-end
-
-return autocommands

+ 0 - 28
lua/core/builtins/init.lua

@@ -1,28 +0,0 @@
-local M = {}
-
-local builtins = {
-  "keymappings",
-  "core.which-key",
-  "core.gitsigns",
-  "core.cmp",
-  "core.dashboard",
-  "core.dap",
-  "core.terminal",
-  "core.telescope",
-  "core.treesitter",
-  "core.nvimtree",
-  "core.project",
-  "core.bufferline",
-  "core.autopairs",
-  "core.comment",
-  "core.lualine",
-}
-
-function M.config(config)
-  for _, builtin_path in ipairs(builtins) do
-    local builtin = require(builtin_path)
-    builtin.config(config)
-  end
-end
-
-return M

+ 0 - 31
lua/core/comment.lua

@@ -1,31 +0,0 @@
-local M = {}
-
-function M.config()
-  lvim.builtin.comment = {
-    active = true,
-    on_config_done = nil,
-    -- Linters prefer comment and line to have a space in between markers
-    marker_padding = true,
-    -- should comment out empty or whitespace only lines
-    comment_empty = false,
-    -- Should key mappings be created
-    create_mappings = true,
-    -- Normal mode mapping left hand side
-    line_mapping = "gcc",
-    -- Visual/Operator mapping left hand side
-    operator_mapping = "gc",
-    -- Hook function to call before commenting takes place
-    hook = nil,
-  }
-end
-
-function M.setup()
-  local nvim_comment = require "nvim_comment"
-
-  nvim_comment.setup(lvim.builtin.comment)
-  if lvim.builtin.comment.on_config_done then
-    lvim.builtin.comment.on_config_done(nvim_comment)
-  end
-end
-
-return M

+ 0 - 60
lua/core/log.lua

@@ -1,60 +0,0 @@
-local Log = {}
-
---- Adds a log entry using Plenary.log
----@param msg any
----@param level string [same as vim.log.log_levels]
-function Log:add_entry(msg, level)
-  assert(type(level) == "string")
-  if self.__handle then
-    -- plenary uses lower-case log levels
-    self.__handle[level:lower()](msg)
-    return
-  end
-  local status_ok, plenary = pcall(require, "plenary")
-  if status_ok then
-    local default_opts = { plugin = "lunarvim", level = lvim.log.level }
-    local handle = plenary.log.new(default_opts)
-    handle[level:lower()](msg)
-    self.__handle = handle
-  end
-  -- don't do anything if plenary is not available
-end
-
----Retrieves the path of the logfile
----@return string path of the logfile
-function Log:get_path()
-  return string.format("%s/%s.log", vim.fn.stdpath "cache", "lunarvim")
-end
-
----Add a log entry at TRACE level
----@param msg any
-function Log:trace(msg)
-  self:add_entry(msg, "TRACE")
-end
-
----Add a log entry at DEBUG level
----@param msg any
-function Log:debug(msg)
-  self:add_entry(msg, "DEBUG")
-end
-
----Add a log entry at INFO level
----@param msg any
-function Log:info(msg)
-  self:add_entry(msg, "INFO")
-end
-
----Add a log entry at WARN level
----@param msg any
-function Log:warn(msg)
-  self:add_entry(msg, "WARN")
-end
-
----Add a log entry at ERROR level
----@param msg any
-function Log:error(msg)
-  self:add_entry(msg, "ERROR")
-end
-
-setmetatable({}, Log)
-return Log

+ 0 - 194
lua/core/telescope.lua

@@ -1,194 +0,0 @@
-local M = {}
-
-local utils = require "utils"
-
-function M.config()
-  -- Define this minimal config so that it's available if telescope is not yet available.
-  lvim.builtin.telescope = {
-    ---@usage disable telescope completely [not recommeded]
-    active = true,
-    on_config_done = nil,
-  }
-
-  local status_ok, actions = pcall(require, "telescope.actions")
-  if not status_ok then
-    return
-  end
-
-  lvim.builtin.telescope = vim.tbl_extend("force", lvim.builtin.telescope, {
-    defaults = {
-      prompt_prefix = " ",
-      selection_caret = " ",
-      entry_prefix = "  ",
-      initial_mode = "insert",
-      selection_strategy = "reset",
-      sorting_strategy = "descending",
-      layout_strategy = "horizontal",
-      layout_config = {
-        width = 0.75,
-        preview_cutoff = 120,
-        horizontal = { mirror = false },
-        vertical = { mirror = false },
-      },
-      file_sorter = require("telescope.sorters").get_fzy_sorter,
-      file_ignore_patterns = {},
-      generic_sorter = require("telescope.sorters").get_generic_fuzzy_sorter,
-      path_display = { shorten = 5 },
-      winblend = 0,
-      border = {},
-      borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" },
-      color_devicons = true,
-      use_less = true,
-      set_env = { ["COLORTERM"] = "truecolor" }, -- default = nil,
-      file_previewer = require("telescope.previewers").vim_buffer_cat.new,
-      grep_previewer = require("telescope.previewers").vim_buffer_vimgrep.new,
-      qflist_previewer = require("telescope.previewers").vim_buffer_qflist.new,
-
-      -- Developer configurations: Not meant for general override
-      -- buffer_previewer_maker = require("telescope.previewers").buffer_previewer_maker,
-      mappings = {
-        i = {
-          ["<C-n>"] = actions.move_selection_next,
-          ["<C-p>"] = actions.move_selection_previous,
-          ["<C-c>"] = actions.close,
-          ["<C-j>"] = actions.cycle_history_next,
-          ["<C-k>"] = actions.cycle_history_prev,
-          ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,
-          ["<CR>"] = actions.select_default + actions.center,
-          -- To disable a keymap, put [map] = false
-          -- So, to not map "<C-n>", just put
-          -- ["<c-t>"] = trouble.open_with_trouble,
-          -- ["<c-x>"] = false,
-          -- ["<esc>"] = actions.close,
-          -- Otherwise, just set the mapping to the function that you want it to be.
-          -- ["<C-i>"] = actions.select_horizontal,
-          -- Add up multiple actions
-          -- You can perform as many actions in a row as you like
-          -- ["<CR>"] = actions.select_default + actions.center + my_cool_custom_action,
-        },
-        n = {
-          ["<C-n>"] = actions.move_selection_next,
-          ["<C-p>"] = actions.move_selection_previous,
-          ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,
-          -- ["<c-t>"] = trouble.open_with_trouble,
-          -- ["<C-i>"] = my_cool_custom_action,
-        },
-      },
-    },
-    extensions = {
-      fzy_native = {
-        override_generic_sorter = false,
-        override_file_sorter = true,
-      },
-    },
-  })
-end
-
-function M.find_lunarvim_files(opts)
-  opts = opts or {}
-  local themes = require "telescope.themes"
-  local theme_opts = themes.get_ivy {
-    sorting_strategy = "ascending",
-    layout_strategy = "bottom_pane",
-    prompt_prefix = ">> ",
-    prompt_title = "~ LunarVim files ~",
-    cwd = utils.join_paths(get_runtime_dir(), "lvim"),
-    find_command = { "git", "ls-files" },
-  }
-  opts = vim.tbl_deep_extend("force", theme_opts, opts)
-  require("telescope.builtin").find_files(opts)
-end
-
-function M.grep_lunarvim_files(opts)
-  opts = opts or {}
-  local themes = require "telescope.themes"
-  local theme_opts = themes.get_ivy {
-    sorting_strategy = "ascending",
-    layout_strategy = "bottom_pane",
-    prompt_prefix = ">> ",
-    prompt_title = "~ search LunarVim ~",
-    cwd = utils.join_paths(get_runtime_dir(), "lvim"),
-  }
-  opts = vim.tbl_deep_extend("force", theme_opts, opts)
-  require("telescope.builtin").live_grep(opts)
-end
-
-function M.view_lunarvim_changelog()
-  local finders = require "telescope.finders"
-  local make_entry = require "telescope.make_entry"
-  local pickers = require "telescope.pickers"
-  local previewers = require "telescope.previewers"
-  local actions = require "telescope.actions"
-  local opts = {}
-
-  local conf = require("telescope.config").values
-  opts.entry_maker = make_entry.gen_from_git_commits(opts)
-
-  pickers.new(opts, {
-    prompt_title = "LunarVim changelog",
-
-    finder = finders.new_oneshot_job(
-      vim.tbl_flatten {
-        "git",
-        "log",
-        "--pretty=oneline",
-        "--abbrev-commit",
-        "--",
-        ".",
-      },
-      opts
-    ),
-    previewer = {
-      previewers.git_commit_diff_to_parent.new(opts),
-      previewers.git_commit_diff_to_head.new(opts),
-      previewers.git_commit_diff_as_was.new(opts),
-      previewers.git_commit_message.new(opts),
-    },
-
-    --TODO: consider opening a diff view when pressing enter
-    attach_mappings = function(_, map)
-      map("i", "<enter>", actions._close)
-      map("n", "<enter>", actions._close)
-      map("i", "<esc>", actions._close)
-      map("n", "<esc>", actions._close)
-      map("n", "q", actions._close)
-      return true
-    end,
-    sorter = conf.file_sorter(opts),
-  }):find()
-end
-
-function M.code_actions()
-  local opts = {
-    winblend = 15,
-    layout_config = {
-      prompt_position = "top",
-      width = 80,
-      height = 12,
-    },
-    borderchars = {
-      prompt = { "─", "│", " ", "│", "╭", "╮", "│", "│" },
-      results = { "─", "│", "─", "│", "├", "┤", "╯", "╰" },
-      preview = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" },
-    },
-    border = {},
-    previewer = false,
-    shorten_path = false,
-  }
-  require("telescope.builtin").lsp_code_actions(require("telescope.themes").get_dropdown(opts))
-end
-
-function M.setup()
-  local telescope = require "telescope"
-
-  telescope.setup(lvim.builtin.telescope)
-  if lvim.builtin.project.active then
-    telescope.load_extension "projects"
-  end
-
-  if lvim.builtin.telescope.on_config_done then
-    lvim.builtin.telescope.on_config_done(telescope)
-  end
-end
-
-return M

+ 50 - 52
lua/bootstrap.lua → lua/lvim/bootstrap.lua

@@ -1,13 +1,14 @@
 local M = {}
 
-package.loaded["utils.hooks"] = nil
-local _, hooks = pcall(require, "utils.hooks")
+package.loaded["lvim.utils.hooks"] = nil
+local _, hooks = pcall(require, "lvim.utils.hooks")
+
+local uv = vim.loop
+local path_sep = uv.os_uname().version:match "Windows" and "\\" or "/"
 
 ---Join path segments that were passed as input
 ---@return string
 function _G.join_paths(...)
-  local uv = vim.loop
-  local path_sep = uv.os_uname().version:match "Windows" and "\\" or "/"
   local result = table.concat({ ... }, path_sep)
   return result
 end
@@ -18,7 +19,7 @@ function _G.get_runtime_dir()
   local lvim_runtime_dir = os.getenv "LUNARVIM_RUNTIME_DIR"
   if not lvim_runtime_dir then
     -- when nvim is used directly
-    return vim.fn.stdpath "config"
+    return vim.fn.stdpath "data"
   end
   return lvim_runtime_dir
 end
@@ -43,47 +44,24 @@ function _G.get_cache_dir()
   return lvim_cache_dir
 end
 
----Get the full path to the currently installed lunarvim repo
----@return string
-local function get_install_path()
-  local lvim_runtime_dir = os.getenv "LUNARVIM_RUNTIME_DIR"
-  if not lvim_runtime_dir then
-    -- when nvim is used directly
-    return vim.fn.stdpath "config"
-  end
-  return join_paths(lvim_runtime_dir, "lvim")
-end
-
----Get currently installed version of LunarVim
----@param type string can be "short"
----@return string
-function _G.get_version(type)
-  type = type or ""
-  local lvim_full_ver = vim.fn.system("git -C " .. get_install_path() .. " describe --tags")
-
-  if string.match(lvim_full_ver, "%d") == nil then
-    return nil
-  end
-  if type == "short" then
-    return vim.fn.split(lvim_full_ver, "-")[1]
-  else
-    return string.sub(lvim_full_ver, 1, #lvim_full_ver - 1)
-  end
-end
-
 ---Initialize the `&runtimepath` variables and prepare for startup
 ---@return table
-function M:init()
+function M:init(base_dir)
   self.runtime_dir = get_runtime_dir()
   self.config_dir = get_config_dir()
   self.cache_path = get_cache_dir()
-  self.install_path = get_install_path()
-
   self.pack_dir = join_paths(self.runtime_dir, "site", "pack")
   self.packer_install_dir = join_paths(self.runtime_dir, "site", "pack", "packer", "start", "packer.nvim")
   self.packer_cache_path = join_paths(self.config_dir, "plugin", "packer_compiled.lua")
 
+  ---Get the full path to LunarVim's base directory
+  ---@return string
+  function _G.get_lvim_base_dir()
+    return base_dir
+  end
+
   if os.getenv "LUNARVIM_RUNTIME_DIR" then
+    -- vim.opt.rtp:append(os.getenv "LUNARVIM_RUNTIME_DIR" .. path_sep .. "lvim")
     vim.opt.rtp:remove(join_paths(vim.fn.stdpath "data", "site"))
     vim.opt.rtp:remove(join_paths(vim.fn.stdpath "data", "site", "after"))
     vim.opt.rtp:prepend(join_paths(self.runtime_dir, "site"))
@@ -99,22 +77,20 @@ function M:init()
     vim.cmd("set spellfile=" .. join_paths(self.config_dir, "spell", "en.utf-8.add"))
   end
 
-  vim.fn.mkdir(vim.fn.stdpath "cache", "p")
+  vim.fn.mkdir(get_cache_dir(), "p")
 
   -- FIXME: currently unreliable in unit-tests
   if not os.getenv "LVIM_TEST_ENV" then
-    require("impatient").setup {
+    _G.PLENARY_DEBUG = false
+    require("lvim.impatient").setup {
       path = vim.fn.stdpath "cache" .. "/lvim_cache",
       enable_profiling = true,
     }
   end
 
-  local config = require "config"
-  config:init {
-    path = join_paths(self.config_dir, "config.lua"),
-  }
+  require("lvim.config"):init()
 
-  require("plugin-loader"):init {
+  require("lvim.plugin-loader"):init {
     package_root = self.pack_dir,
     install_path = self.packer_install_dir,
   }
@@ -130,10 +106,10 @@ function M:update()
   hooks.run_post_update()
 end
 
-local function git_cmd(subcmd)
+local function git_cmd(subcmd, opts)
   local Job = require "plenary.job"
-  local Log = require "core.log"
-  local args = { "-C", get_install_path() }
+  local Log = require "lvim.core.log"
+  local args = { "-C", opts.cwd }
   vim.list_extend(args, subcmd)
 
   local stderr = {}
@@ -141,7 +117,7 @@ local function git_cmd(subcmd)
     :new({
       command = "git",
       args = args,
-      cwd = get_install_path(),
+      cwd = opts.cwd,
       on_stderr = function(_, data)
         table.insert(stderr, data)
       end,
@@ -156,33 +132,36 @@ local function git_cmd(subcmd)
     Log:debug(stdout)
   end
 
-  return ret
+  return ret, stdout
 end
 
 ---pulls the latest changes from github
 function M:update_repo()
-  local Log = require "core.log"
+  local Log = require "lvim.core.log"
   local sub_commands = {
     fetch = { "fetch" },
     diff = { "diff", "--quiet", "@{upstream}" },
     merge = { "merge", "--ff-only", "--progress" },
   }
+  local opts = {
+    cwd = get_lvim_base_dir(),
+  }
   Log:info "Checking for updates"
 
-  local ret = git_cmd(sub_commands.fetch)
+  local ret = git_cmd(sub_commands.fetch, opts)
   if ret ~= 0 then
     Log:error "Update failed! Check the log for further information"
     return
   end
 
-  ret = git_cmd(sub_commands.diff)
+  ret = git_cmd(sub_commands.diff, opts)
 
   if ret == 0 then
     Log:info "LunarVim is already up-to-date"
     return
   end
 
-  ret = git_cmd(sub_commands.merge)
+  ret = git_cmd(sub_commands.merge, opts)
 
   if ret ~= 0 then
     Log:error "Update failed! Please pull the changes manually instead."
@@ -190,4 +169,23 @@ function M:update_repo()
   end
 end
 
+---Get currently installed version of LunarVim
+---@param type string can be "short"
+---@return string
+function M:get_version(type)
+  type = type or ""
+  local opts = { cwd = get_lvim_base_dir() }
+  local status_ok, results = git_cmd({ "describe", "--tags" }, opts)
+  local lvim_full_ver = results[1] or ""
+
+  if not status_ok or string.match(lvim_full_ver, "%d") == nil then
+    return nil
+  end
+  if type == "short" then
+    return vim.fn.split(lvim_full_ver, "-")[1]
+  else
+    return string.sub(lvim_full_ver, 1, #lvim_full_ver - 1)
+  end
+end
+
 return M

+ 9 - 12
lua/config/defaults.lua → lua/lvim/config/defaults.lua

@@ -1,18 +1,19 @@
-local home_dir = vim.loop.os_homedir()
-local utils = require "utils"
-
-lvim = {
+return {
   leader = "space",
   colorscheme = "onedarker",
   line_wrap_cursor_movement = true,
   transparent_window = false,
   format_on_save = true,
-  vsnip_dir = utils.join_paths(home_dir, ".config", "snippets"),
-  database = { save_location = utils.join_paths(home_dir, ".config", "lunarvim_db"), auto_execute = 1 },
   keys = {},
 
   builtin = {},
 
+  plugins = {
+    -- use config.lua for this not put here
+  },
+
+  autocommands = {},
+  lang = {},
   log = {
     ---@usage can be { "trace", "debug", "info", "warn", "error", "fatal" },
     level = "warn",
@@ -27,11 +28,7 @@ lvim = {
         float_opts = {},
       },
     },
+    ---@usage set to false to restore the default behavior of vim.notify
+    override_notify = true,
   },
-  plugins = {
-    -- use config.lua for this not put here
-  },
-
-  autocommands = {},
-  lang = {},
 }

+ 62 - 29
lua/config/init.lua → lua/lvim/config/init.lua

@@ -1,29 +1,36 @@
+local utils = require "lvim.utils"
+local Log = require "lvim.core.log"
+
 local M = {}
+local user_config_dir = get_config_dir()
+local user_config_file = utils.join_paths(user_config_dir, "config.lua")
+
+---Get the full path to the user configuration file
+---@return string
+function M:get_user_config_path()
+  return user_config_file
+end
 
 --- Initialize lvim default configuration
 -- Define lvim global variable
-function M:init(opts)
-  opts = opts or {}
-  self.path = opts.path
-  local utils = require "utils"
-
-  require "config.defaults"
-
-  -- Fallback config.lua to lv-config.lua
-  if not utils.is_file(self.path) then
-    local lv_config = self.path:gsub("config.lua$", "lv-config.lua")
-    print(self.path, "not found, falling back to", lv_config)
-
-    self.path = lv_config
+function M:init()
+  if vim.tbl_isempty(lvim or {}) then
+    lvim = require "lvim.config.defaults"
+    local home_dir = vim.loop.os_homedir()
+    lvim.vsnip_dir = utils.join_paths(home_dir, ".config", "snippets")
+    lvim.database = { save_location = utils.join_paths(home_dir, ".config", "lunarvim_db"), auto_execute = 1 }
   end
 
-  local builtins = require "core.builtins"
-  builtins.config(self)
+  local builtins = require "lvim.core.builtins"
+  builtins.config { user_config_file = user_config_file }
 
-  local settings = require "config.settings"
+  local settings = require "lvim.config.settings"
   settings.load_options()
 
-  local lvim_lsp_config = require "lsp.config"
+  local autocmds = require "lvim.core.autocmds"
+  lvim.autocommands = autocmds.load_augroups()
+
+  local lvim_lsp_config = require "lvim.lsp.config"
   lvim.lsp = vim.deepcopy(lvim_lsp_config)
 
   local supported_languages = {
@@ -121,7 +128,7 @@ function M:init(opts)
     "zig",
   }
 
-  require("lsp.manager").init_defaults(supported_languages)
+  require("lvim.lsp.manager").init_defaults(supported_languages)
 end
 
 local function deprecation_notice()
@@ -131,7 +138,7 @@ local function deprecation_notice()
   end
 
   for lang, entry in pairs(lvim.lang) do
-    local deprecated_config = entry["lsp"] or {}
+    local deprecated_config = entry["lvim.lsp"] or {}
     if not vim.tbl_isempty(deprecated_config) then
       local msg = string.format(
         "Deprecation notice: [lvim.lang.%s.lsp] setting is no longer supported. See https://github.com/LunarVim/LunarVim#breaking-changes",
@@ -147,24 +154,50 @@ end
 --- Override the configuration with a user provided one
 -- @param config_path The path to the configuration overrides
 function M:load(config_path)
-  local autocmds = require "core.autocmds"
-
-  config_path = config_path or self.path
-  local ok, err = pcall(vim.cmd, "luafile " .. config_path)
+  local autocmds = require "lvim.core.autocmds"
+  config_path = config_path or self.get_user_config_path()
+  local ok, err = pcall(dofile, config_path)
   if not ok then
-    print("Invalid configuration", config_path)
-    print(err)
-    return
+    if utils.is_file(user_config_file) then
+      Log:warn("Invalid configuration: " .. err)
+    else
+      Log:warn(string.format("Unable to find configuration file [%s]", config_path))
+    end
   end
 
   deprecation_notice()
 
-  self.path = config_path
-
   autocmds.define_augroups(lvim.autocommands)
 
-  local settings = require "config.settings"
+  local settings = require "lvim.config.settings"
   settings.load_commands()
 end
 
+--- Override the configuration with a user provided one
+-- @param config_path The path to the configuration overrides
+function M:reload()
+  local lvim_modules = {}
+  for module, _ in pairs(package.loaded) do
+    if module:match "lvim" then
+      package.loaded.module = nil
+      table.insert(lvim_modules, module)
+    end
+  end
+
+  M:init()
+  M:load()
+
+  require("lvim.keymappings").setup() -- this should be done before loading the plugins
+  local plugins = require "lvim.plugins"
+  utils.toggle_autoformat()
+  local plugin_loader = require "lvim.plugin-loader"
+  plugin_loader:cache_reset()
+  plugin_loader:load { plugins, lvim.plugins }
+  vim.cmd ":PackerInstall"
+  vim.cmd ":PackerCompile"
+  -- vim.cmd ":PackerClean"
+  require("lvim.lsp").setup()
+  Log:info "Reloaded configuration"
+end
+
 return M

+ 1 - 1
lua/config/settings.lua → lua/lvim/config/settings.lua

@@ -1,5 +1,5 @@
 local M = {}
-local utils = require "utils"
+local utils = require "lvim.utils"
 M.load_options = function()
   local default_options = {
     backup = false, -- creates a backup file

+ 88 - 0
lua/lvim/core/autocmds.lua

@@ -0,0 +1,88 @@
+local M = {}
+
+--- Load the default set of autogroups and autocommands.
+function M.load_augroups()
+  local user_config_file = vim.fn.resolve(require("lvim.config"):get_user_config_path())
+
+  return {
+    _general_settings = {
+      {
+        "Filetype",
+        "*",
+        "lua require('lvim.utils.ft').do_filetype(vim.fn.expand(\"<amatch>\"))",
+      },
+      { "FileType", "qf,help,man", "nnoremap <silent> <buffer> q :close<CR>" },
+      {
+        "TextYankPost",
+        "*",
+        "lua require('vim.highlight').on_yank({higroup = 'Search', timeout = 200})",
+      },
+      {
+        "BufWinEnter",
+        "dashboard",
+        "setlocal cursorline signcolumn=yes cursorcolumn number",
+      },
+      { "BufWritePost", user_config_file, "lua require('lvim.config'):reload()" },
+      { "FileType", "qf", "set nobuflisted" },
+      -- { "VimLeavePre", "*", "set title set titleold=" },
+    },
+    _formatoptions = {
+      {
+        "BufWinEnter,BufRead,BufNewFile",
+        "*",
+        "setlocal formatoptions-=c formatoptions-=r formatoptions-=o",
+      },
+    },
+    _filetypechanges = {
+      { "BufWinEnter", ".tf", "setlocal filetype=terraform" },
+      { "BufRead", "*.tf", "setlocal filetype=terraform" },
+      { "BufNewFile", "*.tf", "setlocal filetype=terraform" },
+      { "BufWinEnter", ".zsh", "setlocal filetype=sh" },
+      { "BufRead", "*.zsh", "setlocal filetype=sh" },
+      { "BufNewFile", "*.zsh", "setlocal filetype=sh" },
+    },
+    _git = {
+      { "FileType", "gitcommit", "setlocal wrap" },
+      { "FileType", "gitcommit", "setlocal spell" },
+    },
+    _markdown = {
+      { "FileType", "markdown", "setlocal wrap" },
+      { "FileType", "markdown", "setlocal spell" },
+    },
+    _buffer_bindings = {
+      { "FileType", "floaterm", "nnoremap <silent> <buffer> q :q<CR>" },
+    },
+    _auto_resize = {
+      -- will cause split windows to be resized evenly if main window is resized
+      { "VimResized", "*", "tabdo wincmd =" },
+    },
+    _general_lsp = {
+      { "FileType", "lspinfo,lsp-installer,null-ls-info", "nnoremap <silent> <buffer> q :close<CR>" },
+    },
+    custom_groups = {},
+  }
+end
+
+function M.define_augroups(definitions) -- {{{1
+  -- Create autocommand groups based on the passed definitions
+  --
+  -- The key will be the name of the group, and each definition
+  -- within the group should have:
+  --    1. Trigger
+  --    2. Pattern
+  --    3. Text
+  -- just like how they would normally be defined from Vim itself
+  for group_name, definition in pairs(definitions) do
+    vim.cmd("augroup " .. group_name)
+    vim.cmd "autocmd!"
+
+    for _, def in pairs(definition) do
+      local command = table.concat(vim.tbl_flatten { "autocmd", def }, " ")
+      vim.cmd(command)
+    end
+
+    vim.cmd "augroup END"
+  end
+end
+
+return M

+ 0 - 0
lua/core/autopairs.lua → lua/lvim/core/autopairs.lua


+ 1 - 1
lua/core/bufferline.lua → lua/lvim/core/bufferline.lua

@@ -14,7 +14,7 @@ M.config = function()
 end
 
 M.setup = function()
-  local keymap = require "keymappings"
+  local keymap = require "lvim.keymappings"
   keymap.append_to_defaults(lvim.builtin.bufferline.keymap)
 
   if lvim.builtin.bufferline.on_config_done then

+ 28 - 0
lua/lvim/core/builtins/init.lua

@@ -0,0 +1,28 @@
+local M = {}
+
+local builtins = {
+  "lvim.keymappings",
+  "lvim.core.which-key",
+  "lvim.core.gitsigns",
+  "lvim.core.cmp",
+  "lvim.core.dashboard",
+  "lvim.core.dap",
+  "lvim.core.terminal",
+  "lvim.core.telescope",
+  "lvim.core.treesitter",
+  "lvim.core.nvimtree",
+  "lvim.core.project",
+  "lvim.core.bufferline",
+  "lvim.core.autopairs",
+  "lvim.core.comment",
+  "lvim.core.lualine",
+}
+
+function M.config(config)
+  for _, builtin_path in ipairs(builtins) do
+    local builtin = require(builtin_path)
+    builtin.config(config)
+  end
+end
+
+return M

+ 22 - 15
lua/core/cmp.lua → lua/lvim/core/cmp.lua

@@ -158,23 +158,28 @@ M.config = function()
         Value = " ",
         Variable = " ",
       },
+      source_names = {
+        nvim_lsp = "(LSP)",
+        emoji = "(Emoji)",
+        path = "(Path)",
+        calc = "(Calc)",
+        cmp_tabnine = "(Tabnine)",
+        vsnip = "(Snippet)",
+        luasnip = "(Snippet)",
+        buffer = "(Buffer)",
+      },
+      duplicates = {
+        buffer = 1,
+        path = 1,
+        nvim_lsp = 0,
+        luasnip = 1,
+      },
+      duplicates_default = 0,
       format = function(entry, vim_item)
         vim_item.kind = lvim.builtin.cmp.formatting.kind_icons[vim_item.kind]
-        vim_item.menu = ({
-          nvim_lsp = "(LSP)",
-          emoji = "(Emoji)",
-          path = "(Path)",
-          calc = "(Calc)",
-          cmp_tabnine = "(Tabnine)",
-          vsnip = "(Snippet)",
-          luasnip = "(Snippet)",
-          buffer = "(Buffer)",
-        })[entry.source.name]
-        vim_item.dup = ({
-          buffer = 1,
-          path = 1,
-          nvim_lsp = 0,
-        })[entry.source.name] or 0
+        vim_item.menu = lvim.builtin.cmp.formatting.source_names[entry.source.name]
+        vim_item.dup = lvim.builtin.cmp.formatting.duplicates[entry.source.name]
+          or lvim.builtin.cmp.formatting.duplicates_default
         return vim_item
       end,
     },
@@ -199,6 +204,8 @@ M.config = function()
       { name = "crates" },
     },
     mapping = {
+      ["<C-k>"] = cmp.mapping.select_prev_item(),
+      ["<C-j>"] = cmp.mapping.select_next_item(),
       ["<C-d>"] = cmp.mapping.scroll_docs(-4),
       ["<C-f>"] = cmp.mapping.scroll_docs(4),
       -- TODO: potentially fix emmet nonsense

+ 3 - 3
lua/core/commands.lua → lua/lvim/core/commands.lua

@@ -11,9 +11,9 @@ M.defaults = {
   endfunction
   ]],
   -- :LvimInfo
-  [[ command! LvimInfo lua require('core.info').toggle_popup(vim.bo.filetype) ]],
-  [[ command! LvimCacheReset lua require('utils.hooks').reset_cache() ]],
-  [[ command! LvimUpdate lua require('bootstrap').update() ]],
+  [[ command! LvimInfo lua require('lvim.core.info').toggle_popup(vim.bo.filetype) ]],
+  [[ command! LvimCacheReset lua require('lvim.utils.hooks').reset_cache() ]],
+  [[ command! LvimUpdate lua require('lvim.bootstrap').update() ]],
 }
 
 M.load = function(commands)

+ 71 - 0
lua/lvim/core/comment.lua

@@ -0,0 +1,71 @@
+local M = {}
+
+function M.config()
+  local pre_hook = nil
+  if lvim.builtin.treesitter.context_commentstring.enable then
+    pre_hook = function(_ctx)
+      return require("ts_context_commentstring.internal").calculate_commentstring()
+    end
+  end
+  lvim.builtin.comment = {
+    active = true,
+    on_config_done = nil,
+    ---Add a space b/w comment and the line
+    ---@type boolean
+    padding = true,
+
+    ---Lines to be ignored while comment/uncomment.
+    ---Could be a regex string or a function that returns a regex string.
+    ---Example: Use '^$' to ignore empty lines
+    ---@type string|function
+    ignore = "^$",
+
+    ---Whether to create basic (operator-pending) and extra mappings for NORMAL/VISUAL mode
+    ---@type table
+    mappings = {
+      ---operator-pending mapping
+      ---Includes `gcc`, `gcb`, `gc[count]{motion}` and `gb[count]{motion}`
+      basic = true,
+      ---extended mapping
+      ---Includes `g>`, `g<`, `g>[count]{motion}` and `g<[count]{motion}`
+      extra = false,
+    },
+
+    ---LHS of line and block comment toggle mapping in NORMAL/VISUAL mode
+    ---@type table
+    toggler = {
+      ---line-comment toggle
+      line = "gcc",
+      ---block-comment toggle
+      block = "gbc",
+    },
+
+    ---LHS of line and block comment operator-mode mapping in NORMAL/VISUAL mode
+    ---@type table
+    opleader = {
+      ---line-comment opfunc mapping
+      line = "gc",
+      ---block-comment opfunc mapping
+      block = "gb",
+    },
+
+    ---Pre-hook, called before commenting the line
+    ---@type function|nil
+    pre_hook = pre_hook,
+
+    ---Post-hook, called after commenting is done
+    ---@type function|nil
+    post_hook = nil,
+  }
+end
+
+function M.setup()
+  local nvim_comment = require "Comment"
+
+  nvim_comment.setup(lvim.builtin.comment)
+  if lvim.builtin.comment.on_config_done then
+    lvim.builtin.comment.on_config_done(nvim_comment)
+  end
+end
+
+return M

+ 0 - 0
lua/core/dap.lua → lua/lvim/core/dap.lua


+ 5 - 5
lua/core/dashboard.lua → lua/lvim/core/dashboard.lua

@@ -1,5 +1,5 @@
 local M = {}
-local utils = require "utils"
+local utils = require "lvim.utils"
 
 M.config = function(config)
   lvim.builtin.dashboard = {
@@ -48,7 +48,7 @@ M.config = function(config)
       },
       e = {
         description = { "  Configuration      " },
-        command = ":e " .. config.path,
+        command = ":e " .. config.user_config_file,
       },
     },
 
@@ -70,7 +70,7 @@ M.setup = function()
   vim.g.dashboard_session_directory = lvim.builtin.dashboard.session_directory
 
   local lvim_site = "lunarvim.org"
-  local lvim_version = get_version "short"
+  local lvim_version = require("lvim.bootstrap"):get_version "short"
   local num_plugins_loaded = #vim.fn.globpath(get_runtime_dir() .. "/site/pack/packer/start", "*", 0, 1)
 
   local footer = {
@@ -84,10 +84,10 @@ M.setup = function()
     table.insert(footer, 3, "v" .. lvim_version)
   end
 
-  local text = require "interface.text"
+  local text = require "lvim.interface.text"
   vim.g.dashboard_custom_footer = text.align_center({ width = 0 }, footer, 0.49) -- Use 0.49 as  counts for 2 characters
 
-  require("core.autocmds").define_augroups {
+  require("lvim.core.autocmds").define_augroups {
     _dashboard = {
       -- seems to be nobuflisted that makes my stuff disappear will do more testing
       {

+ 0 - 0
lua/core/gitsigns.lua → lua/lvim/core/gitsigns.lua


+ 62 - 66
lua/core/info.lua → lua/lvim/core/info.lua

@@ -10,54 +10,44 @@ local M = {
 }
 
 local fmt = string.format
-local text = require "interface.text"
-local lsp_utils = require "lsp.utils"
+local text = require "lvim.interface.text"
+local lsp_utils = require "lvim.lsp.utils"
 
 local function str_list(list)
   return fmt("[ %s ]", table.concat(list, ", "))
 end
 
-local function get_formatter_suggestion_msg(ft)
-  local config = require "config"
-  local null_formatters = require "lsp.null-ls.formatters"
+local function make_formatters_info(ft)
+  local null_formatters = require "lvim.lsp.null-ls.formatters"
+  local registered_formatters = null_formatters.list_registered_providers(ft)
   local supported_formatters = null_formatters.list_available(ft)
   local section = {
-    " HINT ",
-    "",
-    fmt("* List of supported formatters: %s", str_list(supported_formatters)),
+    "Formatters info",
+    fmt(
+      "* Active: %s%s",
+      table.concat(registered_formatters, "  , "),
+      vim.tbl_count(registered_formatters) > 0 and "  " or ""
+    ),
+    fmt("* Supported: %s", str_list(supported_formatters)),
   }
 
-  if not vim.tbl_isempty(supported_formatters) then
-    vim.list_extend(section, {
-      "* Configured formatter needs to be installed and executable.",
-      fmt("* Enable installed formatter(s) with following config in %s", config.path),
-      "",
-      fmt("  lvim.lang.%s.formatters = { { exe = '%s' } }", ft, table.concat(supported_formatters, "│")),
-    })
-  end
-
   return section
 end
 
-local function get_linter_suggestion_msg(ft)
-  local config = require "config"
-  local null_linters = require "lsp.null-ls.linters"
+local function make_linters_info(ft)
+  local null_linters = require "lvim.lsp.null-ls.linters"
   local supported_linters = null_linters.list_available(ft)
+  local registered_linters = null_linters.list_registered_providers(ft)
   local section = {
-    " HINT ",
-    "",
-    fmt("* List of supported linters: %s", str_list(supported_linters)),
+    "Linters info",
+    fmt(
+      "* Active: %s%s",
+      table.concat(registered_linters, "  , "),
+      vim.tbl_count(registered_linters) > 0 and "  " or ""
+    ),
+    fmt("* Supported: %s", str_list(supported_linters)),
   }
 
-  if not vim.tbl_isempty(supported_linters) then
-    vim.list_extend(section, {
-      "* Configured linter needs to be installed and executable.",
-      fmt("* Enable installed linter(s) with following config in %s", config.path),
-      "",
-      fmt("  lvim.lang.%s.linters = { { exe = '%s' } }", ft, table.concat(supported_linters, "│")),
-    })
-  end
-
   return section
 end
 
@@ -72,13 +62,15 @@ local function make_client_info(client)
   local name = client.name
   local id = client.id
   local document_formatting = client.resolved_capabilities.document_formatting
+  local attached_buffers_list = table.concat(vim.lsp.get_buffers_by_client_id(client.id), ", ")
   local client_info = {
-    fmt("* Name:                 %s", name),
-    fmt("* Id:                   %s", tostring(id)),
-    fmt("* Supports formatting:  %s", tostring(document_formatting)),
+    fmt("* Name:                      %s", name),
+    fmt("* Id:                        [%s]", tostring(id)),
+    fmt("* Attached buffers:          [%s]", tostring(attached_buffers_list)),
+    fmt("* Supports formatting:       %s", tostring(document_formatting)),
   }
   if not vim.tbl_isempty(client_enabled_caps) then
-    local caps_text = "* Capabilities list:    "
+    local caps_text = "* Capabilities list:         "
     local caps_text_len = caps_text:len()
     local enabled_caps = text.format_table(client_enabled_caps, 3, " | ")
     enabled_caps = text.shift_right(enabled_caps, caps_text_len)
@@ -92,10 +84,24 @@ end
 function M.toggle_popup(ft)
   local clients = lsp_utils.get_active_clients_by_ft(ft)
   local client_names = {}
-
+  local bufnr = vim.api.nvim_get_current_buf()
+  local ts_active_buffers = vim.tbl_keys(vim.treesitter.highlighter.active)
+  local is_treesitter_active = function()
+    local status = "inactive"
+    if vim.tbl_contains(ts_active_buffers, bufnr) then
+      status = "active"
+    end
+    return status
+  end
   local header = {
-    fmt("Detected filetype:      %s", ft),
-    fmt("Treesitter active:      %s", tostring(next(vim.treesitter.highlighter.active) ~= nil)),
+    fmt("Detected filetype:           %s", ft),
+    fmt("Current buffer number:       [%s]", bufnr),
+  }
+
+  local ts_info = {
+    "Treesitter info",
+    fmt("* current buffer:            %s", is_treesitter_active()),
+    fmt("* list:                      [%s]", table.concat(ts_active_buffers, ", ")),
   }
 
   local lsp_info = {
@@ -108,22 +114,9 @@ function M.toggle_popup(ft)
     table.insert(client_names, client.name)
   end
 
-  local null_formatters = require "lsp.null-ls.formatters"
-  local null_linters = require "lsp.null-ls.linters"
-  local registered_formatters = null_formatters.list_supported_names(ft)
-  local registered_linters = null_linters.list_supported_names(ft)
-  local registered_providers = {}
-  vim.list_extend(registered_providers, registered_formatters)
-  vim.list_extend(registered_providers, registered_linters)
-  local registered_count = vim.tbl_count(registered_providers)
-  local null_ls_info = {
-    "Formatters and linters",
-    fmt(
-      "* Configured providers: %s%s",
-      table.concat(registered_providers, "  , "),
-      registered_count > 0 and "  " or ""
-    ),
-  }
+  local formatters_info = make_formatters_info(ft)
+
+  local linters_info = make_linters_info(ft)
 
   local content_provider = function(popup)
     local content = {}
@@ -134,15 +127,13 @@ function M.toggle_popup(ft)
       { "" },
       header,
       { "" },
-      lsp_info,
-      { "" },
-      null_ls_info,
+      ts_info,
       { "" },
+      lsp_info,
       { "" },
-      get_formatter_suggestion_msg(ft),
-      { "" },
+      formatters_info,
       { "" },
-      get_linter_suggestion_msg(ft),
+      linters_info,
     } do
       vim.list_extend(content, section)
     end
@@ -153,17 +144,22 @@ function M.toggle_popup(ft)
   local function set_syntax_hl()
     vim.cmd [[highlight LvimInfoIdentifier gui=bold]]
     vim.cmd [[highlight link LvimInfoHeader Type]]
+    vim.cmd [[let m=matchadd("LvimInfoHeader", "Treesitter info")]]
     vim.cmd [[let m=matchadd("LvimInfoHeader", "Language Server Protocol (LSP) info")]]
-    vim.cmd [[let m=matchadd("LvimInfoHeader", "Formatters and linters")]]
+    vim.cmd [[let m=matchadd("LvimInfoHeader", "Formatters info")]]
+    vim.cmd [[let m=matchadd("LvimInfoHeader", "Linters info")]]
     vim.cmd('let m=matchadd("LvimInfoIdentifier", " ' .. ft .. '$")')
     vim.cmd 'let m=matchadd("string", "true")'
+    vim.cmd 'let m=matchadd("string", "active")'
+    vim.cmd 'let m=matchadd("boolean", "inactive")'
+    vim.cmd 'let m=matchadd("string", "")'
     vim.cmd 'let m=matchadd("error", "false")'
-    tbl_set_highlight(registered_providers, "LvimInfoIdentifier")
-    -- tbl_set_highlight(require("lsp.null-ls.formatters").list_available(ft), "LvimInfoIdentifier")
-    -- tbl_set_highlight(require("lsp.null-ls.linters").list_available(ft), "LvimInfoIdentifier")
+    -- tbl_set_highlight(registered_providers, "LvimInfoIdentifier")
+    tbl_set_highlight(require("lvim.lsp.null-ls.formatters").list_available(ft), "LvimInfoIdentifier")
+    tbl_set_highlight(require("lvim.lsp.null-ls.linters").list_available(ft), "LvimInfoIdentifier")
   end
 
-  local Popup = require("interface.popup"):new {
+  local Popup = require("lvim.interface.popup"):new {
     win_opts = { number = false },
     buf_opts = { modifiable = false, filetype = "lspinfo" },
   }

+ 161 - 0
lua/lvim/core/log.lua

@@ -0,0 +1,161 @@
+local Log = {}
+
+local logfile = string.format("%s/%s.log", vim.fn.stdpath "cache", "lvim")
+
+Log.levels = {
+  TRACE = 1,
+  DEBUG = 2,
+  INFO = 3,
+  WARN = 4,
+  ERROR = 5,
+}
+
+vim.tbl_add_reverse_lookup(Log.levels)
+
+function Log:init()
+  local status_ok, structlog = pcall(require, "structlog")
+  if not status_ok then
+    return nil
+  end
+
+  local nvim_notify_params = {}
+  local nvim_notify_params_injecter = function(_, entry)
+    for key, value in pairs(nvim_notify_params) do
+      entry[key] = value
+    end
+    return entry
+  end
+
+  local nvim_notify_default_namer = function(logger, entry)
+    entry["title"] = logger.name
+    return entry
+  end
+
+  nvim_notify_params_injecter(nil, {})
+  local log_level = Log.levels[(lvim.log.level):upper() or "WARN"]
+  structlog.configure {
+    lvim = {
+      sinks = {
+        structlog.sinks.Console(log_level, {
+          async = false,
+          processors = {
+            structlog.processors.Namer(),
+            structlog.processors.StackWriter({ "line", "file" }, { max_parents = 0, stack_level = 2 }),
+            structlog.processors.Timestamper "%H:%M:%S",
+          },
+          formatter = structlog.formatters.FormatColorizer( --
+            "%s [%-5s] %s: %-30s",
+            { "timestamp", "level", "logger_name", "msg" },
+            { level = structlog.formatters.FormatColorizer.color_level() }
+          ),
+        }),
+        structlog.sinks.NvimNotify(Log.levels.INFO, {
+          processors = {
+            nvim_notify_default_namer,
+            nvim_notify_params_injecter,
+          },
+          formatter = structlog.formatters.Format( --
+            "%s",
+            { "msg" },
+            { blacklist_all = true }
+          ),
+          params_map = {
+            icon = "icon",
+            keep = "keep",
+            on_open = "on_open",
+            on_close = "on_close",
+            timeout = "timeout",
+            title = "title",
+          },
+        }),
+        structlog.sinks.File(Log.levels.TRACE, logfile, {
+          processors = {
+            structlog.processors.Namer(),
+            structlog.processors.StackWriter({ "line", "file" }, { max_parents = 3, stack_level = 2 }),
+            structlog.processors.Timestamper "%H:%M:%S",
+          },
+          formatter = structlog.formatters.Format( --
+            "%s [%-5s] %s: %-30s",
+            { "timestamp", "level", "logger_name", "msg" }
+          ),
+        }),
+      },
+    },
+  }
+
+  local logger = structlog.get_logger "lvim"
+
+  if lvim.log.override_notify then
+    -- Overwrite vim.notify to use the logger
+    vim.notify = function(msg, vim_log_level, opts)
+      nvim_notify_params = opts or {}
+      -- https://github.com/neovim/neovim/blob/685cf398130c61c158401b992a1893c2405cd7d2/runtime/lua/vim/lsp/log.lua#L5
+      logger:log(vim_log_level + 1, msg)
+    end
+  end
+
+  return logger
+end
+
+--- Adds a log entry using Plenary.log
+---@fparam msg any
+---@param level string [same as vim.log.log_levels]
+function Log:add_entry(level, msg, event)
+  if self.__handle then
+    self.__handle:log(level, msg, event)
+    return
+  end
+
+  local logger = self:init()
+  if not logger then
+    return
+  end
+
+  self.__handle = logger
+  self.__handle:log(level, msg, event)
+end
+
+---Retrieves the path of the logfile
+---@return string path of the logfile
+function Log:get_path()
+  return logfile
+end
+
+---Add a log entry at TRACE level
+---@param msg any
+---@param event any
+function Log:trace(msg, event)
+  self:add_entry(self.levels.TRACE, msg, event)
+end
+
+---Add a log entry at DEBUG level
+---@param msg any
+---@param event any
+function Log:debug(msg, event)
+  self:add_entry(self.levels.DEBUG, msg, event)
+end
+
+---Add a log entry at INFO level
+---@param msg any
+---@param event any
+function Log:info(msg, event)
+  self:add_entry(self.levels.INFO, msg, event)
+end
+
+---Add a log entry at WARN level
+---@param msg any
+---@param event any
+function Log:warn(msg, event)
+  self:add_entry(self.levels.WARN, msg, event)
+end
+
+---Add a log entry at ERROR level
+---@param msg any
+---@param event any
+function Log:error(msg, event)
+  self:add_entry(self.levels.ERROR, msg, event)
+end
+
+setmetatable({}, Log)
+
+return Log

+ 0 - 0
lua/core/lualine/colors.lua → lua/lvim/core/lualine/colors.lua


+ 7 - 7
lua/core/lualine/components.lua → lua/lvim/core/lualine/components.lua

@@ -1,5 +1,5 @@
-local conditions = require "core.lualine.conditions"
-local colors = require "core.lualine.colors"
+local conditions = require "lvim.core.lualine.conditions"
+local colors = require "lvim.core.lualine.colors"
 
 local function diff_source()
   local gitsigns = vim.b.gitsigns_status_dict
@@ -46,7 +46,7 @@ return {
   },
   python_env = {
     function()
-      local utils = require "core.lualine.utils"
+      local utils = require "lvim.core.lualine.utils"
       if vim.bo.filetype == "python" then
         local venv = os.getenv "CONDA_DEFAULT_ENV"
         if venv then
@@ -103,13 +103,13 @@ return {
       end
 
       -- add formatter
-      local formatters = require "lsp.null-ls.formatters"
-      local supported_formatters = formatters.list_supported_names(buf_ft)
+      local formatters = require "lvim.lsp.null-ls.formatters"
+      local supported_formatters = formatters.list_registered_providers(buf_ft)
       vim.list_extend(buf_client_names, supported_formatters)
 
       -- add linter
-      local linters = require "lsp.null-ls.linters"
-      local supported_linters = linters.list_supported_names(buf_ft)
+      local linters = require "lvim.lsp.null-ls.linters"
+      local supported_linters = linters.list_registered_providers(buf_ft)
       vim.list_extend(buf_client_names, supported_linters)
 
       return table.concat(buf_client_names, ", ")

+ 0 - 0
lua/core/lualine/conditions.lua → lua/lvim/core/lualine/conditions.lua


+ 2 - 2
lua/core/lualine/init.lua → lua/lvim/core/lualine/init.lua

@@ -33,8 +33,8 @@ M.config = function()
 end
 
 M.setup = function()
-  require("core.lualine.styles").update()
-  require("core.lualine.utils").validate_theme()
+  require("lvim.core.lualine.styles").update()
+  require("lvim.core.lualine.utils").validate_theme()
 
   local lualine = require "lualine"
   lualine.setup(lvim.builtin.lualine)

+ 2 - 2
lua/core/lualine/styles.lua → lua/lvim/core/lualine/styles.lua

@@ -1,5 +1,5 @@
 local M = {}
-local components = require "core.lualine.components"
+local components = require "lvim.core.lualine.components"
 
 local styles = {
   lvim = nil,
@@ -111,7 +111,7 @@ styles.lvim = {
 function M.get_style(style)
   local style_keys = vim.tbl_keys(styles)
   if not vim.tbl_contains(style_keys, style) then
-    local Log = require "core.log"
+    local Log = require "lvim.core.log"
     Log:error(
       "Invalid lualine style",
       string.format('"%s"', style),

+ 0 - 0
lua/core/lualine/utils.lua → lua/lvim/core/lualine/utils.lua


+ 19 - 11
lua/core/nvimtree.lua → lua/lvim/core/nvimtree.lua

@@ -1,18 +1,26 @@
 local M = {}
-local Log = require "core.log"
+local Log = require "lvim.core.log"
 
 function M.config()
   lvim.builtin.nvimtree = {
     active = true,
     on_config_done = nil,
     setup = {
-      open_on_setup = 0,
-      auto_close = 1,
-      open_on_tab = 0,
+      open_on_setup = false,
+      auto_close = true,
+      open_on_tab = false,
       update_focused_file = {
-        enable = 1,
+        enable = true,
+      },
+      diagnostics = {
+        enable = true,
+        icons = {
+          hint = "",
+          info = "",
+          warning = "",
+          error = "",
+        },
       },
-      lsp_diagnostics = 1,
       view = {
         width = 30,
         side = "left",
@@ -74,10 +82,10 @@ function M.setup()
   -- Implicitly update nvim-tree when project module is active
   if lvim.builtin.project.active then
     lvim.builtin.nvimtree.respect_buf_cwd = 1
-    lvim.builtin.nvimtree.setup.update_cwd = 1
-    lvim.builtin.nvimtree.setup.disable_netrw = 0
-    lvim.builtin.nvimtree.setup.hijack_netrw = 0
-    vim.g.netrw_banner = 0
+    lvim.builtin.nvimtree.setup.update_cwd = true
+    lvim.builtin.nvimtree.setup.disable_netrw = false
+    lvim.builtin.nvimtree.setup.hijack_netrw = false
+    vim.g.netrw_banner = false
   end
 
   local tree_cb = nvim_tree_config.nvim_tree_callback
@@ -101,7 +109,7 @@ function M.setup()
     open()
   end
 
-  vim.cmd "au WinClosed * lua require('core.nvimtree').on_close()"
+  vim.cmd "au WinClosed * lua require('lvim.core.nvimtree').on_close()"
 
   if lvim.builtin.nvimtree.on_config_done then
     lvim.builtin.nvimtree.on_config_done(nvim_tree_config)

+ 0 - 0
lua/core/project.lua → lua/lvim/core/project.lua


+ 134 - 0
lua/lvim/core/telescope.lua

@@ -0,0 +1,134 @@
+local M = {}
+
+function M.config()
+  -- Define this minimal config so that it's available if telescope is not yet available.
+  lvim.builtin.telescope = {
+    ---@usage disable telescope completely [not recommeded]
+    active = true,
+    on_config_done = nil,
+  }
+
+  lvim.builtin.telescope = vim.tbl_extend("force", lvim.builtin.telescope, {
+    defaults = {
+      prompt_prefix = " ",
+      selection_caret = " ",
+      entry_prefix = "  ",
+      initial_mode = "insert",
+      selection_strategy = "reset",
+      sorting_strategy = "descending",
+      layout_strategy = "horizontal",
+      layout_config = {
+        width = 0.75,
+        preview_cutoff = 120,
+        horizontal = { mirror = false },
+        vertical = { mirror = false },
+      },
+      vimgrep_arguments = {
+        "rg",
+        "--color=never",
+        "--no-heading",
+        "--with-filename",
+        "--line-number",
+        "--column",
+        "--smart-case",
+        "--hidden",
+      },
+      file_ignore_patterns = {},
+      path_display = { shorten = 5 },
+      winblend = 0,
+      border = {},
+      borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" },
+      color_devicons = true,
+      set_env = { ["COLORTERM"] = "truecolor" }, -- default = nil,
+      pickers = {
+        find_files = {
+          find_command = { "fd", "--type=file", "--hidden", "--smart-case" },
+        },
+        live_grep = {
+          --@usage don't include the filename in the search results
+          only_sort_text = true,
+        },
+      },
+    },
+    extensions = {
+      fzf = {
+        fuzzy = true, -- false will only do exact matching
+        override_generic_sorter = true, -- override the generic sorter
+        override_file_sorter = true, -- override the file sorter
+        case_mode = "smart_case", -- or "ignore_case" or "respect_case"
+      },
+    },
+  })
+end
+
+function M.code_actions()
+  local opts = {
+    winblend = 15,
+    layout_config = {
+      prompt_position = "top",
+      width = 80,
+      height = 12,
+    },
+    borderchars = {
+      prompt = { "─", "│", " ", "│", "╭", "╮", "│", "│" },
+      results = { "─", "│", "─", "│", "├", "┤", "╯", "╰" },
+      preview = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" },
+    },
+    border = {},
+    previewer = false,
+    shorten_path = false,
+  }
+  local builtin = require "telescope.builtin"
+  local themes = require "telescope.themes"
+  builtin.lsp_code_actions(themes.get_dropdown(opts))
+end
+
+function M.setup()
+  local previewers = require "telescope.previewers"
+  local sorters = require "telescope.sorters"
+  local actions = require "telescope.actions"
+
+  lvim.builtin.telescope = vim.tbl_extend("keep", {
+    file_previewer = previewers.vim_buffer_cat.new,
+    grep_previewer = previewers.vim_buffer_vimgrep.new,
+    qflist_previewer = previewers.vim_buffer_qflist.new,
+    file_sorter = sorters.get_fuzzy_file,
+    generic_sorter = sorters.get_generic_fuzzy_sorter,
+    ---@usage Mappings are fully customizable. Many familiar mapping patterns are setup as defaults.
+    mappings = {
+      i = {
+        ["<C-n>"] = actions.move_selection_next,
+        ["<C-p>"] = actions.move_selection_previous,
+        ["<C-c>"] = actions.close,
+        ["<C-j>"] = actions.cycle_history_next,
+        ["<C-k>"] = actions.cycle_history_prev,
+        ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,
+        ["<CR>"] = actions.select_default + actions.center,
+      },
+      n = {
+        ["<C-n>"] = actions.move_selection_next,
+        ["<C-p>"] = actions.move_selection_previous,
+        ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,
+      },
+    },
+  }, lvim.builtin.telescope)
+
+  local telescope = require "telescope"
+  telescope.setup(lvim.builtin.telescope)
+
+  if lvim.builtin.project.active then
+    pcall(function()
+      require("telescope").load_extension "projects"
+    end)
+  end
+
+  if lvim.builtin.telescope.on_config_done then
+    lvim.builtin.telescope.on_config_done(telescope)
+  end
+
+  if lvim.builtin.telescope.extensions and lvim.builtin.telescope.extensions.fzf then
+    require("telescope").load_extension "fzf"
+  end
+end
+
+return M

+ 80 - 0
lua/lvim/core/telescope/custom-finders.lua

@@ -0,0 +1,80 @@
+local M = {}
+
+local _, builtin = pcall(require, "telescope.builtin")
+local _, finders = pcall(require, "telescope.finders")
+local _, pickers = pcall(require, "telescope.pickers")
+local _, sorters = pcall(require, "telescope.sorters")
+local _, themes = pcall(require, "telescope.themes")
+local _, actions = pcall(require, "telescope.actions")
+local _, previewers = pcall(require, "telescope.previewers")
+local _, make_entry = pcall(require, "telescope.make_entry")
+
+local utils = require "lvim.utils"
+
+function M.find_lunarvim_files(opts)
+  opts = opts or {}
+  local theme_opts = themes.get_ivy {
+    sorting_strategy = "ascending",
+    layout_strategy = "bottom_pane",
+    prompt_prefix = ">> ",
+    prompt_title = "~ LunarVim files ~",
+    cwd = get_runtime_dir(),
+    search_dirs = { utils.join_paths(get_runtime_dir(), "lvim"), lvim.lsp.templates_dir },
+  }
+  opts = vim.tbl_deep_extend("force", theme_opts, opts)
+  builtin.find_files(opts)
+end
+
+function M.grep_lunarvim_files(opts)
+  opts = opts or {}
+  local theme_opts = themes.get_ivy {
+    sorting_strategy = "ascending",
+    layout_strategy = "bottom_pane",
+    prompt_prefix = ">> ",
+    prompt_title = "~ search LunarVim ~",
+    cwd = get_runtime_dir(),
+    search_dirs = { utils.join_paths(get_runtime_dir(), "lvim"), lvim.lsp.templates_dir },
+  }
+  opts = vim.tbl_deep_extend("force", theme_opts, opts)
+  builtin.live_grep(opts)
+end
+
+function M.view_lunarvim_changelog()
+  local opts = {}
+  opts.entry_maker = make_entry.gen_from_git_commits(opts)
+
+  pickers.new(opts, {
+    prompt_title = "LunarVim changelog",
+
+    finder = finders.new_oneshot_job(
+      vim.tbl_flatten {
+        "git",
+        "log",
+        "--pretty=oneline",
+        "--abbrev-commit",
+        "--",
+        ".",
+      },
+      opts
+    ),
+    previewer = {
+      previewers.git_commit_diff_to_parent.new(opts),
+      previewers.git_commit_diff_to_head.new(opts),
+      previewers.git_commit_diff_as_was.new(opts),
+      previewers.git_commit_message.new(opts),
+    },
+
+    --TODO: consider opening a diff view when pressing enter
+    attach_mappings = function(_, map)
+      map("i", "<enter>", actions._close)
+      map("n", "<enter>", actions._close)
+      map("i", "<esc>", actions._close)
+      map("n", "<esc>", actions._close)
+      map("n", "q", actions._close)
+      return true
+    end,
+    sorter = sorters.generic_sorter,
+  }):find()
+end
+
+return M

+ 3 - 3
lua/core/terminal.lua → lua/lvim/core/terminal.lua

@@ -1,5 +1,5 @@
 local M = {}
-local Log = require "core.log"
+local Log = require "lvim.core.log"
 
 M.config = function()
   lvim.builtin["terminal"] = {
@@ -48,7 +48,7 @@ end
 M.setup = function()
   local terminal = require "toggleterm"
   for _, exec in pairs(lvim.builtin.terminal.execs) do
-    require("core.terminal").add_exec(exec[1], exec[2], exec[3])
+    require("lvim.core.terminal").add_exec(exec[1], exec[2], exec[3])
   end
   terminal.setup(lvim.builtin.terminal)
 
@@ -61,7 +61,7 @@ M.add_exec = function(exec, keymap, name)
   vim.api.nvim_set_keymap(
     "n",
     "<leader>" .. keymap,
-    "<cmd>lua require('core.terminal')._exec_toggle('" .. exec .. "')<CR>",
+    "<cmd>lua require('lvim.core.terminal')._exec_toggle('" .. exec .. "')<CR>",
     { noremap = true, silent = true }
   )
   lvim.builtin.which_key.mappings[keymap] = name

+ 1 - 1
lua/core/treesitter.lua → lua/lvim/core/treesitter.lua

@@ -1,5 +1,5 @@
 local M = {}
-local Log = require "core.log"
+local Log = require "lvim.core.log"
 
 M.config = function()
   lvim.builtin.treesitter = {

+ 21 - 18
lua/core/which-key.lua → lua/lvim/core/which-key.lua

@@ -61,12 +61,12 @@ M.config = function()
     -- NOTE: Prefer using : over <cmd> as the latter avoids going back in normal-mode.
     -- see https://neovim.io/doc/user/map.html#:map-cmd
     vmappings = {
-      ["/"] = { ":CommentToggle<CR>", "Comment" },
+      ["/"] = { "<ESC><CMD>lua ___comment_gc(vim.fn.visualmode())<CR>", "Comment" },
     },
     mappings = {
       ["w"] = { "<cmd>w!<CR>", "Save" },
       ["q"] = { "<cmd>q!<CR>", "Quit" },
-      ["/"] = { "<cmd>CommentToggle<CR>", "Comment" },
+      ["/"] = { "<cmd>lua require('Comment').toggle()<CR>", "Comment" },
       ["c"] = { "<cmd>BufferClose!<CR>", "Close Buffer" },
       ["f"] = { "<cmd>Telescope find_files<CR>", "Find File" },
       ["h"] = { "<cmd>nohlsearch<CR>", "No Highlight" },
@@ -98,7 +98,7 @@ M.config = function()
         name = "Packer",
         c = { "<cmd>PackerCompile<cr>", "Compile" },
         i = { "<cmd>PackerInstall<cr>", "Install" },
-        r = { "<cmd>lua require('utils').reload_lv_config()<cr>", "Reload" },
+        r = { "<cmd>lua require('lvim.utils').reload_lv_config()<cr>", "Reload" },
         s = { "<cmd>PackerSync<cr>", "Sync" },
         S = { "<cmd>PackerStatus<cr>", "Status" },
         u = { "<cmd>PackerUpdate<cr>", "Update" },
@@ -139,7 +139,7 @@ M.config = function()
 
       l = {
         name = "LSP",
-        a = { "<cmd>lua require('core.telescope').code_actions()<cr>", "Code Action" },
+        a = { "<cmd>lua require('lvim.core.telescope').code_actions()<cr>", "Code Action" },
         d = {
           "<cmd>Telescope lsp_document_diagnostics<cr>",
           "Document Diagnostics",
@@ -162,9 +162,9 @@ M.config = function()
         l = { "<cmd>lua vim.lsp.codelens.run()<cr>", "CodeLens Action" },
         p = {
           name = "Peek",
-          d = { "<cmd>lua require('lsp.peek').Peek('definition')<cr>", "Definition" },
-          t = { "<cmd>lua require('lsp.peek').Peek('typeDefinition')<cr>", "Type Definition" },
-          i = { "<cmd>lua require('lsp.peek').Peek('implementation')<cr>", "Implementation" },
+          d = { "<cmd>lua require('lvim.lsp.peek').Peek('definition')<cr>", "Definition" },
+          t = { "<cmd>lua require('lvim.lsp.peek').Peek('typeDefinition')<cr>", "Type Definition" },
+          i = { "<cmd>lua require('lvim.lsp.peek').Peek('implementation')<cr>", "Implementation" },
         },
         q = { "<cmd>lua vim.lsp.diagnostic.set_loclist()<cr>", "Quickfix" },
         r = { "<cmd>lua vim.lsp.buf.rename()<cr>", "Rename" },
@@ -181,43 +181,46 @@ M.config = function()
           "Edit config.lua",
         },
         f = {
-          "<cmd>lua require('core.telescope').find_lunarvim_files()<cr>",
+          "<cmd>lua require('lvim.core.telescope.custom-finders').find_lunarvim_files()<cr>",
           "Find LunarVim files",
         },
         g = {
-          "<cmd>lua require('core.telescope').grep_lunarvim_files()<cr>",
+          "<cmd>lua require('lvim.core.telescope.custom-finders').grep_lunarvim_files()<cr>",
           "Grep LunarVim files",
         },
-        k = { "<cmd>lua require('keymappings').print()<cr>", "View LunarVim's default keymappings" },
+        k = { "<cmd>lua require('lvim.keymappings').print()<cr>", "View LunarVim's default keymappings" },
         i = {
-          "<cmd>lua require('core.info').toggle_popup(vim.bo.filetype)<cr>",
+          "<cmd>lua require('lvim.core.info').toggle_popup(vim.bo.filetype)<cr>",
           "Toggle LunarVim Info",
         },
         I = {
-          "<cmd>lua require('core.telescope').view_lunarvim_changelog()<cr>",
+          "<cmd>lua require('lvim.core.telescope.custom-finders').view_lunarvim_changelog()<cr>",
           "View LunarVim's changelog",
         },
         l = {
           name = "+logs",
           d = {
-            "<cmd>lua require('core.terminal').toggle_log_view(require('core.log').get_path())<cr>",
+            "<cmd>lua require('lvim.core.terminal').toggle_log_view(require('lvim.core.log').get_path())<cr>",
             "view default log",
           },
-          D = { "<cmd>lua vim.fn.execute('edit ' .. require('core.log').get_path())<cr>", "Open the default logfile" },
-          l = { "<cmd>lua require('core.terminal').toggle_log_view(vim.lsp.get_log_path())<cr>", "view lsp log" },
+          D = {
+            "<cmd>lua vim.fn.execute('edit ' .. require('lvim.core.log').get_path())<cr>",
+            "Open the default logfile",
+          },
+          l = { "<cmd>lua require('lvim.core.terminal').toggle_log_view(vim.lsp.get_log_path())<cr>", "view lsp log" },
           L = { "<cmd>lua vim.fn.execute('edit ' .. vim.lsp.get_log_path())<cr>", "Open the LSP logfile" },
           n = {
-            "<cmd>lua require('core.terminal').toggle_log_view(os.getenv('NVIM_LOG_FILE'))<cr>",
+            "<cmd>lua require('lvim.core.terminal').toggle_log_view(os.getenv('NVIM_LOG_FILE'))<cr>",
             "view neovim log",
           },
           N = { "<cmd>edit $NVIM_LOG_FILE<cr>", "Open the Neovim logfile" },
           p = {
-            "<cmd>lua require('core.terminal').toggle_log_view('packer.nvim')<cr>",
+            "<cmd>lua require('lvim.core.terminal').toggle_log_view('packer.nvim')<cr>",
             "view packer log",
           },
           P = { "<cmd>exe 'edit '.stdpath('cache').'/packer.nvim.log'<cr>", "Open the Packer logfile" },
         },
-        r = { "<cmd>lua require('utils').reload_lv_config()<cr>", "Reload configurations" },
+        r = { "<cmd>lua require('lvim.utils').reload_lv_config()<cr>", "Reload configurations" },
         u = { "<cmd>LvimUpdate<cr>", "Update LunarVim" },
       },
       s = {

+ 2 - 2
lua/impatient.lua → lua/lvim/impatient.lua

@@ -121,12 +121,12 @@ end
 function M.enable_profile()
   M.profile = {}
   M.print_profile = function()
-    M.profile["impatient"] = {
+    M.profile["lvim.impatient"] = {
       resolve = 0,
       load = impatient_dur,
       loader = "standard",
     }
-    require("impatient.profile").print_profile(M.profile)
+    require("lvim.impatient.profile").print_profile(M.profile)
   end
   vim.cmd [[command! LuaCacheProfile lua _G.__luacache.print_profile()]]
 end

+ 0 - 0
lua/impatient/profile.lua → lua/lvim/impatient/profile.lua


+ 0 - 0
lua/interface/popup.lua → lua/lvim/interface/popup.lua


+ 0 - 0
lua/interface/text.lua → lua/lvim/interface/text.lua


+ 1 - 5
lua/keymappings.lua → lua/lvim/keymappings.lua

@@ -1,5 +1,5 @@
 local M = {}
-local Log = require "core.log"
+local Log = require "lvim.core.log"
 
 local generic_opts_any = { noremap = true, silent = true }
 
@@ -81,10 +81,6 @@ function M.config()
       ["<A-Down>"] = "<C-\\><C-N><C-w>j",
       ["<A-Left>"] = "<C-\\><C-N><C-w>h",
       ["<A-Right>"] = "<C-\\><C-N><C-w>l",
-      -- navigate tab completion with <c-j> and <c-k>
-      -- runs conditionally
-      ["<C-j>"] = { 'pumvisible() ? "\\<down>" : "\\<C-j>"', { expr = true, noremap = true } },
-      ["<C-k>"] = { 'pumvisible() ? "\\<up>" : "\\<C-k>"', { expr = true, noremap = true } },
     },
 
     ---@usage change or add keymappings for normal mode

+ 2 - 2
lua/lsp/config.lua → lua/lvim/lsp/config.lua

@@ -30,9 +30,9 @@ return {
       ["gr"] = { "<cmd>lua vim.lsp.buf.references()<CR>", "Goto references" },
       ["gI"] = { "<cmd>lua vim.lsp.buf.implementation()<CR>", "Goto Implementation" },
       ["gs"] = { "<cmd>lua vim.lsp.buf.signature_help()<CR>", "show signature help" },
-      ["gp"] = { "<cmd>lua require'lsp.peek'.Peek('definition')<CR>", "Peek definition" },
+      ["gp"] = { "<cmd>lua require'lvim.lsp.peek'.Peek('definition')<CR>", "Peek definition" },
       ["gl"] = {
-        "<cmd>lua require'lsp.handlers'.show_line_diagnostics()<CR>",
+        "<cmd>lua require'lvim.lsp.handlers'.show_line_diagnostics()<CR>",
         "Show line diagnostics",
       },
     },

+ 0 - 0
lua/lsp/handlers.lua → lua/lvim/lsp/handlers.lua


+ 9 - 10
lua/lsp/init.lua → lua/lvim/lsp/init.lua

@@ -1,6 +1,6 @@
 local M = {}
-local Log = require "core.log"
-local utils = require "utils"
+local Log = require "lvim.core.log"
+local utils = require "lvim.utils"
 
 local function lsp_highlight_document(client)
   if lvim.lsp.document_highlight == false then
@@ -86,15 +86,14 @@ function M.common_capabilities()
 end
 
 local function select_default_formater(client)
-  local client_formatting = client.resolved_capabilities.document_formatting
-    or client.resolved_capabilities.document_range_formatting
-  if client.name == "null-ls" or not client_formatting then
+  if client.name == "null-ls" or not client.resolved_capabilities.document_formatting then
     return
   end
   Log:debug("Checking for formatter overriding for " .. client.name)
+  local formatters = require "lvim.lsp.null-ls.formatters"
   local client_filetypes = client.config.filetypes or {}
   for _, filetype in ipairs(client_filetypes) do
-    if lvim.lang[filetype] and #vim.tbl_keys(lvim.lang[filetype].formatters) > 0 then
+    if #vim.tbl_keys(formatters.list_registered_providers(filetype)) > 0 then
       Log:debug("Formatter overriding detected. Disabling formatting capabilities for " .. client.name)
       client.resolved_capabilities.document_formatting = false
       client.resolved_capabilities.document_range_formatting = false
@@ -149,17 +148,17 @@ function M.setup()
     vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name })
   end
 
-  require("lsp.handlers").setup()
+  require("lvim.lsp.handlers").setup()
 
   if not utils.is_directory(lvim.lsp.templates_dir) then
-    require("lsp.templates").generate_templates()
+    require("lvim.lsp.templates").generate_templates()
   end
 
   bootstrap_nlsp { config_home = utils.join_paths(get_config_dir(), "lsp-settings") }
 
-  require("lsp.null-ls").setup()
+  require("lvim.lsp.null-ls").setup()
 
-  require("utils").toggle_autoformat()
+  require("lvim.utils").toggle_autoformat()
 end
 
 return M

+ 6 - 6
lua/lsp/manager.lua → lua/lvim/lsp/manager.lua

@@ -1,7 +1,7 @@
 local M = {}
 
-local Log = require "core.log"
-local lsp_utils = require "lsp.utils"
+local Log = require "lvim.core.log"
+local lsp_utils = require "lvim.lsp.utils"
 
 function M.init_defaults(languages)
   for _, entry in ipairs(languages) do
@@ -30,12 +30,12 @@ end
 ---@return table
 local function resolve_config(name, user_config)
   local config = {
-    on_attach = require("lsp").common_on_attach,
-    on_init = require("lsp").common_on_init,
-    capabilities = require("lsp").common_capabilities(),
+    on_attach = require("lvim.lsp").common_on_attach,
+    on_init = require("lvim.lsp").common_on_init,
+    capabilities = require("lvim.lsp").common_capabilities(),
   }
 
-  local status_ok, custom_config = pcall(require, "lsp/providers/" .. name)
+  local status_ok, custom_config = pcall(require, "lvim.lsp/providers/" .. name)
   if status_ok then
     Log:debug("Using custom configuration for requested server: " .. name)
     config = vim.tbl_deep_extend("force", config, custom_config)

+ 4 - 4
lua/lsp/null-ls/formatters.lua → lua/lvim/lsp/null-ls/formatters.lua

@@ -1,10 +1,10 @@
 local M = {}
 
 local null_ls = require "null-ls"
-local services = require "lsp.null-ls.services"
-local Log = require "core.log"
+local services = require "lvim.lsp.null-ls.services"
+local Log = require "lvim.core.log"
 
-function M.list_supported_names(filetype)
+function M.list_registered_providers(filetype)
   local null_ls_methods = require "null-ls.methods"
   local formatter_method = null_ls_methods.internal["FORMATTING"]
   local registered_providers = services.list_registered_providers_names(filetype)
@@ -13,7 +13,7 @@ end
 
 function M.list_available(filetype)
   local formatters = {}
-  local tbl = require "utils.table"
+  local tbl = require "lvim.utils.table"
   for _, provider in pairs(null_ls.builtins.formatting) do
     if tbl.contains(provider.filetypes or {}, function(ft)
       return ft == "*" or ft == filetype

+ 9 - 3
lua/lsp/null-ls/init.lua → lua/lvim/lsp/null-ls/init.lua

@@ -1,8 +1,8 @@
 local M = {}
 
-local Log = require "core.log"
-local formatters = require "lsp.null-ls.formatters"
-local linters = require "lsp.null-ls.linters"
+local Log = require "lvim.core.log"
+local formatters = require "lvim.lsp.null-ls.formatters"
+local linters = require "lvim.lsp.null-ls.linters"
 
 function M:setup()
   local status_ok, null_ls = pcall(require, "null-ls")
@@ -12,6 +12,12 @@ function M:setup()
   end
 
   null_ls.config()
+  local default_opts = require("lvim.lsp").get_common_opts()
+
+  if vim.tbl_isempty(lvim.lsp.null_ls.setup or {}) then
+    lvim.lsp.null_ls.setup = default_opts
+  end
+
   require("lspconfig")["null-ls"].setup(lvim.lsp.null_ls.setup)
   for filetype, config in pairs(lvim.lang) do
     if not vim.tbl_isempty(config.formatters) then

+ 4 - 4
lua/lsp/null-ls/linters.lua → lua/lvim/lsp/null-ls/linters.lua

@@ -1,10 +1,10 @@
 local M = {}
 
 local null_ls = require "null-ls"
-local services = require "lsp.null-ls.services"
-local Log = require "core.log"
+local services = require "lvim.lsp.null-ls.services"
+local Log = require "lvim.core.log"
 
-function M.list_supported_names(filetype)
+function M.list_registered_providers(filetype)
   local null_ls_methods = require "null-ls.methods"
   local linter_method = null_ls_methods.internal["DIAGNOSTICS"]
   local registered_providers = services.list_registered_providers_names(filetype)
@@ -13,7 +13,7 @@ end
 
 function M.list_available(filetype)
   local linters = {}
-  local tbl = require "utils.table"
+  local tbl = require "lvim.utils.table"
   for _, provider in pairs(null_ls.builtins.diagnostics) do
     if tbl.contains(provider.filetypes or {}, function(ft)
       return ft == "*" or ft == filetype

+ 1 - 1
lua/lsp/null-ls/services.lua → lua/lvim/lsp/null-ls/services.lua

@@ -2,7 +2,7 @@ local M = {}
 
 local function find_root_dir()
   local util = require "lspconfig/util"
-  local lsp_utils = require "lsp.utils"
+  local lsp_utils = require "lvim.lsp.utils"
 
   local ts_client = lsp_utils.is_client_active "typescript"
   if ts_client then

+ 1 - 1
lua/lsp/peek.lua → lua/lvim/lsp/peek.lua

@@ -130,7 +130,7 @@ function M.Peek(what)
       M.floating_buf,
       "n",
       "<CR>",
-      ":lua require('lsp.peek').open_file()<CR>",
+      ":lua require('lvim.lsp.peek').open_file()<CR>",
       { noremap = true, silent = true }
     )
   else

+ 0 - 0
lua/lsp/providers/jsonls.lua → lua/lvim/lsp/providers/jsonls.lua


+ 1 - 1
lua/lsp/providers/sumneko_lua.lua → lua/lvim/lsp/providers/sumneko_lua.lua

@@ -6,7 +6,7 @@ local opts = {
       },
       workspace = {
         library = {
-          [require("utils").join_paths(get_runtime_dir(), "lvim", "lua")] = true,
+          [require("lvim.utils").join_paths(get_runtime_dir(), "lvim", "lua")] = true,
           [vim.fn.expand "$VIMRUNTIME/lua"] = true,
           [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true,
         },

+ 1 - 1
lua/lsp/providers/vuels.lua → lua/lvim/lsp/providers/vuels.lua

@@ -1,7 +1,7 @@
 local opts = {
   setup = {
     root_dir = function(fname)
-      local util = require "lspconfig/util"
+      local util = require "lvim.lspconfig/util"
       return util.root_pattern "package.json"(fname) or util.root_pattern "vue.config.js"(fname) or vim.fn.getcwd()
     end,
     init_options = {

+ 0 - 0
lua/lsp/providers/yamlls.lua → lua/lvim/lsp/providers/yamlls.lua


+ 4 - 4
lua/lsp/templates.lua → lua/lvim/lsp/templates.lua

@@ -1,8 +1,8 @@
 local M = {}
 
-local Log = require "core.log"
-local utils = require "utils"
-local get_supported_filetypes = require("lsp.utils").get_supported_filetypes
+local Log = require "lvim.core.log"
+local utils = require "lvim.utils"
+local get_supported_filetypes = require("lvim.lsp.utils").get_supported_filetypes
 
 local ftplugin_dir = lvim.lsp.templates_dir
 
@@ -59,7 +59,7 @@ function M.generate_ftplugin(server_name, dir)
 
   for _, filetype in ipairs(filetypes) do
     local filename = join_paths(dir, filetype .. ".lua")
-    local setup_cmd = string.format([[require("lsp.manager").setup(%q)]], server_name)
+    local setup_cmd = string.format([[require("lvim.lsp.manager").setup(%q)]], server_name)
     -- print("using setup_cmd: " .. setup_cmd)
     -- overwrite the file completely
     utils.write_file(filename, setup_cmd .. "\n", "a")

+ 1 - 1
lua/lsp/utils.lua → lua/lvim/lsp/utils.lua

@@ -1,6 +1,6 @@
 local M = {}
 
-local tbl = require "utils.table"
+local tbl = require "lvim.utils.table"
 
 function M.is_client_active(name)
   local clients = vim.lsp.get_active_clients()

+ 0 - 0
lua/lualine/themes/onedarker.lua → lua/lvim/lualine/themes/onedarker.lua


+ 2 - 2
lua/plugin-loader.lua → lua/lvim/plugin-loader.lua

@@ -1,7 +1,7 @@
 local plugin_loader = {}
 
-local utils = require "utils"
-local Log = require "core.log"
+local utils = require "lvim.utils"
+local Log = require "lvim.core.log"
 -- we need to reuse this outside of init()
 local compile_path = get_config_dir() .. "/plugin/packer_compiled.lua"
 

+ 26 - 18
lua/plugins.lua → lua/lvim/plugins.lua

@@ -8,6 +8,8 @@ return {
   {
     "williamboman/nvim-lsp-installer",
   },
+  { "rcarriga/nvim-notify" },
+  { "Tastyep/structlog.nvim" },
 
   { "nvim-lua/popup.nvim" },
   { "nvim-lua/plenary.nvim" },
@@ -15,15 +17,20 @@ return {
   {
     "nvim-telescope/telescope.nvim",
     config = function()
-      require("core.telescope").setup()
+      require("lvim.core.telescope").setup()
     end,
     disable = not lvim.builtin.telescope.active,
   },
+  {
+    "nvim-telescope/telescope-fzf-native.nvim",
+    run = "make",
+    disable = not lvim.builtin.telescope.active,
+  },
   -- Install nvim-cmp, and buffer source as a dependency
   {
     "hrsh7th/nvim-cmp",
     config = function()
-      require("core.cmp").setup()
+      require("lvim.core.cmp").setup()
     end,
     requires = {
       "L3MON4D3/LuaSnip",
@@ -36,7 +43,7 @@ return {
     run = function()
       -- cmp's config requires cmp to be installed to run the first time
       if not lvim.builtin.cmp then
-        require("core.cmp").config()
+        require("lvim.core.cmp").config()
       end
     end,
   },
@@ -50,9 +57,8 @@ return {
   {
     "windwp/nvim-autopairs",
     -- event = "InsertEnter",
-    after = "nvim-cmp",
     config = function()
-      require("core.autopairs").setup()
+      require("lvim.core.autopairs").setup()
     end,
     disable = not lvim.builtin.autopairs.active,
   },
@@ -63,7 +69,7 @@ return {
     branch = "0.5-compat",
     -- run = ":TSUpdate",
     config = function()
-      require("core.treesitter").setup()
+      require("lvim.core.treesitter").setup()
     end,
   },
 
@@ -74,7 +80,7 @@ return {
     -- cmd = "NvimTreeToggle",
     commit = "edc74ee6c4aebdcbaea092557db372b93929f9d0",
     config = function()
-      require("core.nvimtree").setup()
+      require("lvim.core.nvimtree").setup()
     end,
     disable = not lvim.builtin.nvimtree.active,
   },
@@ -83,17 +89,19 @@ return {
     "lewis6991/gitsigns.nvim",
 
     config = function()
-      require("core.gitsigns").setup()
+      require("lvim.core.gitsigns").setup()
     end,
     event = "BufRead",
     disable = not lvim.builtin.gitsigns.active,
   },
 
   -- Whichkey
+  -- TODO: change back to folke/which-key.nvim after folke got back
   {
-    "folke/which-key.nvim",
+    "abzcoding/which-key.nvim",
+    branch = "fix/neovim-6-position",
     config = function()
-      require("core.which-key").setup()
+      require("lvim.core.which-key").setup()
     end,
     event = "BufWinEnter",
     disable = not lvim.builtin.which_key.active,
@@ -101,10 +109,10 @@ return {
 
   -- Comments
   {
-    "terrortylor/nvim-comment",
+    "numToStr/Comment.nvim",
     event = "BufRead",
     config = function()
-      require("core.comment").setup()
+      require("lvim.core.comment").setup()
     end,
     disable = not lvim.builtin.comment.active,
   },
@@ -113,7 +121,7 @@ return {
   {
     "ahmedkhalf/project.nvim",
     config = function()
-      require("core.project").setup()
+      require("lvim.core.project").setup()
     end,
     disable = not lvim.builtin.project.active,
   },
@@ -127,7 +135,7 @@ return {
     "shadmansaleh/lualine.nvim",
     -- "Lunarvim/lualine.nvim",
     config = function()
-      require("core.lualine").setup()
+      require("lvim.core.lualine").setup()
     end,
     disable = not lvim.builtin.lualine.active,
   },
@@ -135,7 +143,7 @@ return {
   {
     "romgrk/barbar.nvim",
     config = function()
-      require("core.bufferline").setup()
+      require("lvim.core.bufferline").setup()
     end,
     event = "BufWinEnter",
     disable = not lvim.builtin.bufferline.active,
@@ -146,7 +154,7 @@ return {
     "mfussenegger/nvim-dap",
     -- event = "BufWinEnter",
     config = function()
-      require("core.dap").setup()
+      require("lvim.core.dap").setup()
     end,
     disable = not lvim.builtin.dap.active,
   },
@@ -164,7 +172,7 @@ return {
     "ChristianChiarulli/dashboard-nvim",
     event = "BufWinEnter",
     config = function()
-      require("core.dashboard").setup()
+      require("lvim.core.dashboard").setup()
     end,
     disable = not lvim.builtin.dashboard.active,
   },
@@ -174,7 +182,7 @@ return {
     "akinsho/toggleterm.nvim",
     event = "BufWinEnter",
     config = function()
-      require("core.terminal").setup()
+      require("lvim.core.terminal").setup()
     end,
     disable = not lvim.builtin.terminal.active,
   },

+ 0 - 0
lua/utils/ft.lua → lua/lvim/utils/ft.lua


+ 7 - 5
lua/utils/hooks.lua → lua/lvim/utils/hooks.lua

@@ -1,24 +1,26 @@
 local M = {}
 
-local Log = require "core.log"
+local Log = require "lvim.core.log"
 local in_headless = #vim.api.nvim_list_uis() == 0
 
 function M.run_pre_update()
   Log:debug "Starting pre-update hook"
+  _G.__luacache.clear_cache()
 end
 
 ---Reset any startup cache files used by Packer and Impatient
+---It also forces regenerating any template ftplugin files
 ---Tip: Useful for clearing any outdated settings
 function M.reset_cache()
   _G.__luacache.clear_cache()
-  require("plugin-loader"):cache_reset()
+  require("lvim.plugin-loader"):cache_reset()
+  package.loaded["lvim.lsp.templates"] = nil
+  require("lvim.lsp.templates").generate_templates()
 end
 
 function M.run_post_update()
-  M.reset_cache()
   Log:debug "Starting post-update hook"
-  package.loaded["lsp.templates"] = nil
-  require("lsp.templates").generate_templates()
+  M.reset_cache()
 
   if not in_headless then
     vim.schedule(function()

+ 3 - 35
lua/utils/init.lua → lua/lvim/utils/init.lua

@@ -1,5 +1,5 @@
 local utils = {}
-local Log = require "core.log"
+local Log = require "lvim.core.log"
 local uv = vim.loop
 
 -- recursive Print (structure, limit, separator)
@@ -61,7 +61,7 @@ end
 -- autoformat
 function utils.toggle_autoformat()
   if lvim.format_on_save then
-    require("core.autocmds").define_augroups {
+    require("lvim.core.autocmds").define_augroups {
       autoformat = {
         {
           "BufWritePre",
@@ -83,26 +83,6 @@ function utils.toggle_autoformat()
   end
 end
 
-function utils.reload_lv_config()
-  require("core.lualine").config()
-
-  local config = require "config"
-  config:load()
-
-  require("keymappings").setup() -- this should be done before loading the plugins
-  vim.cmd("source " .. utils.join_paths(get_runtime_dir(), "lvim", "lua", "plugins.lua"))
-  local plugins = require "plugins"
-  utils.toggle_autoformat()
-  local plugin_loader = require "plugin-loader"
-  plugin_loader:cache_reset()
-  plugin_loader:load { plugins, lvim.plugins }
-  vim.cmd ":PackerInstall"
-  vim.cmd ":PackerCompile"
-  -- vim.cmd ":PackerClean"
-  require("lsp").setup()
-  Log:info "Reloaded configuration"
-end
-
 function utils.unrequire(m)
   package.loaded[m] = nil
   _G[m] = nil
@@ -147,18 +127,6 @@ function utils.is_directory(path)
   return stat and stat.type == "directory" or false
 end
 
-function utils.write_file(path, txt, flag)
-  uv.fs_open(path, flag, 438, function(open_err, fd)
-    assert(not open_err, open_err)
-    uv.fs_write(fd, txt, -1, function(write_err)
-      assert(not write_err, write_err)
-      uv.fs_close(fd, function(close_err)
-        assert(not close_err, close_err)
-      end)
-    end)
-  end)
-end
-
 utils.join_paths = _G.join_paths
 
 function utils.write_file(path, txt, flag)
@@ -215,7 +183,7 @@ function utils.file_contains(file, query)
 end
 
 function utils.log_contains(query)
-  local logfile = require("core.log"):get_path()
+  local logfile = require("lvim.core.log"):get_path()
   local stdout, ret, stderr = utils.search_file(logfile, query)
   if ret == 0 then
     return true

+ 0 - 0
lua/utils/table.lua → lua/lvim/utils/table.lua


+ 1 - 1
tests/bootstrap_spec.lua

@@ -8,7 +8,7 @@ a.describe("initial start", function()
 
   a.it("shoud be able to detect test environment", function()
     assert.truthy(os.getenv "LVIM_TEST_ENV")
-    assert.falsy(package.loaded["impatient"])
+    assert.falsy(package.loaded["lvim.impatient"])
   end)
 
   a.it("should not be reading default neovim directories in the home directoies", function()

+ 37 - 0
tests/config_loader_spec.lua

@@ -0,0 +1,37 @@
+local a = require "plenary.async_lib.tests"
+local config = require "lvim.config"
+
+a.describe("config-loader", function()
+  local user_config_path = config:get_user_config_path()
+
+  a.it("should be able to find user-config", function()
+    assert.equal(user_config_path, get_config_dir() .. "/config.lua")
+  end)
+
+  a.it("should be able to load user-config without errors", function()
+    config:load(user_config_path)
+    local errmsg = vim.fn.eval "v:errmsg"
+    local exception = vim.fn.eval "v:exception"
+    assert.equal("", errmsg) -- v:errmsg was not updated.
+    assert.equal("", exception)
+  end)
+
+  a.it("should be able to reload user-config without errors", function()
+    vim.opt.undodir = "/tmp"
+    assert.equal(vim.opt.undodir:get()[1], "/tmp")
+    config:reload()
+    assert.equal(vim.opt.undodir:get()[1], get_cache_dir() .. "/undo")
+  end)
+
+  a.it("should not get interrupted by errors in user-config", function()
+    vim.opt.undodir = "/tmp"
+    assert.equal(vim.opt.undodir:get()[1], "/tmp")
+    os.execute("echo bad_string_test >> " .. user_config_path)
+    local error_handler = function(msg)
+      return msg
+    end
+    local err = xpcall(config:reload(), error_handler)
+    assert.falsy(err)
+    assert.equal(vim.opt.undodir:get()[1], get_cache_dir() .. "/undo")
+  end)
+end)

+ 11 - 11
tests/lsp_spec.lua

@@ -1,9 +1,9 @@
 local a = require "plenary.async_lib.tests"
-local utils = require "utils"
+local utils = require "lvim.utils"
 lvim.lsp.templates_dir = join_paths(get_runtime_dir(), "lvim", "tests", "artifacts")
 
 a.describe("lsp workflow", function()
-  local Log = require "core.log"
+  local Log = require "lvim.core.log"
   local logfile = Log:get_path()
 
   a.it("shoud be able to delete ftplugin templates", function()
@@ -17,7 +17,7 @@ a.describe("lsp workflow", function()
     if utils.is_directory(lvim.lsp.templates_dir) then
       assert.equal(vim.fn.delete(lvim.lsp.templates_dir, "rf"), 0)
     end
-    require("lsp").setup()
+    require("lvim.lsp").setup()
 
     -- we need to delay this check until the generation is completed
     vim.schedule(function()
@@ -28,15 +28,15 @@ a.describe("lsp workflow", function()
   a.it("shoud not attempt to re-generate ftplugin templates", function()
     lvim.log.level = "debug"
 
-    local plugins = require "plugins"
-    require("plugin-loader"):load { plugins, lvim.plugins }
+    local plugins = require "lvim.plugins"
+    require("lvim.plugin-loader"):load { plugins, lvim.plugins }
 
     if utils.is_file(logfile) then
       assert.equal(vim.fn.delete(logfile), 0)
     end
 
     assert.True(utils.is_directory(lvim.lsp.templates_dir))
-    require("lsp").setup()
+    require("lvim.lsp").setup()
 
     -- we need to delay this check until the log gets populated
     vim.schedule(function()
@@ -49,7 +49,7 @@ a.describe("lsp workflow", function()
       name = "ocamlls",
       filetypes = { "ocaml", "reason" },
     }
-    local ocaml_fts = require("lsp.utils").get_supported_filetypes(ocaml.name)
+    local ocaml_fts = require("lvim.lsp.utils").get_supported_filetypes(ocaml.name)
     assert.True(vim.deep_equal(ocaml.filetypes, ocaml_fts))
 
     local tsserver = {
@@ -63,17 +63,17 @@ a.describe("lsp workflow", function()
         "typescript.tsx",
       },
     }
-    local tsserver_fts = require("lsp.utils").get_supported_filetypes(tsserver.name)
+    local tsserver_fts = require("lvim.lsp.utils").get_supported_filetypes(tsserver.name)
     assert.True(vim.deep_equal(tsserver.filetypes, tsserver_fts))
   end)
 
   a.it("shoud ignore all javascript servers except tsserver and tailwindcss when generating templates", function()
     local test_server = { name = "denols", filetypes = {} }
-    test_server.filetypes = require("lsp.utils").get_supported_filetypes(test_server.name)
+    test_server.filetypes = require("lvim.lsp.utils").get_supported_filetypes(test_server.name)
 
     assert.True(vim.tbl_contains(test_server.filetypes, "javascript"))
 
-    local is_ignored = require("lsp.templates").is_ignored(test_server.name)
+    local is_ignored = require("lvim.lsp.templates").is_ignored(test_server.name)
     assert.True(is_ignored)
 
     local ts_template = utils.join_paths(lvim.lsp.templates_dir, "typescript.lua")
@@ -84,7 +84,7 @@ a.describe("lsp workflow", function()
 
   a.it("shoud not include blacklisted servers in the generated templates", function()
     assert.True(utils.is_directory(lvim.lsp.templates_dir))
-    require("lsp").setup()
+    require("lvim.lsp").setup()
 
     local blacklisted = { "jedi_language_server", "pylsp", "sqlls", "sqls", "angularls", "ansiblels" }
 

+ 1 - 5
tests/minimal_init.lua

@@ -2,8 +2,4 @@ local path_sep = vim.loop.os_uname().version:match "Windows" and "\\" or "/"
 
 vim.opt.rtp:append(os.getenv "LUNARVIM_RUNTIME_DIR" .. path_sep .. "lvim")
 
-require("bootstrap"):init()
-
-local config = require "config"
--- config:init()
-config:load()
+require("lvim.bootstrap"):init()

+ 107 - 0
tests/minimal_lsp.lua

@@ -0,0 +1,107 @@
+vim.cmd [[set runtimepath=$VIMRUNTIME]]
+vim.cmd [[set packpath=/tmp/nvim/site]]
+
+local package_root = "/tmp/nvim/site/pack"
+local install_path = package_root .. "/packer/start/packer.nvim"
+
+-- Choose whether to use the executable that's managed by lsp-installer
+local use_lsp_installer = true
+
+local function load_plugins()
+  require("packer").startup {
+    {
+      "wbthomason/packer.nvim",
+      "neovim/nvim-lspconfig",
+      { "williamboman/nvim-lsp-installer", disable = not use_lsp_installer },
+    },
+    config = {
+      package_root = package_root,
+      compile_path = install_path .. "/plugin/packer_compiled.lua",
+    },
+  }
+end
+
+function _G.dump(...)
+  local objects = vim.tbl_map(vim.inspect, { ... })
+  print(unpack(objects))
+  return ...
+end
+
+_G.load_config = function()
+  vim.lsp.set_log_level "trace"
+  if vim.fn.has "nvim-0.5.1" == 1 then
+    require("vim.lsp.log").set_format_func(vim.inspect)
+  end
+  local nvim_lsp = require "lspconfig"
+  local on_attach = function(_, bufnr)
+    local function buf_set_keymap(...)
+      vim.api.nvim_buf_set_keymap(bufnr, ...)
+    end
+    local function buf_set_option(...)
+      vim.api.nvim_buf_set_option(bufnr, ...)
+    end
+
+    buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc")
+
+    -- Mappings.
+    local opts = { noremap = true, silent = true }
+    buf_set_keymap("n", "gD", "<Cmd>lua vim.lsp.buf.declaration()<CR>", opts)
+    buf_set_keymap("n", "gd", "<Cmd>lua vim.lsp.buf.definition()<CR>", opts)
+    buf_set_keymap("n", "K", "<Cmd>lua vim.lsp.buf.hover()<CR>", opts)
+    buf_set_keymap("n", "gi", "<cmd>lua vim.lsp.buf.implementation()<CR>", opts)
+    buf_set_keymap("n", "<C-k>", "<cmd>lua vim.lsp.buf.signature_help()<CR>", opts)
+    buf_set_keymap("n", "<space>wa", "<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>", opts)
+    buf_set_keymap("n", "<space>wr", "<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>", opts)
+    buf_set_keymap("n", "<space>wl", "<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>", opts)
+    buf_set_keymap("n", "<space>lD", "<cmd>lua vim.lsp.buf.type_definition()<CR>", opts)
+    buf_set_keymap("n", "<space>lr", "<cmd>lua vim.lsp.buf.rename()<CR>", opts)
+    buf_set_keymap("n", "gr", "<cmd>lua vim.lsp.buf.references()<CR>", opts)
+    buf_set_keymap("n", "gl", "<cmd>lua vim.lsp.diagnostic.show_line_diagnostics()<CR>", opts)
+    buf_set_keymap("n", "<space>lk", "<cmd>lua vim.lsp.diagnostic.goto_prev()<CR>", opts)
+    buf_set_keymap("n", "<space>lj", "<cmd>lua vim.lsp.diagnostic.goto_next()<CR>", opts)
+    buf_set_keymap("n", "<space>lq", "<cmd>lua vim.lsp.diagnostic.set_loclist()<CR>", opts)
+    buf_set_keymap("n", "<space>li", "<cmd>LspInfo<CR>", opts)
+    buf_set_keymap("n", "<space>lI", "<cmd>LspInstallInfo<CR>", opts)
+  end
+
+  -- Add the server that troubles you here, e.g. "sumneko_lua", "pyright", "tsserver"
+  local name = "clangd"
+
+  -- You need to specify the server's command manually
+  local cmd
+
+  if use_lsp_installer then
+    local server_available, server = require("nvim-lsp-installer.servers").get_server(name)
+    if not server_available then
+      server:install()
+    end
+    local default_opts = server:get_default_options()
+    cmd = default_opts.cmd
+  end
+
+  if not name then
+    print "You have not defined a server name, please edit minimal_init.lua"
+  end
+  if not nvim_lsp[name].document_config.default_config.cmd and not cmd then
+    print [[You have not defined a server default cmd for a server
+      that requires it please edit minimal_init.lua]]
+  end
+
+  nvim_lsp[name].setup {
+    cmd = cmd,
+    on_attach = on_attach,
+  }
+
+  print [[You can find your log at $HOME/.cache/nvim/lsp.log. Please paste in a github issue under a details tag as described in the issue template.]]
+end
+
+if vim.fn.isdirectory(install_path) == 0 then
+  vim.fn.system { "git", "clone", "https://github.com/wbthomason/packer.nvim", install_path }
+  load_plugins()
+  require("packer").sync()
+  vim.cmd [[autocmd User PackerComplete ++once lua load_config()]]
+else
+  load_plugins()
+  require("packer").sync()
+  _G.load_config()
+end

+ 6 - 5
tests/plugins_load_spec.lua

@@ -1,9 +1,11 @@
 local a = require "plenary.async_lib.tests"
 
 a.describe("plugin-loader", function()
+  local plugins = require "lvim.plugins"
+  local loader = require "lvim.plugin-loader"
+
   a.it("should be able to load default packages without errors", function()
-    local plugins = require "plugins"
-    require("plugin-loader"):load { plugins, lvim.plugins }
+    loader:load { plugins, lvim.plugins }
 
     -- TODO: maybe there's a way to avoid hard-coding the names of the modules?
     local startup_plugins = {
@@ -16,10 +18,9 @@ a.describe("plugin-loader", function()
   end)
 
   a.it("should be able to load lsp packages without errors", function()
-    local plugins = require "plugins"
-    require("plugin-loader"):load { plugins, lvim.plugins }
+    loader:load { plugins, lvim.plugins }
 
-    require("lsp").setup()
+    require("lvim.lsp").setup()
 
     local lsp_packages = {
       "lspconfig",

+ 2 - 2
utils/bin/lvim.ps1

@@ -1,6 +1,6 @@
 $env:XDG_DATA_HOME = ($env:XDG_DATA_HOME, "$env:APPDATA", 1 -ne $null)[0]
-$env:XDG_CONFIG_HOME = ($env:XDG_CONFIG_HOME, "$LOCALAPPDATA", 1 -ne $null)[0]
-$env:XDG_CACHE_HOME = ($env:XDG_CACHE_HOME, "$TEMP", 1 -ne $null)[0]
+$env:XDG_CONFIG_HOME = ($env:XDG_CONFIG_HOME, "$env:LOCALAPPDATA", 1 -ne $null)[0]
+$env:XDG_CACHE_HOME = ($env:XDG_CACHE_HOME, "$env:TEMP", 1 -ne $null)[0]
 
 $env:LUNARVIM_RUNTIME_DIR = ($env:LUNARVIM_RUNTIME_DIR, "$env:XDG_DATA_HOME\lunarvim", 1 -ne $null)[0]
 $env:LUNARVIM_CONFIG_DIR = ($env:LUNARVIM_CONFIG_DIR, "$env:XDG_CONFIG_HOME\lvim", 1 -ne $null)[0]

+ 14 - 9
utils/installer/config.example-no-ts.lua

@@ -15,17 +15,22 @@ lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
 -- lvim.keys.normal_mode["<C-q>"] = ":q<cr>"
 
 -- Change Telescope navigation to use j and k for navigation and n and p for history in both input and normal mode.
--- lvim.builtin.telescope.on_config_done = function()
---   local actions = require "telescope.actions"
+-- we use protected-mode (pcall) just in case the plugin wasn't loaded yet.
+-- local _, actions = pcall(require, "telescope.actions")
+-- lvim.builtin.telescope.defaults.mappings = {
 --   -- for input mode
---   lvim.builtin.telescope.defaults.mappings.i["<C-j>"] = actions.move_selection_next
---   lvim.builtin.telescope.defaults.mappings.i["<C-k>"] = actions.move_selection_previous
---   lvim.builtin.telescope.defaults.mappings.i["<C-n>"] = actions.cycle_history_next
---   lvim.builtin.telescope.defaults.mappings.i["<C-p>"] = actions.cycle_history_prev
+--   i = {
+--     ["<C-j>"] = actions.move_selection_next,
+--     ["<C-k>"] = actions.move_selection_previous,
+--     ["<C-n>"] = actions.cycle_history_next,
+--     ["<C-p>"] = actions.cycle_history_prev,
+--   },
 --   -- for normal mode
---   lvim.builtin.telescope.defaults.mappings.n["<C-j>"] = actions.move_selection_next
---   lvim.builtin.telescope.defaults.mappings.n["<C-k>"] = actions.move_selection_previous
--- end
+--   n = {
+--     ["<C-j>"] = actions.move_selection_next,
+--     ["<C-k>"] = actions.move_selection_previous,
+--   },
+-- }
 
 -- Use which-key to add extra bindings with the leader-key prefix
 -- lvim.builtin.which_key.mappings["P"] = { "<cmd>Telescope projects<CR>", "Projects" }

+ 14 - 9
utils/installer/config.example.lua

@@ -23,17 +23,22 @@ lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
 -- lvim.keys.normal_mode["<C-q>"] = ":q<cr>"
 
 -- Change Telescope navigation to use j and k for navigation and n and p for history in both input and normal mode.
--- lvim.builtin.telescope.on_config_done = function()
---   local actions = require "telescope.actions"
+-- we use protected-mode (pcall) just in case the plugin wasn't loaded yet.
+-- local _, actions = pcall(require, "telescope.actions")
+-- lvim.builtin.telescope.defaults.mappings = {
 --   -- for input mode
---   lvim.builtin.telescope.defaults.mappings.i["<C-j>"] = actions.move_selection_next
---   lvim.builtin.telescope.defaults.mappings.i["<C-k>"] = actions.move_selection_previous
---   lvim.builtin.telescope.defaults.mappings.i["<C-n>"] = actions.cycle_history_next
---   lvim.builtin.telescope.defaults.mappings.i["<C-p>"] = actions.cycle_history_prev
+--   i = {
+--     ["<C-j>"] = actions.move_selection_next,
+--     ["<C-k>"] = actions.move_selection_previous,
+--     ["<C-n>"] = actions.cycle_history_next,
+--     ["<C-p>"] = actions.cycle_history_prev,
+--   },
 --   -- for normal mode
---   lvim.builtin.telescope.defaults.mappings.n["<C-j>"] = actions.move_selection_next
---   lvim.builtin.telescope.defaults.mappings.n["<C-k>"] = actions.move_selection_previous
--- end
+--   n = {
+--     ["<C-j>"] = actions.move_selection_next,
+--     ["<C-k>"] = actions.move_selection_previous,
+--   },
+-- }
 
 -- Use which-key to add extra bindings with the leader-key prefix
 -- lvim.builtin.which_key.mappings["P"] = { "<cmd>Telescope projects<CR>", "Projects" }

+ 2 - 3
utils/installer/install.ps1

@@ -6,8 +6,8 @@ $LV_REMOTE = ($LV_REMOTE, "lunarvim/lunarvim.git", 1 -ne $null)[0]
 $INSTALL_PREFIX = ($INSTALL_PREFIX, "$HOME\.local", 1 -ne $null)[0]
 
 $env:XDG_DATA_HOME = ($env:XDG_DATA_HOME, "$env:APPDATA", 1 -ne $null)[0]
-$env:XDG_CONFIG_HOME = ($env:XDG_CONFIG_HOME, "$LOCALAPPDATA", 1 -ne $null)[0]
-$env:XDG_CACHE_HOME = ($env:XDG_CACHE_HOME, "$TEMP", 1 -ne $null)[0]
+$env:XDG_CONFIG_HOME = ($env:XDG_CONFIG_HOME, "$env:LOCALAPPDATA", 1 -ne $null)[0]
+$env:XDG_CACHE_HOME = ($env:XDG_CACHE_HOME, "$env:TEMP", 1 -ne $null)[0]
 $env:LUNARVIM_RUNTIME_DIR = ($env:LUNARVIM_RUNTIME_DIR, "$env:XDG_DATA_HOME\lunarvim", 1 -ne $null)[0]
 $env:LUNARVIM_CONFIG_DIR = ($env:LUNARVIM_CONFIG_DIR, "$env:XDG_CONFIG_HOME\lvim", 1 -ne $null)[0]
 $env:LUNARVIM_CACHE_DIR = ($env:LUNARVIM_CACHE_DIR, "$env:XDG_CACHE_HOME\lvim", 1 -ne $null)[0]
@@ -276,4 +276,3 @@ function create_alias {
 }
 
 main "$args"
-

+ 11 - 2
utils/installer/install.sh

@@ -2,7 +2,7 @@
 set -eo pipefail
 
 #Set branch to master unless specified by the user
-declare LV_BRANCH="${LV_BRANCH:-"rolling"}"
+declare LV_BRANCH="${LV_BRANCH:-"master"}"
 declare -r LV_REMOTE="${LV_REMOTE:-lunarvim/lunarvim.git}"
 declare -r INSTALL_PREFIX="${INSTALL_PREFIX:-"$HOME/.local"}"
 
@@ -146,6 +146,15 @@ function detect_platform() {
         RECOMMEND_INSTALL="sudo apt install -y"
       fi
       ;;
+    FreeBSD)
+      RECOMMEND_INSTALL="sudo pkg install -y"
+      ;;
+    NetBSD)
+      RECOMMEND_INSTALL="sudo pkgin install"
+      ;;
+    OpenBSD)
+      RECOMMEND_INSTALL="doas pkg_add"
+      ;;
     Darwin)
       RECOMMEND_INSTALL="brew install"
       ;;
@@ -256,7 +265,7 @@ function backup_old_config() {
     else
       OS="$(uname -s)"
       case "$OS" in
-        Linux)
+        Linux | *BSD)
           cp -r "$dir/"* "$dir.bak/."
           ;;
         Darwin)