Преглед изворни кода

Merge remote-tracking branch 'origin/rolling'

kylo252 пре 2 година
родитељ
комит
4ef0731500
83 измењених фајлова са 2456 додато и 921 уклоњено
  1. 2 1
      .github/FUNDING.yml
  2. 1 1
      .github/ISSUE_TEMPLATE/general-issue-form.yaml
  3. 1 1
      .github/ISSUE_TEMPLATE/lsp-issue-form.yaml
  4. 22 0
      .github/workflows/close-inactive-bot.yml
  5. 2 2
      .github/workflows/commitlint.yml
  6. 4 3
      .github/workflows/format.yaml
  7. 6 6
      .github/workflows/install.yaml
  8. 2 2
      .github/workflows/lint.yaml
  9. 2 4
      .github/workflows/plugins.yml
  10. 0 1
      .gitignore
  11. 3 0
      .luacheckrc
  12. 9 0
      .luarc.json
  13. 1 1
      CONTRIBUTING.md
  14. 18 15
      README.md
  15. 88 0
      ftplugin/lua.lua
  16. 8 2
      init.lua
  17. 10 15
      lua/lvim/bootstrap.lua
  18. 3 1
      lua/lvim/config/defaults.lua
  19. 19 8
      lua/lvim/config/init.lua
  20. 7 5
      lua/lvim/config/settings.lua
  21. 4 1
      lua/lvim/core/alpha.lua
  22. 100 37
      lua/lvim/core/alpha/dashboard.lua
  23. 1 1
      lua/lvim/core/alpha/startify.lua
  24. 66 15
      lua/lvim/core/autocmds.lua
  25. 4 1
      lua/lvim/core/autopairs.lua
  26. 226 0
      lua/lvim/core/breadcrumbs.lua
  27. 18 8
      lua/lvim/core/bufferline.lua
  28. 7 1
      lua/lvim/core/builtins/init.lua
  29. 113 34
      lua/lvim/core/cmp.lua
  30. 20 24
      lua/lvim/core/comment.lua
  31. 76 27
      lua/lvim/core/dap.lua
  32. 6 6
      lua/lvim/core/gitsigns.lua
  33. 68 0
      lua/lvim/core/illuminate.lua
  34. 42 0
      lua/lvim/core/indentlines.lua
  35. 7 7
      lua/lvim/core/info.lua
  36. 118 0
      lua/lvim/core/lir.lua
  37. 21 19
      lua/lvim/core/log.lua
  38. 74 24
      lua/lvim/core/lualine/components.lua
  39. 2 2
      lua/lvim/core/lualine/conditions.lua
  40. 6 3
      lua/lvim/core/lualine/init.lua
  41. 42 14
      lua/lvim/core/lualine/styles.lua
  42. 2 1
      lua/lvim/core/mason.lua
  43. 12 8
      lua/lvim/core/notify.lua
  44. 40 33
      lua/lvim/core/nvimtree.lua
  45. 1 1
      lua/lvim/core/project.lua
  46. 64 30
      lua/lvim/core/telescope.lua
  47. 4 3
      lua/lvim/core/telescope/custom-finders.lua
  48. 29 6
      lua/lvim/core/terminal.lua
  49. 113 0
      lua/lvim/core/theme.lua
  50. 11 16
      lua/lvim/core/which-key.lua
  51. 154 0
      lua/lvim/icons.lua
  52. 211 98
      lua/lvim/impatient.lua
  53. 60 49
      lua/lvim/impatient/profile.lua
  54. 0 10
      lua/lvim/keymappings.lua
  55. 13 19
      lua/lvim/lsp/config.lua
  56. 6 5
      lua/lvim/lsp/init.lua
  57. 0 157
      lua/lvim/lsp/peek.lua
  58. 45 18
      lua/lvim/lsp/providers/sumneko_lua.lua
  59. 53 66
      lua/lvim/lsp/utils.lua
  60. 8 5
      lua/lvim/plugin-loader.lua
  61. 59 22
      lua/lvim/plugins.lua
  62. 13 0
      lua/lvim/utils/functions.lua
  63. 15 2
      lua/lvim/utils/git.lua
  64. 6 9
      lua/lvim/utils/hooks.lua
  65. 98 0
      lua/lvim/utils/modules.lua
  66. 46 34
      snapshots/default.json
  67. 1 1
      tests/minimal_lsp.lua
  68. 1 1
      tests/specs/plugins_load_spec.lua
  69. 1 1
      utils/bin/lvim.ps1
  70. 4 2
      utils/bin/lvim.template
  71. 4 4
      utils/ci/verify_plugins.lua
  72. 10 0
      utils/desktop/16x16/lvim.svg
  73. 16 0
      utils/desktop/22x22/lvim.svg
  74. 16 0
      utils/desktop/24x24/lvim.svg
  75. 16 0
      utils/desktop/32x32/lvim.svg
  76. 16 0
      utils/desktop/48x48/lvim.svg
  77. 16 0
      utils/desktop/64x64/lvim.svg
  78. 1 1
      utils/desktop/lvim.desktop
  79. 8 5
      utils/installer/config.example.lua
  80. 7 4
      utils/installer/config_win.example.lua
  81. 34 17
      utils/installer/install.sh
  82. 2 1
      utils/installer/install_bin.sh
  83. 11 0
      utils/installer/uninstall.sh

+ 2 - 1
.github/FUNDING.yml

@@ -2,4 +2,5 @@
 
 
 github: christianchiarulli
 github: christianchiarulli
 patreon: chrisatmachine
 patreon: chrisatmachine
-
+ko_fi: chrisatmachine
+custom:  ["https://www.buymeacoffee.com/chrisatmachine", "https://www.paypal.com/paypalme/chrisatmachine", "https://strike.me/chrisatmachine"]

+ 1 - 1
.github/ISSUE_TEMPLATE/general-issue-form.yaml

@@ -33,7 +33,7 @@ body:
   - type: input
   - type: input
     id: nvim-version
     id: nvim-version
     attributes:
     attributes:
-      label: Neovim version (>= 0.7.2)
+      label: Neovim version (>= 0.8.0)
       description: "Output of `nvim --version`"
       description: "Output of `nvim --version`"
       placeholder: |
       placeholder: |
         NVIM v0.8.0-dev+199-g2875d45e7
         NVIM v0.8.0-dev+199-g2875d45e7

+ 1 - 1
.github/ISSUE_TEMPLATE/lsp-issue-form.yaml

@@ -27,7 +27,7 @@ body:
   - type: input
   - type: input
     id: nvim-version
     id: nvim-version
     attributes:
     attributes:
-      label: Neovim version (>= 0.7)
+      label: Neovim version (>= 0.8.0)
       description: "Output of `nvim --version`"
       description: "Output of `nvim --version`"
       placeholder: |
       placeholder: |
         NVIM v0.8.0-dev+199-g2875d45e7
         NVIM v0.8.0-dev+199-g2875d45e7

+ 22 - 0
.github/workflows/close-inactive-bot.yml

@@ -0,0 +1,22 @@
+name: Close inactive issues
+on:
+  schedule:
+    - cron: '30 1 * * *'
+
+jobs:
+  close-issues:
+    runs-on: ubuntu-latest
+    permissions:
+      issues: write
+      pull-requests: write
+    steps:
+      - uses: actions/stale@v5
+        with:
+          days-before-issue-stale: 30
+          days-before-issue-close: 14
+          stale-issue-label: 'stale'
+          stale-issue-message: 'This issue is stale because it has been open for 30 days with no activity.'
+          close-issue-message: 'This issue was closed because it has been inactive for 14 days since being marked as stale.'
+          days-before-pr-stale: -1
+          days-before-pr-close: -1
+          repo-token: ${{ secrets.GITHUB_TOKEN }}

+ 2 - 2
.github/workflows/commitlint.yml

@@ -10,10 +10,10 @@ jobs:
     env:
     env:
       GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
       GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
     steps:
     steps:
-      - uses: actions/checkout@v2.3.1
+      - uses: actions/checkout@v3
         with:
         with:
           fetch-depth: 0
           fetch-depth: 0
-      - uses: wagoid/commitlint-github-action@v4
+      - uses: wagoid/commitlint-github-action@v5
         with:
         with:
           configFile: .github/workflows/commitlint.config.js
           configFile: .github/workflows/commitlint.config.js
           helpURL: https://github.com/LunarVim/LunarVim/blob/rolling/CONTRIBUTING.md#commit-messages
           helpURL: https://github.com/LunarVim/LunarVim/blob/rolling/CONTRIBUTING.md#commit-messages

+ 4 - 3
.github/workflows/format.yaml

@@ -15,20 +15,21 @@ jobs:
     name: "Formatting check with Stylua"
     name: "Formatting check with Stylua"
     runs-on: ubuntu-20.04
     runs-on: ubuntu-20.04
     steps:
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
 
       - name: Lint with stylua
       - name: Lint with stylua
-        uses: JohnnyMorganz/stylua-action@1.0.0
+        uses: JohnnyMorganz/stylua-action@v1
         with:
         with:
           token: ${{ secrets.GITHUB_TOKEN }}
           token: ${{ secrets.GITHUB_TOKEN }}
           # CLI arguments
           # CLI arguments
+          version: 0.15.1
           args: --check .
           args: --check .
 
 
   shfmt-check:
   shfmt-check:
     name: "Formatting check with shfmt"
     name: "Formatting check with shfmt"
     runs-on: ubuntu-20.04
     runs-on: ubuntu-20.04
     steps:
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
 
       - name: Setup Go
       - name: Setup Go
         uses: actions/setup-go@v2
         uses: actions/setup-go@v2

+ 6 - 6
.github/workflows/install.yaml

@@ -21,10 +21,10 @@ jobs:
         include:
         include:
           - runner: ubuntu-latest
           - runner: ubuntu-latest
             os: linux
             os: linux
-            neovim: v0.7.0
+            neovim: v0.8.0
           - runner: macos-latest
           - runner: macos-latest
             os: osx
             os: osx
-            neovim: v0.7.0
+            neovim: v0.8.0
           - runner: ubuntu-22.04
           - runner: ubuntu-22.04
             os: linux
             os: linux
             neovim: nightly
             neovim: nightly
@@ -33,13 +33,13 @@ jobs:
             neovim: nightly
             neovim: nightly
     runs-on: ${{ matrix.runner }}
     runs-on: ${{ matrix.runner }}
     steps:
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
 
       - name: Install neovim binary from release
       - name: Install neovim binary from release
         env:
         env:
           RELEASE_VER: ${{ matrix.neovim }}
           RELEASE_VER: ${{ matrix.neovim }}
         run: |
         run: |
-          echo "$HOME/.local/bin" >> $GITHUB_PATH
+          echo "$HOME/.local/bin" >> "$GITHUB_PATH"
           bash ./utils/installer/install-neovim-from-release
           bash ./utils/installer/install-neovim-from-release
 
 
       - name: Install LunarVim
       - name: Install LunarVim
@@ -72,13 +72,13 @@ jobs:
         shell: pwsh
         shell: pwsh
     steps:
     steps:
       # it's not currently possbile to run tests on windows, see nvim-lua/plenary.nvim#255
       # it's not currently possbile to run tests on windows, see nvim-lua/plenary.nvim#255
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
 
       - name: Install neovim binary
       - name: Install neovim binary
         uses: rhysd/action-setup-vim@v1
         uses: rhysd/action-setup-vim@v1
         with:
         with:
           neovim: true
           neovim: true
-          version: v0.7.0
+          version: v0.8.0
 
 
       - name: Install LunarVim
       - name: Install LunarVim
         timeout-minutes: 4
         timeout-minutes: 4

+ 2 - 2
.github/workflows/lint.yaml

@@ -15,7 +15,7 @@ jobs:
     name: "Linting with luacheck"
     name: "Linting with luacheck"
     runs-on: ubuntu-20.04
     runs-on: ubuntu-20.04
     steps:
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
 
       - uses: leafo/gh-actions-lua@v8
       - uses: leafo/gh-actions-lua@v8
       - uses: leafo/gh-actions-luarocks@v4
       - uses: leafo/gh-actions-luarocks@v4
@@ -30,7 +30,7 @@ jobs:
     name: Shellcheck
     name: Shellcheck
     runs-on: ubuntu-latest
     runs-on: ubuntu-latest
     steps:
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Run ShellCheck
       - name: Run ShellCheck
         uses: ludeeus/action-shellcheck@master
         uses: ludeeus/action-shellcheck@master
         with:
         with:

+ 2 - 4
.github/workflows/plugins.yml

@@ -25,15 +25,13 @@ jobs:
       contents: write
       contents: write
       pull-requests: write
       pull-requests: write
     steps:
     steps:
-      - uses: actions/checkout@v2
-        with:
-          ref: ${{ github.head_ref }}
+      - uses: actions/checkout@v3
 
 
       - name: Install neovim binary
       - name: Install neovim binary
         uses: rhysd/action-setup-vim@v1
         uses: rhysd/action-setup-vim@v1
         with:
         with:
           neovim: true
           neovim: true
-          version: v0.7.0
+          version: nightly
 
 
       - name: Install LunarVim
       - name: Install LunarVim
         timeout-minutes: 4
         timeout-minutes: 4

+ 0 - 1
.gitignore

@@ -1,4 +1,3 @@
-plugin/
 dein
 dein
 tags*
 tags*
 .netrwhist
 .netrwhist

+ 3 - 0
.luacheckrc

@@ -1,8 +1,10 @@
+---@diagnostic disable
 -- vim: ft=lua tw=80
 -- vim: ft=lua tw=80
 
 
 stds.nvim = {
 stds.nvim = {
   globals = {
   globals = {
     "lvim",
     "lvim",
+    "reload",
     vim = { fields = { "g" } },
     vim = { fields = { "g" } },
     "TERMINAL",
     "TERMINAL",
     "USER",
     "USER",
@@ -29,6 +31,7 @@ stds.nvim = {
 std = "lua51+nvim"
 std = "lua51+nvim"
 
 
 files["tests/*_spec.lua"].std = "lua51+nvim+busted"
 files["tests/*_spec.lua"].std = "lua51+nvim+busted"
+files["lua/lvim/impatient*"].ignore = {"121"}
 
 
 -- Don't report unused self arguments of methods.
 -- Don't report unused self arguments of methods.
 self = false
 self = false

+ 9 - 0
.luarc.json

@@ -0,0 +1,9 @@
+{
+  "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json",
+  "Lua.diagnostics.disable": [
+    "redundant-parameter",
+    "param-type-mismatch",
+    "missing-parameter"
+  ],
+  "diagnostics.libraryFiles": "Disable"
+}

+ 1 - 1
CONTRIBUTING.md

@@ -10,7 +10,7 @@ One of the best ways to begin contributing in a meaningful way is by helping fin
 
 
 ## Getting Started
 ## Getting Started
 
 
-1. Follow the [Installation](https://www.lunarvim.org/01-installing.html) guide
+1. Follow the [Installation](https://www.lunarvim.org/docs/installation) guide
 2. Link your fork with the repository `git remote add upstream https://github.com/lunarvim/LunarVim.git`, or use `gh fork`
 2. Link your fork with the repository `git remote add upstream https://github.com/lunarvim/LunarVim.git`, or use `gh fork`
 3. That's it! You can now `git fetch upstream` and `git rebase [-i] upstream/rolling` to update your branches with the latest contributions.
 3. That's it! You can now `git fetch upstream` and `git rebase [-i] upstream/rolling` to update your branches with the latest contributions.
 
 

+ 18 - 15
README.md

@@ -21,22 +21,31 @@
 </div>
 </div>
 
 
 ## Showcase
 ## Showcase
-![intro1](https://user-images.githubusercontent.com/59826753/159939936-3a9a8e94-05ea-48fa-8c46-69378276451b.png)
-![info](https://user-images.githubusercontent.com/59826753/159939984-ac0190d7-a3fb-46c0-95ca-a6fec626bbac.png)
+![intro1](https://user-images.githubusercontent.com/29136904/191624232-a7b13f11-cc9f-495e-879e-67ea0444c568.png)
+![info](https://user-images.githubusercontent.com/29136904/191624942-3d75ef87-35cf-434d-850e-3e7cd5ce2ad0.png)
 
 
-![demo1](https://user-images.githubusercontent.com/59826753/159940004-84975294-5703-4bf1-aa98-2cc97cb38d96.png)
-![demo2](https://user-images.githubusercontent.com/59826753/159940040-375a0a28-4c81-4fdf-80f2-62853edf9b4f.png)
+![demo1](https://user-images.githubusercontent.com/29136904/191625579-ce9efb1f-1e23-4a05-aebc-915a0f614d72.png)
+![demo2](https://user-images.githubusercontent.com/29136904/191626018-2e9ee682-043c-4ce5-a5dd-c11b94759782.png)
+![demo3](https://user-images.githubusercontent.com/29136904/191626246-ce0cc0c5-4b41-49e3-9cb7-4b1867ab0dcb.png)
 
 
 ## Install In One Command!
 ## Install In One Command!
 
 
-Make sure you have the release version of Neovim (0.7+).
+Make sure you have the release version of Neovim (0.8+).
 
 
-### Linux:
+### Linux/MacOS:
+
+If you are running Neovim 0.8+
 
 
 ```bash
 ```bash
 bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh)
 bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh)
 ```
 ```
 
 
+If you are running Neovim 0.8+
+
+```bash
+export LV_BRANCH="rolling"; bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/rolling/utils/installer/install.sh)
+```
+
 To run the install script without any interaction you can pass the `-y` flag to automatically install all dependencies and have no prompts. This is particularly useful in automated installations.
 To run the install script without any interaction you can pass the `-y` flag to automatically install all dependencies and have no prompts. This is particularly useful in automated installations.
 
 
 In the same way, you can use `--no-install-dependencies` to skip the dependency installation.
 In the same way, you can use `--no-install-dependencies` to skip the dependency installation.
@@ -62,7 +71,7 @@ Example:
 ```lua
 ```lua
 -- general
 -- general
 lvim.format_on_save = true
 lvim.format_on_save = true
-lvim.colorscheme = "onedarker"
+lvim.colorscheme = "tokyonight"
 
 
 lvim.leader = "space"
 lvim.leader = "space"
 -- add your own keymapping
 -- add your own keymapping
@@ -83,7 +92,7 @@ lvim.builtin.notify.active = true
 lvim.builtin.terminal.active = true
 lvim.builtin.terminal.active = true
 
 
 -- Treesitter parsers change this to a table of the languages you want i.e. {"java", "python", javascript}
 -- Treesitter parsers change this to a table of the languages you want i.e. {"java", "python", javascript}
-lvim.builtin.treesitter.ensure_installed = "maintained"
+lvim.builtin.treesitter.ensure_installed = "all"
 lvim.builtin.treesitter.ignore_install = { "haskell" }
 lvim.builtin.treesitter.ignore_install = { "haskell" }
 
 
 -- Disable virtual text
 -- Disable virtual text
@@ -117,7 +126,7 @@ linters.setup {
 -- Additional Plugins
 -- Additional Plugins
 lvim.plugins = {
 lvim.plugins = {
     {"lunarvim/colorschemes"},
     {"lunarvim/colorschemes"},
-    {"folke/tokyonight.nvim"}, {
+    {
         "ray-x/lsp_signature.nvim",
         "ray-x/lsp_signature.nvim",
         config = function() require"lsp_signature".on_attach() end,
         config = function() require"lsp_signature".on_attach() end,
         event = "BufRead"
         event = "BufRead"
@@ -134,12 +143,6 @@ lvim.plugins = {
 
 
 - inside LunarVim `:PackerUpdate`
 - inside LunarVim `:PackerUpdate`
 
 
-## Breaking changes
-
-- `lvim.lang.FOO` is no longer supported. Refer to <https://www.lunarvim.org/languages> for up-to-date instructions.
-- `lvim.lsp.popup_border` has been deprecated in favor of `lvim.lsp.float.border` and `lvim.lsp.diagnostics.float.border`.
-- `lvim.builtin.dashboard` has been replaced with `lvim.builtin.alpha`, see <https://github.com/LunarVim/LunarVim/pull/1906>
-
 ## Resources
 ## Resources
 
 
 - [Documentation](https://www.lunarvim.org)
 - [Documentation](https://www.lunarvim.org)

+ 88 - 0
ftplugin/lua.lua

@@ -0,0 +1,88 @@
+local fmt = string.format
+-- luacheck: ignore
+-- TODO: fix lint violations
+
+-- Iterator that splits a string o a given delimiter
+local function split(str, delim)
+  delim = delim or "%s"
+  return string.gmatch(str, fmt("[^%s]+", delim))
+end
+
+-- Find the proper directory separator depending
+-- on lua installation or OS.
+local function dir_separator()
+  -- Look at package.config for directory separator string (it's the first line)
+  if package.config then
+    return string.match(package.config, "^[^\n]")
+  elseif vim.fn.has "win32" == 1 then
+    return "\\"
+  else
+    return "/"
+  end
+end
+
+-- Search for lua traditional include paths.
+-- This mimics how require internally works.
+local function include_paths(fname, ext)
+  ext = ext or "lua"
+  local sep = dir_separator()
+  local paths = string.gsub(package.path, "%?", fname)
+  for path in split(paths, "%;") do
+    if vim.fn.filereadable(path) == 1 then
+      return path
+    end
+  end
+end
+
+-- Search for nvim lua include paths
+local function include_rtpaths(fname, ext)
+  ext = ext or "lua"
+  local sep = dir_separator()
+  local rtpaths = vim.api.nvim_list_runtime_paths()
+  local modfile, initfile = fmt("%s.%s", fname, ext), fmt("init.%s", ext)
+  for _, path in ipairs(rtpaths) do
+    -- Look on runtime path for 'lua/*.lua' files
+    local path1 = table.concat({ path, ext, modfile }, sep)
+    if vim.fn.filereadable(path1) == 1 then
+      return path1
+    end
+    -- Look on runtime path for 'lua/*/init.lua' files
+    local path2 = table.concat({ path, ext, fname, initfile }, sep)
+    if vim.fn.filereadable(path2) == 1 then
+      return path2
+    end
+  end
+end
+
+-- Global function that searches the path for the required file
+function find_required_path(module)
+  -- Look at package.config for directory separator string (it's the first line)
+  local sep = string.match(package.config, "^[^\n]")
+  -- Properly change '.' to separator (probably '/' on *nix and '\' on Windows)
+  local fname = vim.fn.substitute(module, "\\.", sep, "g")
+  local f
+  ---- First search for lua modules
+  f = include_paths(fname, "lua")
+  if f then
+    return f
+  end
+  -- This part is just for nvim modules
+  f = include_rtpaths(fname, "lua")
+  if f then
+    return f
+  end
+  ---- Now search for Fennel modules
+  f = include_paths(fname, "fnl")
+  if f then
+    return f
+  end
+  -- This part is just for nvim modules
+  f = include_rtpaths(fname, "fnl")
+  if f then
+    return f
+  end
+end
+
+-- Set options to open require with gf
+vim.opt_local.include = [=[\v<((do|load)file|require)\s*\(?['"]\zs[^'"]+\ze['"]]=]
+vim.opt_local.includeexpr = "v:lua.find_required_path(v:fname)"

+ 8 - 2
init.lua

@@ -1,5 +1,8 @@
-local init_path = debug.getinfo(1, "S").source:sub(2)
-local base_dir = init_path:match("(.*[/\\])"):sub(1, -2)
+local base_dir = vim.env.LUNARVIM_BASE_DIR
+  or (function()
+    local init_path = debug.getinfo(1, "S").source
+    return init_path:sub(2):match("(.*[/\\])"):sub(1, -2)
+  end)()
 
 
 if not vim.tbl_contains(vim.opt.rtp:get(), base_dir) then
 if not vim.tbl_contains(vim.opt.rtp:get(), base_dir) then
   vim.opt.rtp:append(base_dir)
   vim.opt.rtp:append(base_dir)
@@ -10,8 +13,11 @@ require("lvim.bootstrap"):init(base_dir)
 require("lvim.config"):load()
 require("lvim.config"):load()
 
 
 local plugins = require "lvim.plugins"
 local plugins = require "lvim.plugins"
+
 require("lvim.plugin-loader").load { plugins, lvim.plugins }
 require("lvim.plugin-loader").load { plugins, lvim.plugins }
 
 
+require("lvim.core.theme").setup()
+
 local Log = require "lvim.core.log"
 local Log = require "lvim.core.log"
 Log:debug "Starting LunarVim"
 Log:debug "Starting LunarVim"
 
 

+ 10 - 15
lua/lvim/bootstrap.lua

@@ -1,7 +1,7 @@
 local M = {}
 local M = {}
 
 
-if vim.fn.has "nvim-0.7" ~= 1 then
-  vim.notify("Please upgrade your Neovim base installation. Lunarvim requires v0.7+", vim.log.levels.WARN)
+if vim.fn.has "nvim-0.8" ~= 1 then
+  vim.notify("Please upgrade your Neovim base installation. Lunarvim requires v0.8+", vim.log.levels.WARN)
   vim.wait(5000, function()
   vim.wait(5000, function()
     return false
     return false
   end)
   end)
@@ -19,15 +19,9 @@ function _G.join_paths(...)
   return result
   return result
 end
 end
 
 
----Require a module in protected mode without relying on its cached value
----@param module string
----@return any
-function _G.require_clean(module)
-  package.loaded[module] = nil
-  _G[module] = nil
-  local _, requested = pcall(require, module)
-  return requested
-end
+_G.require_clean = require("lvim.utils.modules").require_clean
+_G.require_safe = require("lvim.utils.modules").require_safe
+_G.reload = require("lvim.utils.modules").reload
 
 
 ---Get the full path to `$LUNARVIM_RUNTIME_DIR`
 ---Get the full path to `$LUNARVIM_RUNTIME_DIR`
 ---@return string
 ---@return string
@@ -70,7 +64,7 @@ function M:init(base_dir)
   self.packer_install_dir = join_paths(self.runtime_dir, "site", "pack", "packer", "start", "packer.nvim")
   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")
   self.packer_cache_path = join_paths(self.config_dir, "plugin", "packer_compiled.lua")
 
 
-  ---@meta overridden to use LUNARVIM_CACHE_DIR instead, since a lot of plugins call this function interally
+  ---@meta overridden to use LUNARVIM_CACHE_DIR instead, since a lot of plugins call this function internally
   ---NOTE: changes to "data" are currently unstable, see #2507
   ---NOTE: changes to "data" are currently unstable, see #2507
   vim.fn.stdpath = function(what)
   vim.fn.stdpath = function(what)
     if what == "cache" then
     if what == "cache" then
@@ -90,6 +84,7 @@ function M:init(base_dir)
     vim.opt.rtp:remove(join_paths(vim.call("stdpath", "data"), "site"))
     vim.opt.rtp:remove(join_paths(vim.call("stdpath", "data"), "site"))
     vim.opt.rtp:remove(join_paths(vim.call("stdpath", "data"), "site", "after"))
     vim.opt.rtp:remove(join_paths(vim.call("stdpath", "data"), "site", "after"))
     vim.opt.rtp:prepend(join_paths(self.runtime_dir, "site"))
     vim.opt.rtp:prepend(join_paths(self.runtime_dir, "site"))
+    vim.opt.rtp:append(join_paths(self.runtime_dir, "lvim", "after"))
     vim.opt.rtp:append(join_paths(self.runtime_dir, "site", "after"))
     vim.opt.rtp:append(join_paths(self.runtime_dir, "site", "after"))
 
 
     vim.opt.rtp:remove(vim.call("stdpath", "config"))
     vim.opt.rtp:remove(vim.call("stdpath", "config"))
@@ -120,10 +115,10 @@ end
 ---Update LunarVim
 ---Update LunarVim
 ---pulls the latest changes from github and, resets the startup cache
 ---pulls the latest changes from github and, resets the startup cache
 function M:update()
 function M:update()
-  require_clean("lvim.utils.hooks").run_pre_update()
-  local ret = require_clean("lvim.utils.git").update_base_lvim()
+  reload("lvim.utils.hooks").run_pre_update()
+  local ret = reload("lvim.utils.git").update_base_lvim()
   if ret then
   if ret then
-    require_clean("lvim.utils.hooks").run_post_update()
+    reload("lvim.utils.hooks").run_post_update()
   end
   end
 end
 end
 
 

+ 3 - 1
lua/lvim/config/defaults.lua

@@ -1,6 +1,7 @@
 return {
 return {
   leader = "space",
   leader = "space",
-  colorscheme = "onedarker",
+  reload_config_on_save = true,
+  colorscheme = "tokyonight",
   transparent_window = false,
   transparent_window = false,
   format_on_save = {
   format_on_save = {
     ---@usage pattern string pattern used for the autocommand (Default: '*')
     ---@usage pattern string pattern used for the autocommand (Default: '*')
@@ -13,6 +14,7 @@ return {
   keys = {},
   keys = {},
 
 
   use_icons = true,
   use_icons = true,
+  icons = require "lvim.icons",
 
 
   builtin = {},
   builtin = {},
 
 

+ 19 - 8
lua/lvim/config/init.lua

@@ -111,45 +111,56 @@ end
 --- Override the configuration with a user provided one
 --- Override the configuration with a user provided one
 -- @param config_path The path to the configuration overrides
 -- @param config_path The path to the configuration overrides
 function M:load(config_path)
 function M:load(config_path)
-  local autocmds = require "lvim.core.autocmds"
+  local autocmds = reload "lvim.core.autocmds"
   config_path = config_path or self:get_user_config_path()
   config_path = config_path or self:get_user_config_path()
   local ok, err = pcall(dofile, config_path)
   local ok, err = pcall(dofile, config_path)
   if not ok then
   if not ok then
     if utils.is_file(user_config_file) then
     if utils.is_file(user_config_file) then
       Log:warn("Invalid configuration: " .. err)
       Log:warn("Invalid configuration: " .. err)
     else
     else
-      vim.notify_once(string.format("Unable to find configuration file [%s]", config_path), vim.log.levels.WARN)
+      vim.notify_once(
+        string.format("User-configuration not found. Creating an example configuration in %s", config_path)
+      )
+      local example_config = join_paths(get_lvim_base_dir(), "utils", "installer", "config.example.lua")
+      vim.loop.fs_copyfile(example_config, config_path)
     end
     end
   end
   end
 
 
+  Log:set_level(lvim.log.level)
+
   handle_deprecated_settings()
   handle_deprecated_settings()
 
 
   autocmds.define_autocmds(lvim.autocommands)
   autocmds.define_autocmds(lvim.autocommands)
 
 
   vim.g.mapleader = (lvim.leader == "space" and " ") or lvim.leader
   vim.g.mapleader = (lvim.leader == "space" and " ") or lvim.leader
 
 
-  require("lvim.keymappings").load(lvim.keys)
+  reload("lvim.keymappings").load(lvim.keys)
 
 
   if lvim.transparent_window then
   if lvim.transparent_window then
     autocmds.enable_transparent_mode()
     autocmds.enable_transparent_mode()
   end
   end
+
+  if lvim.reload_config_on_save then
+    autocmds.enable_reload_config_on_save()
+  end
 end
 end
 
 
 --- Override the configuration with a user provided one
 --- Override the configuration with a user provided one
 -- @param config_path The path to the configuration overrides
 -- @param config_path The path to the configuration overrides
 function M:reload()
 function M:reload()
   vim.schedule(function()
   vim.schedule(function()
-    require_clean("lvim.utils.hooks").run_pre_reload()
+    reload("lvim.utils.hooks").run_pre_reload()
 
 
     M:load()
     M:load()
 
 
-    require("lvim.core.autocmds").configure_format_on_save()
+    reload("lvim.core.autocmds").configure_format_on_save()
 
 
-    local plugins = require "lvim.plugins"
-    local plugin_loader = require "lvim.plugin-loader"
+    local plugins = reload "lvim.plugins"
+    local plugin_loader = reload "lvim.plugin-loader"
 
 
     plugin_loader.reload { plugins, lvim.plugins }
     plugin_loader.reload { plugins, lvim.plugins }
-    require_clean("lvim.utils.hooks").run_post_reload()
+    reload("lvim.core.theme").setup()
+    reload("lvim.utils.hooks").run_post_reload()
   end)
   end)
 end
 end
 
 

+ 7 - 5
lua/lvim/config/settings.lua

@@ -13,8 +13,7 @@ M.load_default_options = function()
   local default_options = {
   local default_options = {
     backup = false, -- creates a backup file
     backup = false, -- creates a backup file
     clipboard = "unnamedplus", -- allows neovim to access the system clipboard
     clipboard = "unnamedplus", -- allows neovim to access the system clipboard
-    cmdheight = 2, -- more space in the neovim command line for displaying messages
-    colorcolumn = "99999", -- fixes indentline for now
+    cmdheight = 1, -- more space in the neovim command line for displaying messages
     completeopt = { "menuone", "noselect" },
     completeopt = { "menuone", "noselect" },
     conceallevel = 0, -- so that `` is visible in markdown files
     conceallevel = 0, -- so that `` is visible in markdown files
     fileencoding = "utf-8", -- the encoding written to a file
     fileencoding = "utf-8", -- the encoding written to a file
@@ -34,28 +33,31 @@ M.load_default_options = function()
     splitright = true, -- force all vertical splits to go to the right of current window
     splitright = true, -- force all vertical splits to go to the right of current window
     swapfile = false, -- creates a swapfile
     swapfile = false, -- creates a swapfile
     termguicolors = true, -- set term gui colors (most terminals support this)
     termguicolors = true, -- set term gui colors (most terminals support this)
-    timeoutlen = 250, -- time to wait for a mapped sequence to complete (in milliseconds)
+    timeoutlen = 1000, -- time to wait for a mapped sequence to complete (in milliseconds)
     title = true, -- set the title of window to the value of the titlestring
     title = true, -- set the title of window to the value of the titlestring
     -- opt.titlestring = "%<%F%=%l/%L - nvim" -- what the title of the window will be set to
     -- opt.titlestring = "%<%F%=%l/%L - nvim" -- what the title of the window will be set to
     undodir = undodir, -- set an undo directory
     undodir = undodir, -- set an undo directory
     undofile = true, -- enable persistent undo
     undofile = true, -- enable persistent undo
-    updatetime = 300, -- faster completion
+    updatetime = 100, -- faster completion
     writebackup = false, -- if a file is being edited by another program (or was written to file while editing with another program), it is not allowed to be edited
     writebackup = false, -- if a file is being edited by another program (or was written to file while editing with another program), it is not allowed to be edited
     expandtab = true, -- convert tabs to spaces
     expandtab = true, -- convert tabs to spaces
     shiftwidth = 2, -- the number of spaces inserted for each indentation
     shiftwidth = 2, -- the number of spaces inserted for each indentation
     tabstop = 2, -- insert 2 spaces for a tab
     tabstop = 2, -- insert 2 spaces for a tab
     cursorline = true, -- highlight the current line
     cursorline = true, -- highlight the current line
     number = true, -- set numbered lines
     number = true, -- set numbered lines
-    relativenumber = false, -- set relative numbered lines
     numberwidth = 4, -- set number column width to 2 {default 4}
     numberwidth = 4, -- set number column width to 2 {default 4}
     signcolumn = "yes", -- always show the sign column, otherwise it would shift the text each time
     signcolumn = "yes", -- always show the sign column, otherwise it would shift the text each time
     wrap = false, -- display lines as one long line
     wrap = false, -- display lines as one long line
     shadafile = join_paths(get_cache_dir(), "lvim.shada"),
     shadafile = join_paths(get_cache_dir(), "lvim.shada"),
     scrolloff = 8, -- minimal number of screen lines to keep above and below the cursor.
     scrolloff = 8, -- minimal number of screen lines to keep above and below the cursor.
     sidescrolloff = 8, -- minimal number of screen lines to keep left and right of the cursor.
     sidescrolloff = 8, -- minimal number of screen lines to keep left and right of the cursor.
+    showcmd = false,
+    ruler = false,
+    laststatus = 3,
   }
   }
 
 
   ---  SETTINGS  ---
   ---  SETTINGS  ---
+  vim.opt.spelllang:append "cjk" -- disable spellchecking for asian characters (VIM algorithm does not support it)
   vim.opt.shortmess:append "c" -- don't show redundant messages from ins-completion-menu
   vim.opt.shortmess:append "c" -- don't show redundant messages from ins-completion-menu
   vim.opt.shortmess:append "I" -- don't show the default intro message
   vim.opt.shortmess:append "I" -- don't show the default intro message
   vim.opt.whichwrap:append "<,>,[,],h,l"
   vim.opt.whichwrap:append "<,>,[,],h,l"

+ 4 - 1
lua/lvim/core/alpha.lua

@@ -65,7 +65,10 @@ local function configure_additional_autocmds()
 end
 end
 
 
 function M.setup()
 function M.setup()
-  local alpha = require "alpha"
+  local status_ok, alpha = pcall(require, "alpha")
+  if not status_ok then
+    return
+  end
   local mode = lvim.builtin.alpha.mode
   local mode = lvim.builtin.alpha.mode
   local config = lvim.builtin.alpha[mode].config
   local config = lvim.builtin.alpha[mode].config
 
 

+ 100 - 37
lua/lvim/core/alpha/dashboard.lua

@@ -1,32 +1,86 @@
 local M = {}
 local M = {}
 
 
+local banner = {
+  "                ⢀⣀⣤⣤⣤⣶⣶⣶⣶⣶⣶⣤⣤⣤⣀⡀                ",
+  "             ⣀⣤⣶⣿⠿⠟⠛⠉⠉⠉⠁⠈⠉⠉⠉⠛⠛⠿⣿⣷⣦⣀             ",
+  "          ⢀⣤⣾⡿⠛⠉                ⠉⠛⢿⣷⣤⡀          ",
+  "         ⣴⣿⡿⠃                      ⠙⠻⣿⣦         ",
+  " ⢀⣠⣤⣤⣤⣤⣤⣾⣿⣉⣀⡀                        ⠙⢻⣷⡄       ",
+  "⣼⠋⠁   ⢠⣿⡟ ⠉⠉⠉⠛⠛⠶⠶⣤⣄⣀    ⣀⣀      ⢠⣤⣤⡄   ⢻⣿⣆      ",
+  "⢻⡄   ⢰⣿⡟        ⢠⣿⣿⣿⠉⠛⠲⣾⣿⣿⣷    ⢀⣾⣿⣿⠁    ⢻⣿⡆     ",
+  " ⠹⣦⡀ ⣿⣿⠁        ⢸⣿⣿⡇   ⠻⣿⣿⠟⠳⠶⣤⣀⣸⣿⣿⠇      ⣿⣷     ",
+  "   ⠙⢷⣿⡇         ⣸⣿⣿⠃          ⢸⣿⣿⢷⣤⡀     ⢸⣿⡆    ",
+  "    ⢸⣿⠇         ⣿⣿⣿     ⣿⣿⣷  ⢠⣿⣿⡏ ⠈⠙⠳⢦⣄  ⠈⣿⡇    ",
+  "    ⢸⣿⡆        ⢸⣿⣿⡇     ⣿⣿⣿ ⢀⣿⣿⡟      ⠈⠙⠷⣤⣿⡇    ",
+  "    ⠘⣿⡇        ⣼⣿⣿⠁     ⣿⣿⣿ ⣼⣿⣿⠃         ⢸⣿⠷⣄⡀  ",
+  "     ⣿⣿        ⣿⣿⡿      ⣿⣿⣿⢸⣿⣿⠃          ⣾⡿ ⠈⠻⣆ ",
+  "     ⠸⣿⣧      ⢸⣿⣿⣇⣀⣀⣀⣀⣀⣀⣸⣿⣿⣿⣿⠇          ⣼⣿⠇   ⠘⣧",
+  "      ⠹⣿⣧     ⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏          ⣼⣿⠏    ⣠⡿",
+  "       ⠘⢿⣷⣄   ⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉         ⢠⣼⡿⠛⠛⠛⠛⠛⠛⠉ ",
+  "         ⠻⣿⣦⣄                      ⣀⣴⣿⠟         ",
+  "          ⠈⠛⢿⣶⣤⣀                ⣀⣤⣶⡿⠛⠁          ",
+  "             ⠉⠻⢿⣿⣶⣤⣤⣀⣀⡀  ⢀⣀⣀⣠⣤⣶⣿⡿⠟⠋             ",
+  "                ⠈⠉⠙⠛⠻⠿⠿⠿⠿⠿⠿⠟⠛⠋⠉⠁                ",
+}
+
+M.banner_alt_1 = {
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣤⣶⣶⣶⣶⣶⣶⣶⣦⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⣾⣿⠿⠛⠛⠉⠉⠉⠉⠉⠉⠉⠙⠛⠻⢿⣿⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠻⢿⣷⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠒⠈⠉⠉⠉⠉⠉⣹⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡀⠀⠀⠀⠀⠀⠀⣰⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⠀⢰⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⡀⠀⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢺⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠉⠑⠢⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡇⠀⠀⠀⠈⠑⠢⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠉⠐⠢⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⡟⠀⠈⠑⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠁⠒⠠⠤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⠁⠀⠀⢀⣼⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠁⠒⠂⠤⠤⠀⣀⡀⠀⠀⠀⣼⣿⠇⠀⠀⢀⣸⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠀⣿⡟⠀⠀⠀⠀⠀⠀⣤⡄⠀⠀⠀⣠⣤⠀⠀⢠⣭⣀⣤⣤⣤⡀⠀⠀⠀⢀⣤⣤⣤⣤⡀⠀⠀⠀⢠⣤⢀⣤⣤⣄⠀⠀⣿⣿⠀⠉⣹⣿⠏⠉⠉⢱⣶⣶⣶⡦⠀⠀⠀⢠⣶⣦⣴⣦⣠⣴⣦⡀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⢠⣿⠇⠀⠀⠀⣿⡇⠀⠀⣿⡿⠉⠀⠈⣿⣧⠀⠀⠰⠿⠋⠀⠀⢹⣿⠀⠀⠀⣿⡿⠋⠀⠹⠿⠀⠀⢻⣿⡇⢠⣿⡟⠀⠀⠀⠈⠉⢹⣿⡇⠀⠀⠀⢸⣿⡏⢹⣿⡏⢹⣿⡇⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⢰⣿⠃⠀⢠⣿⡇⠀⠀⠀⣿⡇⠀⠀⣠⣴⡶⠶⠶⣿⣿⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⠀⢸⣿⣇⣿⡿⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⠀⣿⣿⠀⣾⣿⠀⣾⣿⠁⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⣿⣟⠀⠀⠀⠀⠀⠀⢻⣿⡀⠀⢀⣼⣿⠀⠀⢸⣿⠀⠀⠀⢰⣿⠇⠀⢰⣿⣇⠀⠀⣠⣿⡏⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⠁⠀⠀⠀⣀⣀⣠⣿⣿⣀⡀⠀⢠⣿⡟⢠⣿⡟⢀⣿⡿⠀⠀⠀⠀⠀",
+  "⠀⠀⠀⠀⠀⠛⠛⠛⠛⠛⠛⠁⠀⠈⠛⠿⠟⠋⠛⠃⠀⠀⠛⠛⠀⠀⠀⠘⠛⠀⠀⠀⠙⠿⠿⠛⠙⠛⠃⠀⠀⠚⠛⠀⠀⠀⠀⠀⠀⠀⠘⠿⠿⠃⠀⠀⠀⠀⠿⠿⠿⠿⠿⠿⠿⠀⠸⠿⠇⠸⠿⠇⠸⠿⠇⠀⠀⠀⠀⠀",
+  "                                                                                ",
+}
+
+M.banner_alt_2 = {
+  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠟⠛⠛⠉⠉⠉⠉⠉⠉⠛⠛⠻⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⠉⠀⣀⣤⣴⣶⣶⣾⣿⣿⣷⣶⣶⣦⣤⣀⠀⠉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⢀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠈⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+  "⣿⣿⠿⠟⠛⠛⠛⠛⠛⠁⠀⠾⠿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿",
+  "⣿⠁⣴⣾⣿⣿⣿⡟⠀⣰⣿⣶⣶⣶⣤⣤⣉⣉⠛⠛⠿⠿⣿⣿⡿⠿⠿⣿⣿⣿⣿⣿⣿⡟⠛⠛⢛⣿⣿⣿⣆⠀⢻⣿⣿⣿⣿⣿⣿⣿",
+  "⣿⡄⠻⣿⣿⣿⡟⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⣦⣤⡈⠀⠀⠀⠈⣿⣿⣿⣿⡿⠁⠀⠀⣾⣿⣿⣿⣿⡄⠀⢻⣿⣿⣿⣿⣿⣿",
+  "⣿⣿⣄⠙⠿⣿⠁⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣄⠀⠀⣠⣄⣉⠛⠻⠃⠀⠀⣼⣿⣿⣿⣿⣿⣿⡀⠈⣿⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣷⣦⡈⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠆⠀⠀⡀⠛⠿⣿⣿⣿⣿⣿⡇⠀⢻⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⡇⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⢀⣿⣿⣿⣿⡇⠀⠀⠘⣿⣿⡟⠀⠀⢰⣿⣷⣦⣌⡙⠻⢿⣿⣷⠀⢸⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⡇⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⠀⠀⠀⣿⡿⠀⠀⢀⣿⣿⣿⣿⣿⣿⣷⣤⣈⠛⠀⢸⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⣧⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⣾⣿⣿⣿⣿⣿⠀⠀⠀⣿⠁⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⡈⠻⢿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⣿⡀⠈⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⢀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠃⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⢀⣿⣶⣄⠙⣿⣿",
+  "⣿⣿⣿⣿⣿⣿⣧⠀⠘⣿⣿⣿⣿⣿⣿⡇⠀⠀⠸⠿⠿⠿⠿⠿⠿⠇⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⣼⣿⣿⣿⣦⠘⣿",
+  "⣿⣿⣿⣿⣿⣿⣿⣧⠀⠹⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⣼⣿⣿⣿⡿⠟⢀⣿",
+  "⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠈⢿⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⢀⣤⣤⣤⣤⣤⣴⣶⣿⣿",
+  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠈⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⢀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⣀⠀⠉⠛⠻⠿⠿⢿⣿⣿⡿⠿⠿⠟⠛⠉⠀⣀⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣦⣤⣤⣀⣀⣀⣀⣀⣀⣤⣤⣴⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+}
+
+if vim.o.lines < 36 then
+  banner = vim.list_slice(banner, 16, 22)
+end
+
 function M.get_sections()
 function M.get_sections()
   local header = {
   local header = {
     type = "text",
     type = "text",
-    val = {
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣤⣶⣶⣶⣶⣶⣶⣶⣦⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⣾⣿⠿⠛⠛⠉⠉⠉⠉⠉⠉⠉⠙⠛⠻⢿⣿⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠻⢿⣷⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠒⠈⠉⠉⠉⠉⠉⣹⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡀⠀⠀⠀⠀⠀⠀⣰⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⠀⢰⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⡀⠀⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢺⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠉⠑⠢⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡇⠀⠀⠀⠈⠑⠢⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠉⠐⠢⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⡟⠀⠈⠑⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠁⠒⠠⠤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⠁⠀⠀⢀⣼⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠁⠒⠂⠤⠤⠀⣀⡀⠀⠀⠀⣼⣿⠇⠀⠀⢀⣸⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠀⣿⡟⠀⠀⠀⠀⠀⠀⣤⡄⠀⠀⠀⣠⣤⠀⠀⢠⣭⣀⣤⣤⣤⡀⠀⠀⠀⢀⣤⣤⣤⣤⡀⠀⠀⠀⢠⣤⢀⣤⣤⣄⠀⠀⣿⣿⠀⠉⣹⣿⠏⠉⠉⢱⣶⣶⣶⡦⠀⠀⠀⢠⣶⣦⣴⣦⣠⣴⣦⡀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⢠⣿⠇⠀⠀⠀⣿⡇⠀⠀⣿⡿⠉⠀⠈⣿⣧⠀⠀⠰⠿⠋⠀⠀⢹⣿⠀⠀⠀⣿⡿⠋⠀⠹⠿⠀⠀⢻⣿⡇⢠⣿⡟⠀⠀⠀⠈⠉⢹⣿⡇⠀⠀⠀⢸⣿⡏⢹⣿⡏⢹⣿⡇⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⢰⣿⠃⠀⢠⣿⡇⠀⠀⠀⣿⡇⠀⠀⣠⣴⡶⠶⠶⣿⣿⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⠀⢸⣿⣇⣿⡿⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⠀⣿⣿⠀⣾⣿⠀⣾⣿⠁⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⣿⣟⠀⠀⠀⠀⠀⠀⢻⣿⡀⠀⢀⣼⣿⠀⠀⢸⣿⠀⠀⠀⢰⣿⠇⠀⢰⣿⣇⠀⠀⣠⣿⡏⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⠁⠀⠀⠀⣀⣀⣠⣿⣿⣀⡀⠀⢠⣿⡟⢠⣿⡟⢀⣿⡿⠀⠀⠀⠀⠀",
-      "⠀⠀⠀⠀⠀⠛⠛⠛⠛⠛⠛⠁⠀⠈⠛⠿⠟⠋⠛⠃⠀⠀⠛⠛⠀⠀⠀⠘⠛⠀⠀⠀⠙⠿⠿⠛⠙⠛⠃⠀⠀⠚⠛⠀⠀⠀⠀⠀⠀⠀⠘⠿⠿⠃⠀⠀⠀⠀⠿⠿⠿⠿⠿⠿⠿⠀⠸⠿⠇⠸⠿⠇⠸⠿⠇⠀⠀⠀⠀⠀",
-      "                                                                                ",
-    },
+    val = banner,
     opts = {
     opts = {
       position = "center",
       position = "center",
       hl = "Label",
       hl = "Label",
@@ -48,21 +102,30 @@ function M.get_sections()
       hl = "Number",
       hl = "Number",
     },
     },
   }
   }
+  local buttons = {}
 
 
-  local buttons = {
-    entries = {
-      { "SPC f", "  Find File", "<CMD>Telescope find_files<CR>" },
-      { "SPC n", "  New File", "<CMD>ene!<CR>" },
-      { "SPC P", "  Recent Projects ", "<CMD>Telescope projects<CR>" },
-      { "SPC s r", "  Recently Used Files", "<CMD>Telescope oldfiles<CR>" },
-      { "SPC s t", "  Find Word", "<CMD>Telescope live_grep<CR>" },
-      {
-        "SPC L c",
-        "  Configuration",
-        "<CMD>edit " .. require("lvim.config"):get_user_config_path() .. " <CR>",
+  local status_ok, dashboard = pcall(require, "alpha.themes.dashboard")
+  if status_ok then
+    local function button(sc, txt, keybind, keybind_opts)
+      local b = dashboard.button(sc, txt, keybind, keybind_opts)
+      b.opts.hl_shortcut = "Macro"
+      return b
+    end
+    buttons = {
+      val = {
+        button("f", lvim.icons.ui.FindFile .. "  Find File", "<CMD>Telescope find_files<CR>"),
+        button("n", lvim.icons.ui.NewFile .. "  New File", "<CMD>ene!<CR>"),
+        button("p", lvim.icons.ui.Project .. "  Projects ", "<CMD>Telescope projects<CR>"),
+        button("r", lvim.icons.ui.History .. "  Recent files", ":Telescope oldfiles <CR>"),
+        button("t", lvim.icons.ui.FindText .. "  Find Text", "<CMD>Telescope live_grep<CR>"),
+        button(
+          "c",
+          lvim.icons.ui.Gear .. "  Configuration",
+          "<CMD>edit " .. require("lvim.config"):get_user_config_path() .. " <CR>"
+        ),
       },
       },
-    },
-  }
+    }
+  end
 
 
   return {
   return {
     header = header,
     header = header,

+ 1 - 1
lua/lvim/core/alpha/startify.lua

@@ -19,7 +19,7 @@ function M.get_sections()
 
 
   local top_buttons = {
   local top_buttons = {
     entries = {
     entries = {
-      { "e", "  New File", "<CMD>ene!<CR>" },
+      { "e", lvim.icons.ui.NewFile .. " New File", "<CMD>ene!<CR>" },
     },
     },
     val = {},
     val = {},
   }
   }

+ 66 - 15
lua/lvim/core/autocmds.lua

@@ -3,13 +3,25 @@ local Log = require "lvim.core.log"
 
 
 --- Load the default set of autogroups and autocommands.
 --- Load the default set of autogroups and autocommands.
 function M.load_defaults()
 function M.load_defaults()
-  local user_config_file = require("lvim.config"):get_user_config_path()
-
-  if vim.loop.os_uname().version:match "Windows" then
-    -- autocmds require forward slashes even on windows
-    user_config_file = user_config_file:gsub("\\", "/")
-  end
-
+  vim.api.nvim_create_autocmd({ "FileType" }, {
+    pattern = {
+      "Jaq",
+      "qf",
+      "help",
+      "man",
+      "lspinfo",
+      "spectre_panel",
+      "lir",
+      "DressingSelect",
+      "tsplayground",
+    },
+    callback = function()
+      vim.cmd [[
+      nnoremap <silent> <buffer> q :close<CR>
+      set nobuflisted
+    ]]
+    end,
+  })
   local definitions = {
   local definitions = {
     {
     {
       "TextYankPost",
       "TextYankPost",
@@ -18,19 +30,16 @@ function M.load_defaults()
         pattern = "*",
         pattern = "*",
         desc = "Highlight text on yank",
         desc = "Highlight text on yank",
         callback = function()
         callback = function()
-          require("vim.highlight").on_yank { higroup = "Search", timeout = 200 }
+          require("vim.highlight").on_yank { higroup = "Search", timeout = 100 }
         end,
         end,
       },
       },
     },
     },
     {
     {
-      "BufWritePost",
+      "FileType",
       {
       {
-        group = "_general_settings",
-        pattern = user_config_file,
-        desc = "Trigger LvimReload on saving " .. vim.fn.expand "%:~",
-        callback = function()
-          require("lvim.config"):reload()
-        end,
+        group = "_hide_dap_repl",
+        pattern = "dap-repl",
+        command = "set nobuflisted",
       },
       },
     },
     },
     {
     {
@@ -73,6 +82,31 @@ function M.load_defaults()
         command = "tabdo wincmd =",
         command = "tabdo wincmd =",
       },
       },
     },
     },
+    {
+      "FileType",
+      {
+        group = "_filetype_settings",
+        pattern = "alpha",
+        callback = function()
+          vim.cmd [[
+            nnoremap <silent> <buffer> q :qa<CR>
+            nnoremap <silent> <buffer> <esc> :qa<CR>
+            set nobuflisted
+          ]]
+        end,
+      },
+    },
+    {
+      "FileType",
+      {
+        group = "_filetype_settings",
+        pattern = "lir",
+        callback = function()
+          vim.opt_local.number = false
+          vim.opt_local.relativenumber = false
+        end,
+      },
+    },
   }
   }
 
 
   M.define_autocmds(definitions)
   M.define_autocmds(definitions)
@@ -129,6 +163,23 @@ function M.toggle_format_on_save()
   end
   end
 end
 end
 
 
+function M.enable_reload_config_on_save()
+  local user_config_file = require("lvim.config"):get_user_config_path()
+
+  if vim.loop.os_uname().version:match "Windows" then
+    -- autocmds require forward slashes even on windows
+    user_config_file = user_config_file:gsub("\\", "/")
+  end
+  vim.api.nvim_create_autocmd("BufWritePost", {
+    group = "_general_settings",
+    pattern = user_config_file,
+    desc = "Trigger LvimReload on saving config.lua",
+    callback = function()
+      require("lvim.config"):reload()
+    end,
+  })
+end
+
 function M.enable_transparent_mode()
 function M.enable_transparent_mode()
   vim.api.nvim_create_autocmd("ColorScheme", {
   vim.api.nvim_create_autocmd("ColorScheme", {
     pattern = "*",
     pattern = "*",

+ 4 - 1
lua/lvim/core/autopairs.lua

@@ -47,7 +47,10 @@ function M.config()
 end
 end
 
 
 M.setup = function()
 M.setup = function()
-  local autopairs = require "nvim-autopairs"
+  local status_ok, autopairs = pcall(require, "nvim-autopairs")
+  if not status_ok then
+    return
+  end
   local Rule = require "nvim-autopairs.rule"
   local Rule = require "nvim-autopairs.rule"
 
 
   autopairs.setup {
   autopairs.setup {

+ 226 - 0
lua/lvim/core/breadcrumbs.lua

@@ -0,0 +1,226 @@
+local M = {}
+
+-- local Log = require "lvim.core.log"
+
+local icons = lvim.icons.kind
+
+M.config = function()
+  lvim.builtin.breadcrumbs = {
+    active = true,
+    on_config_done = nil,
+    winbar_filetype_exclude = {
+      "help",
+      "startify",
+      "dashboard",
+      "packer",
+      "neo-tree",
+      "neogitstatus",
+      "NvimTree",
+      "Trouble",
+      "alpha",
+      "lir",
+      "Outline",
+      "spectre_panel",
+      "toggleterm",
+      "DressingSelect",
+      "Jaq",
+      "harpoon",
+      "dap-repl",
+      "dap-terminal",
+      "dapui_console",
+      "lab",
+      "Markdown",
+      "notify",
+      "noice",
+      "",
+    },
+    options = {
+      icons = {
+        Array = icons.Array .. " ",
+        Boolean = icons.Boolean,
+        Class = icons.Class .. " ",
+        Color = icons.Color .. " ",
+        Constant = icons.Constant .. " ",
+        Constructor = icons.Constructor .. " ",
+        Enum = icons.Enum .. " ",
+        EnumMember = icons.EnumMember .. " ",
+        Event = icons.Event .. " ",
+        Field = icons.Field .. " ",
+        File = icons.File .. " ",
+        Folder = icons.Folder .. " ",
+        Function = icons.Function .. " ",
+        Interface = icons.Interface .. " ",
+        Key = icons.Key .. " ",
+        Keyword = icons.Keyword .. " ",
+        Method = icons.Method .. " ",
+        Module = icons.Module .. " ",
+        Namespace = icons.Namespace .. " ",
+        Null = icons.Null .. " ",
+        Number = icons.Number .. " ",
+        Object = icons.Object .. " ",
+        Operator = icons.Operator .. " ",
+        Package = icons.Package .. " ",
+        Property = icons.Property .. " ",
+        Reference = icons.Reference .. " ",
+        Snippet = icons.Snippet .. " ",
+        String = icons.String .. " ",
+        Struct = icons.Struct .. " ",
+        Text = icons.Text .. " ",
+        TypeParameter = icons.TypeParameter .. " ",
+        Unit = icons.Unit .. " ",
+        Value = icons.Value .. " ",
+        Variable = icons.Variable .. " ",
+      },
+      highlight = true,
+      separator = " " .. ">" .. " ",
+      depth_limit = 0,
+      depth_limit_indicator = "..",
+    },
+  }
+end
+
+M.setup = function()
+  local status_ok, navic = pcall(require, "nvim-navic")
+  if not status_ok then
+    return
+  end
+
+  M.create_winbar()
+  navic.setup(lvim.builtin.breadcrumbs.options)
+
+  if lvim.builtin.breadcrumbs.on_config_done then
+    lvim.builtin.breadcrumbs.on_config_done()
+  end
+end
+
+M.get_filename = function()
+  local filename = vim.fn.expand "%:t"
+  local extension = vim.fn.expand "%:e"
+  local f = require "lvim.utils.functions"
+
+  if not f.isempty(filename) then
+    local file_icon, file_icon_color =
+      require("nvim-web-devicons").get_icon_color(filename, extension, { default = true })
+
+    local hl_group = "FileIconColor" .. extension
+
+    vim.api.nvim_set_hl(0, hl_group, { fg = file_icon_color })
+    if f.isempty(file_icon) then
+      file_icon = lvim.icons.kind.File
+    end
+
+    local buf_ft = vim.bo.filetype
+
+    if buf_ft == "dapui_breakpoints" then
+      file_icon = lvim.icons.ui.Bug
+    end
+
+    if buf_ft == "dapui_stacks" then
+      file_icon = lvim.icons.ui.Stacks
+    end
+
+    if buf_ft == "dapui_scopes" then
+      file_icon = lvim.icons.ui.Scopes
+    end
+
+    if buf_ft == "dapui_watches" then
+      file_icon = lvim.icons.ui.Watches
+    end
+
+    -- if buf_ft == "dapui_console" then
+    --   file_icon = lvim.icons.ui.DebugConsole
+    -- end
+
+    local navic_text = vim.api.nvim_get_hl_by_name("Normal", true)
+    vim.api.nvim_set_hl(0, "Winbar", { fg = navic_text.foreground })
+
+    return " " .. "%#" .. hl_group .. "#" .. file_icon .. "%*" .. " " .. "%#Winbar#" .. filename .. "%*"
+  end
+end
+
+local get_gps = function()
+  local status_gps_ok, gps = pcall(require, "nvim-navic")
+  if not status_gps_ok then
+    return ""
+  end
+
+  local status_ok, gps_location = pcall(gps.get_location, {})
+  if not status_ok then
+    return ""
+  end
+
+  if not gps.is_available() or gps_location == "error" then
+    return ""
+  end
+
+  if not require("lvim.utils.functions").isempty(gps_location) then
+    -- TODO: replace with chevron
+    return ">" .. " " .. gps_location
+  else
+    return ""
+  end
+end
+
+local excludes = function()
+  return vim.tbl_contains(lvim.builtin.breadcrumbs.winbar_filetype_exclude or {}, vim.bo.filetype)
+end
+
+M.get_winbar = function()
+  if excludes() then
+    return
+  end
+  local f = require "lvim.utils.functions"
+  local value = M.get_filename()
+
+  local gps_added = false
+  if not f.isempty(value) then
+    local gps_value = get_gps()
+    value = value .. " " .. gps_value
+    if not f.isempty(gps_value) then
+      gps_added = true
+    end
+  end
+
+  if not f.isempty(value) and f.get_buf_option "mod" then
+    -- TODO: replace with circle
+    local mod = "%#LspCodeLens#" .. lvim.icons.ui.Circle .. "%*"
+    if gps_added then
+      value = value .. " " .. mod
+    else
+      value = value .. mod
+    end
+  end
+
+  local num_tabs = #vim.api.nvim_list_tabpages()
+
+  if num_tabs > 1 and not f.isempty(value) then
+    local tabpage_number = tostring(vim.api.nvim_tabpage_get_number(0))
+    value = value .. "%=" .. tabpage_number .. "/" .. tostring(num_tabs)
+  end
+
+  local status_ok, _ = pcall(vim.api.nvim_set_option_value, "winbar", value, { scope = "local" })
+  if not status_ok then
+    return
+  end
+end
+
+M.create_winbar = function()
+  vim.api.nvim_create_augroup("_winbar", {})
+  if vim.fn.has "nvim-0.8" == 1 then
+    vim.api.nvim_create_autocmd(
+      { "CursorMoved", "CursorHold", "BufWinEnter", "BufFilePost", "InsertEnter", "BufWritePost", "TabClosed" },
+      {
+        group = "_winbar",
+        callback = function()
+          local status_ok, _ = pcall(vim.api.nvim_buf_get_var, 0, "lsp_floating_window")
+          if not status_ok then
+            -- TODO:
+            require("lvim.core.breadcrumbs").get_winbar()
+          end
+        end,
+      }
+    )
+  end
+end
+
+return M

+ 18 - 8
lua/lvim/core/bufferline.lua

@@ -6,7 +6,11 @@ end
 
 
 local function diagnostics_indicator(num, _, diagnostics, _)
 local function diagnostics_indicator(num, _, diagnostics, _)
   local result = {}
   local result = {}
-  local symbols = { error = "", warning = "", info = "" }
+  local symbols = {
+    error = lvim.icons.diagnostics.Error,
+    warning = lvim.icons.diagnostics.Warning,
+    info = lvim.icons.diagnostics.Information,
+  }
   if not lvim.use_icons then
   if not lvim.use_icons then
     return "(" .. num .. ")"
     return "(" .. num .. ")"
   end
   end
@@ -59,14 +63,14 @@ M.config = function()
       left_mouse_command = "buffer %d", -- can be a string | function, see "Mouse actions"
       left_mouse_command = "buffer %d", -- can be a string | function, see "Mouse actions"
       middle_mouse_command = nil, -- can be a string | function, see "Mouse actions"
       middle_mouse_command = nil, -- can be a string | function, see "Mouse actions"
       indicator = {
       indicator = {
-        icon = "▎", -- this should be omitted if indicator style is not 'icon'
+        icon = lvim.icons.ui.BoldLineLeft, -- this should be omitted if indicator style is not 'icon'
         style = "icon", -- can also be 'underline'|'none',
         style = "icon", -- can also be 'underline'|'none',
       },
       },
-      buffer_close_icon = "",
-      modified_icon = "●",
-      close_icon = "",
-      left_trunc_marker = "",
-      right_trunc_marker = "",
+      buffer_close_icon = lvim.icons.ui.Close,
+      modified_icon = lvim.icons.ui.Circle,
+      close_icon = lvim.icons.ui.BoldClose,
+      left_trunc_marker = lvim.icons.ui.ArrowCircleLeft,
+      right_trunc_marker = lvim.icons.ui.ArrowCircleRight,
       --- name_formatter can be used to change the buffer's label in the bufferline.
       --- name_formatter can be used to change the buffer's label in the bufferline.
       --- Please note some names can/will break the
       --- Please note some names can/will break the
       --- bufferline so use this at your discretion knowing that it has
       --- bufferline so use this at your discretion knowing that it has
@@ -140,7 +144,13 @@ end
 
 
 M.setup = function()
 M.setup = function()
   require("lvim.keymappings").load(lvim.builtin.bufferline.keymap)
   require("lvim.keymappings").load(lvim.builtin.bufferline.keymap)
-  require("bufferline").setup {
+
+  local status_ok, bufferline = pcall(require, "bufferline")
+  if not status_ok then
+    return
+  end
+
+  bufferline.setup {
     options = lvim.builtin.bufferline.options,
     options = lvim.builtin.bufferline.options,
     highlights = lvim.builtin.bufferline.highlights,
     highlights = lvim.builtin.bufferline.highlights,
   }
   }

+ 7 - 1
lua/lvim/core/builtins/init.lua

@@ -1,6 +1,7 @@
 local M = {}
 local M = {}
 
 
 local builtins = {
 local builtins = {
+  "lvim.core.theme",
   "lvim.core.which-key",
   "lvim.core.which-key",
   "lvim.core.gitsigns",
   "lvim.core.gitsigns",
   "lvim.core.cmp",
   "lvim.core.cmp",
@@ -9,6 +10,10 @@ local builtins = {
   "lvim.core.telescope",
   "lvim.core.telescope",
   "lvim.core.treesitter",
   "lvim.core.treesitter",
   "lvim.core.nvimtree",
   "lvim.core.nvimtree",
+  "lvim.core.lir",
+  "lvim.core.illuminate",
+  "lvim.core.indentlines",
+  "lvim.core.breadcrumbs",
   "lvim.core.project",
   "lvim.core.project",
   "lvim.core.bufferline",
   "lvim.core.bufferline",
   "lvim.core.autopairs",
   "lvim.core.autopairs",
@@ -21,7 +26,8 @@ local builtins = {
 
 
 function M.config(config)
 function M.config(config)
   for _, builtin_path in ipairs(builtins) do
   for _, builtin_path in ipairs(builtins) do
-    local builtin = require(builtin_path)
+    local builtin = reload(builtin_path)
+
     builtin.config(config)
     builtin.config(config)
   end
   end
 end
 end

+ 113 - 34
lua/lvim/core/cmp.lua

@@ -19,6 +19,7 @@ end
 local function feedkeys(key, mode)
 local function feedkeys(key, mode)
   vim.api.nvim_feedkeys(T(key), mode, true)
   vim.api.nvim_feedkeys(T(key), mode, true)
 end
 end
+
 M.methods.feedkeys = feedkeys
 M.methods.feedkeys = feedkeys
 
 
 ---when inside a snippet, seeks to the nearest luasnip field if possible, and checks if it is jumpable
 ---when inside a snippet, seeks to the nearest luasnip field if possible, and checks if it is jumpable
@@ -113,6 +114,7 @@ local function jumpable(dir)
     return luasnip.in_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable(1)
     return luasnip.in_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable(1)
   end
   end
 end
 end
+
 M.methods.jumpable = jumpable
 M.methods.jumpable = jumpable
 
 
 M.config = function()
 M.config = function()
@@ -135,39 +137,13 @@ M.config = function()
       keyword_length = 1,
       keyword_length = 1,
     },
     },
     experimental = {
     experimental = {
-      ghost_text = true,
+      ghost_text = false,
       native_menu = false,
       native_menu = false,
     },
     },
     formatting = {
     formatting = {
       fields = { "kind", "abbr", "menu" },
       fields = { "kind", "abbr", "menu" },
       max_width = 0,
       max_width = 0,
-      kind_icons = {
-        Class = " ",
-        Color = " ",
-        Constant = "ﲀ ",
-        Constructor = " ",
-        Enum = "練",
-        EnumMember = " ",
-        Event = " ",
-        Field = " ",
-        File = "",
-        Folder = " ",
-        Function = " ",
-        Interface = "ﰮ ",
-        Keyword = " ",
-        Method = " ",
-        Module = " ",
-        Operator = "",
-        Property = " ",
-        Reference = " ",
-        Snippet = " ",
-        Struct = " ",
-        Text = " ",
-        TypeParameter = " ",
-        Unit = "塞",
-        Value = " ",
-        Variable = " ",
-      },
+      kind_icons = lvim.icons.kind,
       source_names = {
       source_names = {
         nvim_lsp = "(LSP)",
         nvim_lsp = "(LSP)",
         emoji = "(Emoji)",
         emoji = "(Emoji)",
@@ -178,6 +154,8 @@ M.config = function()
         luasnip = "(Snippet)",
         luasnip = "(Snippet)",
         buffer = "(Buffer)",
         buffer = "(Buffer)",
         tmux = "(TMUX)",
         tmux = "(TMUX)",
+        copilot = "(Copilot)",
+        treesitter = "(TreeSitter)",
       },
       },
       duplicates = {
       duplicates = {
         buffer = 1,
         buffer = 1,
@@ -189,10 +167,40 @@ M.config = function()
       format = function(entry, vim_item)
       format = function(entry, vim_item)
         local max_width = lvim.builtin.cmp.formatting.max_width
         local max_width = lvim.builtin.cmp.formatting.max_width
         if max_width ~= 0 and #vim_item.abbr > max_width then
         if max_width ~= 0 and #vim_item.abbr > max_width then
-          vim_item.abbr = string.sub(vim_item.abbr, 1, max_width - 1) .. "…"
+          vim_item.abbr = string.sub(vim_item.abbr, 1, max_width - 1) .. lvim.icons.ui.Ellipsis
         end
         end
         if lvim.use_icons then
         if lvim.use_icons then
           vim_item.kind = lvim.builtin.cmp.formatting.kind_icons[vim_item.kind]
           vim_item.kind = lvim.builtin.cmp.formatting.kind_icons[vim_item.kind]
+
+          -- TODO: not sure why I can't put this anywhere else
+          vim.api.nvim_set_hl(0, "CmpItemKindCopilot", { fg = "#6CC644" })
+          if entry.source.name == "copilot" then
+            vim_item.kind = lvim.icons.git.Octoface
+            vim_item.kind_hl_group = "CmpItemKindCopilot"
+          end
+
+          vim.api.nvim_set_hl(0, "CmpItemKindTabnine", { fg = "#CA42F0" })
+          if entry.source.name == "cmp_tabnine" then
+            vim_item.kind = lvim.icons.misc.Robot
+            vim_item.kind_hl_group = "CmpItemKindTabnine"
+          end
+
+          vim.api.nvim_set_hl(0, "CmpItemKindCrate", { fg = "#F64D00" })
+          if entry.source.name == "crates" then
+            vim_item.kind = lvim.icons.misc.Package
+            vim_item.kind_hl_group = "CmpItemKindCrate"
+          end
+
+          if entry.source.name == "lab.quick_data" then
+            vim_item.kind = lvim.icons.misc.CircuitBoard
+            vim_item.kind_hl_group = "CmpItemKindConstant"
+          end
+
+          vim.api.nvim_set_hl(0, "CmpItemKindEmoji", { fg = "#FDE030" })
+          if entry.source.name == "emoji" then
+            vim_item.kind = lvim.icons.misc.Smiley
+            vim_item.kind_hl_group = "CmpItemKindEmoji"
+          end
         end
         end
         vim_item.menu = lvim.builtin.cmp.formatting.source_names[entry.source.name]
         vim_item.menu = lvim.builtin.cmp.formatting.source_names[entry.source.name]
         vim_item.dup = lvim.builtin.cmp.formatting.duplicates[entry.source.name]
         vim_item.dup = lvim.builtin.cmp.formatting.duplicates[entry.source.name]
@@ -210,7 +218,50 @@ M.config = function()
       documentation = cmp.config.window.bordered(),
       documentation = cmp.config.window.bordered(),
     },
     },
     sources = {
     sources = {
-      { name = "nvim_lsp" },
+      {
+        name = "copilot",
+        -- keyword_length = 0,
+        max_item_count = 3,
+        trigger_characters = {
+          {
+            ".",
+            ":",
+            "(",
+            "'",
+            '"',
+            "[",
+            ",",
+            "#",
+            "*",
+            "@",
+            "|",
+            "=",
+            "-",
+            "{",
+            "/",
+            "\\",
+            "+",
+            "?",
+            " ",
+            -- "\t",
+            -- "\n",
+          },
+        },
+      },
+      {
+        name = "nvim_lsp",
+        entry_filter = function(entry, ctx)
+          local kind = require("cmp.types").lsp.CompletionItemKind[entry:get_kind()]
+          if kind == "Snippet" and ctx.prev_context.filetype == "java" then
+            return false
+          end
+          if kind == "Text" then
+            return false
+          end
+          return true
+        end,
+      },
+
       { name = "path" },
       { name = "path" },
       { name = "luasnip" },
       { name = "luasnip" },
       { name = "cmp_tabnine" },
       { name = "cmp_tabnine" },
@@ -223,8 +274,8 @@ M.config = function()
       { name = "tmux" },
       { name = "tmux" },
     },
     },
     mapping = cmp.mapping.preset.insert {
     mapping = cmp.mapping.preset.insert {
-      ["<C-k>"] = cmp.mapping.select_prev_item(),
-      ["<C-j>"] = cmp.mapping.select_next_item(),
+      ["<C-k>"] = cmp.mapping(cmp.mapping.select_prev_item(), { "i", "c" }),
+      ["<C-j>"] = cmp.mapping(cmp.mapping.select_next_item(), { "i", "c" }),
       ["<Down>"] = cmp.mapping(cmp.mapping.select_next_item { behavior = cmp.SelectBehavior.Select }, { "i" }),
       ["<Down>"] = cmp.mapping(cmp.mapping.select_next_item { behavior = cmp.SelectBehavior.Select }, { "i" }),
       ["<Up>"] = cmp.mapping(cmp.mapping.select_prev_item { behavior = cmp.SelectBehavior.Select }, { "i" }),
       ["<Up>"] = cmp.mapping(cmp.mapping.select_prev_item { behavior = cmp.SelectBehavior.Select }, { "i" }),
       ["<C-d>"] = cmp.mapping.scroll_docs(-4),
       ["<C-d>"] = cmp.mapping.scroll_docs(-4),
@@ -247,7 +298,8 @@ M.config = function()
         elseif jumpable(1) then
         elseif jumpable(1) then
           luasnip.jump(1)
           luasnip.jump(1)
         elseif has_words_before() then
         elseif has_words_before() then
-          cmp.complete()
+          -- cmp.complete()
+          fallback()
         else
         else
           fallback()
           fallback()
         end
         end
@@ -283,11 +335,38 @@ M.config = function()
         fallback() -- if not exited early, always fallback
         fallback() -- if not exited early, always fallback
       end),
       end),
     },
     },
+    cmdline = {
+      enable = true,
+      options = {
+        {
+          type = ":",
+          sources = {
+            { name = "path" },
+          },
+        },
+        {
+          type = { "/", "?" },
+          sources = {
+            { name = "buffer" },
+          },
+        },
+      },
+    },
   }
   }
 end
 end
 
 
 function M.setup()
 function M.setup()
-  require("cmp").setup(lvim.builtin.cmp)
+  local cmp = require "cmp"
+  cmp.setup(lvim.builtin.cmp)
+
+  if lvim.builtin.cmp.cmdline.enable then
+    for _, option in ipairs(lvim.builtin.cmp.cmdline.options) do
+      cmp.setup.cmdline(option.type, {
+        mapping = cmp.mapping.preset.cmdline(),
+        sources = option.sources,
+      })
+    end
+  end
 end
 end
 
 
 return M
 return M

+ 20 - 24
lua/lvim/core/comment.lua

@@ -1,27 +1,10 @@
 local M = {}
 local M = {}
 
 
 function M.config()
 function M.config()
-  local pre_hook = nil
-  if lvim.builtin.treesitter.context_commentstring.enable then
-    pre_hook = function(ctx)
-      local U = require "Comment.utils"
-
-      -- Determine whether to use linewise or blockwise commentstring
-      local type = ctx.ctype == U.ctype.linewise and "__default" or "__multiline"
-
-      -- Determine the location where to calculate commentstring from
-      local location = nil
-      if ctx.ctype == U.ctype.blockwise then
-        location = require("ts_context_commentstring.utils").get_cursor_location()
-      elseif ctx.cmotion == U.cmotion.v or ctx.cmotion == U.cmotion.V then
-        location = require("ts_context_commentstring.utils").get_visual_start_location()
-      end
-
-      return require("ts_context_commentstring.internal").calculate_commentstring {
-        key = type,
-        location = location,
-      }
-    end
+  local pre_hook
+  local loaded, ts_comment = pcall(require, "ts_context_commentstring.integrations.comment_nvim")
+  if loaded and ts_comment then
+    pre_hook = ts_comment.create_pre_hook()
   end
   end
   lvim.builtin.comment = {
   lvim.builtin.comment = {
     active = true,
     active = true,
@@ -30,6 +13,11 @@ function M.config()
     ---@type boolean
     ---@type boolean
     padding = true,
     padding = true,
 
 
+    ---Whether cursor should stay at the
+    ---same position. Only works in NORMAL
+    ---mode mappings
+    sticky = true,
+
     ---Lines to be ignored while comment/uncomment.
     ---Lines to be ignored while comment/uncomment.
     ---Could be a regex string or a function that returns a regex string.
     ---Could be a regex string or a function that returns a regex string.
     ---Example: Use '^$' to ignore empty lines
     ---Example: Use '^$' to ignore empty lines
@@ -45,9 +33,6 @@ function M.config()
       ---Extra mapping
       ---Extra mapping
       ---Includes `gco`, `gcO`, `gcA`
       ---Includes `gco`, `gcO`, `gcA`
       extra = true,
       extra = true,
-      ---Extended mapping
-      ---Includes `g>`, `g<`, `g>[count]{motion}` and `g<[count]{motion}`
-      extended = false,
     },
     },
 
 
     ---LHS of line and block comment toggle mapping in NORMAL/VISUAL mode
     ---LHS of line and block comment toggle mapping in NORMAL/VISUAL mode
@@ -68,6 +53,17 @@ function M.config()
       block = "gb",
       block = "gb",
     },
     },
 
 
+    ---LHS of extra mappings
+    ---@type table
+    extra = {
+      ---Add comment on the line above
+      above = "gcO",
+      ---Add comment on the line below
+      below = "gco",
+      ---Add comment at the end of line
+      eol = "gcA",
+    },
+
     ---Pre-hook, called before commenting the line
     ---Pre-hook, called before commenting the line
     ---@type function|nil
     ---@type function|nil
     pre_hook = pre_hook,
     pre_hook = pre_hook,

+ 76 - 27
lua/lvim/core/dap.lua

@@ -2,31 +2,37 @@ local M = {}
 
 
 M.config = function()
 M.config = function()
   lvim.builtin.dap = {
   lvim.builtin.dap = {
-    active = false,
+    active = true,
     on_config_done = nil,
     on_config_done = nil,
     breakpoint = {
     breakpoint = {
-      text = "",
-      texthl = "LspDiagnosticsSignError",
+      text = lvim.icons.ui.Bug,
+      texthl = "DiagnosticSignError",
       linehl = "",
       linehl = "",
       numhl = "",
       numhl = "",
     },
     },
     breakpoint_rejected = {
     breakpoint_rejected = {
-      text = "",
-      texthl = "LspDiagnosticsSignHint",
+      text = lvim.icons.ui.Bug,
+      texthl = "DiagnosticSignError",
       linehl = "",
       linehl = "",
       numhl = "",
       numhl = "",
     },
     },
     stopped = {
     stopped = {
-      text = "",
-      texthl = "LspDiagnosticsSignInformation",
-      linehl = "DiagnosticUnderlineInfo",
-      numhl = "LspDiagnosticsSignInformation",
+      text = lvim.icons.ui.BoldArrowRight,
+      texthl = "DiagnosticSignWarn",
+      linehl = "Visual",
+      numhl = "DiagnosticSignWarn",
+    },
+    ui = {
+      auto_open = true,
     },
     },
   }
   }
 end
 end
 
 
 M.setup = function()
 M.setup = function()
-  local dap = require "dap"
+  local status_ok, dap = pcall(require, "dap")
+  if not status_ok then
+    return
+  end
 
 
   if lvim.use_icons then
   if lvim.use_icons then
     vim.fn.sign_define("DapBreakpoint", lvim.builtin.dap.breakpoint)
     vim.fn.sign_define("DapBreakpoint", lvim.builtin.dap.breakpoint)
@@ -34,8 +40,6 @@ M.setup = function()
     vim.fn.sign_define("DapStopped", lvim.builtin.dap.stopped)
     vim.fn.sign_define("DapStopped", lvim.builtin.dap.stopped)
   end
   end
 
 
-  dap.defaults.fallback.terminal_win_cmd = "50vsplit new"
-
   lvim.builtin.which_key.mappings["d"] = {
   lvim.builtin.which_key.mappings["d"] = {
     name = "Debug",
     name = "Debug",
     t = { "<cmd>lua require'dap'.toggle_breakpoint()<cr>", "Toggle Breakpoint" },
     t = { "<cmd>lua require'dap'.toggle_breakpoint()<cr>", "Toggle Breakpoint" },
@@ -51,6 +55,7 @@ M.setup = function()
     r = { "<cmd>lua require'dap'.repl.toggle()<cr>", "Toggle Repl" },
     r = { "<cmd>lua require'dap'.repl.toggle()<cr>", "Toggle Repl" },
     s = { "<cmd>lua require'dap'.continue()<cr>", "Start" },
     s = { "<cmd>lua require'dap'.continue()<cr>", "Start" },
     q = { "<cmd>lua require'dap'.close()<cr>", "Quit" },
     q = { "<cmd>lua require'dap'.close()<cr>", "Quit" },
+    U = { "<cmd>lua require'dapui'.toggle()<cr>", "Toggle UI" },
   }
   }
 
 
   if lvim.builtin.dap.on_config_done then
   if lvim.builtin.dap.on_config_done then
@@ -58,21 +63,65 @@ M.setup = function()
   end
   end
 end
 end
 
 
--- TODO put this up there ^^^ call in ftplugin
+M.setup_ui = function()
+  local status_ok, dap = pcall(require, "dap")
+  if not status_ok then
+    return
+  end
+  local dapui = require "dapui"
+  dapui.setup {
+    expand_lines = true,
+    icons = { expanded = "", collapsed = "", circular = "" },
+    mappings = {
+      -- Use a table to apply multiple mappings
+      expand = { "<CR>", "<2-LeftMouse>" },
+      open = "o",
+      remove = "d",
+      edit = "e",
+      repl = "r",
+      toggle = "t",
+    },
+    layouts = {
+      {
+        elements = {
+          { id = "scopes", size = 0.33 },
+          { id = "breakpoints", size = 0.17 },
+          { id = "stacks", size = 0.25 },
+          { id = "watches", size = 0.25 },
+        },
+        size = 0.33,
+        position = "right",
+      },
+      {
+        elements = {
+          { id = "repl", size = 0.45 },
+          { id = "console", size = 0.55 },
+        },
+        size = 0.27,
+        position = "bottom",
+      },
+    },
+    floating = {
+      max_height = 0.9,
+      max_width = 0.5, -- Floats will be treated as percentage of your screen.
+      border = vim.g.border_chars, -- Border style. Can be 'single', 'double' or 'rounded'
+      mappings = {
+        close = { "q", "<Esc>" },
+      },
+    },
+  }
 
 
--- M.dap = function()
---   if lvim.plugin.dap.active then
---     local dap_install = require "dap-install"
---     dap_install.config("python_dbg", {})
---   end
--- end
---
--- M.dap = function()
---   -- gem install readapt ruby-debug-ide
---   if lvim.plugin.dap.active then
---     local dap_install = require "dap-install"
---     dap_install.config("ruby_vsc_dbg", {})
---   end
--- end
+  if lvim.builtin.dap.ui.auto_open then
+    dap.listeners.after.event_initialized["dapui_config"] = function()
+      dapui.open()
+    end
+    -- dap.listeners.before.event_terminated["dapui_config"] = function()
+    --   dapui.close()
+    -- end
+    -- dap.listeners.before.event_exited["dapui_config"] = function()
+    --   dapui.close()
+    -- end
+  end
+end
 
 
 return M
 return M

+ 6 - 6
lua/lvim/core/gitsigns.lua

@@ -8,31 +8,31 @@ M.config = function()
       signs = {
       signs = {
         add = {
         add = {
           hl = "GitSignsAdd",
           hl = "GitSignsAdd",
-          text = "▎",
+          text = lvim.icons.ui.BoldLineLeft,
           numhl = "GitSignsAddNr",
           numhl = "GitSignsAddNr",
           linehl = "GitSignsAddLn",
           linehl = "GitSignsAddLn",
         },
         },
         change = {
         change = {
           hl = "GitSignsChange",
           hl = "GitSignsChange",
-          text = "▎",
+          text = lvim.icons.ui.BoldLineLeft,
           numhl = "GitSignsChangeNr",
           numhl = "GitSignsChangeNr",
           linehl = "GitSignsChangeLn",
           linehl = "GitSignsChangeLn",
         },
         },
         delete = {
         delete = {
           hl = "GitSignsDelete",
           hl = "GitSignsDelete",
-          text = "契",
+          text = lvim.icons.ui.Triangle,
           numhl = "GitSignsDeleteNr",
           numhl = "GitSignsDeleteNr",
           linehl = "GitSignsDeleteLn",
           linehl = "GitSignsDeleteLn",
         },
         },
         topdelete = {
         topdelete = {
           hl = "GitSignsDelete",
           hl = "GitSignsDelete",
-          text = "契",
+          text = lvim.icons.ui.Triangle,
           numhl = "GitSignsDeleteNr",
           numhl = "GitSignsDeleteNr",
           linehl = "GitSignsDeleteLn",
           linehl = "GitSignsDeleteLn",
         },
         },
         changedelete = {
         changedelete = {
           hl = "GitSignsChange",
           hl = "GitSignsChange",
-          text = "▎",
+          text = lvim.icons.ui.BoldLineLeft,
           numhl = "GitSignsChangeNr",
           numhl = "GitSignsChangeNr",
           linehl = "GitSignsChangeLn",
           linehl = "GitSignsChangeLn",
         },
         },
@@ -79,7 +79,7 @@ M.config = function()
 end
 end
 
 
 M.setup = function()
 M.setup = function()
-  local gitsigns = require "gitsigns"
+  local gitsigns = reload "gitsigns"
 
 
   gitsigns.setup(lvim.builtin.gitsigns.opts)
   gitsigns.setup(lvim.builtin.gitsigns.opts)
   if lvim.builtin.gitsigns.on_config_done then
   if lvim.builtin.gitsigns.on_config_done then

+ 68 - 0
lua/lvim/core/illuminate.lua

@@ -0,0 +1,68 @@
+local M = {}
+
+M.config = function()
+  lvim.builtin.illuminate = {
+    active = true,
+    on_config_done = nil,
+    options = {
+      -- providers: provider used to get references in the buffer, ordered by priority
+      providers = {
+        "lsp",
+        "treesitter",
+        "regex",
+      },
+      -- delay: delay in milliseconds
+      delay = 120,
+      -- filetypes_denylist: filetypes to not illuminate, this overrides filetypes_allowlist
+      filetypes_denylist = {
+        "dirvish",
+        "fugitive",
+        "alpha",
+        "NvimTree",
+        "packer",
+        "neogitstatus",
+        "Trouble",
+        "lir",
+        "Outline",
+        "spectre_panel",
+        "toggleterm",
+        "DressingSelect",
+        "TelescopePrompt",
+      },
+      -- filetypes_allowlist: filetypes to illuminate, this is overridden by filetypes_denylist
+      filetypes_allowlist = {},
+      -- modes_denylist: modes to not illuminate, this overrides modes_allowlist
+      modes_denylist = {},
+      -- modes_allowlist: modes to illuminate, this is overridden by modes_denylist
+      modes_allowlist = {},
+      -- providers_regex_syntax_denylist: syntax to not illuminate, this overrides providers_regex_syntax_allowlist
+      -- Only applies to the 'regex' provider
+      -- Use :echom synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name')
+      providers_regex_syntax_denylist = {},
+      -- providers_regex_syntax_allowlist: syntax to illuminate, this is overridden by providers_regex_syntax_denylist
+      -- Only applies to the 'regex' provider
+      -- Use :echom synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name')
+      providers_regex_syntax_allowlist = {},
+      -- under_cursor: whether or not to illuminate under the cursor
+      under_cursor = true,
+    },
+  }
+end
+
+M.setup = function()
+  local status_ok, illuminate = pcall(reload, "illuminate")
+  if not status_ok then
+    return
+  end
+
+  local config_ok, _ = pcall(illuminate.configure, lvim.builtin.illuminate.options)
+  if not config_ok then
+    return
+  end
+
+  if lvim.builtin.illuminate.on_config_done then
+    lvim.builtin.illuminate.on_config_done()
+  end
+end
+
+return M

+ 42 - 0
lua/lvim/core/indentlines.lua

@@ -0,0 +1,42 @@
+local M = {}
+
+M.config = function()
+  lvim.builtin.indentlines = {
+    active = true,
+    on_config_done = nil,
+    options = {
+      enabled = true,
+      buftype_exclude = { "terminal", "nofile" },
+      filetype_exclude = {
+        "help",
+        "startify",
+        "dashboard",
+        "packer",
+        "neogitstatus",
+        "NvimTree",
+        "Trouble",
+        "text",
+      },
+      char = lvim.icons.ui.LineLeft,
+      show_trailing_blankline_indent = false,
+      show_first_indent_level = true,
+      use_treesitter = true,
+      show_current_context = true,
+    },
+  }
+end
+
+M.setup = function()
+  local status_ok, indent_blankline = pcall(reload, "indent_blankline")
+  if not status_ok then
+    return
+  end
+
+  indent_blankline.setup(lvim.builtin.indentlines.options)
+
+  if lvim.builtin.indentlines.on_config_done then
+    lvim.builtin.indentlines.on_config_done()
+  end
+end
+
+return M

+ 7 - 7
lua/lvim/core/info.lua

@@ -25,8 +25,8 @@ local function make_formatters_info(ft)
     "Formatters info",
     "Formatters info",
     fmt(
     fmt(
       "* Active: %s%s",
       "* Active: %s%s",
-      table.concat(registered_formatters, "  , "),
-      vim.tbl_count(registered_formatters) > 0 and "  " or ""
+      table.concat(registered_formatters, " " .. lvim.icons.ui.BoxChecked .. " , "),
+      vim.tbl_count(registered_formatters) > 0 and " " .. lvim.icons.ui.BoxChecked .. " " or ""
     ),
     ),
     fmt("* Supported: %s", str_list(supported_formatters)),
     fmt("* Supported: %s", str_list(supported_formatters)),
   }
   }
@@ -41,8 +41,8 @@ local function make_code_actions_info(ft)
     "Code actions info",
     "Code actions info",
     fmt(
     fmt(
       "* Active: %s%s",
       "* Active: %s%s",
-      table.concat(registered_actions, "  , "),
-      vim.tbl_count(registered_actions) > 0 and "  " or ""
+      table.concat(registered_actions, " " .. lvim.icons.ui.BoxChecked .. " , "),
+      vim.tbl_count(registered_actions) > 0 and " " .. lvim.icons.ui.BoxChecked .. " " or ""
     ),
     ),
   }
   }
 
 
@@ -57,8 +57,8 @@ local function make_linters_info(ft)
     "Linters info",
     "Linters info",
     fmt(
     fmt(
       "* Active: %s%s",
       "* Active: %s%s",
-      table.concat(registered_linters, "  , "),
-      vim.tbl_count(registered_linters) > 0 and "  " or ""
+      table.concat(registered_linters, " " .. lvim.icons.ui.BoxChecked .. " , "),
+      vim.tbl_count(registered_linters) > 0 and " " .. lvim.icons.ui.BoxChecked .. " " or ""
     ),
     ),
     fmt("* Supported: %s", str_list(supported_linters)),
     fmt("* Supported: %s", str_list(supported_linters)),
   }
   }
@@ -202,7 +202,7 @@ function M.toggle_popup(ft)
     vim.fn.matchadd("LvimInfoIdentifier", " " .. ft .. "$")
     vim.fn.matchadd("LvimInfoIdentifier", " " .. ft .. "$")
     vim.fn.matchadd("string", "true")
     vim.fn.matchadd("string", "true")
     vim.fn.matchadd("string", "active")
     vim.fn.matchadd("string", "active")
-    vim.fn.matchadd("string", "")
+    vim.fn.matchadd("string", lvim.icons.ui.BoxChecked)
     vim.fn.matchadd("boolean", "inactive")
     vim.fn.matchadd("boolean", "inactive")
     vim.fn.matchadd("error", "false")
     vim.fn.matchadd("error", "false")
     tbl_set_highlight(require("lvim.lsp.null-ls.formatters").list_registered(ft), "LvimInfoIdentifier")
     tbl_set_highlight(require("lvim.lsp.null-ls.formatters").list_registered(ft), "LvimInfoIdentifier")

+ 118 - 0
lua/lvim/core/lir.lua

@@ -0,0 +1,118 @@
+local M = {}
+
+M.config = function()
+  lvim.builtin.lir = {
+    active = true,
+    on_config_done = nil,
+    icon = "",
+  }
+
+  local status_ok, _ = pcall(require, "lir")
+  if not status_ok then
+    return
+  end
+
+  local actions = require "lir.actions"
+  local mark_actions = require "lir.mark.actions"
+  local clipboard_actions = require "lir.clipboard.actions"
+
+  lvim.builtin.lir = vim.tbl_extend("force", lvim.builtin.lir, {
+    show_hidden_files = false,
+    devicons_enable = true,
+    mappings = {
+      ["l"] = actions.edit,
+      ["<CR>"] = actions.edit,
+      ["<C-s>"] = actions.split,
+      ["v"] = actions.vsplit,
+      ["<C-t>"] = actions.tabedit,
+
+      ["h"] = actions.up,
+      ["q"] = actions.quit,
+
+      ["A"] = actions.mkdir,
+      ["a"] = actions.newfile,
+      ["r"] = actions.rename,
+      ["@"] = actions.cd,
+      ["Y"] = actions.yank_path,
+      ["i"] = actions.toggle_show_hidden,
+      ["d"] = actions.delete,
+
+      ["J"] = function()
+        mark_actions.toggle_mark()
+        vim.cmd "normal! j"
+      end,
+      ["c"] = clipboard_actions.copy,
+      ["x"] = clipboard_actions.cut,
+      ["p"] = clipboard_actions.paste,
+    },
+    float = {
+      winblend = 0,
+      curdir_window = {
+        enable = false,
+        highlight_dirname = true,
+      },
+
+      -- -- You can define a function that returns a table to be passed as the third
+      -- -- argument of nvim_open_win().
+      win_opts = function()
+        local width = math.floor(vim.o.columns * 0.7)
+        local height = math.floor(vim.o.lines * 0.7)
+        return {
+          border = "rounded",
+          width = width,
+          height = height,
+          -- row = 1,
+          -- col = math.floor((vim.o.columns - width) / 2),
+        }
+      end,
+    },
+    hide_cursor = false,
+    on_init = function()
+      -- use visual mode
+      vim.api.nvim_buf_set_keymap(
+        0,
+        "x",
+        "J",
+        ':<C-u>lua require"lir.mark.actions".toggle_mark("v")<CR>',
+        { noremap = true, silent = true }
+      )
+
+      -- echo cwd
+      -- vim.api.nvim_echo({ { vim.fn.expand "%:p", "Normal" } }, false, {})
+    end,
+  })
+end
+
+function M.icon_setup()
+  local function get_hl_by_name(name)
+    local ret = vim.api.nvim_get_hl_by_name(name.group, true)
+    return string.format("#%06x", ret[name.property])
+  end
+
+  local found, icon_hl = pcall(get_hl_by_name, { group = "NvimTreeFolderIcon", property = "foreground" })
+  if not found then
+    icon_hl = "#42A5F5"
+  end
+
+  reload("nvim-web-devicons").set_icon {
+    lir_folder_icon = {
+      icon = lvim.builtin.lir.icon,
+      color = icon_hl,
+      name = "LirFolderNode",
+    },
+  }
+end
+
+function M.setup()
+  local status_ok, lir = pcall(reload, "lir")
+  if not status_ok then
+    return
+  end
+  lir.setup(lvim.builtin.lir)
+
+  if lvim.builtin.lir.on_config_done then
+    lvim.builtin.lir.on_config_done(lir)
+  end
+end
+
+return M

+ 21 - 19
lua/lvim/core/log.lua

@@ -12,26 +12,23 @@ vim.tbl_add_reverse_lookup(Log.levels)
 local notify_opts = {}
 local notify_opts = {}
 
 
 function Log:set_level(level)
 function Log:set_level(level)
-  local logger_ok, _ = xpcall(function()
-    local log_level = Log.levels[level:upper()]
-    local structlog = require "structlog"
-    if structlog then
-      local logger = structlog.get_logger "lvim"
-      for _, s in ipairs(logger.sinks) do
-        s.level = log_level
-      end
+  local logger_ok, logger = pcall(function()
+    return require("structlog").get_logger "lvim"
+  end)
+  local log_level = Log.levels[level:upper()]
+  if logger_ok and logger and log_level then
+    for _, s in ipairs(logger.sinks) do
+      s.level = log_level
     end
     end
-  end, debug.traceback)
-  if not logger_ok then
-    Log:debug("Unable to set logger's level: " .. debug.traceback())
+  else
+    vim.notify_once("Unable to set logger's level to " .. level)
   end
   end
 
 
   local packer_ok, _ = xpcall(function()
   local packer_ok, _ = xpcall(function()
-    package.loaded["packer.log"] = nil
-    require("packer.log").new { level = lvim.log.level }
+    require("packer.log").cfg { log = { level = level } }
   end, debug.traceback)
   end, debug.traceback)
   if not packer_ok then
   if not packer_ok then
-    Log:debug("Unable to set packer's log level: " .. debug.traceback())
+    vim.notify_once("Unable to set packer's log level to " .. level)
   end
   end
 end
 end
 
 
@@ -91,7 +88,7 @@ function Log:init()
         vim_log_level = vim_log_level + 1
         vim_log_level = vim_log_level + 1
       end
       end
 
 
-      logger:log(vim_log_level, msg)
+      self:info(vim_log_level, msg)
     end
     end
   end
   end
 
 
@@ -145,8 +142,9 @@ function Log:configure_notifications(notif_handle)
 end
 end
 
 
 --- Adds a log entry using Plenary.log
 --- Adds a log entry using Plenary.log
+---@param level integer [same as vim.log.levels]
 ---@param msg any
 ---@param msg any
----@param level string [same as vim.log.log_levels]
+---@param event any
 function Log:add_entry(level, msg, event)
 function Log:add_entry(level, msg, event)
   local logger = self:get_logger()
   local logger = self:get_logger()
   if not logger then
   if not logger then
@@ -158,11 +156,15 @@ end
 ---Retrieves the handle of the logger object
 ---Retrieves the handle of the logger object
 ---@return table|nil logger handle if found
 ---@return table|nil logger handle if found
 function Log:get_logger()
 function Log:get_logger()
-  if self.__handle then
-    return self.__handle
+  local logger_ok, logger = pcall(function()
+    return require("structlog").get_logger "lvim"
+  end)
+  if logger_ok and logger then
+    return logger
   end
   end
 
 
-  local logger = self:init()
+  logger = self:init()
+
   if not logger then
   if not logger then
     return
     return
   end
   end

+ 74 - 24
lua/lvim/core/lualine/components.lua

@@ -12,10 +12,35 @@ local function diff_source()
   end
   end
 end
 end
 
 
+local statusline_hl = vim.api.nvim_get_hl_by_name("StatusLine", true)
+local cursorline_hl = vim.api.nvim_get_hl_by_name("CursorLine", true)
+local normal_hl = vim.api.nvim_get_hl_by_name("Normal", true)
+
+vim.api.nvim_set_hl(0, "SLCopilot", { fg = "#6CC644", bg = statusline_hl.background })
+vim.api.nvim_set_hl(0, "SLGitIcon", { fg = "#E8AB53", bg = cursorline_hl.background })
+vim.api.nvim_set_hl(0, "SLBranchName", { fg = normal_hl.foreground, bg = cursorline_hl.background })
+vim.api.nvim_set_hl(0, "SLProgress", { fg = "#ECBE7B", bg = statusline_hl.background })
+
+local location_color = nil
+local branch = lvim.icons.git.Branch
+local separator = lvim.icons.ui.LineMiddle
+
+if lvim.colorscheme == "tokyonight" then
+  location_color = "SLBranchName"
+  branch = "%#SLGitIcon#" .. lvim.icons.git.Branch .. "%*" .. "%#SLBranchName#"
+
+  local status_ok, tnc = pcall(require, "tokyonight.colors")
+  if status_ok then
+    local tncolors = tnc.setup { transform = true }
+    vim.api.nvim_set_hl(0, "SLSeparator", { fg = cursorline_hl.background, bg = tncolors.black })
+    separator = "%#SLSeparator#" .. lvim.icons.ui.LineMiddle .. "%*"
+  end
+end
+
 return {
 return {
   mode = {
   mode = {
     function()
     function()
-      return " "
+      return " " .. lvim.icons.ui.Target .. " "
     end,
     end,
     padding = { left = 0, right = 0 },
     padding = { left = 0, right = 0 },
     color = {},
     color = {},
@@ -23,9 +48,8 @@ return {
   },
   },
   branch = {
   branch = {
     "b:gitsigns_head",
     "b:gitsigns_head",
-    icon = " ",
+    icon = branch,
     color = { gui = "bold" },
     color = { gui = "bold" },
-    cond = conditions.hide_in_width,
   },
   },
   filename = {
   filename = {
     "filename",
     "filename",
@@ -35,7 +59,12 @@ return {
   diff = {
   diff = {
     "diff",
     "diff",
     source = diff_source,
     source = diff_source,
-    symbols = { added = "  ", modified = " ", removed = " " },
+    symbols = {
+      added = lvim.icons.git.LineAdded .. " ",
+      modified = lvim.icons.git.LineModified .. " ",
+      removed = lvim.icons.git.LineRemoved .. " ",
+    },
+    padding = { left = 2, right = 1 },
     diff_color = {
     diff_color = {
       added = { fg = colors.green },
       added = { fg = colors.green },
       modified = { fg = colors.yellow },
       modified = { fg = colors.yellow },
@@ -49,7 +78,9 @@ return {
       if vim.bo.filetype == "python" then
       if vim.bo.filetype == "python" then
         local venv = os.getenv "CONDA_DEFAULT_ENV" or os.getenv "VIRTUAL_ENV"
         local venv = os.getenv "CONDA_DEFAULT_ENV" or os.getenv "VIRTUAL_ENV"
         if venv then
         if venv then
-          return string.format("  (%s)", utils.env_cleanup(venv))
+          local icons = require "nvim-web-devicons"
+          local py_icon, _ = icons.get_icon ".py"
+          return string.format(" " .. py_icon .. " (%s)", utils.env_cleanup(venv))
         end
         end
       end
       end
       return ""
       return ""
@@ -60,12 +91,17 @@ return {
   diagnostics = {
   diagnostics = {
     "diagnostics",
     "diagnostics",
     sources = { "nvim_diagnostic" },
     sources = { "nvim_diagnostic" },
-    symbols = { error = " ", warn = " ", info = " ", hint = " " },
-    cond = conditions.hide_in_width,
+    symbols = {
+      error = lvim.icons.diagnostics.BoldError .. " ",
+      warn = lvim.icons.diagnostics.BoldWarning .. " ",
+      info = lvim.icons.diagnostics.BoldInformation .. " ",
+      hint = lvim.icons.diagnostics.BoldHint .. " ",
+    },
+    -- cond = conditions.hide_in_width,
   },
   },
   treesitter = {
   treesitter = {
     function()
     function()
-      return ""
+      return lvim.icons.ui.Tree
     end,
     end,
     color = function()
     color = function()
       local buf = vim.api.nvim_get_current_buf()
       local buf = vim.api.nvim_get_current_buf()
@@ -87,12 +123,17 @@ return {
       end
       end
       local buf_ft = vim.bo.filetype
       local buf_ft = vim.bo.filetype
       local buf_client_names = {}
       local buf_client_names = {}
+      local copilot_active = false
 
 
       -- add client
       -- add client
       for _, client in pairs(buf_clients) do
       for _, client in pairs(buf_clients) do
-        if client.name ~= "null-ls" then
+        if client.name ~= "null-ls" and client.name ~= "copilot" then
           table.insert(buf_client_names, client.name)
           table.insert(buf_client_names, client.name)
         end
         end
+
+        if client.name == "copilot" then
+          copilot_active = true
+        end
       end
       end
 
 
       -- add formatter
       -- add formatter
@@ -106,26 +147,35 @@ return {
       vim.list_extend(buf_client_names, supported_linters)
       vim.list_extend(buf_client_names, supported_linters)
 
 
       local unique_client_names = vim.fn.uniq(buf_client_names)
       local unique_client_names = vim.fn.uniq(buf_client_names)
-      return "[" .. table.concat(unique_client_names, ", ") .. "]"
+
+      local language_servers = "[" .. table.concat(unique_client_names, ", ") .. "]"
+
+      if copilot_active then
+        language_servers = language_servers .. "%#SLCopilot#" .. " " .. lvim.icons.git.Octoface .. "%*"
+      end
+
+      return language_servers
     end,
     end,
+    separator = separator,
     color = { gui = "bold" },
     color = { gui = "bold" },
     cond = conditions.hide_in_width,
     cond = conditions.hide_in_width,
   },
   },
-  location = { "location", cond = conditions.hide_in_width, color = {} },
-  progress = { "progress", cond = conditions.hide_in_width, color = {} },
+  location = { "location", color = location_color },
+  progress = {
+    "progress",
+    fmt = function()
+      return "%P/%L"
+    end,
+    color = {},
+  },
+
   spaces = {
   spaces = {
     function()
     function()
-      if not vim.api.nvim_buf_get_option(0, "expandtab") then
-        return "Tab size: " .. vim.api.nvim_buf_get_option(0, "tabstop") .. " "
-      end
-      local size = vim.api.nvim_buf_get_option(0, "shiftwidth")
-      if size == 0 then
-        size = vim.api.nvim_buf_get_option(0, "tabstop")
-      end
-      return "Spaces: " .. size .. " "
+      local shiftwidth = vim.api.nvim_buf_get_option(0, "shiftwidth")
+      return lvim.icons.ui.Tab .. " " .. shiftwidth
     end,
     end,
-    cond = conditions.hide_in_width,
-    color = {},
+    separator = separator,
+    padding = 1,
   },
   },
   encoding = {
   encoding = {
     "o:encoding",
     "o:encoding",
@@ -133,7 +183,7 @@ return {
     color = {},
     color = {},
     cond = conditions.hide_in_width,
     cond = conditions.hide_in_width,
   },
   },
-  filetype = { "filetype", cond = conditions.hide_in_width },
+  filetype = { "filetype", cond = nil, padding = { left = 1, right = 1 } },
   scrollbar = {
   scrollbar = {
     function()
     function()
       local current_line = vim.fn.line "."
       local current_line = vim.fn.line "."
@@ -144,7 +194,7 @@ return {
       return chars[index]
       return chars[index]
     end,
     end,
     padding = { left = 0, right = 0 },
     padding = { left = 0, right = 0 },
-    color = { fg = colors.yellow, bg = colors.bg },
+    color = "SLProgress",
     cond = nil,
     cond = nil,
   },
   },
 }
 }

+ 2 - 2
lua/lvim/core/lualine/conditions.lua

@@ -1,11 +1,11 @@
-local window_width_limit = 70
+local window_width_limit = 100
 
 
 local conditions = {
 local conditions = {
   buffer_not_empty = function()
   buffer_not_empty = function()
     return vim.fn.empty(vim.fn.expand "%:t") ~= 1
     return vim.fn.empty(vim.fn.expand "%:t") ~= 1
   end,
   end,
   hide_in_width = function()
   hide_in_width = function()
-    return vim.fn.winwidth(0) > window_width_limit
+    return vim.o.columns > window_width_limit
   end,
   end,
   -- check_git_workspace = function()
   -- check_git_workspace = function()
   --   local filepath = vim.fn.expand "%:p:h"
   --   local filepath = vim.fn.expand "%:p:h"

+ 6 - 3
lua/lvim/core/lualine/init.lua

@@ -9,7 +9,7 @@ M.config = function()
       section_separators = nil,
       section_separators = nil,
       theme = nil,
       theme = nil,
       disabled_filetypes = nil,
       disabled_filetypes = nil,
-      globalstatus = false,
+      globalstatus = true,
     },
     },
     sections = {
     sections = {
       lualine_a = nil,
       lualine_a = nil,
@@ -34,16 +34,19 @@ M.config = function()
 end
 end
 
 
 M.setup = function()
 M.setup = function()
-  -- avoid running in headless mode since it's harder to detect failures
   if #vim.api.nvim_list_uis() == 0 then
   if #vim.api.nvim_list_uis() == 0 then
     local Log = require "lvim.core.log"
     local Log = require "lvim.core.log"
     Log:debug "headless mode detected, skipping running setup for lualine"
     Log:debug "headless mode detected, skipping running setup for lualine"
     return
     return
   end
   end
 
 
+  local status_ok, lualine = pcall(require, "lualine")
+  if not status_ok then
+    return
+  end
+
   require("lvim.core.lualine.styles").update()
   require("lvim.core.lualine.styles").update()
 
 
-  local lualine = require "lualine"
   lualine.setup(lvim.builtin.lualine)
   lualine.setup(lvim.builtin.lualine)
 
 
   if lvim.builtin.lualine.on_config_done then
   if lvim.builtin.lualine.on_config_done then

+ 42 - 14
lua/lvim/core/lualine/styles.lua

@@ -11,6 +11,7 @@ styles.none = {
   style = "none",
   style = "none",
   options = {
   options = {
     theme = "auto",
     theme = "auto",
+    globalstatus = true,
     icons_enabled = lvim.use_icons,
     icons_enabled = lvim.use_icons,
     component_separators = { left = "", right = "" },
     component_separators = { left = "", right = "" },
     section_separators = { left = "", right = "" },
     section_separators = { left = "", right = "" },
@@ -40,9 +41,16 @@ styles.default = {
   style = "default",
   style = "default",
   options = {
   options = {
     theme = "auto",
     theme = "auto",
+    globalstatus = true,
     icons_enabled = lvim.use_icons,
     icons_enabled = lvim.use_icons,
-    component_separators = { left = "", right = "" },
-    section_separators = { left = "", right = "" },
+    component_separators = {
+      left = lvim.icons.ui.DividerRight,
+      right = lvim.icons.ui.DividerLeft,
+    },
+    section_separators = {
+      left = lvim.icons.ui.BoldDividerRight,
+      right = lvim.icons.ui.BoldDividerLeft,
+    },
     disabled_filetypes = {},
     disabled_filetypes = {},
   },
   },
   sections = {
   sections = {
@@ -69,10 +77,11 @@ styles.lvim = {
   style = "lvim",
   style = "lvim",
   options = {
   options = {
     theme = "auto",
     theme = "auto",
+    globalstatus = true,
     icons_enabled = lvim.use_icons,
     icons_enabled = lvim.use_icons,
     component_separators = { left = "", right = "" },
     component_separators = { left = "", right = "" },
     section_separators = { left = "", right = "" },
     section_separators = { left = "", right = "" },
-    disabled_filetypes = { "alpha", "NvimTree", "Outline" },
+    disabled_filetypes = { "alpha" },
   },
   },
   sections = {
   sections = {
     lualine_a = {
     lualine_a = {
@@ -80,7 +89,6 @@ styles.lvim = {
     },
     },
     lualine_b = {
     lualine_b = {
       components.branch,
       components.branch,
-      components.filename,
     },
     },
     lualine_c = {
     lualine_c = {
       components.diff,
       components.diff,
@@ -88,27 +96,39 @@ styles.lvim = {
     },
     },
     lualine_x = {
     lualine_x = {
       components.diagnostics,
       components.diagnostics,
-      components.treesitter,
       components.lsp,
       components.lsp,
+      components.spaces,
       components.filetype,
       components.filetype,
     },
     },
-    lualine_y = {},
+    lualine_y = { components.location },
     lualine_z = {
     lualine_z = {
-      components.scrollbar,
+      components.progress,
     },
     },
   },
   },
   inactive_sections = {
   inactive_sections = {
     lualine_a = {
     lualine_a = {
-      "filename",
+      components.mode,
+    },
+    lualine_b = {
+      components.branch,
+    },
+    lualine_c = {
+      components.diff,
+      components.python_env,
+    },
+    lualine_x = {
+      components.diagnostics,
+      components.lsp,
+      components.spaces,
+      components.filetype,
+    },
+    lualine_y = { components.location },
+    lualine_z = {
+      components.progress,
     },
     },
-    lualine_b = {},
-    lualine_c = {},
-    lualine_x = {},
-    lualine_y = {},
-    lualine_z = {},
   },
   },
   tabline = {},
   tabline = {},
-  extensions = { "nvim-tree" },
+  extensions = {},
 }
 }
 
 
 function M.get_style(style)
 function M.get_style(style)
@@ -132,6 +152,14 @@ function M.update()
   local style = M.get_style(lvim.builtin.lualine.style)
   local style = M.get_style(lvim.builtin.lualine.style)
 
 
   lvim.builtin.lualine = vim.tbl_deep_extend("keep", lvim.builtin.lualine, style)
   lvim.builtin.lualine = vim.tbl_deep_extend("keep", lvim.builtin.lualine, style)
+
+  local color_template = vim.g.colors_name or lvim.colorscheme
+  local theme_supported, template = pcall(function()
+    require("lualine.utils.loader").load_theme(color_template)
+  end)
+  if theme_supported and template then
+    lvim.builtin.lualine.options.theme = color_template
+  end
 end
 end
 
 
 return M
 return M

+ 2 - 1
lua/lvim/core/mason.lua

@@ -3,6 +3,7 @@ local M = {}
 function M.config()
 function M.config()
   lvim.builtin.mason = {
   lvim.builtin.mason = {
     ui = {
     ui = {
+      border = "rounded",
       keymaps = {
       keymaps = {
         toggle_package_expand = "<CR>",
         toggle_package_expand = "<CR>",
         install_package = "i",
         install_package = "i",
@@ -30,7 +31,7 @@ function M.config()
 end
 end
 
 
 function M.setup()
 function M.setup()
-  local status_ok, mason = pcall(require, "mason")
+  local status_ok, mason = pcall(reload, "mason")
   if not status_ok then
   if not status_ok then
     return
     return
   end
   end

+ 12 - 8
lua/lvim/core/notify.lua

@@ -3,7 +3,7 @@ local M = {}
 local Log = require "lvim.core.log"
 local Log = require "lvim.core.log"
 
 
 local defaults = {
 local defaults = {
-  active = false,
+  active = true,
   on_config_done = nil,
   on_config_done = nil,
   opts = {
   opts = {
     ---@usage Animation style one of { "fade", "slide", "fade_in_slide_out", "static" }
     ---@usage Animation style one of { "fade", "slide", "fade_in_slide_out", "static" }
@@ -29,11 +29,11 @@ local defaults = {
 
 
     ---@usage Icons for the different levels
     ---@usage Icons for the different levels
     icons = {
     icons = {
-      ERROR = "",
-      WARN = "",
-      INFO = "",
-      DEBUG = "",
-      TRACE = "✎",
+      ERROR = lvim.icons.diagnostics.Error,
+      WARN = lvim.icons.diagnostics.Warning,
+      INFO = lvim.icons.diagnostics.Information,
+      DEBUG = lvim.icons.diagnostics.Debug,
+      TRACE = lvim.icons.diagnostics.Trace,
     },
     },
   },
   },
 }
 }
@@ -43,7 +43,7 @@ function M.config()
     defaults.opts.icons = {
     defaults.opts.icons = {
       ERROR = "[ERROR]",
       ERROR = "[ERROR]",
       WARN = "[WARNING]",
       WARN = "[WARNING]",
-      INFO = "[INFo]",
+      INFO = "[INFO]",
       DEBUG = "[DEBUG]",
       DEBUG = "[DEBUG]",
       TRACE = "[TRACE]",
       TRACE = "[TRACE]",
     }
     }
@@ -58,7 +58,11 @@ function M.setup()
   end
   end
 
 
   local opts = lvim.builtin.notify and lvim.builtin.notify.opts or defaults
   local opts = lvim.builtin.notify and lvim.builtin.notify.opts or defaults
-  local notify = require "notify"
+
+  local status_ok, notify = pcall(require, "notify")
+  if not status_ok then
+    return
+  end
 
 
   notify.setup(opts)
   notify.setup(opts)
   vim.notify = notify
   vim.notify = notify

+ 40 - 33
lua/lvim/core/nvimtree.lua

@@ -6,34 +6,24 @@ function M.config()
     active = true,
     active = true,
     on_config_done = nil,
     on_config_done = nil,
     setup = {
     setup = {
-      disable_netrw = true,
-      hijack_netrw = true,
-      open_on_setup = false,
-      open_on_setup_file = false,
-      sort_by = "name",
-      ignore_buffer_on_setup = false,
       ignore_ft_on_setup = {
       ignore_ft_on_setup = {
         "startify",
         "startify",
         "dashboard",
         "dashboard",
         "alpha",
         "alpha",
       },
       },
-      auto_reload_on_write = true,
-      hijack_unnamed_buffer_when_opening = false,
+      auto_reload_on_write = false,
       hijack_directories = {
       hijack_directories = {
-        enable = true,
-        auto_open = true,
+        enable = false,
       },
       },
-      open_on_tab = false,
-      hijack_cursor = false,
-      update_cwd = false,
+      update_cwd = true,
       diagnostics = {
       diagnostics = {
         enable = lvim.use_icons,
         enable = lvim.use_icons,
         show_on_dirs = false,
         show_on_dirs = false,
         icons = {
         icons = {
-          hint = "",
-          info = "",
-          warning = "",
-          error = "",
+          hint = lvim.icons.diagnostics.BoldHint,
+          info = lvim.icons.diagnostics.BoldInformation,
+          warning = lvim.icons.diagnostics.BoldWarning,
+          error = lvim.icons.diagnostics.BoldError,
         },
         },
       },
       },
       update_focused_file = {
       update_focused_file = {
@@ -52,10 +42,8 @@ function M.config()
       },
       },
       view = {
       view = {
         width = 30,
         width = 30,
-        height = 30,
         hide_root_folder = false,
         hide_root_folder = false,
         side = "left",
         side = "left",
-        preserve_window_proportions = false,
         mappings = {
         mappings = {
           custom_only = false,
           custom_only = false,
           list = {},
           list = {},
@@ -83,27 +71,28 @@ function M.config()
             folder_arrow = lvim.use_icons,
             folder_arrow = lvim.use_icons,
           },
           },
           glyphs = {
           glyphs = {
-            default = "",
-            symlink = "",
+            default = lvim.icons.ui.Text,
+            symlink = lvim.icons.ui.FileSymlink,
             git = {
             git = {
-              unstaged = "",
-              staged = "S",
-              unmerged = "",
-              renamed = "➜",
-              deleted = "",
-              untracked = "U",
-              ignored = "◌",
+              deleted = lvim.icons.git.FileDeleted,
+              ignored = lvim.icons.git.FileIgnored,
+              renamed = lvim.icons.git.FileRenamed,
+              staged = lvim.icons.git.FileStaged,
+              unmerged = lvim.icons.git.FileUnmerged,
+              unstaged = lvim.icons.git.FileUnstaged,
+              untracked = lvim.icons.git.FileUntracked,
             },
             },
             folder = {
             folder = {
-              default = "",
-              open = "",
-              empty = "",
-              empty_open = "",
-              symlink = "",
+              default = lvim.icons.ui.Folder,
+              empty = lvim.icons.ui.EmptyFolder,
+              empty_open = lvim.icons.ui.EmptyFolderOpen,
+              open = lvim.icons.ui.FolderOpen,
+              symlink = lvim.icons.ui.FolderSymlink,
             },
             },
           },
           },
         },
         },
         highlight_git = true,
         highlight_git = true,
+        group_empty = false,
         root_folder_modifier = ":t",
         root_folder_modifier = ":t",
       },
       },
       filters = {
       filters = {
@@ -158,6 +147,24 @@ function M.setup()
     return
     return
   end
   end
 
 
+  local status_ok_1, utils = pcall(require, "nvim-tree.utils")
+  if not status_ok_1 then
+    return
+  end
+
+  local function notify_level()
+    return function(msg)
+      vim.schedule(function()
+        vim.api.nvim_echo({ { msg, "WarningMsg" } }, false, {})
+      end)
+    end
+  end
+
+  utils.notify.warn = notify_level(vim.log.levels.WARN)
+  utils.notify.error = notify_level(vim.log.levels.ERROR)
+  utils.notify.info = notify_level(vim.log.levels.INFO)
+  utils.notify.debug = notify_level(vim.log.levels.DEBUG)
+
   if lvim.builtin.nvimtree._setup_called then
   if lvim.builtin.nvimtree._setup_called then
     Log:debug "ignoring repeated setup call for nvim-tree, see kyazdani42/nvim-tree.lua#1308"
     Log:debug "ignoring repeated setup call for nvim-tree, see kyazdani42/nvim-tree.lua#1308"
     return
     return

+ 1 - 1
lua/lvim/core/project.lua

@@ -22,7 +22,7 @@ function M.config()
     detection_methods = { "pattern" },
     detection_methods = { "pattern" },
 
 
     ---@usage patterns used to detect root dir, when **"pattern"** is in detection_methods
     ---@usage patterns used to detect root dir, when **"pattern"** is in detection_methods
-    patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json" },
+    patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json", "pom.xml" },
 
 
     ---@ Show hidden files in telescope when searching for files in a project
     ---@ Show hidden files in telescope when searching for files in a project
     show_hidden = false,
     show_hidden = false,

+ 64 - 30
lua/lvim/core/telescope.lua

@@ -1,5 +1,63 @@
 local M = {}
 local M = {}
 
 
+local function get_pickers(actions)
+  return {
+    find_files = {
+      theme = "dropdown",
+      hidden = true,
+      previewer = false,
+    },
+    live_grep = {
+      --@usage don't include the filename in the search results
+      only_sort_text = true,
+      theme = "dropdown",
+    },
+    grep_string = {
+      only_sort_text = true,
+      theme = "dropdown",
+    },
+    buffers = {
+      theme = "dropdown",
+      previewer = false,
+      initial_mode = "normal",
+      mappings = {
+        i = {
+          ["<C-d>"] = actions.delete_buffer,
+        },
+        n = {
+          ["dd"] = actions.delete_buffer,
+        },
+      },
+    },
+    planets = {
+      show_pluto = true,
+      show_moon = true,
+    },
+    git_files = {
+      theme = "dropdown",
+      hidden = true,
+      previewer = false,
+      show_untracked = true,
+    },
+    lsp_references = {
+      theme = "dropdown",
+      initial_mode = "normal",
+    },
+    lsp_definitions = {
+      theme = "dropdown",
+      initial_mode = "normal",
+    },
+    lsp_declarations = {
+      theme = "dropdown",
+      initial_mode = "normal",
+    },
+    lsp_implementations = {
+      theme = "dropdown",
+      initial_mode = "normal",
+    },
+  }
+end
+
 function M.config()
 function M.config()
   -- Define this minimal config so that it's available if telescope is not yet available.
   -- Define this minimal config so that it's available if telescope is not yet available.
 
 
@@ -15,8 +73,8 @@ function M.config()
   end
   end
   lvim.builtin.telescope = vim.tbl_extend("force", lvim.builtin.telescope, {
   lvim.builtin.telescope = vim.tbl_extend("force", lvim.builtin.telescope, {
     defaults = {
     defaults = {
-      prompt_prefix = " ",
-      selection_caret = " ",
+      prompt_prefix = lvim.icons.ui.Telescope .. " ",
+      selection_caret = lvim.icons.ui.Forward .. " ",
       entry_prefix = "  ",
       entry_prefix = "  ",
       initial_mode = "insert",
       initial_mode = "insert",
       selection_strategy = "reset",
       selection_strategy = "reset",
@@ -47,6 +105,7 @@ function M.config()
         "--hidden",
         "--hidden",
         "--glob=!.git/",
         "--glob=!.git/",
       },
       },
+      ---@usage Mappings are fully customizable. Many familiar mapping patterns are setup as defaults.
       mappings = {
       mappings = {
         i = {
         i = {
           ["<C-n>"] = actions.move_selection_next,
           ["<C-n>"] = actions.move_selection_next,
@@ -63,23 +122,16 @@ function M.config()
           ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,
           ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,
         },
         },
       },
       },
+      pickers = get_pickers(actions),
       file_ignore_patterns = {},
       file_ignore_patterns = {},
-      path_display = { shorten = 5 },
+      path_display = { "smart" },
       winblend = 0,
       winblend = 0,
       border = {},
       border = {},
       borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" },
       borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" },
       color_devicons = true,
       color_devicons = true,
       set_env = { ["COLORTERM"] = "truecolor" }, -- default = nil,
       set_env = { ["COLORTERM"] = "truecolor" }, -- default = nil,
     },
     },
-    pickers = {
-      find_files = {
-        hidden = true,
-      },
-      live_grep = {
-        --@usage don't include the filename in the search results
-        only_sort_text = true,
-      },
-    },
+    pickers = get_pickers(actions),
     extensions = {
     extensions = {
       fzf = {
       fzf = {
         fuzzy = true, -- false will only do exact matching
         fuzzy = true, -- false will only do exact matching
@@ -94,7 +146,6 @@ end
 function M.setup()
 function M.setup()
   local previewers = require "telescope.previewers"
   local previewers = require "telescope.previewers"
   local sorters = require "telescope.sorters"
   local sorters = require "telescope.sorters"
-  local actions = require "telescope.actions"
 
 
   lvim.builtin.telescope = vim.tbl_extend("keep", {
   lvim.builtin.telescope = vim.tbl_extend("keep", {
     file_previewer = previewers.vim_buffer_cat.new,
     file_previewer = previewers.vim_buffer_cat.new,
@@ -102,23 +153,6 @@ function M.setup()
     qflist_previewer = previewers.vim_buffer_qflist.new,
     qflist_previewer = previewers.vim_buffer_qflist.new,
     file_sorter = sorters.get_fuzzy_file,
     file_sorter = sorters.get_fuzzy_file,
     generic_sorter = sorters.get_generic_fuzzy_sorter,
     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)
   }, lvim.builtin.telescope)
 
 
   local telescope = require "telescope"
   local telescope = require "telescope"

+ 4 - 3
lua/lvim/core/telescope/custom-finders.lua

@@ -88,11 +88,12 @@ end
 
 
 -- Smartly opens either git_files or find_files, depending on whether the working directory is
 -- Smartly opens either git_files or find_files, depending on whether the working directory is
 -- contained in a Git repo.
 -- contained in a Git repo.
-function M.find_project_files()
-  local ok = pcall(builtin.git_files)
+function M.find_project_files(opts)
+  opts = opts or {}
+  local ok = pcall(builtin.git_files, opts)
 
 
   if not ok then
   if not ok then
-    builtin.find_files()
+    builtin.find_files(opts)
   end
   end
 end
 end
 
 

+ 29 - 6
lua/lvim/core/terminal.lua

@@ -3,11 +3,11 @@ local Log = require "lvim.core.log"
 
 
 M.config = function()
 M.config = function()
   lvim.builtin["terminal"] = {
   lvim.builtin["terminal"] = {
+    active = true,
     on_config_done = nil,
     on_config_done = nil,
     -- size can be a number or function which is passed the current terminal
     -- size can be a number or function which is passed the current terminal
     size = 20,
     size = 20,
-    -- open_mapping = [[<c-\>]],
-    open_mapping = [[<c-t>]],
+    open_mapping = [[<c-\>]],
     hide_numbers = true, -- hide the number column in toggleterm buffers
     hide_numbers = true, -- hide the number column in toggleterm buffers
     shade_filetypes = {},
     shade_filetypes = {},
     shade_terminals = true,
     shade_terminals = true,
@@ -39,8 +39,11 @@ M.config = function()
     -- { exec, keymap, name}
     -- { exec, keymap, name}
     -- lvim.builtin.terminal.execs = {{}} to overwrite
     -- lvim.builtin.terminal.execs = {{}} to overwrite
     -- lvim.builtin.terminal.execs[#lvim.builtin.terminal.execs+1] = {"gdb", "tg", "GNU Debugger"}
     -- lvim.builtin.terminal.execs[#lvim.builtin.terminal.execs+1] = {"gdb", "tg", "GNU Debugger"}
+    -- TODO: pls add mappings in which key and refactor this
     execs = {
     execs = {
-      { "lazygit", "<leader>gg", "LazyGit", "float" },
+      { vim.o.shell, "<M-1>", "Horizontal Terminal", "horizontal", 10 },
+      { vim.o.shell, "<M-2>", "Vertical Terminal", "vertical", 60 },
+      { vim.o.shell, "<M-3>", "Float Terminal", "float", nil },
     },
     },
   }
   }
 end
 end
@@ -57,7 +60,7 @@ M.setup = function()
       -- NOTE: unable to consistently bind id/count <= 9, see #2146
       -- NOTE: unable to consistently bind id/count <= 9, see #2146
       count = i + 100,
       count = i + 100,
       direction = exec[4] or lvim.builtin.terminal.direction,
       direction = exec[4] or lvim.builtin.terminal.direction,
-      size = lvim.builtin.terminal.size,
+      size = exec[5] or lvim.builtin.terminal.size,
     }
     }
 
 
     M.add_exec(opts)
     M.add_exec(opts)
@@ -76,14 +79,14 @@ M.add_exec = function(opts)
   end
   end
 
 
   vim.keymap.set({ "n", "t" }, opts.keymap, function()
   vim.keymap.set({ "n", "t" }, opts.keymap, function()
-    M._exec_toggle { cmd = opts.cmd, count = opts.count, direction = opts.direction }
+    M._exec_toggle { cmd = opts.cmd, count = opts.count, direction = opts.direction, size = opts.size }
   end, { desc = opts.label, noremap = true, silent = true })
   end, { desc = opts.label, noremap = true, silent = true })
 end
 end
 
 
 M._exec_toggle = function(opts)
 M._exec_toggle = function(opts)
   local Terminal = require("toggleterm.terminal").Terminal
   local Terminal = require("toggleterm.terminal").Terminal
   local term = Terminal:new { cmd = opts.cmd, count = opts.count, direction = opts.direction }
   local term = Terminal:new { cmd = opts.cmd, count = opts.count, direction = opts.direction }
-  term:toggle(lvim.builtin.terminal.size, opts.direction)
+  term:toggle(opts.size, opts.direction)
 end
 end
 
 
 ---Toggles a log viewer according to log.viewer.layout_config
 ---Toggles a log viewer according to log.viewer.layout_config
@@ -109,4 +112,24 @@ M.toggle_log_view = function(logfile)
   log_view:toggle()
   log_view:toggle()
 end
 end
 
 
+M.lazygit_toggle = function()
+  local Terminal = require("toggleterm.terminal").Terminal
+  local lazygit = Terminal:new {
+    cmd = "lazygit",
+    hidden = true,
+    direction = "float",
+    float_opts = {
+      border = "none",
+      width = 100000,
+      height = 100000,
+    },
+    on_open = function(_)
+      vim.cmd "startinsert!"
+    end,
+    on_close = function(_) end,
+    count = 99,
+  }
+  lazygit:toggle()
+end
+
 return M
 return M

+ 113 - 0
lua/lvim/core/theme.lua

@@ -0,0 +1,113 @@
+local Log = require "lvim.core.log"
+
+local M = {}
+
+M.config = function()
+  lvim.builtin.theme = {
+    name = "tokyonight",
+    options = {
+      on_highlights = function(hl, c)
+        hl.IndentBlanklineContextChar = {
+          fg = c.dark5,
+        }
+        hl.TSConstructor = {
+          fg = c.blue1,
+        }
+        hl.TSTagDelimiter = {
+          fg = c.dark5,
+        }
+        -- local prompt = "#2d3149"
+        -- hl.TelescopeNormal = {
+        --   bg = c.bg_dark,
+        --   fg = c.fg_dark,
+        -- }
+        -- hl.TelescopeBorder = {
+        --   bg = c.bg_dark,
+        --   fg = c.bg_dark,
+        -- }
+        -- hl.TelescopePromptNormal = {
+        --   bg = prompt,
+        -- }
+        -- hl.TelescopePromptBorder = {
+        --   bg = prompt,
+        --   fg = prompt,
+        -- }
+        -- hl.TelescopePromptTitle = {
+        --   bg = prompt,
+        --   fg = prompt,
+        -- }
+        -- hl.TelescopePreviewTitle = {
+        --   bg = c.bg_dark,
+        --   fg = c.bg_dark,
+        -- }
+        -- hl.TelescopeResultsTitle = {
+        --   bg = c.bg_dark,
+        --   fg = c.bg_dark,
+        -- }
+      end,
+      style = "night", -- The theme comes in three styles, `storm`, a darker variant `night` and `day`
+      transparent = lvim.transparent_window, -- Enable this to disable setting the background color
+      terminal_colors = true, -- Configure the colors used when opening a `:terminal` in Neovim
+      styles = {
+        -- Style to be applied to different syntax groups
+        -- Value is any valid attr-list value for `:help nvim_set_hl`
+        comments = { italic = true },
+        keywords = { italic = true },
+        functions = {},
+        variables = {},
+        -- Background styles. Can be "dark", "transparent" or "normal"
+        sidebars = "dark", -- style for sidebars, see below
+        floats = "dark", -- style for floating windows
+      },
+      -- Set a darker background on sidebar-like windows. For example: `["qf", "vista_kind", "terminal", "packer"]`
+      sidebars = {
+        "qf",
+        "vista_kind",
+        "terminal",
+        "packer",
+        "spectre_panel",
+        "NeogitStatus",
+        "help",
+      },
+      day_brightness = 0.3, -- Adjusts the brightness of the colors of the **Day** style. Number between 0 and 1, from dull to vibrant colors
+      hide_inactive_statusline = false, -- Enabling this option, will hide inactive statuslines and replace them with a thin border instead. Should work with the standard **StatusLine** and **LuaLine**.
+      dim_inactive = false, -- dims inactive windows
+      lualine_bold = false, -- When `true`, section headers in the lualine theme will be bold
+      use_background = true, -- can be light/dark/auto. When auto, background will be set to vim.o.background
+    },
+  }
+  local status_ok, theme = pcall(require, "tokyonight")
+  if not status_ok then
+    return
+  end
+
+  theme.setup(lvim.builtin.theme.options)
+end
+
+M.setup = function()
+  -- avoid running in headless mode since it's harder to detect failures
+  if #vim.api.nvim_list_uis() == 0 then
+    Log:debug "headless mode detected, skipping running setup for lualine"
+    return
+  end
+
+  local status_ok, theme = pcall(require, "tokyonight")
+  if status_ok and theme then
+    theme.setup(lvim.builtin.theme.options)
+  end
+
+  -- ref: https://github.com/neovim/neovim/issues/18201#issuecomment-1104754564
+  local colors = vim.api.nvim_get_runtime_file(("colors/%s.*"):format(lvim.colorscheme), false)
+  if #colors == 0 then
+    Log:warn(string.format("Could not find '%s' colorscheme", lvim.colorscheme))
+    lvim.colorscheme = "tokyonight"
+  end
+
+  vim.g.colors_name = lvim.colorscheme
+  vim.cmd("colorscheme " .. lvim.colorscheme)
+
+  require("lvim.core.lualine").setup()
+  require("lvim.core.lir").icon_setup()
+end
+
+return M

+ 11 - 16
lua/lvim/core/which-key.lua

@@ -6,8 +6,8 @@ M.config = function()
     on_config_done = nil,
     on_config_done = nil,
     setup = {
     setup = {
       plugins = {
       plugins = {
-        marks = true, -- shows a list of your marks on ' and `
-        registers = true, -- shows your registers on " in NORMAL or <C-r> in INSERT mode
+        marks = false, -- shows a list of your marks on ' and `
+        registers = false, -- shows your registers on " in NORMAL or <C-r> in INSERT mode
         -- the presets plugin, adds help for a bunch of default keybindings in Neovim
         -- the presets plugin, adds help for a bunch of default keybindings in Neovim
         -- No actual key bindings are created
         -- No actual key bindings are created
         presets = {
         presets = {
@@ -15,16 +15,16 @@ M.config = function()
           motions = false, -- adds help for motions
           motions = false, -- adds help for motions
           text_objects = false, -- help for text objects triggered after entering an operator
           text_objects = false, -- help for text objects triggered after entering an operator
           windows = false, -- default bindings on <c-w>
           windows = false, -- default bindings on <c-w>
-          nav = true, -- misc bindings to work with windows
-          z = true, -- bindings for folds, spelling and others prefixed with z
-          g = true, -- bindings for prefixed with g
+          nav = false, -- misc bindings to work with windows
+          z = false, -- bindings for folds, spelling and others prefixed with z
+          g = false, -- bindings for prefixed with g
         },
         },
         spelling = { enabled = true, suggestions = 20 }, -- use which-key for spelling hints
         spelling = { enabled = true, suggestions = 20 }, -- use which-key for spelling hints
       },
       },
       icons = {
       icons = {
-        breadcrumb = "»", -- symbol used in the command line area that shows your active key combo
-        separator = "➜", -- symbol used between a key and it's label
-        group = "+", -- symbol prepended to a group
+        breadcrumb = lvim.icons.ui.DoubleChevronRight, -- symbol used in the command line area that shows your active key combo
+        separator = lvim.icons.ui.BoldArrowRight, -- symbol used between a key and it's label
+        group = lvim.icons.ui.Plus, -- symbol prepended to a group
       },
       },
       popup_mappings = {
       popup_mappings = {
         scroll_down = "<c-d>", -- binding to scroll down inside the popup
         scroll_down = "<c-d>", -- binding to scroll down inside the popup
@@ -130,8 +130,9 @@ M.config = function()
       -- " Debugging
       -- " Debugging
       g = {
       g = {
         name = "Git",
         name = "Git",
-        j = { "<cmd>lua require 'gitsigns'.next_hunk()<cr>", "Next Hunk" },
-        k = { "<cmd>lua require 'gitsigns'.prev_hunk()<cr>", "Prev Hunk" },
+        g = { "<cmd>lua require 'lvim.core.terminal'.lazygit_toggle()<cr>", "Lazygit" },
+        j = { "<cmd>lua require 'gitsigns'.next_hunk({navigation_message = false})<cr>", "Next Hunk" },
+        k = { "<cmd>lua require 'gitsigns'.prev_hunk({navigation_message = false})<cr>", "Prev Hunk" },
         l = { "<cmd>lua require 'gitsigns'.blame_line()<cr>", "Blame" },
         l = { "<cmd>lua require 'gitsigns'.blame_line()<cr>", "Blame" },
         p = { "<cmd>lua require 'gitsigns'.preview_hunk()<cr>", "Preview Hunk" },
         p = { "<cmd>lua require 'gitsigns'.preview_hunk()<cr>", "Preview Hunk" },
         r = { "<cmd>lua require 'gitsigns'.reset_hunk()<cr>", "Reset Hunk" },
         r = { "<cmd>lua require 'gitsigns'.reset_hunk()<cr>", "Reset Hunk" },
@@ -170,12 +171,6 @@ M.config = function()
           "Prev Diagnostic",
           "Prev Diagnostic",
         },
         },
         l = { vim.lsp.codelens.run, "CodeLens Action" },
         l = { vim.lsp.codelens.run, "CodeLens Action" },
-        p = {
-          name = "Peek",
-          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 = { vim.diagnostic.setloclist, "Quickfix" },
         q = { vim.diagnostic.setloclist, "Quickfix" },
         r = { vim.lsp.buf.rename, "Rename" },
         r = { vim.lsp.buf.rename, "Rename" },
         s = { "<cmd>Telescope lsp_document_symbols<cr>", "Document Symbols" },
         s = { "<cmd>Telescope lsp_document_symbols<cr>", "Document Symbols" },

+ 154 - 0
lua/lvim/icons.lua

@@ -0,0 +1,154 @@
+return {
+  kind = {
+    Array = "",
+    Boolean = "蘒",
+    Class = "",
+    Color = "",
+    Constant = "",
+    Constructor = "",
+    Enum = "",
+    EnumMember = "",
+    Event = "",
+    Field = "",
+    File = "",
+    Folder = "",
+    Function = "",
+    Interface = "",
+    Key = "",
+    Keyword = "",
+    Method = "",
+    Module = "",
+    Namespace = "",
+    Null = "ﳠ",
+    Number = "",
+    Object = "",
+    Operator = "",
+    Package = "",
+    Property = "",
+    Reference = "",
+    Snippet = "",
+    String = "",
+    Struct = "",
+    Text = "",
+    TypeParameter = "",
+    Unit = "",
+    Value = "",
+    Variable = "",
+  },
+  git = {
+    LineAdded = "",
+    LineModified = "",
+    LineRemoved = "",
+    FileDeleted = "",
+    FileIgnored = "◌",
+    FileRenamed = "➜",
+    FileStaged = "S",
+    FileUnmerged = "",
+    FileUnstaged = "",
+    FileUntracked = "U",
+    Diff = "",
+    Repo = "",
+    Octoface = "",
+    Branch = "",
+  },
+  ui = {
+    ArrowCircleDown = "",
+    ArrowCircleLeft = "",
+    ArrowCircleRight = "",
+    ArrowCircleUp = "",
+    BoldArrowDown = "",
+    BoldArrowLeft = "",
+    BoldArrowRight = "",
+    BoldArrowUp = "",
+    BoldClose = "",
+    BoldDividerLeft = "",
+    BoldDividerRight = "",
+    BoldLineLeft = "▎",
+    BookMark = "",
+    BoxChecked = "",
+    Bug = "",
+    Stacks = " ",
+    Scopes = "",
+    Watches = "",
+    DebugConsole = " ",
+    Calendar = "",
+    Check = "",
+    ChevronRight = ">",
+    ChevronShortDown = "",
+    ChevronShortLeft = "",
+    ChevronShortRight = "",
+    ChevronShortUp = "",
+    Circle = "",
+    Close = "",
+    CloudDownload = "",
+    Code = "",
+    Comment = "",
+    Dashboard = "",
+    DividerLeft = "",
+    DividerRight = "",
+    DoubleChevronRight = "»",
+    Ellipsis = "…",
+    EmptyFolder = "",
+    EmptyFolderOpen = "",
+    File = "",
+    FileSymlink = "",
+    Files = "",
+    FindFile = "",
+    FindText = "",
+    Fire = "",
+    Folder = "",
+    FolderOpen = "",
+    FolderSymlink = "",
+    Forward = "",
+    Gear = "",
+    History = "",
+    Lightbulb = "",
+    LineLeft = "▏",
+    LineMiddle = "│",
+    List = "",
+    Lock = "",
+    NewFile = "",
+    Note = "",
+    Package = "",
+    Pencil = "",
+    Plus = "",
+    Project = "",
+    Search = "",
+    SignIn = "",
+    SignOut = "",
+    Tab = "",
+    Table = "",
+    Target = "",
+    Telescope = "",
+    Text = "",
+    Tree = "",
+    Triangle = "契",
+    TriangleShortArrowDown = "",
+    TriangleShortArrowLeft = "",
+    TriangleShortArrowRight = "",
+    TriangleShortArrowUp = "",
+  },
+  diagnostics = {
+    BoldError = "",
+    Error = "",
+    BoldWarning = "",
+    Warning = "",
+    BoldInformation = "",
+    Information = "",
+    BoldQuestion = "",
+    Question = "",
+    BoldHint = "",
+    Hint = "",
+    Debug = "",
+    Trace = "✎",
+  },
+  misc = {
+    Robot = "ﮧ",
+    Squirrel = "",
+    Tag = "",
+    Watch = "",
+    Smiley = "ﲃ",
+    Package = "",
+    CircuitBoard = "",
+  },
+}

+ 211 - 98
lua/lvim/impatient.lua

@@ -1,5 +1,4 @@
 -- modified version from https://github.com/lewis6991/impatient.nvim
 -- modified version from https://github.com/lewis6991/impatient.nvim
-
 local vim = vim
 local vim = vim
 local api = vim.api
 local api = vim.api
 local uv = vim.loop
 local uv = vim.loop
@@ -7,66 +6,96 @@ local _loadfile = loadfile
 local get_runtime = api.nvim__get_runtime
 local get_runtime = api.nvim__get_runtime
 local fs_stat = uv.fs_stat
 local fs_stat = uv.fs_stat
 local mpack = vim.mpack
 local mpack = vim.mpack
+local loadlib = package.loadlib
+
+local std_cache = vim.fn.stdpath "cache"
+
+local sep
+if jit.os == "Windows" then
+  sep = "\\"
+else
+  sep = "/"
+end
+
+local std_dirs = {
+  ["<APPDIR>"] = os.getenv "APPDIR",
+  ["<VIMRUNTIME>"] = os.getenv "VIMRUNTIME",
+  ["<STD_DATA>"] = vim.fn.stdpath "data",
+  ["<STD_CONFIG>"] = vim.fn.stdpath "config",
+  ["<LVIM_BASE>"] = get_lvim_base_dir(),
+  ["<LVIM_RUNTIME>"] = get_runtime_dir(),
+  ["<LVIM_CONFIG>"] = get_config_dir(),
+}
 
 
-local appdir = os.getenv "APPDIR"
+local function modpath_mangle(modpath)
+  for name, dir in pairs(std_dirs) do
+    modpath = modpath:gsub(dir, name)
+  end
+  return modpath
+end
 
 
-local M = {
+local function modpath_unmangle(modpath)
+  for name, dir in pairs(std_dirs) do
+    modpath = modpath:gsub(name, dir)
+  end
+  return modpath
+end
+
+-- Overridable by user
+local default_config = {
+  chunks = {
+    enable = true,
+    path = std_cache .. sep .. "luacache_chunks",
+  },
+  modpaths = {
+    enable = true,
+    path = std_cache .. sep .. "luacache_modpaths",
+  },
+}
+
+-- State used internally
+local default_state = {
   chunks = {
   chunks = {
     cache = {},
     cache = {},
     profile = nil,
     profile = nil,
     dirty = false,
     dirty = false,
-    path = vim.fn.stdpath "cache" .. "/luacache_chunks",
+    get = function(self, path)
+      return self.cache[modpath_mangle(path)]
+    end,
+    set = function(self, path, chunk)
+      self.cache[modpath_mangle(path)] = chunk
+    end,
   },
   },
   modpaths = {
   modpaths = {
     cache = {},
     cache = {},
     profile = nil,
     profile = nil,
     dirty = false,
     dirty = false,
-    path = vim.fn.stdpath "cache" .. "/luacache_modpaths",
+    get = function(self, mod)
+      if self.cache[mod] then
+        return modpath_unmangle(self.cache[mod])
+      end
+    end,
+    set = function(self, mod, path)
+      self.cache[mod] = modpath_mangle(path)
+    end,
   },
   },
   log = {},
   log = {},
 }
 }
 
 
+---@diagnostic disable-next-line: undefined-field
+local M = vim.tbl_deep_extend("keep", _G.__luacache_config or {}, default_config, default_state)
 _G.__luacache = M
 _G.__luacache = M
 
 
-if not get_runtime then
-  -- nvim 0.5 compat
-  get_runtime = function(paths, all, _)
-    local r = {}
-    for _, path in ipairs(paths) do
-      local found = api.nvim_get_runtime_file(path, all)
-      for i = 1, #found do
-        r[#r + 1] = found[i]
-      end
-    end
-    return r
-  end
-end
-
 local function log(...)
 local function log(...)
   M.log[#M.log + 1] = table.concat({ string.format(...) }, " ")
   M.log[#M.log + 1] = table.concat({ string.format(...) }, " ")
 end
 end
 
 
-function M.print_log()
+local function print_log()
   for _, l in ipairs(M.log) do
   for _, l in ipairs(M.log) do
     print(l)
     print(l)
   end
   end
 end
 end
 
 
-function M.enable_profile()
-  local P = require "lvim.impatient.profile"
-
-  M.chunks.profile = {}
-  M.modpaths.profile = {}
-
-  P.setup(M.modpaths.profile)
-
-  M.print_profile = function()
-    P.print_profile(M)
-  end
-
-  vim.cmd [[command! LuaCacheProfile lua _G.__luacache.print_profile()]]
-end
-
 local function hash(modpath)
 local function hash(modpath)
   local stat = fs_stat(modpath)
   local stat = fs_stat(modpath)
   if stat then
   if stat then
@@ -75,20 +104,6 @@ local function hash(modpath)
   error("Could not hash " .. modpath)
   error("Could not hash " .. modpath)
 end
 end
 
 
-local function modpath_mangle(modpath)
-  if appdir then
-    modpath = modpath:gsub(appdir, "/$APPDIR")
-  end
-  return modpath
-end
-
-local function modpath_unmangle(modpath)
-  if appdir then
-    modpath = modpath:gsub("/$APPDIR", appdir)
-  end
-  return modpath
-end
-
 local function profile(m, entry, name, loader)
 local function profile(m, entry, name, loader)
   if m.profile then
   if m.profile then
     local mp = m.profile
     local mp = m.profile
@@ -107,18 +122,41 @@ local function mprofile(mod, name, loader)
 end
 end
 
 
 local function cprofile(path, name, loader)
 local function cprofile(path, name, loader)
+  if M.chunks.profile then
+    path = modpath_mangle(path)
+  end
   profile(M.chunks, path, name, loader)
   profile(M.chunks, path, name, loader)
 end
 end
 
 
-local function get_runtime_file(basename, paths)
+function M.enable_profile()
+  local P = require "lvim.impatient.profile"
+
+  M.chunks.profile = {}
+  M.modpaths.profile = {}
+
+  loadlib = function(path, fun)
+    cprofile(path, "load_start")
+    local f, err = package.loadlib(path, fun)
+    cprofile(path, "load_end", "standard")
+    return f, err
+  end
+
+  P.setup(M.modpaths.profile)
+
+  api.nvim_create_user_command("LuaCacheProfile", function()
+    P.print_profile(M, std_dirs)
+  end, {})
+end
+
+local function get_runtime_file_from_parent(basename, paths)
   -- Look in the cache to see if we have already loaded a parent module.
   -- Look in the cache to see if we have already loaded a parent module.
   -- If we have then try looking in the parents directory first.
   -- If we have then try looking in the parents directory first.
-  local parents = vim.split(basename, "/")
+  local parents = vim.split(basename, sep)
   for i = #parents, 1, -1 do
   for i = #parents, 1, -1 do
-    local parent = table.concat(vim.list_slice(parents, 1, i), "/")
-    local ppath = M.modpaths.cache[parent]
+    local parent = table.concat(vim.list_slice(parents, 1, i), sep)
+    local ppath = M.modpaths:get(parent)
     if ppath then
     if ppath then
-      if ppath:sub(-9) == "/init.lua" then
+      if ppath:sub(-9) == (sep .. "init.lua") then
         ppath = ppath:sub(1, -10) -- a/b/init.lua -> a/b
         ppath = ppath:sub(1, -10) -- a/b/init.lua -> a/b
       else
       else
         ppath = ppath:sub(1, -5) -- a/b.lua -> a/b
         ppath = ppath:sub(1, -5) -- a/b.lua -> a/b
@@ -126,38 +164,71 @@ local function get_runtime_file(basename, paths)
 
 
       for _, path in ipairs(paths) do
       for _, path in ipairs(paths) do
         -- path should be of form 'a/b/c.lua' or 'a/b/c/init.lua'
         -- path should be of form 'a/b/c.lua' or 'a/b/c/init.lua'
-        local modpath = ppath .. "/" .. path:sub(#("lua/" .. parent) + 2)
+        local modpath = ppath .. sep .. path:sub(#("lua" .. sep .. parent) + 2)
         if fs_stat(modpath) then
         if fs_stat(modpath) then
           return modpath, "cache(p)"
           return modpath, "cache(p)"
         end
         end
       end
       end
     end
     end
   end
   end
+end
+
+local rtp = vim.split(vim.o.rtp, ",")
 
 
-  -- What Neovim does by default; slowest
-  local modpath = get_runtime(paths, false, { is_lua = true })[1]
-  return modpath, "standard"
+-- Make sure modpath is in rtp and that modpath is in paths.
+local function validate_modpath(modpath, paths)
+  local match = false
+  for _, p in ipairs(paths) do
+    if vim.endswith(modpath, p) then
+      match = true
+      break
+    end
+  end
+  if not match then
+    return false
+  end
+  for _, dir in ipairs(rtp) do
+    if vim.startswith(modpath, dir) then
+      return fs_stat(modpath) ~= nil
+    end
+  end
+  return false
 end
 end
 
 
 local function get_runtime_file_cached(basename, paths)
 local function get_runtime_file_cached(basename, paths)
+  local modpath, loader
   local mp = M.modpaths
   local mp = M.modpaths
-  if mp.cache[basename] then
-    local modpath = mp.cache[basename]
-    if fs_stat(modpath) then
-      mprofile(basename, "resolve_end", "cache")
-      return modpath
+  if mp.enable then
+    local modpath_cached = mp:get(basename)
+    if modpath_cached then
+      modpath, loader = modpath_cached, "cache"
+    else
+      modpath, loader = get_runtime_file_from_parent(basename, paths)
+    end
+
+    if modpath and not validate_modpath(modpath, paths) then
+      modpath = nil
+
+      -- Invalidate
+      mp.cache[basename] = nil
+      mp.dirty = true
     end
     end
-    mp.cache[basename] = nil
-    mp.dirty = true
   end
   end
 
 
-  local modpath, loader = get_runtime_file(basename, paths)
+  if not modpath then
+    -- What Neovim does by default; slowest
+    modpath, loader = get_runtime(paths, false, { is_lua = true })[1], "standard"
+  end
+
   if modpath then
   if modpath then
     mprofile(basename, "resolve_end", loader)
     mprofile(basename, "resolve_end", loader)
-    log("Creating cache for module %s", basename)
-    mp.cache[basename] = modpath_mangle(modpath)
-    mp.dirty = true
+    if mp.enable and loader ~= "cache" then
+      log("Creating cache for module %s", basename)
+      mp:set(basename, modpath)
+      mp.dirty = true
+    end
   end
   end
+
   return modpath
   return modpath
 end
 end
 
 
@@ -168,8 +239,12 @@ local function extract_basename(pats)
   for _, pat in ipairs(pats) do
   for _, pat in ipairs(pats) do
     for i, npat in ipairs {
     for i, npat in ipairs {
       -- Ordered by most specific
       -- Ordered by most specific
-      "lua/(.*)/init%.lua",
-      "lua/(.*)%.lua",
+      "lua"
+        .. sep
+        .. "(.*)"
+        .. sep
+        .. "init%.lua",
+      "lua" .. sep .. "(.*)%.lua",
     } do
     } do
       local m = pat:match(npat)
       local m = pat:match(npat)
       if i == 2 and m and m:sub(-4) == "init" then
       if i == 2 and m and m:sub(-4) == "init" then
@@ -211,8 +286,8 @@ end
 
 
 -- Copied from neovim/src/nvim/lua/vim.lua with two lines changed
 -- Copied from neovim/src/nvim/lua/vim.lua with two lines changed
 local function load_package(name)
 local function load_package(name)
-  local basename = name:gsub("%.", "/")
-  local paths = { "lua/" .. basename .. ".lua", "lua/" .. basename .. "/init.lua" }
+  local basename = name:gsub("%.", sep)
+  local paths = { "lua" .. sep .. basename .. ".lua", "lua" .. sep .. basename .. sep .. "init.lua" }
 
 
   -- Original line:
   -- Original line:
   -- local found = vim.api.nvim__get_runtime(paths, false, {is_lua=true})
   -- local found = vim.api.nvim__get_runtime(paths, false, {is_lua=true})
@@ -239,7 +314,7 @@ local function load_package(name)
     -- So "foo-bar.baz" should result in "luaopen_bar_baz"
     -- So "foo-bar.baz" should result in "luaopen_bar_baz"
     local dash = name:find("-", 1, true)
     local dash = name:find("-", 1, true)
     local modname = dash and name:sub(dash + 1) or name
     local modname = dash and name:sub(dash + 1) or name
-    local f, err = package.loadlib(found[1], "luaopen_" .. modname:gsub("%.", "_"))
+    local f, err = loadlib(found[1], "luaopen_" .. modname:gsub("%.", "_"))
     return f or error(err)
     return f or error(err)
   end
   end
   return nil
   return nil
@@ -248,14 +323,16 @@ end
 local function load_from_cache(path)
 local function load_from_cache(path)
   local mc = M.chunks
   local mc = M.chunks
 
 
-  if not mc.cache[path] then
+  local cache = mc:get(path)
+
+  if not cache then
     return nil, string.format("No cache for path %s", path)
     return nil, string.format("No cache for path %s", path)
   end
   end
 
 
-  local mhash, codes = unpack(mc.cache[path])
+  local mhash, codes = unpack(cache)
 
 
-  if mhash ~= hash(modpath_unmangle(path)) then
-    mc.cache[path] = nil
+  if mhash ~= hash(path) then
+    mc:set(path)
     mc.dirty = true
     mc.dirty = true
     return nil, string.format("Stale cache for path %s", path)
     return nil, string.format("Stale cache for path %s", path)
   end
   end
@@ -263,7 +340,7 @@ local function load_from_cache(path)
   local chunk = loadstring(codes)
   local chunk = loadstring(codes)
 
 
   if not chunk then
   if not chunk then
-    mc.cache[path] = nil
+    mc:set(path)
     mc.dirty = true
     mc.dirty = true
     return nil, string.format("Cache error for path %s", path)
     return nil, string.format("Cache error for path %s", path)
   end
   end
@@ -274,19 +351,23 @@ end
 local function loadfile_cached(path)
 local function loadfile_cached(path)
   cprofile(path, "load_start")
   cprofile(path, "load_start")
 
 
-  local chunk, err = load_from_cache(path)
-  if chunk and not err then
-    log("Loaded cache for path %s", path)
-    cprofile(path, "load_end", "cache")
-    return chunk
+  local chunk, err
+
+  if M.chunks.enable then
+    chunk, err = load_from_cache(path)
+    if chunk and not err then
+      log("Loaded cache for path %s", path)
+      cprofile(path, "load_end", "cache")
+      return chunk
+    end
+    log(err)
   end
   end
-  log(err)
 
 
   chunk, err = _loadfile(path)
   chunk, err = _loadfile(path)
 
 
-  if not err then
+  if not err and M.chunks.enable then
     log("Creating cache for path %s", path)
     log("Creating cache for path %s", path)
-    M.chunks.cache[modpath_mangle(path)] = { hash(path), string.dump(chunk) }
+    M.chunks:set(path, { hash(path), string.dump(chunk) })
     M.chunks.dirty = true
     M.chunks.dirty = true
   end
   end
 
 
@@ -296,9 +377,12 @@ end
 
 
 function M.save_cache()
 function M.save_cache()
   local function _save_cache(t)
   local function _save_cache(t)
+    if not t.enable then
+      return
+    end
     if t.dirty then
     if t.dirty then
       log("Updating chunk cache file: %s", t.path)
       log("Updating chunk cache file: %s", t.path)
-      local f = io.open(t.path, "w+b")
+      local f = assert(io.open(t.path, "w+b"))
       f:write(mpack.encode(t.cache))
       f:write(mpack.encode(t.cache))
       f:flush()
       f:flush()
       t.dirty = false
       t.dirty = false
@@ -308,7 +392,7 @@ function M.save_cache()
   _save_cache(M.modpaths)
   _save_cache(M.modpaths)
 end
 end
 
 
-function M.clear_cache()
+local function clear_cache()
   local function _clear_cache(t)
   local function _clear_cache(t)
     t.cache = {}
     t.cache = {}
     os.remove(t.path)
     os.remove(t.path)
@@ -319,9 +403,12 @@ end
 
 
 local function init_cache()
 local function init_cache()
   local function _init_cache(t)
   local function _init_cache(t)
+    if not t.enable then
+      return
+    end
     if fs_stat(t.path) then
     if fs_stat(t.path) then
       log("Loading cache file %s", t.path)
       log("Loading cache file %s", t.path)
-      local f = io.open(t.path, "rb")
+      local f = assert(io.open(t.path, "rb"))
       local ok
       local ok
       ok, t.cache = pcall(function()
       ok, t.cache = pcall(function()
         return mpack.decode(f:read "*a")
         return mpack.decode(f:read "*a")
@@ -336,6 +423,10 @@ local function init_cache()
     end
     end
   end
   end
 
 
+  if not uv.fs_stat(std_cache) then
+    vim.fn.mkdir(std_cache, "p")
+  end
+
   _init_cache(M.chunks)
   _init_cache(M.chunks)
   _init_cache(M.modpaths)
   _init_cache(M.modpaths)
 end
 end
@@ -343,20 +434,42 @@ end
 local function setup()
 local function setup()
   init_cache()
   init_cache()
 
 
+  -- Usual package loaders
+  -- 1. package.preload
+  -- 2. vim._load_package
+  -- 3. package.path
+  -- 4. package.cpath
+  -- 5. all-in-one
+
   -- Override default functions
   -- Override default functions
+  for i, loader in ipairs(package.loaders) do
+    if loader == vim._load_package then
+      package.loaders[i] = load_package
+      break
+    end
+  end
   vim._load_package = load_package
   vim._load_package = load_package
+
   vim.api.nvim__get_runtime = get_runtime_cached
   vim.api.nvim__get_runtime = get_runtime_cached
-  -- luacheck: ignore 121
   loadfile = loadfile_cached
   loadfile = loadfile_cached
 
 
-  vim.cmd [[
-    augroup impatient
-      autocmd VimEnter,VimLeave * lua _G.__luacache.save_cache()
-    augroup END
+  local augroup = api.nvim_create_augroup("impatient", {})
+
+  api.nvim_create_user_command("LuaCacheClear", clear_cache, {})
+  api.nvim_create_user_command("LuaCacheLog", print_log, {})
+
+  api.nvim_create_autocmd({ "VimEnter", "VimLeave" }, {
+    group = augroup,
+    callback = M.save_cache,
+  })
 
 
-    command! LuaCacheClear lua _G.__luacache.clear_cache()
-    command! LuaCacheLog   lua _G.__luacache.print_log()
-  ]]
+  api.nvim_create_autocmd("OptionSet", {
+    group = augroup,
+    pattern = "runtimepath",
+    callback = function()
+      rtp = vim.split(vim.o.rtp, ",")
+    end,
+  })
 end
 end
 
 
 setup()
 setup()

+ 60 - 49
lua/lvim/impatient/profile.lua

@@ -1,12 +1,13 @@
 local M = {}
 local M = {}
 
 
-local api, uv = vim.api, vim.loop
+local sep
+if jit.os == "Windows" then
+  sep = "\\"
+else
+  sep = "/"
+end
 
 
-local std_data = vim.fn.stdpath "data"
-local std_config = vim.fn.stdpath "config"
-local vimruntime = os.getenv "VIMRUNTIME"
-local lvim_runtime = get_runtime_dir()
-local lvim_config = get_config_dir()
+local api, uv = vim.api, vim.loop
 
 
 local function load_buffer(title, lines)
 local function load_buffer(title, lines)
   local bufnr = api.nvim_create_buf(false, false)
   local bufnr = api.nvim_create_buf(false, false)
@@ -19,19 +20,6 @@ local function load_buffer(title, lines)
   api.nvim_set_current_buf(bufnr)
   api.nvim_set_current_buf(bufnr)
 end
 end
 
 
-local function mod_path(path)
-  if not path then
-    return "?"
-  end
-  path = path:gsub(std_data .. "/site/pack/packer/", "<PACKER>/")
-  path = path:gsub(std_data .. "/", "<STD_DATA>/")
-  path = path:gsub(std_config .. "/", "<STD_CONFIG>/")
-  path = path:gsub(vimruntime .. "/", "<VIMRUNTIME>/")
-  path = path:gsub(lvim_runtime .. "/", "<LVIM_RUNTIME>/")
-  path = path:gsub(lvim_config .. "/", "<LVIM_CONFIG>/")
-  return path
-end
-
 local function time_tostr(x)
 local function time_tostr(x)
   if x == 0 then
   if x == 0 then
     return "?"
     return "?"
@@ -51,7 +39,7 @@ local function mem_tostr(x)
   return string.format("%1.1f%s", x, unit)
   return string.format("%1.1f%s", x, unit)
 end
 end
 
 
-function M.print_profile(I)
+function M.print_profile(I, std_dirs)
   local mod_profile = I.modpaths.profile
   local mod_profile = I.modpaths.profile
   local chunk_profile = I.chunks.profile
   local chunk_profile = I.chunks.profile
 
 
@@ -67,42 +55,50 @@ function M.print_profile(I)
   for path, m in pairs(chunk_profile) do
   for path, m in pairs(chunk_profile) do
     m.load = m.load_end - m.load_start
     m.load = m.load_end - m.load_start
     m.load = m.load / 1000000
     m.load = m.load / 1000000
-    m.path = mod_path(path)
+    m.path = path or "?"
   end
   end
 
 
   local module_content_width = 0
   local module_content_width = 0
 
 
+  local unloaded = {}
+
   for module, m in pairs(mod_profile) do
   for module, m in pairs(mod_profile) do
-    m.resolve = 0
-    if m.resolve_end then
-      m.resolve = m.resolve_end - m.resolve_start
-      m.resolve = m.resolve / 1000000
-    end
+    local module_dot = module:gsub(sep, ".")
+    m.module = module_dot
 
 
-    m.module = module:gsub("/", ".")
-    m.loader = m.loader or m.loader_guess
+    if not package.loaded[module_dot] and not package.loaded[module] then
+      unloaded[#unloaded + 1] = m
+    else
+      m.resolve = 0
+      if m.resolve_start and m.resolve_end then
+        m.resolve = m.resolve_end - m.resolve_start
+        m.resolve = m.resolve / 1000000
+      end
 
 
-    local path = I.modpaths.cache[module]
-    local path_prof = chunk_profile[path]
-    m.path = mod_path(path)
+      m.loader = m.loader or m.loader_guess
 
 
-    if path_prof then
-      chunk_profile[path] = nil
-      m.load = path_prof.load
-      m.ploader = path_prof.loader
-    else
-      m.load = 0
-      m.ploader = "NA"
-    end
+      local path = I.modpaths.cache[module]
+      local path_prof = chunk_profile[path]
+      m.path = path or "?"
 
 
-    total_resolve = total_resolve + m.resolve
-    total_load = total_load + m.load
+      if path_prof then
+        chunk_profile[path] = nil
+        m.load = path_prof.load
+        m.ploader = path_prof.loader
+      else
+        m.load = 0
+        m.ploader = "NA"
+      end
 
 
-    if #module > module_content_width then
-      module_content_width = #module
-    end
+      total_resolve = total_resolve + m.resolve
+      total_load = total_load + m.load
+
+      if #module > module_content_width then
+        module_content_width = #module
+      end
 
 
-    modules[#modules + 1] = m
+      modules[#modules + 1] = m
+    end
   end
   end
 
 
   table.sort(modules, function(a, b)
   table.sort(modules, function(a, b)
@@ -181,6 +177,12 @@ function M.print_profile(I)
   end
   end
   add ""
   add ""
 
 
+  add "Standard directories:"
+  for alias, path in pairs(std_dirs) do
+    add("  %-12s -> %s", alias, path)
+  end
+  add ""
+
   add("%s─%s┬%s─%s┐", tcwl, lcwl, tcwl, lcwl)
   add("%s─%s┬%s─%s┐", tcwl, lcwl, tcwl, lcwl)
   add(title1_fmt, "Resolve", "Load")
   add(title1_fmt, "Resolve", "Load")
   add("%s┬%s┼%s┬%s┼%s┬%s", tcwl, lcwl, tcwl, lcwl, mcwl, n)
   add("%s┬%s┼%s┬%s┼%s┬%s", tcwl, lcwl, tcwl, lcwl, mcwl, n)
@@ -207,7 +209,17 @@ function M.print_profile(I)
       add(f3, p.load, p.loader, p.path)
       add(f3, p.load, p.loader, p.path)
     end
     end
     add("%s┴%s┴%s", tcwl, lcwl, n)
     add("%s┴%s┴%s", tcwl, lcwl, n)
+  end
+
+  if #unloaded > 0 then
     add ""
     add ""
+    add(n)
+    add "Modules which were unable to loaded"
+    add(n)
+    for _, p in ipairs(unloaded) do
+      lines[#lines + 1] = p.module
+    end
+    add(n)
   end
   end
 
 
   load_buffer("Impatient Profile Report", lines)
   load_buffer("Impatient Profile Report", lines)
@@ -216,13 +228,12 @@ end
 M.setup = function(profile)
 M.setup = function(profile)
   local _require = require
   local _require = require
 
 
-  -- luacheck: ignore 121
   require = function(mod)
   require = function(mod)
-    local basename = mod:gsub("%.", "/")
+    local basename = mod:gsub("%.", sep)
     if not profile[basename] then
     if not profile[basename] then
       profile[basename] = {}
       profile[basename] = {}
       profile[basename].resolve_start = uv.hrtime()
       profile[basename].resolve_start = uv.hrtime()
-      profile[basename].loader_guess = "C"
+      profile[basename].loader_guess = ""
     end
     end
     return _require(mod)
     return _require(mod)
   end
   end
@@ -232,7 +243,7 @@ M.setup = function(profile)
   for i = 1, #pl do
   for i = 1, #pl do
     local l = pl[i]
     local l = pl[i]
     pl[i] = function(mod)
     pl[i] = function(mod)
-      local basename = mod:gsub("%.", "/")
+      local basename = mod:gsub("%.", sep)
       profile[basename].loader_guess = i == 1 and "preloader" or "loader #" .. i
       profile[basename].loader_guess = i == 1 and "preloader" or "loader #" .. i
       return l(mod)
       return l(mod)
     end
     end

+ 0 - 10
lua/lvim/keymappings.lua

@@ -31,12 +31,6 @@ local mode_adapters = {
 
 
 local defaults = {
 local defaults = {
   insert_mode = {
   insert_mode = {
-    -- 'jk' for quitting insert mode
-    ["jk"] = "<ESC>",
-    -- 'kj' for quitting insert mode
-    ["kj"] = "<ESC>",
-    -- 'jj' for quitting insert mode
-    ["jj"] = "<ESC>",
     -- Move current line / block with Alt-j/k ala vscode.
     -- Move current line / block with Alt-j/k ala vscode.
     ["<A-j>"] = "<Esc>:m .+1<CR>==gi",
     ["<A-j>"] = "<Esc>:m .+1<CR>==gi",
     -- Move current line / block with Alt-j/k ala vscode.
     -- Move current line / block with Alt-j/k ala vscode.
@@ -89,10 +83,6 @@ local defaults = {
   },
   },
 
 
   visual_block_mode = {
   visual_block_mode = {
-    -- Move selected line / block of text in visual mode
-    ["K"] = ":move '<-2<CR>gv-gv",
-    ["J"] = ":move '>+1<CR>gv-gv",
-
     -- Move current line / block with Alt-j/k ala vscode.
     -- Move current line / block with Alt-j/k ala vscode.
     ["<A-j>"] = ":m '>+1<CR>gv-gv",
     ["<A-j>"] = ":m '>+1<CR>gv-gv",
     ["<A-k>"] = ":m '<-2<CR>gv-gv",
     ["<A-k>"] = ":m '<-2<CR>gv-gv",

+ 13 - 19
lua/lvim/lsp/config.lua

@@ -10,6 +10,7 @@ local skipped_servers = {
   "eslint",
   "eslint",
   "eslintls",
   "eslintls",
   "golangci_lint_ls",
   "golangci_lint_ls",
+  "gradle_ls",
   "graphql",
   "graphql",
   "jedi_language_server",
   "jedi_language_server",
   "ltex",
   "ltex",
@@ -18,10 +19,12 @@ local skipped_servers = {
   "psalm",
   "psalm",
   "pylsp",
   "pylsp",
   "quick_lint_js",
   "quick_lint_js",
-  "rome",
   "reason_ls",
   "reason_ls",
+  "rome",
+  "ruby_ls",
   "scry",
   "scry",
   "solang",
   "solang",
+  "solc",
   "solidity_ls",
   "solidity_ls",
   "sorbet",
   "sorbet",
   "sourcekit",
   "sourcekit",
@@ -30,8 +33,8 @@ local skipped_servers = {
   "sqlls",
   "sqlls",
   "sqls",
   "sqls",
   "stylelint_lsp",
   "stylelint_lsp",
-  "tflint",
   "svlangserver",
   "svlangserver",
+  "tflint",
   "verible",
   "verible",
   "vuels",
   "vuels",
 }
 }
@@ -46,10 +49,10 @@ return {
     signs = {
     signs = {
       active = true,
       active = true,
       values = {
       values = {
-        { name = "DiagnosticSignError", text = "" },
-        { name = "DiagnosticSignWarn", text = "" },
-        { name = "DiagnosticSignHint", text = "" },
-        { name = "DiagnosticSignInfo", text = "" },
+        { name = "DiagnosticSignError", text = lvim.icons.diagnostics.Error },
+        { name = "DiagnosticSignWarn", text = lvim.icons.diagnostics.Warning },
+        { name = "DiagnosticSignHint", text = lvim.icons.diagnostics.Hint },
+        { name = "DiagnosticSignInfo", text = lvim.icons.diagnostics.Info },
       },
       },
     },
     },
     virtual_text = true,
     virtual_text = true,
@@ -72,18 +75,13 @@ return {
       end,
       end,
     },
     },
   },
   },
-  document_highlight = true,
+  document_highlight = false,
   code_lens_refresh = true,
   code_lens_refresh = true,
   float = {
   float = {
     focusable = true,
     focusable = true,
     style = "minimal",
     style = "minimal",
     border = "rounded",
     border = "rounded",
   },
   },
-  peek = {
-    max_height = 15,
-    max_width = 30,
-    context = 10,
-  },
   on_attach_callback = nil,
   on_attach_callback = nil,
   on_init_callback = nil,
   on_init_callback = nil,
   automatic_configuration = {
   automatic_configuration = {
@@ -100,12 +98,6 @@ return {
       ["gr"] = { vim.lsp.buf.references, "Goto references" },
       ["gr"] = { vim.lsp.buf.references, "Goto references" },
       ["gI"] = { vim.lsp.buf.implementation, "Goto Implementation" },
       ["gI"] = { vim.lsp.buf.implementation, "Goto Implementation" },
       ["gs"] = { vim.lsp.buf.signature_help, "show signature help" },
       ["gs"] = { vim.lsp.buf.signature_help, "show signature help" },
-      ["gp"] = {
-        function()
-          require("lvim.lsp.peek").Peek "definition"
-        end,
-        "Peek definition",
-      },
       ["gl"] = {
       ["gl"] = {
         function()
         function()
           local config = lvim.lsp.diagnostics.float
           local config = lvim.lsp.diagnostics.float
@@ -143,7 +135,9 @@ return {
     },
     },
   },
   },
   null_ls = {
   null_ls = {
-    setup = {},
+    setup = {
+      debug = false,
+    },
     config = {},
     config = {},
   },
   },
   ---@deprecated use lvim.lsp.automatic_configuration.skipped_servers instead
   ---@deprecated use lvim.lsp.automatic_configuration.skipped_servers instead

+ 6 - 5
lua/lvim/lsp/init.lua

@@ -25,6 +25,11 @@ local function add_lsp_buffer_keybindings(bufnr)
 end
 end
 
 
 function M.common_capabilities()
 function M.common_capabilities()
+  local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
+  if status_ok then
+    return cmp_nvim_lsp.default_capabilities()
+  end
+
   local capabilities = vim.lsp.protocol.make_client_capabilities()
   local capabilities = vim.lsp.protocol.make_client_capabilities()
   capabilities.textDocument.completion.completionItem.snippetSupport = true
   capabilities.textDocument.completion.completionItem.snippetSupport = true
   capabilities.textDocument.completion.completionItem.resolveSupport = {
   capabilities.textDocument.completion.completionItem.resolveSupport = {
@@ -35,11 +40,6 @@ function M.common_capabilities()
     },
     },
   }
   }
 
 
-  local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
-  if status_ok then
-    capabilities = cmp_nvim_lsp.update_capabilities(capabilities)
-  end
-
   return capabilities
   return capabilities
 end
 end
 
 
@@ -74,6 +74,7 @@ function M.common_on_attach(client, bufnr)
   end
   end
   add_lsp_buffer_keybindings(bufnr)
   add_lsp_buffer_keybindings(bufnr)
   add_lsp_buffer_options(bufnr)
   add_lsp_buffer_options(bufnr)
+  lu.setup_document_symbols(client, bufnr)
 end
 end
 
 
 function M.get_common_opts()
 function M.get_common_opts()

+ 0 - 157
lua/lvim/lsp/peek.lua

@@ -1,157 +0,0 @@
-local M = {
-  floating_buf = nil,
-  floating_win = nil,
-  prev_result = nil,
-}
-
-local function create_floating_file(location, opts)
-  vim.validate {
-    location = { location, "t" },
-    opts = { opts, "t", true },
-  }
-
-  -- Set some defaults
-  opts = opts or {}
-  local close_events = opts.close_events or { "CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre" }
-
-  -- location may be LocationLink or Location
-  local uri = location.targetUri or location.uri
-  if uri == nil then
-    return
-  end
-  local bufnr = vim.uri_to_bufnr(uri)
-  if not vim.api.nvim_buf_is_loaded(bufnr) then
-    vim.fn.bufload(bufnr)
-  end
-
-  local range = location.targetRange or location.range
-
-  local contents = vim.api.nvim_buf_get_lines(
-    bufnr,
-    range.start.line,
-    math.min(
-      range["end"].line + 1 + (opts.context or lvim.lsp.peek.max_height),
-      range.start.line + (opts.max_height or lvim.lsp.peek.max_height)
-    ),
-    false
-  )
-  if next(contents) == nil then
-    vim.notify("peek: Unable to get contents of the file!", vim.log.levels.WARN)
-    return
-  end
-  local width, height = vim.lsp.util._make_floating_popup_size(contents, opts)
-  local if_nil = vim.F.if_nil
-  opts = vim.lsp.util.make_floating_popup_options(
-    if_nil(width, lvim.lsp.peek.max_width),
-    if_nil(height, lvim.lsp.peek.max_height),
-    opts
-  )
-  -- Don't make it minimal as it is meant to be fully featured
-  opts["style"] = nil
-
-  vim.api.nvim_buf_set_option(bufnr, "bufhidden", "wipe")
-
-  local winnr = vim.api.nvim_open_win(bufnr, false, opts)
-  vim.api.nvim_win_set_option(winnr, "winblend", 0)
-
-  vim.api.nvim_win_set_cursor(winnr, { range.start.line + 1, range.start.character })
-  vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr)
-
-  -- Set some autocmds to close the window
-  vim.api.nvim_command(
-    string.format("autocmd %s <buffer> ++once lua pcall(vim.api.nvim_win_close, %d, true)", unpack(close_events), winnr)
-  )
-
-  return bufnr, winnr
-end
-
-local function preview_location_callback(result)
-  if result == nil or vim.tbl_isempty(result) then
-    return nil
-  end
-
-  local opts = {
-    border = "rounded",
-    context = lvim.lsp.peek.context,
-  }
-
-  if vim.tbl_islist(result) then
-    M.prev_result = result[1]
-    M.floating_buf, M.floating_win = create_floating_file(result[1], opts)
-  else
-    M.prev_result = result
-    M.floating_buf, M.floating_win = create_floating_file(result, opts)
-  end
-end
-
-local function preview_location_callback_new_signature(_, result)
-  return preview_location_callback(result)
-end
-
-function M.open_file()
-  -- Get the file currently open in the floating window
-  local filepath = vim.fn.expand "%:."
-
-  if not filepath then
-    vim.notify("peek: Unable to open the file!", vim.log.levels.ERROR)
-    return
-  end
-
-  -- Close the floating window
-  pcall(vim.api.nvim_win_close, M.floating_win, true)
-
-  -- Edit the file
-  vim.cmd("edit " .. filepath)
-
-  local winnr = vim.api.nvim_get_current_win()
-
-  -- Set the cursor at the right position
-  M.set_cursor_to_prev_pos(winnr)
-end
-
-function M.set_cursor_to_prev_pos(winnr)
-  -- Get position of the thing to peek at
-  local location = M.prev_result
-  local range = location.targetRange or location.range
-  local cursor_pos = { range.start.line + 1, range.start.character }
-
-  -- Set the winnr to the floating window if none was passed in
-  winnr = winnr or M.floating_win
-  -- Set the cursor at the correct position in the floating window
-  vim.api.nvim_win_set_cursor(winnr, cursor_pos)
-end
-
-function M.Peek(what)
-  -- If a window already exists, focus it at the right position!
-  if vim.tbl_contains(vim.api.nvim_list_wins(), M.floating_win) then
-    local success_1, _ = pcall(vim.api.nvim_set_current_win, M.floating_win)
-    if not success_1 then
-      vim.notify("peek: You cannot edit the current file in a preview!", vim.log.levels.ERROR)
-      return
-    end
-
-    -- Set the cursor at the correct position in the floating window
-    M.set_cursor_to_prev_pos()
-
-    vim.api.nvim_buf_set_keymap(
-      M.floating_buf,
-      "n",
-      "<CR>",
-      ":lua require('lvim.lsp.peek').open_file()<CR>",
-      { noremap = true, silent = true }
-    )
-  else
-    -- Make a new request and then create the new window in the callback
-    local params = vim.lsp.util.make_position_params()
-    local preview_callback = preview_location_callback_new_signature
-    local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_callback)
-    if not success then
-      vim.notify(
-        'peek: Error calling LSP method "textDocument/' .. what .. '". The current language lsp might not support it.',
-        vim.log.levels.ERROR
-      )
-    end
-  end
-end
-
-return M

+ 45 - 18
lua/lvim/lsp/providers/sumneko_lua.lua

@@ -1,32 +1,59 @@
-local dev_opts = {
+local default_workspace = {
   library = {
   library = {
-    vimruntime = true, -- runtime path
-    types = true, -- full signature, docs and completion of vim.api, vim.treesitter, vim.lsp and others
-    -- plugins = true, -- installed opt or start plugins in packpath
-    -- you can also specify the list of plugins to make available as a workspace library
-    plugins = { "plenary.nvim" },
+    vim.fn.expand "$VIMRUNTIME",
+    get_lvim_base_dir(),
+    require("neodev.config").types(),
   },
   },
-  override = nil, -- function(root_dir, options) end,
+
+  maxPreload = 5000,
+  preloadFileSize = 10000,
 }
 }
 
 
-local lua_dev_loaded, lua_dev = pcall(require, "lua-dev")
-if lua_dev_loaded then
-  lua_dev.setup(dev_opts)
+local add_packages_to_workspace = function(packages, config)
+  -- config.settings.Lua = config.settings.Lua or { workspace = default_workspace }
+  local runtimedirs = vim.api.nvim__get_runtime({ "lua" }, true, { is_lua = true })
+  local workspace = config.settings.Lua.workspace
+  for _, v in pairs(runtimedirs) do
+    for _, pack in ipairs(packages) do
+      if v:match(pack) and not vim.tbl_contains(workspace.library, v) then
+        table.insert(workspace.library, v)
+      end
+    end
+  end
+end
+
+local lspconfig = require "lspconfig"
+
+local make_on_new_config = function(on_new_config, _)
+  return lspconfig.util.add_hook_before(on_new_config, function(new_config, _)
+    local server_name = new_config.name
+
+    if server_name ~= "sumneko_lua" then
+      return
+    end
+    local plugins = { "plenary.nvim", "telescope.nvim", "nvim-treesitter", "LuaSnip" }
+    add_packages_to_workspace(plugins, new_config)
+  end)
 end
 end
 
 
+lspconfig.util.default_config = vim.tbl_extend("force", lspconfig.util.default_config, {
+  on_new_config = make_on_new_config(lspconfig.util.default_config.on_new_config),
+})
+
 local opts = {
 local opts = {
   settings = {
   settings = {
     Lua = {
     Lua = {
-      diagnostics = {
-        globals = { "vim", "lvim", "packer_plugins" },
-      },
-      workspace = {
-        library = {
-          [require("lvim.utils").join_paths(get_runtime_dir(), "lvim", "lua")] = true,
+      telemetry = { enable = false },
+      runtime = {
+        version = "LuaJIT",
+        special = {
+          reload = "require",
         },
         },
-        maxPreload = 100000,
-        preloadFileSize = 10000,
       },
       },
+      diagnostics = {
+        globals = { "vim", "lvim", "packer_plugins", "reload" },
+      },
+      workspace = default_workspace,
     },
     },
   },
   },
 }
 }

+ 53 - 66
lua/lvim/lsp/utils.lua

@@ -1,6 +1,7 @@
 local M = {}
 local M = {}
 
 
 local tbl = require "lvim.utils.table"
 local tbl = require "lvim.utils.table"
+local Log = require "lvim.core.log"
 
 
 function M.is_client_active(name)
 function M.is_client_active(name)
   local clients = vim.lsp.get_active_clients()
   local clients = vim.lsp.get_active_clients()
@@ -22,25 +23,14 @@ function M.get_active_clients_by_ft(filetype)
 end
 end
 
 
 function M.get_client_capabilities(client_id)
 function M.get_client_capabilities(client_id)
-  local client
-  if not client_id then
-    local buf_clients = vim.lsp.buf_get_clients()
-    for _, buf_client in pairs(buf_clients) do
-      if buf_client.name ~= "null-ls" then
-        client = buf_client
-        break
-      end
-    end
-  else
-    client = vim.lsp.get_client_by_id(tonumber(client_id))
-  end
+  local client = vim.lsp.get_client_by_id(tonumber(client_id))
   if not client then
   if not client then
-    error "Unable to determine client_id"
+    Log:warn("Unable to determine client from client_id: " .. client_id)
     return
     return
   end
   end
 
 
   local enabled_caps = {}
   local enabled_caps = {}
-  for capability, status in pairs(client.server_capabilities or client.resolved_capabilities) do
+  for capability, status in pairs(client.server_capabilities) do
     if status == true then
     if status == true then
       table.insert(enabled_caps, capability)
       table.insert(enabled_caps, capability)
     end
     end
@@ -82,30 +72,55 @@ function M.get_all_supported_filetypes()
 end
 end
 
 
 function M.setup_document_highlight(client, bufnr)
 function M.setup_document_highlight(client, bufnr)
+  if lvim.builtin.illuminate.active then
+    Log:debug "skipping setup for document_highlight, illuminate already active"
+    return
+  end
   local status_ok, highlight_supported = pcall(function()
   local status_ok, highlight_supported = pcall(function()
     return client.supports_method "textDocument/documentHighlight"
     return client.supports_method "textDocument/documentHighlight"
   end)
   end)
   if not status_ok or not highlight_supported then
   if not status_ok or not highlight_supported then
     return
     return
   end
   end
-  local augroup_exist, _ = pcall(vim.api.nvim_get_autocmds, {
-    group = "lsp_document_highlight",
+  local group = "lsp_document_highlight"
+  local hl_events = { "CursorHold", "CursorHoldI" }
+
+  local ok, hl_autocmds = pcall(vim.api.nvim_get_autocmds, {
+    group = group,
+    buffer = bufnr,
+    event = hl_events,
   })
   })
-  if not augroup_exist then
-    vim.api.nvim_create_augroup("lsp_document_highlight", {})
+
+  if ok and #hl_autocmds > 0 then
+    return
   end
   end
-  vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
-    group = "lsp_document_highlight",
+
+  vim.api.nvim_create_augroup(group, { clear = false })
+  vim.api.nvim_create_autocmd(hl_events, {
+    group = group,
     buffer = bufnr,
     buffer = bufnr,
     callback = vim.lsp.buf.document_highlight,
     callback = vim.lsp.buf.document_highlight,
   })
   })
   vim.api.nvim_create_autocmd("CursorMoved", {
   vim.api.nvim_create_autocmd("CursorMoved", {
-    group = "lsp_document_highlight",
+    group = group,
     buffer = bufnr,
     buffer = bufnr,
     callback = vim.lsp.buf.clear_references,
     callback = vim.lsp.buf.clear_references,
   })
   })
 end
 end
 
 
+function M.setup_document_symbols(client, bufnr)
+  vim.g.navic_silence = false -- can be set to true to suppress error
+  local symbols_supported = client.supports_method "textDocument/documentSymbol"
+  if not symbols_supported then
+    Log:debug("skipping setup for document_symbols, method not supported by " .. client.name)
+    return
+  end
+  local status_ok, navic = pcall(require, "nvim-navic")
+  if status_ok then
+    navic.attach(client, bufnr)
+  end
+end
+
 function M.setup_codelens_refresh(client, bufnr)
 function M.setup_codelens_refresh(client, bufnr)
   local status_ok, codelens_supported = pcall(function()
   local status_ok, codelens_supported = pcall(function()
     return client.supports_method "textDocument/codeLens"
     return client.supports_method "textDocument/codeLens"
@@ -113,14 +128,20 @@ function M.setup_codelens_refresh(client, bufnr)
   if not status_ok or not codelens_supported then
   if not status_ok or not codelens_supported then
     return
     return
   end
   end
-  local augroup_exist, _ = pcall(vim.api.nvim_get_autocmds, {
-    group = "lsp_code_lens_refresh",
+  local group = "lsp_code_lens_refresh"
+  local cl_events = { "BufEnter", "InsertLeave" }
+  local ok, cl_autocmds = pcall(vim.api.nvim_get_autocmds, {
+    group = group,
+    buffer = bufnr,
+    event = cl_events,
   })
   })
-  if not augroup_exist then
-    vim.api.nvim_create_augroup("lsp_code_lens_refresh", {})
+
+  if ok and #cl_autocmds > 0 then
+    return
   end
   end
-  vim.api.nvim_create_autocmd({ "BufEnter", "InsertLeave" }, {
-    group = "lsp_code_lens_refresh",
+  vim.api.nvim_create_augroup(group, { clear = false })
+  vim.api.nvim_create_autocmd(cl_events, {
+    group = group,
     buffer = bufnr,
     buffer = bufnr,
     callback = vim.lsp.codelens.refresh,
     callback = vim.lsp.codelens.refresh,
   })
   })
@@ -135,9 +156,9 @@ function M.format_filter(client)
   local n = require "null-ls"
   local n = require "null-ls"
   local s = require "null-ls.sources"
   local s = require "null-ls.sources"
   local method = n.methods.FORMATTING
   local method = n.methods.FORMATTING
-  local avalable_formatters = s.get_available(filetype, method)
+  local available_formatters = s.get_available(filetype, method)
 
 
-  if #avalable_formatters > 0 then
+  if #available_formatters > 0 then
     return client.name == "null-ls"
     return client.name == "null-ls"
   elseif client.supports_method "textDocument/formatting" then
   elseif client.supports_method "textDocument/formatting" then
     return true
     return true
@@ -146,47 +167,13 @@ function M.format_filter(client)
   end
   end
 end
 end
 
 
----Provide vim.lsp.buf.format for nvim <0.8
----@param opts table
+---Simple wrapper for vim.lsp.buf.format() to provide defaults
+---@param opts table|nil
 function M.format(opts)
 function M.format(opts)
   opts = opts or {}
   opts = opts or {}
   opts.filter = opts.filter or M.format_filter
   opts.filter = opts.filter or M.format_filter
 
 
-  if vim.lsp.buf.format then
-    return vim.lsp.buf.format(opts)
-  end
-
-  local bufnr = opts.bufnr or vim.api.nvim_get_current_buf()
-
-  ---@type table|nil
-  local clients = vim.lsp.get_active_clients {
-    id = opts.id,
-    bufnr = bufnr,
-    name = opts.name,
-  }
-
-  if opts.filter then
-    clients = vim.tbl_filter(opts.filter, clients)
-  end
-
-  clients = vim.tbl_filter(function(client)
-    return client.supports_method "textDocument/formatting"
-  end, clients)
-
-  if #clients == 0 then
-    vim.notify_once "[LSP] Format request failed, no matching language servers."
-  end
-
-  local timeout_ms = opts.timeout_ms or 1000
-  for _, client in pairs(clients) do
-    local params = vim.lsp.util.make_formatting_params(opts.formatting_options)
-    local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, bufnr)
-    if result and result.result then
-      vim.lsp.util.apply_text_edits(result.result, bufnr, client.offset_encoding)
-    elseif err then
-      vim.notify(string.format("[LSP][%s] %s", client.name, err), vim.log.levels.WARN)
-    end
-  end
+  return vim.lsp.buf.format(opts)
 end
 end
 
 
 return M
 return M

+ 8 - 5
lua/lvim/plugin-loader.lua

@@ -16,14 +16,19 @@ function plugin_loader.init(opts)
   local install_path = opts.install_path
   local install_path = opts.install_path
     or join_paths(vim.fn.stdpath "data", "site", "pack", "packer", "start", "packer.nvim")
     or join_paths(vim.fn.stdpath "data", "site", "pack", "packer", "start", "packer.nvim")
 
 
+  local max_jobs = 100
+  if vim.fn.has "mac" == 1 then
+    max_jobs = 50
+  end
+
   local init_opts = {
   local init_opts = {
     package_root = opts.package_root or join_paths(vim.fn.stdpath "data", "site", "pack"),
     package_root = opts.package_root or join_paths(vim.fn.stdpath "data", "site", "pack"),
     compile_path = compile_path,
     compile_path = compile_path,
     snapshot_path = snapshot_path,
     snapshot_path = snapshot_path,
-    max_jobs = 40,
+    max_jobs = max_jobs,
     log = { level = "warn" },
     log = { level = "warn" },
     git = {
     git = {
-      clone_timeout = 300,
+      clone_timeout = 120,
     },
     },
     display = {
     display = {
       open_fn = function()
       open_fn = function()
@@ -106,10 +111,8 @@ function plugin_loader.load(configurations)
         end
         end
       end
       end
     end)
     end)
-    -- colorscheme must get called after plugins are loaded or it will break new installs.
-    vim.g.colors_name = lvim.colorscheme
-    vim.cmd("colorscheme " .. lvim.colorscheme)
   end, debug.traceback)
   end, debug.traceback)
+
   if not status_ok then
   if not status_ok then
     Log:warn "problems detected while loading plugins' configurations"
     Log:warn "problems detected while loading plugins' configurations"
     Log:trace(debug.traceback())
     Log:trace(debug.traceback())

+ 59 - 22
lua/lvim/plugins.lua

@@ -1,3 +1,4 @@
+-- local require = require("lvim.utils.require").require
 local core_plugins = {
 local core_plugins = {
   -- Packer can manage itself as an optional plugin
   -- Packer can manage itself as an optional plugin
   { "wbthomason/packer.nvim" },
   { "wbthomason/packer.nvim" },
@@ -6,7 +7,6 @@ local core_plugins = {
   {
   {
     "jose-elias-alvarez/null-ls.nvim",
     "jose-elias-alvarez/null-ls.nvim",
   },
   },
-  { "antoinemadec/FixCursorHold.nvim" }, -- Needed while issue https://github.com/neovim/neovim/issues/12587 is still open
   { "williamboman/mason-lspconfig.nvim" },
   { "williamboman/mason-lspconfig.nvim" },
   {
   {
     "williamboman/mason.nvim",
     "williamboman/mason.nvim",
@@ -15,17 +15,7 @@ local core_plugins = {
     end,
     end,
   },
   },
   {
   {
-    "lunarvim/onedarker.nvim",
-    branch = "freeze",
-    config = function()
-      pcall(function()
-        if lvim and lvim.colorscheme == "onedarker" then
-          require("onedarker").setup()
-          lvim.builtin.lualine.options.theme = "onedarker"
-        end
-      end)
-    end,
-    disable = lvim.colorscheme ~= "onedarker",
+    "folke/tokyonight.nvim",
   },
   },
   {
   {
     "rcarriga/nvim-notify",
     "rcarriga/nvim-notify",
@@ -102,8 +92,8 @@ local core_plugins = {
     "hrsh7th/cmp-path",
     "hrsh7th/cmp-path",
   },
   },
   {
   {
-    "folke/lua-dev.nvim",
-    module = "lua-dev",
+    "folke/neodev.nvim",
+    module = "neodev",
   },
   },
 
 
   -- Autopairs
   -- Autopairs
@@ -139,7 +129,15 @@ local core_plugins = {
     end,
     end,
     disable = not lvim.builtin.nvimtree.active,
     disable = not lvim.builtin.nvimtree.active,
   },
   },
-
+  -- Lir
+  {
+    "christianchiarulli/lir.nvim",
+    config = function()
+      require("lvim.core.lir").setup()
+    end,
+    requires = { "kyazdani42/nvim-web-devicons" },
+    disable = not lvim.builtin.lir.active,
+  },
   {
   {
     "lewis6991/gitsigns.nvim",
     "lewis6991/gitsigns.nvim",
 
 
@@ -196,6 +194,15 @@ local core_plugins = {
     disable = not lvim.builtin.lualine.active,
     disable = not lvim.builtin.lualine.active,
   },
   },
 
 
+  -- breadcrumbs
+  {
+    "SmiteshP/nvim-navic",
+    config = function()
+      require("lvim.core.breadcrumbs").setup()
+    end,
+    disable = not lvim.builtin.breadcrumbs.active,
+  },
+
   {
   {
     "akinsho/bufferline.nvim",
     "akinsho/bufferline.nvim",
     config = function()
     config = function()
@@ -216,12 +223,12 @@ local core_plugins = {
     disable = not lvim.builtin.dap.active,
     disable = not lvim.builtin.dap.active,
   },
   },
 
 
-  -- Debugger management
+  -- Debugger user interface
   {
   {
-    "Pocco81/dap-buddy.nvim",
-    branch = "dev",
-    -- event = "BufWinEnter",
-    -- event = "BufRead",
+    "rcarriga/nvim-dap-ui",
+    config = function()
+      require("lvim.core.dap").setup_ui()
+    end,
     disable = not lvim.builtin.dap.active,
     disable = not lvim.builtin.dap.active,
   },
   },
 
 
@@ -249,6 +256,36 @@ local core_plugins = {
   {
   {
     "b0o/schemastore.nvim",
     "b0o/schemastore.nvim",
   },
   },
+
+  {
+    "RRethy/vim-illuminate",
+    config = function()
+      require("lvim.core.illuminate").setup()
+    end,
+    disable = not lvim.builtin.illuminate.active,
+  },
+
+  {
+    "lukas-reineke/indent-blankline.nvim",
+    config = function()
+      require("lvim.core.indentlines").setup()
+    end,
+    disable = not lvim.builtin.indentlines.active,
+  },
+
+  {
+    "lunarvim/onedarker.nvim",
+    branch = "freeze",
+    config = function()
+      pcall(function()
+        if lvim and lvim.colorscheme == "onedarker" then
+          require("onedarker").setup()
+          lvim.builtin.lualine.options.theme = "onedarker"
+        end
+      end)
+    end,
+    disable = lvim.colorscheme ~= "onedarker",
+  },
 }
 }
 
 
 local default_snapshot_path = join_paths(get_lvim_base_dir(), "snapshots", "default.json")
 local default_snapshot_path = join_paths(get_lvim_base_dir(), "snapshots", "default.json")
@@ -260,8 +297,8 @@ local get_default_sha1 = function(spec)
   return default_sha1[short_name] and default_sha1[short_name].commit
   return default_sha1[short_name] and default_sha1[short_name].commit
 end
 end
 
 
-for _, spec in ipairs(core_plugins) do
-  if not vim.env.LVIM_DEV_MODE then
+if not vim.env.LVIM_DEV_MODE then
+  for _, spec in ipairs(core_plugins) do
     -- Manually lock the commit hash since Packer's snapshots are unreliable in headless mode
     -- Manually lock the commit hash since Packer's snapshots are unreliable in headless mode
     spec["commit"] = get_default_sha1(spec)
     spec["commit"] = get_default_sha1(spec)
   end
   end

+ 13 - 0
lua/lvim/utils/functions.lua

@@ -16,4 +16,17 @@ function M.smart_quit()
   end
   end
 end
 end
 
 
+function M.isempty(s)
+  return s == nil or s == ""
+end
+
+function M.get_buf_option(opt)
+  local status_ok, buf_option = pcall(vim.api.nvim_buf_get_option, 0, opt)
+  if not status_ok then
+    return nil
+  else
+    return buf_option
+  end
+end
+
 return M
 return M

+ 15 - 2
lua/lvim/utils/git.lua

@@ -1,6 +1,7 @@
 local M = {}
 local M = {}
 
 
 local Log = require "lvim.core.log"
 local Log = require "lvim.core.log"
+local fmt = string.format
 local if_nil = vim.F.if_nil
 local if_nil = vim.F.if_nil
 
 
 local function git_cmd(opts)
 local function git_cmd(opts)
@@ -39,13 +40,20 @@ local function safe_deep_fetch()
     Log:error(vim.inspect(error))
     Log:error(vim.inspect(error))
     return
     return
   end
   end
-  -- git fetch --unshallow will cause an error on a a complete clone
+  -- git fetch --unshallow will cause an error on a complete clone
   local fetch_mode = result[1] == "true" and "--unshallow" or "--all"
   local fetch_mode = result[1] == "true" and "--unshallow" or "--all"
   ret = git_cmd { args = { "fetch", fetch_mode } }
   ret = git_cmd { args = { "fetch", fetch_mode } }
   if ret ~= 0 then
   if ret ~= 0 then
-    Log:error("Git fetch failed! Please pull the changes manually in " .. get_lvim_base_dir())
+    Log:error(fmt "Git fetch %s failed! Please pull the changes manually in %s", fetch_mode, get_lvim_base_dir())
     return
     return
   end
   end
+  if fetch_mode == "--unshallow" then
+    ret = git_cmd { args = { "remote", "set-branches", "origin", "*" } }
+    if ret ~= 0 then
+      Log:error(fmt "Git fetch %s failed! Please pull the changes manually in %s", fetch_mode, get_lvim_base_dir())
+      return
+    end
+  end
   return true
   return true
 end
 end
 
 
@@ -53,6 +61,11 @@ end
 function M.update_base_lvim()
 function M.update_base_lvim()
   Log:info "Checking for updates"
   Log:info "Checking for updates"
 
 
+  if not vim.loop.fs_access(get_lvim_base_dir(), "w") then
+    Log:warn(fmt("Lunarvim update aborted! cannot write to %s", get_lvim_base_dir()))
+    return
+  end
+
   if not safe_deep_fetch() then
   if not safe_deep_fetch() then
     return
     return
   end
   end

+ 6 - 9
lua/lvim/utils/hooks.lua

@@ -19,7 +19,7 @@ function M.run_on_packer_complete()
   pcall(vim.cmd, "colorscheme " .. lvim.colorscheme)
   pcall(vim.cmd, "colorscheme " .. lvim.colorscheme)
 
 
   if M._reload_triggered then
   if M._reload_triggered then
-    Log:info "Reloaded configuration"
+    Log:debug "Reloaded configuration"
     M._reload_triggered = nil
     M._reload_triggered = nil
   end
   end
 end
 end
@@ -34,10 +34,7 @@ end
 ---It also forces regenerating any template ftplugin files
 ---It also forces regenerating any template ftplugin files
 ---Tip: Useful for clearing any outdated settings
 ---Tip: Useful for clearing any outdated settings
 function M.reset_cache()
 function M.reset_cache()
-  local impatient = _G.__luacache
-  if impatient then
-    impatient.clear_cache()
-  end
+  vim.cmd [[LuaCacheClear]]
   local lvim_modules = {}
   local lvim_modules = {}
   for module, _ in pairs(package.loaded) do
   for module, _ in pairs(package.loaded) do
     if module:match "lvim.core" or module:match "lvim.lsp" then
     if module:match "lvim.core" or module:match "lvim.lsp" then
@@ -52,8 +49,8 @@ end
 function M.run_post_update()
 function M.run_post_update()
   Log:debug "Starting post-update hook"
   Log:debug "Starting post-update hook"
 
 
-  if vim.fn.has "nvim-0.7" ~= 1 then
-    local compat_tag = "1.1.3"
+  if vim.fn.has "nvim-0.8" ~= 1 then
+    local compat_tag = "1.1.4"
     vim.notify(
     vim.notify(
       "Please upgrade your Neovim base installation. Newer version of Lunarvim requires v0.7+",
       "Please upgrade your Neovim base installation. Newer version of Lunarvim requires v0.7+",
       vim.log.levels.WARN
       vim.log.levels.WARN
@@ -61,9 +58,9 @@ function M.run_post_update()
     vim.wait(1000, function()
     vim.wait(1000, function()
       return false
       return false
     end)
     end)
-    local ret = require_clean("lvim.utils.git").switch_lvim_branch(compat_tag)
+    local ret = reload("lvim.utils.git").switch_lvim_branch(compat_tag)
     if ret then
     if ret then
-      vim.notify("Reverted to the last known compatibile version: " .. compat_tag, vim.log.levels.WARN)
+      vim.notify("Reverted to the last known compatible version: " .. compat_tag, vim.log.levels.WARN)
     end
     end
     return
     return
   end
   end

+ 98 - 0
lua/lvim/utils/modules.lua

@@ -0,0 +1,98 @@
+local M = {}
+
+local Log = require "lvim.core.log"
+-- revisit this
+-- function prequire(package)
+--   local status, lib = pcall(require, package)
+--   if status then
+--     return lib
+--   else
+--     vim.notify("Failed to require '" .. package .. "' from " .. debug.getinfo(2).source)
+--     return nil
+--   end
+-- end
+
+local function _assign(old, new, k)
+  local otype = type(old[k])
+  local ntype = type(new[k])
+  -- print("hi")
+  if (otype == "thread" or otype == "userdata") or (ntype == "thread" or ntype == "userdata") then
+    vim.notify(string.format("warning: old or new attr %s type be thread or userdata", k))
+  end
+  old[k] = new[k]
+end
+
+local function _replace(old, new, repeat_tbl)
+  if repeat_tbl[old] then
+    return
+  end
+  repeat_tbl[old] = true
+
+  local dellist = {}
+  for k, _ in pairs(old) do
+    if not new[k] then
+      table.insert(dellist, k)
+    end
+  end
+  for _, v in ipairs(dellist) do
+    old[v] = nil
+  end
+
+  for k, _ in pairs(new) do
+    if not old[k] then
+      old[k] = new[k]
+    else
+      if type(old[k]) ~= type(new[k]) then
+        Log:debug(
+          string.format("Reloader: mismatch between old [%s] and new [%s] type for [%s]", type(old[k]), type(new[k]), k)
+        )
+        _assign(old, new, k)
+      else
+        if type(old[k]) == "table" then
+          _replace(old[k], new[k], repeat_tbl)
+        else
+          _assign(old, new, k)
+        end
+      end
+    end
+  end
+end
+
+M.require_clean = function(m)
+  package.loaded[m] = nil
+  _G[m] = nil
+  local _, module = pcall(require, m)
+  return module
+end
+
+M.require_safe = function(mod)
+  local status_ok, module = pcall(require, mod)
+  if not status_ok then
+    local trace = debug.getinfo(2, "SL")
+    local shorter_src = trace.short_src
+    local lineinfo = shorter_src .. ":" .. (trace.currentline or trace.linedefined)
+    local msg = string.format("%s : skipped loading [%s]", lineinfo, mod)
+    Log:debug(msg)
+  end
+  return module
+end
+
+M.reload = function(mod)
+  if not package.loaded[mod] then
+    return M.require_safe(mod)
+  end
+
+  local old = package.loaded[mod]
+  package.loaded[mod] = nil
+  local new = M.require_safe(mod)
+
+  if type(old) == "table" and type(new) == "table" then
+    local repeat_tbl = {}
+    _replace(old, new, repeat_tbl)
+  end
+
+  package.loaded[mod] = old
+  return old
+end
+
+return M

+ 46 - 34
snapshots/default.json

@@ -1,84 +1,90 @@
 {
 {
   "Comment.nvim": {
   "Comment.nvim": {
-    "commit": "30d23aa"
-  },
-  "FixCursorHold.nvim": {
-    "commit": "5aa5ff1"
+    "commit": "ad7ffa8"
   },
   },
   "LuaSnip": {
   "LuaSnip": {
-    "commit": "6e506ce"
+    "commit": "663d544"
   },
   },
   "alpha-nvim": {
   "alpha-nvim": {
     "commit": "0bb6fc0"
     "commit": "0bb6fc0"
   },
   },
   "bufferline.nvim": {
   "bufferline.nvim": {
-    "commit": "ffa1d00"
+    "commit": "0606cee"
   },
   },
   "cmp-buffer": {
   "cmp-buffer": {
     "commit": "3022dbc"
     "commit": "3022dbc"
   },
   },
   "cmp-nvim-lsp": {
   "cmp-nvim-lsp": {
-    "commit": "affe808"
+    "commit": "2a84710"
   },
   },
   "cmp-path": {
   "cmp-path": {
-    "commit": "447c87c"
+    "commit": "91ff86c"
   },
   },
   "cmp_luasnip": {
   "cmp_luasnip": {
     "commit": "a9de941"
     "commit": "a9de941"
   },
   },
-  "dap-buddy.nvim": {
-    "commit": "3679132"
-  },
   "friendly-snippets": {
   "friendly-snippets": {
-    "commit": "22a9975"
+    "commit": "fd16b4d"
   },
   },
   "gitsigns.nvim": {
   "gitsigns.nvim": {
-    "commit": "d7e0bcb"
+    "commit": "2c6f96d"
   },
   },
-  "lua-dev.nvim": {
-    "commit": "fd7a18e"
+  "indent-blankline.nvim": {
+    "commit": "db7cbcb"
+  },
+  "lir.nvim": {
+    "commit": "7d8c6c4"
   },
   },
   "lualine.nvim": {
   "lualine.nvim": {
-    "commit": "a52f078"
+    "commit": "edca2b0"
   },
   },
   "mason-lspconfig.nvim": {
   "mason-lspconfig.nvim": {
-    "commit": "1534b61"
+    "commit": "bf8ac12"
   },
   },
   "mason.nvim": {
   "mason.nvim": {
-    "commit": "b56ea0b"
+    "commit": "45b9a4d"
+  },
+  "neodev.nvim": {
+    "commit": "08d8455"
   },
   },
   "nlsp-settings.nvim": {
   "nlsp-settings.nvim": {
-    "commit": "e1fcc6e"
+    "commit": "8500c4e"
   },
   },
   "null-ls.nvim": {
   "null-ls.nvim": {
-    "commit": "bf02782"
+    "commit": "643c67a"
   },
   },
   "nvim-autopairs": {
   "nvim-autopairs": {
-    "commit": "5fe2441"
+    "commit": "4fc96c8"
   },
   },
   "nvim-cmp": {
   "nvim-cmp": {
-    "commit": "913eb85"
+    "commit": "3347dd3"
   },
   },
   "nvim-dap": {
   "nvim-dap": {
-    "commit": "d9b315a"
+    "commit": "e71da68"
+  },
+  "nvim-dap-ui": {
+    "commit": "1cd4764"
   },
   },
   "nvim-lspconfig": {
   "nvim-lspconfig": {
-    "commit": "f8b3c24"
+    "commit": "35a731b"
+  },
+  "nvim-navic": {
+    "commit": "132b273"
   },
   },
   "nvim-notify": {
   "nvim-notify": {
-    "commit": "7076ce8"
+    "commit": "af935fd"
   },
   },
   "nvim-tree.lua": {
   "nvim-tree.lua": {
-    "commit": "fb8735e"
+    "commit": "c446527"
   },
   },
   "nvim-treesitter": {
   "nvim-treesitter": {
-    "commit": "2eaf188"
+    "commit": "1da61c9"
   },
   },
   "nvim-ts-context-commentstring": {
   "nvim-ts-context-commentstring": {
-    "commit": "4d3a68c"
+    "commit": "2941f00"
   },
   },
   "nvim-web-devicons": {
   "nvim-web-devicons": {
-    "commit": "2d02a56"
+    "commit": "a8cf88c"
   },
   },
   "onedarker.nvim": {
   "onedarker.nvim": {
     "commit": "b00dd21"
     "commit": "b00dd21"
@@ -87,16 +93,16 @@
     "commit": "6afb674"
     "commit": "6afb674"
   },
   },
   "plenary.nvim": {
   "plenary.nvim": {
-    "commit": "4b66054"
+    "commit": "4b7e520"
   },
   },
   "popup.nvim": {
   "popup.nvim": {
     "commit": "b7404d3"
     "commit": "b7404d3"
   },
   },
   "project.nvim": {
   "project.nvim": {
-    "commit": "090bb11"
+    "commit": "628de7e"
   },
   },
   "schemastore.nvim": {
   "schemastore.nvim": {
-    "commit": "92efc7c"
+    "commit": "03f4f94"
   },
   },
   "structlog.nvim": {
   "structlog.nvim": {
     "commit": "232a8e2"
     "commit": "232a8e2"
@@ -108,9 +114,15 @@
     "commit": "0b1c41a"
     "commit": "0b1c41a"
   },
   },
   "toggleterm.nvim": {
   "toggleterm.nvim": {
-    "commit": "5e393e5"
+    "commit": "2a787c4"
+  },
+  "tokyonight.nvim": {
+    "commit": "e6307e1"
+  },
+  "vim-illuminate": {
+    "commit": "0603e75"
   },
   },
   "which-key.nvim": {
   "which-key.nvim": {
-    "commit": "d5f0c63"
+    "commit": "6885b66"
   }
   }
 }
 }

+ 1 - 1
tests/minimal_lsp.lua

@@ -71,7 +71,7 @@ _G.load_config = function()
     vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts)
     vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts)
     vim.keymap.set("n", "<space>q", vim.diagnostic.setloclist, opts)
     vim.keymap.set("n", "<space>q", vim.diagnostic.setloclist, opts)
     vim.keymap.set("n", "<space>li", "<cmd>LspInfo<CR>", opts)
     vim.keymap.set("n", "<space>li", "<cmd>LspInfo<CR>", opts)
-    vim.keymap.set("n", "<space>lI", "<cmd>MasonCR>", opts)
+    vim.keymap.set("n", "<space>lI", "<cmd>Mason<CR>", opts)
   end
   end
 
 
   -- Add the server that troubles you here, e.g. "clangd", "pyright", "tsserver"
   -- Add the server that troubles you here, e.g. "clangd", "pyright", "tsserver"

+ 1 - 1
tests/specs/plugins_load_spec.lua

@@ -59,7 +59,7 @@ a.describe("plugin-loader", function()
     _G.completed = false
     _G.completed = false
     _G.verify_sha = function()
     _G.verify_sha = function()
       if _G.locked_sha ~= get_current_sha(plugin.path) then
       if _G.locked_sha ~= get_current_sha(plugin.path) then
-        error "unmached results!"
+        error "unmatched results!"
       else
       else
         _G.completed = true
         _G.completed = true
       end
       end

+ 1 - 1
utils/bin/lvim.ps1

@@ -10,4 +10,4 @@ $env:LUNARVIM_CONFIG_DIR = $env:LUNARVIM_CONFIG_DIR ?? "$env:XDG_CONFIG_HOME\lvi
 $env:LUNARVIM_CACHE_DIR = $env:LUNARVIM_CACHE_DIR ?? "$env:XDG_CACHE_HOME\lvim"
 $env:LUNARVIM_CACHE_DIR = $env:LUNARVIM_CACHE_DIR ?? "$env:XDG_CACHE_HOME\lvim"
 $env:LUNARVIM_BASE_DIR = $env:LUNARVIM_BASE_DIR ?? "$env:LUNARVIM_RUNTIME_DIR\lvim"
 $env:LUNARVIM_BASE_DIR = $env:LUNARVIM_BASE_DIR ?? "$env:LUNARVIM_RUNTIME_DIR\lvim"
 
 
-nvim -u "$env:LUNARVIM_RUNTIME_DIR\lvim\init.lua" @args
+nvim -u "$env:LUNARVIM_BASE_DIR\init.lua" @args

+ 4 - 2
utils/bin/lvim.template

@@ -1,7 +1,9 @@
-#!/bin/sh
+#!/usr/bin/env bash
 
 
 export LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-RUNTIME_DIR_VAR}"
 export LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-RUNTIME_DIR_VAR}"
 export LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-CONFIG_DIR_VAR}"
 export LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-CONFIG_DIR_VAR}"
 export LUNARVIM_CACHE_DIR="${LUNARVIM_CACHE_DIR:-CACHE_DIR_VAR}"
 export LUNARVIM_CACHE_DIR="${LUNARVIM_CACHE_DIR:-CACHE_DIR_VAR}"
 
 
-exec nvim -u "$LUNARVIM_RUNTIME_DIR/lvim/init.lua" "$@"
+export LUNARVIM_BASE_DIR="${LUNARVIM_BASE_DIR:-BASE_DIR_VAR}"
+
+exec -a lvim nvim -u "$LUNARVIM_BASE_DIR/init.lua" "$@"

+ 4 - 4
utils/ci/verify_plugins.lua

@@ -33,8 +33,7 @@ end
 local get_install_path = function(spec)
 local get_install_path = function(spec)
   local prefix = is_optional(spec) and packer_config.opt_dir or packer_config.start_dir
   local prefix = is_optional(spec) and packer_config.opt_dir or packer_config.start_dir
   local path = join_paths(prefix, get_short_name(spec))
   local path = join_paths(prefix, get_short_name(spec))
-  assert(is_directory(path))
-  return path
+  return is_directory(path) and path
 end
 end
 
 
 local function call_proc(process, opts, cb)
 local function call_proc(process, opts, cb)
@@ -92,11 +91,12 @@ end
 
 
 local function verify_core_plugins(verbose)
 local function verify_core_plugins(verbose)
   for _, spec in pairs(core_plugins) do
   for _, spec in pairs(core_plugins) do
-    if not spec.disable then
+    local path = get_install_path(spec)
+    if not spec.disable and path then
       table.insert(collection, {
       table.insert(collection, {
         name = get_short_name(spec),
         name = get_short_name(spec),
         commit = get_default_sha1(spec),
         commit = get_default_sha1(spec),
-        path = get_install_path(spec),
+        path = path,
       })
       })
     end
     end
   end
   end

+ 10 - 0
utils/desktop/16x16/lvim.svg

@@ -0,0 +1,10 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
+ <circle style="fill:#4f4f4f" cx="8" cy="8" r="8"/>
+ <path style="fill:#ffffff" d="M 6.270786,6 H 7.270393 L 6.399607,11 H 5.4 Z"/>
+ <path style="fill:#ffffff" d="m 8.9788284,10 v 1 H 5.4000004 L 5.64,10 Z"/>
+ <path style="fill:#6f6fee" d="M 8 3 A 5 5 0 0 0 3 8 A 5 5 0 0 0 8 13 A 5 5 0 0 0 13 8 A 5 5 0 0 0 8 3 z M 8 4 A 4.0000001 4.0000001 0 0 1 12 8 A 4.0000001 4.0000001 0 0 1 8 12 A 4.0000001 4.0000001 0 0 1 4 8 A 4.0000001 4.0000001 0 0 1 8 4 z"/>
+ <path style="fill:#ffffff" d="M 8,7.3304688 V 11 H 9 V 7.3304688 C 8.8433906,7.3753512 8.674825,7.4 8.5,7.4 8.325175,7.4 8.1566094,7.375352 8,7.3304688 Z"/>
+ <path style="fill:#ffffff" d="m 10.34358,6 h 0.99958 L 9.24,11 H 8.24042 Z"/>
+ <path style="fill:#59d4f1" d="M 3.5644531 5.0019531 C 3.2874864 5.0076244 3.0408032 5.0355933 2.8261719 5.0898438 C 2.4446055 5.186288 2.1239441 5.3751204 2.0273438 5.7460938 C 1.9307428 6.1170665 2.1035029 6.4946837 2.3710938 6.8359375 C 2.5408113 7.0523749 2.7626959 7.2697752 3.0273438 7.4902344 C 3.0493821 7.2726184 3.0837732 7.0580708 3.1328125 6.8496094 C 2.9822517 6.7117295 2.8555085 6.578593 2.7617188 6.4589844 C 2.5522032 6.1917933 2.5164475 6.0188003 2.5371094 5.9394531 C 2.5577714 5.8601064 2.6680418 5.7415288 2.9667969 5.6660156 C 3.2655515 5.5905026 3.710536 5.5710215 4.25 5.6171875 C 5.3289283 5.7095195 6.7903586 6.0596776 8.3515625 6.6484375 C 9.9127664 7.2371965 11.279225 7.9539585 12.208984 8.6191406 C 12.673864 8.9517314 13.030718 9.273824 13.240234 9.5410156 C 13.44975 9.8082077 13.483553 9.9811995 13.462891 10.060547 C 13.442231 10.139897 13.331958 10.258473 13.033203 10.333984 C 12.862309 10.377175 12.641933 10.40159 12.384766 10.40625 C 12.273012 10.609478 12.147711 10.803518 12.009766 10.988281 C 12.462418 11.011122 12.855509 10.990613 13.173828 10.910156 C 13.555395 10.813706 13.876056 10.622925 13.972656 10.251953 C 14.069256 9.8809797 13.8965 9.5053164 13.628906 9.1640625 C 13.361315 8.8228159 12.971582 8.4777562 12.478516 8.125 C 11.492385 7.4194869 10.09492 6.6920542 8.4980469 6.0898438 C 6.9011749 5.4876337 5.4080174 5.1252736 4.2636719 5.0273438 C 4.1206289 5.0151036 3.9833613 5.0059394 3.8515625 5.0019531 C 3.7527131 4.9989614 3.6567754 5.0000627 3.5644531 5.0019531 z"/>
+ <circle style="fill:#ffffff" cx="8.45" cy="6.25" r=".75"/>
+</svg>

+ 16 - 0
utils/desktop/22x22/lvim.svg

@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" version="1.1">
+ <circle style="opacity:0.2" cx="11" cy="11.5" r="10"/>
+ <circle style="fill:#4f4f4f" cx="11" cy="11" r="10"/>
+ <path style="opacity:0.2" d="M 8.5878906,8.5 7.5,14.5 h 1 3.472656 H 12 12.300781 l 2.628907,-6 h -1 L 12,12.904297 V 10.910156 A 1.5,1.5 0 0 1 11.5,11 1.5,1.5 0 0 1 11,10.910156 V 13.5 H 8.6816406 l 0.9062504,-5 z"/>
+ <path style="opacity:0.2" d="m 11,5.5 a 6,6 0 0 0 -6,6 6,6 0 0 0 6,6 6,6 0 0 0 6,-6 6,6 0 0 0 -6,-6 z m 0,0.9230769 A 5.0769231,5.0769231 0 0 1 16.076923,11.5 5.0769231,5.0769231 0 0 1 11,16.576923 5.0769231,5.0769231 0 0 1 5.9230769,11.5 5.0769231,5.0769231 0 0 1 11,6.4230769 Z"/>
+ <path style="fill:#ffffff" d="M 8.5884825,8 H 9.588483 L 8.5,14 h -1 z"/>
+ <path style="opacity:0.1;fill:#ffffff" d="M 11,1 A 10,10 0 0 0 1,11 10,10 0 0 0 1.01075,11.291 10,10 0 0 1 11,1.5 10,10 0 0 1 20.9895,11.209 10,10 0 0 0 21,11 10,10 0 0 0 11,1 Z"/>
+ <path style="fill:#ffffff" d="m 11.973536,13 v 1 H 7.5000005 L 7.8,13 Z"/>
+ <path style="fill:#6f6fee" d="m 11,5 a 6,6 0 0 0 -6,6 6,6 0 0 0 6,6 6,6 0 0 0 6,-6 6,6 0 0 0 -6,-6 z m 0,0.9230769 A 5.0769231,5.0769231 0 0 1 16.076923,11 5.0769231,5.0769231 0 0 1 11,16.076923 5.0769231,5.0769231 0 0 1 5.9230769,11 5.0769231,5.0769231 0 0 1 11,5.9230769 Z"/>
+ <path style="fill:#ffffff" d="M 11,10.410156 V 14 h 1 V 10.410156 A 1.5,1.5 0 0 1 11.5,10.5 1.5,1.5 0 0 1 11,10.410156 Z"/>
+ <path style="fill:#ffffff" d="m 13.92895,8 h 1 L 12.3,14 h -1 z"/>
+ <path style="opacity:0.2" d="M 5.0859375,7.5019531 C 4.7166486,7.5095131 4.3857845,7.5468071 4.0996094,7.6191406 3.5908542,7.7477316 3.16591,8.0014688 3.0371094,8.4960938 2.9083084,8.9907183 3.1373532,9.492266 3.4941406,9.947266 3.7722382,10.301914 4.4997487,10.832068 5.0078125,11.216797 5.0214895,10.921995 5.0566015,10.63375 5.1113281,10.351562 4.751879,10.066543 4.1825448,9.660671 4.0136719,9.445313 3.7343179,9.089062 3.6872945,8.8577481 3.7148438,8.7519531 3.7423928,8.6461586 3.8907222,8.4893549 4.2890625,8.3886719 4.6874019,8.2879889 5.2807146,8.2607121 6,8.3222656 c 1.4385712,0.123107 3.387144,0.5919496 5.46875,1.3769534 2.081606,0.785003 3.902899,1.740054 5.142578,2.626953 0.61984,0.443449 1.095646,0.872264 1.375,1.228516 0.279353,0.356249 0.326378,0.587564 0.298828,0.693359 -0.02755,0.105795 -0.175878,0.262598 -0.574218,0.363281 -0.242816,0.06137 -1.007389,0.03264 -1.585938,0.0098 -0.16587,0.271812 -0.352953,0.528429 -0.558594,0.769531 0.788474,0.05519 1.896167,0.100399 2.332032,-0.0098 0.508753,-0.128592 0.937605,-0.382329 1.066406,-0.876953 0.128801,-0.494625 -0.104151,-0.996172 -0.460938,-1.451172 C 18.147118,12.597735 17.628125,12.138305 16.970703,11.667969 15.655861,10.727283 13.793224,9.756063 11.664062,8.953125 9.534898,8.150188 7.5433721,7.6676809 6.0175781,7.5371094 5.8268541,7.5207894 5.6444818,7.5092212 5.46875,7.5039062 5.3369509,7.4999175 5.2090338,7.4994325 5.0859375,7.5019531 Z"/>
+ <path style="fill:#59d4f1" d="M 5.0859375,7.0019531 C 4.7166486,7.0095131 4.3857845,7.0468071 4.0996094,7.1191406 3.5908542,7.2477316 3.16591,7.5014688 3.0371094,7.9960938 2.9083084,8.4907183 3.1373532,8.9922661 3.4941406,9.447266 3.7722382,9.801914 4.4997487,10.332068 5.0078125,10.716797 5.0214895,10.421995 5.0566015,10.13375 5.1113281,9.851562 4.751879,9.566543 4.1825448,9.160671 4.0136719,8.9453125 3.7343179,8.589062 3.6872945,8.3577481 3.7148438,8.2519531 3.7423928,8.1461586 3.8907222,7.9893549 4.2890625,7.8886719 4.6874019,7.7879889 5.2807146,7.7607121 6,7.8222656 c 1.4385712,0.123107 3.387144,0.5919496 5.46875,1.3769534 2.081606,0.785003 3.902899,1.740054 5.142578,2.626953 0.61984,0.443449 1.095646,0.872264 1.375,1.228516 0.279353,0.356249 0.326378,0.587564 0.298828,0.693359 -0.02755,0.105795 -0.175878,0.262598 -0.574218,0.363281 -0.242816,0.06137 -1.007389,0.03264 -1.585938,0.0098 -0.16587,0.271812 -0.352953,0.528429 -0.558594,0.769531 0.788474,0.05519 1.896167,0.100399 2.332032,-0.0098 0.508753,-0.128592 0.937605,-0.382329 1.066406,-0.876953 0.128801,-0.494625 -0.104151,-0.996172 -0.460938,-1.451172 C 18.147118,12.097735 17.628125,11.638305 16.970703,11.167969 15.655861,10.227283 13.793224,9.256063 11.664062,8.453125 9.534898,7.650188 7.5433721,7.1676809 6.0175781,7.0371094 5.8268541,7.0207894 5.6444818,7.0092212 5.46875,7.0039062 5.3369509,6.9999175 5.2090338,6.9994325 5.0859375,7.0019531 Z"/>
+ <circle style="opacity:0.2" cx="11.5" cy="9.5" r="1"/>
+ <circle style="fill:#ffffff" cx="11.5" cy="9" r="1"/>
+</svg>

+ 16 - 0
utils/desktop/24x24/lvim.svg

@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" version="1.1">
+ <circle style="opacity:0.2" cx="12" cy="12.5" r="10"/>
+ <circle style="fill:#4f4f4f" cx="12" cy="12" r="10"/>
+ <path style="opacity:0.2" d="M 9.5878906,9.5 8.5,15.5 h 1 3.472656 H 13 13.300781 l 2.628907,-6 h -1 L 13,13.904297 V 11.910156 A 1.5,1.5 0 0 1 12.5,12 1.5,1.5 0 0 1 12,11.910156 V 14.5 H 9.6816406 l 0.9062504,-5 z"/>
+ <path style="opacity:0.2" d="m 12,6.5 a 6,6 0 0 0 -6,6 6,6 0 0 0 6,6 6,6 0 0 0 6,-6 6,6 0 0 0 -6,-6 z m 0,0.9230769 A 5.0769231,5.0769231 0 0 1 17.076923,12.5 5.0769231,5.0769231 0 0 1 12,17.576923 5.0769231,5.0769231 0 0 1 6.9230769,12.5 5.0769231,5.0769231 0 0 1 12,7.4230769 Z"/>
+ <path style="fill:#ffffff" d="M 9.5884825,9 H 10.588483 L 9.5,15 h -1 z"/>
+ <path style="opacity:0.1;fill:#ffffff" d="M 12,2 A 10,10 0 0 0 2,12 10,10 0 0 0 2.01075,12.291 10,10 0 0 1 12,2.5 10,10 0 0 1 21.9895,12.209 10,10 0 0 0 22,12 10,10 0 0 0 12,2 Z"/>
+ <path style="fill:#ffffff" d="m 12.973536,14 v 1 H 8.5000005 L 8.8,14 Z"/>
+ <path style="fill:#6f6fee" d="m 12,6 a 6,6 0 0 0 -6,6 6,6 0 0 0 6,6 6,6 0 0 0 6,-6 6,6 0 0 0 -6,-6 z m 0,0.9230769 A 5.0769231,5.0769231 0 0 1 17.076923,12 5.0769231,5.0769231 0 0 1 12,17.076923 5.0769231,5.0769231 0 0 1 6.9230769,12 5.0769231,5.0769231 0 0 1 12,6.9230769 Z"/>
+ <path style="fill:#ffffff" d="M 12 11.410156 L 12 15 L 13 15 L 13 11.410156 A 1.5 1.5 0 0 1 12.5 11.5 A 1.5 1.5 0 0 1 12 11.410156 z"/>
+ <path style="fill:#ffffff" d="m 14.92895,9 h 1 L 13.3,15 h -1 z"/>
+ <path style="opacity:0.2" d="m 6.0859375,8.5019531 c -0.3692889,0.00756 -0.700153,0.044854 -0.9863281,0.1171875 -0.5087552,0.128591 -0.9336994,0.3823282 -1.0625,0.8769532 -0.128801,0.4946245 0.1002438,0.9961722 0.4570312,1.4511722 0.2780976,0.354648 1.0056081,0.884802 1.5136719,1.269531 0.013677,-0.294802 0.048789,-0.583047 0.1035156,-0.865235 C 5.751879,11.066543 5.1825448,10.660671 5.0136719,10.445313 4.7343179,10.089062 4.6872945,9.8577481 4.7148438,9.7519531 4.7423928,9.6461586 4.8907222,9.4893549 5.2890625,9.3886719 5.6874019,9.2879889 6.2807146,9.2607121 7,9.3222656 c 1.4385712,0.123107 3.387144,0.5919496 5.46875,1.3769534 2.081606,0.785003 3.902899,1.740054 5.142578,2.626953 0.61984,0.443449 1.095646,0.872264 1.375,1.228516 0.279353,0.356249 0.326378,0.587564 0.298828,0.693359 -0.02755,0.105795 -0.175878,0.262598 -0.574218,0.363281 -0.242816,0.06137 -1.007389,0.03264 -1.585938,0.0098 -0.16587,0.271812 -0.352953,0.528429 -0.558594,0.769531 0.788474,0.05519 1.896167,0.100399 2.332032,-0.0098 0.508753,-0.128592 0.937605,-0.382329 1.066406,-0.876953 0.128801,-0.494625 -0.104151,-0.996172 -0.460938,-1.451172 C 19.147118,13.597735 18.628125,13.138305 17.970703,12.667969 16.655861,11.727283 14.793224,10.756063 12.664062,9.953125 10.534898,9.150188 8.5433721,8.6676809 7.0175781,8.5371094 6.8268541,8.5207894 6.6444818,8.5092212 6.46875,8.5039062 6.3369509,8.4999175 6.2090338,8.4994325 6.0859375,8.5019531 Z"/>
+ <path style="fill:#59d4f1" d="M 6.0859375 8.0019531 C 5.7166486 8.009515 5.3857845 8.0468072 5.0996094 8.1191406 C 4.5908542 8.2477316 4.16591 8.5014688 4.0371094 8.9960938 C 3.9083084 9.4907183 4.1373532 9.9922661 4.4941406 10.447266 C 4.7722382 10.801914 5.4997487 11.332068 6.0078125 11.716797 C 6.0214896 11.421995 6.0566018 11.13375 6.1113281 10.851562 C 5.751879 10.566543 5.1825448 10.160671 5.0136719 9.9453125 C 4.7343179 9.589062 4.6872945 9.3577481 4.7148438 9.2519531 C 4.7423928 9.1461586 4.8907222 8.9893549 5.2890625 8.8886719 C 5.6874019 8.7879889 6.2807146 8.7607121 7 8.8222656 C 8.4385712 8.9453726 10.387144 9.4142152 12.46875 10.199219 C 14.550356 10.984222 16.371649 11.939273 17.611328 12.826172 C 18.231168 13.269621 18.706974 13.698436 18.986328 14.054688 C 19.265681 14.410937 19.312706 14.642252 19.285156 14.748047 C 19.257606 14.853842 19.109278 15.010645 18.710938 15.111328 C 18.468122 15.172698 17.703549 15.14397 17.125 15.121094 C 16.95913 15.392906 16.772047 15.649523 16.566406 15.890625 C 17.35488 15.94582 18.462573 15.991024 18.898438 15.880859 C 19.407191 15.752267 19.836043 15.49853 19.964844 15.003906 C 20.093645 14.509281 19.860693 14.007734 19.503906 13.552734 C 19.147118 13.097735 18.628125 12.638305 17.970703 12.167969 C 16.655861 11.227283 14.793224 10.256063 12.664062 9.453125 C 10.534898 8.650188 8.5433721 8.1676809 7.0175781 8.0371094 C 6.8268541 8.0207894 6.6444818 8.0092212 6.46875 8.0039062 C 6.3369509 7.9999175 6.2090338 7.9994325 6.0859375 8.0019531 z"/>
+ <circle style="opacity:0.2" cx="12.5" cy="10.5" r="1"/>
+ <circle style="fill:#ffffff" cx="12.5" cy="10" r="1"/>
+</svg>

+ 16 - 0
utils/desktop/32x32/lvim.svg

@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" version="1.1">
+ <circle style="opacity:0.2" cx="16" cy="17" r="14"/>
+ <circle style="fill:#4f4f4f" cx="16" cy="16" r="14"/>
+ <path style="opacity:0.2" d="m 12.623047,13 -1.523438,9 h 1 5.263672 0.15625 l 3.681641,-9 H 20.099609 L 17,20.582031 v -4.703125 c -0.156609,0.07489 -0.325175,0.115235 -0.5,0.115235 -0.174825,0 -0.343391,-0.04035 -0.5,-0.115235 V 21 h -3.730469 l 1.353516,-8 z"/>
+ <path style="opacity:0.2" d="m 16,8 a 9,9 0 0 0 -9,9 9,9 0 0 0 9,9 9,9 0 0 0 9,-9 9,9 0 0 0 -9,-9 z m 0,1 a 7.9999999,7.9999999 0 0 1 8,8 7.9999999,7.9999999 0 0 1 -8,8 7.9999999,7.9999999 0 0 1 -8,-8 7.9999999,7.9999999 0 0 1 8,-8 z"/>
+ <path style="fill:#ffffff" d="m 12.623876,12 h 1.000062 l -1.523876,9 H 11.1 Z"/>
+ <path style="fill:#ffffff" d="m 17.36295,20 v 1 H 11.100001 L 11.52,20 Z"/>
+ <path style="fill:#6f6fee" d="M 16 7 A 9 9 0 0 0 7 16 A 9 9 0 0 0 16 25 A 9 9 0 0 0 25 16 A 9 9 0 0 0 16 7 z M 16 8 A 7.9999999 7.9999999 0 0 1 24 16 A 7.9999999 7.9999999 0 0 1 16 24 A 7.9999999 7.9999999 0 0 1 8 16 A 7.9999999 7.9999999 0 0 1 16 8 z"/>
+ <path style="fill:#ffffff" d="M 16,14.878 V 21 h 1 v -6.122 c -0.156609,0.07489 -0.325175,0.116001 -0.5,0.116001 -0.174825,0 -0.343391,-0.04112 -0.5,-0.116001 z"/>
+ <path style="fill:#ffffff" d="m 20.100529,12 h 1.099735 l -3.680529,9 H 16.42 Z"/>
+ <path style="opacity:0.2" d="m 7.8671875,11.001953 c -0.5077723,0.0104 -0.9600248,0.06265 -1.3535156,0.162109 -0.6995383,0.176815 -1.2877432,0.524962 -1.4648438,1.205079 -0.1771015,0.680116 0.1383235,1.370461 0.6289063,1.996093 0.3535818,0.450916 0.8387175,0.906463 1.4140625,1.367188 0.054036,-0.383267 0.1297372,-0.758831 0.2304687,-1.125 C 6.936014,14.274886 6.6151218,13.957096 6.3945312,13.675781 6.0104195,13.18593 5.9445418,12.868126 5.9824219,12.722656 c 0.03788,-0.145468 0.2432978,-0.361559 0.7910156,-0.5 0.5477168,-0.13844 1.3625452,-0.176431 2.3515625,-0.0918 1.978035,0.169274 4.657324,0.813185 7.519531,1.892579 2.862208,1.07939 5.367708,2.391827 7.072266,3.611328 0.85228,0.609749 1.50456,1.199602 1.888672,1.689453 0.38411,0.489849 0.449988,0.807655 0.412109,0.953125 -0.03788,0.14547 -0.243297,0.361559 -0.791016,0.5 -0.297281,0.07514 -0.678568,0.117262 -1.11914,0.128906 -0.181389,0.375764 -0.385371,0.737546 -0.615234,1.082031 0.77116,0.03049 1.443228,-0.01309 1.99414,-0.152343 0.699539,-0.176816 1.287743,-0.526914 1.464844,-1.207032 0.177101,-0.680117 -0.14223,-1.370461 -0.632813,-1.996094 -0.490583,-0.62563 -1.20542,-1.257576 -2.109375,-1.904296 -1.807909,-1.29344 -4.369276,-2.628372 -7.296875,-3.732422 -2.9276,-1.104052 -5.665705,-1.767727 -7.7636715,-1.947266 -0.2622456,-0.02244 -0.5142281,-0.03566 -0.7558594,-0.04297 -0.1812237,-0.0055 -0.3561332,-0.0074 -0.5253906,-0.0039 z"/>
+ <path style="fill:#59d4f1" d="M 7.8671875 10.001953 C 7.3594152 10.01235 6.9071627 10.064605 6.5136719 10.164062 C 5.8141336 10.340877 5.2259287 10.689024 5.0488281 11.369141 C 4.8717266 12.049257 5.1871516 12.739602 5.6777344 13.365234 C 6.0313162 13.81615 6.5164519 14.271697 7.0917969 14.732422 C 7.1458329 14.349155 7.2215341 13.973591 7.3222656 13.607422 C 6.936014 13.274886 6.6151218 12.957096 6.3945312 12.675781 C 6.0104195 12.18593 5.9445418 11.868126 5.9824219 11.722656 C 6.0203019 11.577188 6.2257197 11.361097 6.7734375 11.222656 C 7.3211543 11.084216 8.1359827 11.046225 9.125 11.130859 C 11.103035 11.300133 13.782324 11.944044 16.644531 13.023438 C 19.506739 14.102828 22.012239 15.415265 23.716797 16.634766 C 24.569077 17.244515 25.221357 17.834368 25.605469 18.324219 C 25.989579 18.814068 26.055457 19.131874 26.017578 19.277344 C 25.979698 19.422814 25.774281 19.638903 25.226562 19.777344 C 24.929281 19.852484 24.547994 19.894606 24.107422 19.90625 C 23.926033 20.282014 23.722051 20.643796 23.492188 20.988281 C 24.263348 21.018773 24.935416 20.975188 25.486328 20.835938 C 26.185867 20.659122 26.774071 20.309024 26.951172 19.628906 C 27.128273 18.948789 26.808942 18.258445 26.318359 17.632812 C 25.827776 17.007182 25.112939 16.375236 24.208984 15.728516 C 22.401075 14.435076 19.839708 13.100144 16.912109 11.996094 C 13.984509 10.892042 11.246404 10.228367 9.1484375 10.048828 C 8.8861919 10.026388 8.6342094 10.013169 8.3925781 10.005859 C 8.2113544 10.000372 8.0364449 9.9984875 7.8671875 10.001953 z"/>
+ <circle style="opacity:0.2" cx="16.5" cy="13.5" r="1.5"/>
+ <circle style="fill:#ffffff" cx="16.5" cy="12.5" r="1.5"/>
+ <path style="fill:#ffffff;opacity:0.1" d="M 16 2 A 14 14 0 0 0 2 16 A 14 14 0 0 0 2.0351562 16.5 A 14 14 0 0 1 16 3 A 14 14 0 0 1 29.980469 16.279297 A 14 14 0 0 0 30 16 A 14 14 0 0 0 16 2 z"/>
+</svg>

+ 16 - 0
utils/desktop/48x48/lvim.svg

@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" version="1.1">
+ <circle style="opacity:0.2" cx="24" cy="25" r="20"/>
+ <circle style="fill:#4f4f4f" cx="24" cy="24" r="20"/>
+ <path style="opacity:0.2" d="M 19.177734,19 17,32 H 19 25.947266 26 26.599609 l 5.257813,-13 h -2 L 26,28.537109 V 22.826172 C 25.686781,22.938378 25.34965,23 25,23 24.65035,23 24.313219,22.938378 24,22.826172 V 30 h -4.664062 l 1.841796,-11 z"/>
+ <path style="opacity:0.2" d="M 24,12 A 13,13 0 0 0 11,25 13,13 0 0 0 24,38 13,13 0 0 0 37,25 13,13 0 0 0 24,12 Z m 0,2 A 11,11 0 0 1 35,25 11,11 0 0 1 24,36 11,11 0 0 1 13,25 11,11 0 0 1 24,14 Z"/>
+ <path style="fill:#ffffff" d="m 19.176965,18 h 2 L 19,31 h -2 z"/>
+ <path style="opacity:0.1;fill:#ffffff" d="M 24,4 A 20,20 0 0 0 4,24 20,20 0 0 0 4.0215,24.582 20,20 0 0 1 24,5 20,20 0 0 1 43.979,24.418 20,20 0 0 0 44,24 20,20 0 0 0 24,4 Z"/>
+ <path style="fill:#ffffff" transform="rotate(90)" d="m 29,-25.947071 h 2 v 8.94707 L 29,-17.6 Z"/>
+ <path style="fill:#6f6fee" d="M 24 11 A 13 13 0 0 0 11 24 A 13 13 0 0 0 24 37 A 13 13 0 0 0 37 24 A 13 13 0 0 0 24 11 z M 24 13 A 11 11 0 0 1 35 24 A 11 11 0 0 1 24 35 A 11 11 0 0 1 13 24 A 11 11 0 0 1 24 13 z"/>
+ <path style="fill:#ffffff" d="M 24 21.826172 L 24 31 L 26 31 L 26 21.826172 C 25.686781 21.938378 25.34965 22 25 22 C 24.65035 22 24.313219 21.938378 24 21.826172 z"/>
+ <path style="fill:#ffffff" d="m 29.857899,18 h 2 L 26.6,31 h -2 z"/>
+ <path style="opacity:0.2" d="m 12.589844,17.007812 c -1.087361,-0.03191 -2.033318,0.03758 -2.8203128,0.230469 -1.0493252,0.257182 -1.9296569,0.764657 -2.1953124,1.753907 -0.2656566,0.989249 0.2074728,1.994297 0.9433593,2.904296 0.6108665,0.755397 1.467085,1.517943 2.5117189,2.292969 C 11.065328,23.604184 11.13905,23.030537 11.25,22.46875 10.545728,21.903038 9.9733934,21.364462 9.5917969,20.892578 9.0156194,20.180077 8.9177885,19.717449 8.9746094,19.505859 9.0314304,19.29427 9.3385655,18.97871 10.160156,18.777344 c 0.821589,-0.201366 2.043793,-0.253967 3.527344,-0.13086 2.967103,0.246214 6.985914,1.181947 11.279297,2.751954 4.293384,1.570005 8.050542,3.478156 10.607422,5.251953 1.278442,0.886898 2.257807,1.744529 2.833984,2.457031 0.576176,0.7125 0.674009,1.17513 0.617188,1.386719 -0.05682,0.21159 -0.363957,0.527149 -1.185547,0.728515 -0.628279,0.153987 -1.494373,0.21928 -2.529297,0.1875 -0.30129,0.530516 -0.637404,1.038934 -1.007813,1.519532 1.561087,0.127738 2.882793,0.08766 3.925782,-0.167969 1.049325,-0.257183 1.931608,-0.766611 2.197265,-1.75586 0.265656,-0.98925 -0.211379,-1.992344 -0.947265,-2.902343 -0.735888,-0.909998 -1.808108,-1.82886 -3.164063,-2.769532 -2.711908,-1.881345 -6.553839,-3.823812 -10.945312,-5.429687 -4.391472,-1.605874 -8.499482,-2.570888 -11.646485,-2.832031 -0.393375,-0.03264 -0.770359,-0.05382 -1.132812,-0.06445 z"/>
+ <path style="fill:#59d4f1" d="M 12.589844 16.007812 C 11.502483 15.975907 10.556526 16.045394 9.7695312 16.238281 C 8.720206 16.495463 7.8398743 17.002938 7.5742188 17.992188 C 7.3085622 18.981437 7.7816916 19.986485 8.5175781 20.896484 C 9.1284446 21.651881 9.9846631 22.414427 11.029297 23.189453 C 11.065328 22.604184 11.13905 22.030537 11.25 21.46875 C 10.545728 20.903038 9.9733934 20.364462 9.5917969 19.892578 C 9.0156194 19.180077 8.9177885 18.717449 8.9746094 18.505859 C 9.0314304 18.29427 9.3385655 17.97871 10.160156 17.777344 C 10.981745 17.575978 12.203949 17.523377 13.6875 17.646484 C 16.654603 17.892698 20.673414 18.828431 24.966797 20.398438 C 29.260181 21.968443 33.017339 23.876594 35.574219 25.650391 C 36.852661 26.537289 37.832026 27.39492 38.408203 28.107422 C 38.984379 28.819922 39.082212 29.282552 39.025391 29.494141 C 38.968571 29.705731 38.661434 30.02129 37.839844 30.222656 C 37.211565 30.376643 36.345471 30.441936 35.310547 30.410156 C 35.009257 30.940672 34.673143 31.44909 34.302734 31.929688 C 35.863821 32.057426 37.185527 32.017349 38.228516 31.761719 C 39.277841 31.504536 40.160124 30.995108 40.425781 30.005859 C 40.691437 29.016609 40.214402 28.013515 39.478516 27.103516 C 38.742628 26.193518 37.670408 25.274656 36.314453 24.333984 C 33.602545 22.452639 29.760614 20.510172 25.369141 18.904297 C 20.977669 17.298423 16.869659 16.333409 13.722656 16.072266 C 13.329281 16.039623 12.952297 16.018448 12.589844 16.007812 z"/>
+ <circle style="opacity:0.2" cx="25" cy="20" r="2"/>
+ <circle style="fill:#ffffff" cx="25" cy="19" r="2"/>
+</svg>

+ 16 - 0
utils/desktop/64x64/lvim.svg

@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" version="1.1">
+ <circle style="opacity:0.2" cx="32" cy="33" r="28"/>
+ <circle style="fill:#4f4f4f" cx="32" cy="32" r="28"/>
+ <path style="opacity:0.2" d="M 25.248047,25 22.199219,43 H 25 34.726562 35.640625 L 43.001953,25 H 40.201172 L 35,37.71875 v -7.761719 c -0.469829,0.157088 -0.975524,0.242188 -1.5,0.242188 -0.524476,0 -1.030171,-0.0851 -1.5,-0.242188 V 40 h -6.492188 l 2.539063,-15 z"/>
+ <path style="opacity:0.2" d="M 32,15 A 18,18 0 0 0 14,33 18,18 0 0 0 32,51 18,18 0 0 0 50,33 18,18 0 0 0 32,15 Z m 0,3 A 15,15 0 0 1 47,33 15,15 0 0 1 32,48 15,15 0 0 1 17,33 15,15 0 0 1 32,18 Z"/>
+ <path style="fill:#ffffff" d="m 25.247751,24 h 2.8 L 25,42 h -2.8 z"/>
+ <path style="fill:#ffffff" d="m 34.725899,39 v 3 H 22.200001 L 23.04,39 Z"/>
+ <path style="fill:#6f6fee" d="M 32 14 A 18 18 0 0 0 14 32 A 18 18 0 0 0 32 50 A 18 18 0 0 0 50 32 A 18 18 0 0 0 32 14 z M 32 17 A 15 15 0 0 1 47 32 A 15 15 0 0 1 32 47 A 15 15 0 0 1 17 32 A 15 15 0 0 1 32 17 z"/>
+ <path style="fill:#ffffff" d="M 32,28.956641 V 41.8 h 3 V 28.956641 C 34.530171,29.113729 34.024476,29.2 33.5,29.2 32.975524,29.2 32.469829,29.11373 32,28.956641 Z"/>
+ <path style="fill:#ffffff" d="m 40.201059,24 h 2.8 L 35.64,42 h -2.8 z"/>
+ <path style="opacity:0.2" d="m 14.996094,22.003906 c -1.061706,0.02079 -2.009278,0.123345 -2.832032,0.322266 -1.462671,0.353629 -2.690245,1.051874 -3.0605464,2.412109 -0.3703029,1.360234 0.2906429,2.742877 1.3164064,3.994141 0.835691,1.019402 2.194435,2.048482 3.621094,3.09375 0.05184,-0.804762 0.15637,-1.594664 0.310546,-2.367188 -0.955946,-0.755084 -1.917855,-1.475923 -2.435546,-2.107422 -0.803143,-0.9797 -0.938579,-1.615311 -0.859375,-1.90625 0.0792,-0.290939 0.507115,-0.725071 1.652343,-1.001953 1.145226,-0.276882 2.848071,-0.348962 4.916016,-0.179687 4.135892,0.338547 9.738042,1.624417 15.722656,3.783203 5.984616,2.158783 11.22108,4.783657 14.785156,7.222656 1.782041,1.2195 3.148029,2.397251 3.951172,3.376953 0.803141,0.979699 0.940533,1.617265 0.861328,1.908204 -0.07921,0.290939 -0.509069,0.725072 -1.654296,1.001953 -0.849354,0.205348 -2.199135,0.292392 -3.595704,0.257812 -0.412148,0.732269 -0.875734,1.431516 -1.382812,2.095703 2.118497,0.160889 4.101812,0.104952 5.521484,-0.238281 1.462671,-0.353632 2.692197,-1.05383 3.0625,-2.414063 0.370302,-1.360236 -0.294548,-2.73897 -1.320312,-3.990234 -1.025766,-1.251262 -2.520069,-2.515155 -4.410156,-3.808594 -3.780171,-2.58688 -9.136469,-5.258694 -15.257813,-7.466796 -6.121342,-2.208104 -11.847717,-3.533503 -16.234375,-3.892579 -0.548332,-0.04488 -1.072896,-0.07522 -1.578125,-0.08984 -0.378922,-0.01097 -0.745707,-0.01279 -1.099609,-0.0059 z"/>
+ <path style="fill:#59d4f1" d="M 14.996094 21.003906 C 13.934388 21.0247 12.986816 21.127251 12.164062 21.326172 C 10.701391 21.679801 9.473817 22.378046 9.1035156 23.738281 C 8.7332127 25.098515 9.3941585 26.481158 10.419922 27.732422 C 11.255613 28.751824 12.614357 29.780904 14.041016 30.826172 C 14.09286 30.02141 14.197386 29.231508 14.351562 28.458984 C 13.395616 27.7039 12.433707 26.983061 11.916016 26.351562 C 11.112873 25.371862 10.977437 24.736251 11.056641 24.445312 C 11.135841 24.154373 11.563756 23.720241 12.708984 23.443359 C 13.85421 23.166477 15.557055 23.094397 17.625 23.263672 C 21.760892 23.602219 27.363042 24.888089 33.347656 27.046875 C 39.332272 29.205658 44.568736 31.830532 48.132812 34.269531 C 49.914853 35.489031 51.280841 36.666782 52.083984 37.646484 C 52.887125 38.626183 53.024517 39.263749 52.945312 39.554688 C 52.866102 39.845627 52.436243 40.27976 51.291016 40.556641 C 50.441662 40.761989 49.091881 40.849033 47.695312 40.814453 C 47.283164 41.546722 46.819578 42.245969 46.3125 42.910156 C 48.430997 43.071045 50.414312 43.015108 51.833984 42.671875 C 53.296655 42.318243 54.526181 41.618045 54.896484 40.257812 C 55.266786 38.897576 54.601936 37.518842 53.576172 36.267578 C 52.550406 35.016316 51.056103 33.752423 49.166016 32.458984 C 45.385845 29.872104 40.029547 27.20029 33.908203 24.992188 C 27.786861 22.784084 22.060486 21.458685 17.673828 21.099609 C 17.125496 21.054729 16.600932 21.024386 16.095703 21.009766 C 15.716781 20.998796 15.349996 20.996975 14.996094 21.003906 z"/>
+ <circle style="opacity:0.2" cx="33.5" cy="26.5" r="2.5"/>
+ <circle style="fill:#ffffff" cx="33.5" cy="25.5" r="2.5"/>
+ <path style="fill:#ffffff;opacity:0.1" d="M 32 4 A 28 28 0 0 0 4 32 A 28 28 0 0 0 4.0351562 32.5 A 28 28 0 0 1 32 5 A 28 28 0 0 1 59.982422 32.251953 A 28 28 0 0 0 60 32 A 28 28 0 0 0 32 4 z"/>
+</svg>

+ 1 - 1
utils/desktop/lvim.desktop

@@ -7,7 +7,7 @@ Exec=lvim %F
 Terminal=true
 Terminal=true
 Type=Application
 Type=Application
 Keywords=Text;editor;
 Keywords=Text;editor;
-Icon=nvim
+Icon=lvim
 Categories=Utility;TextEditor;
 Categories=Utility;TextEditor;
 StartupNotify=false
 StartupNotify=false
 MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
 MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;

+ 8 - 5
utils/installer/config.example.lua

@@ -10,8 +10,8 @@ an executable
 
 
 -- general
 -- general
 lvim.log.level = "warn"
 lvim.log.level = "warn"
-lvim.format_on_save = true
-lvim.colorscheme = "onedarker"
+lvim.format_on_save = false
+lvim.colorscheme = "tokyonight"
 -- to disable icons and use a minimalist setup, uncomment the following
 -- to disable icons and use a minimalist setup, uncomment the following
 -- lvim.use_icons = false
 -- lvim.use_icons = false
 
 
@@ -44,6 +44,10 @@ lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
 --   },
 --   },
 -- }
 -- }
 
 
+-- Change theme settings
+-- lvim.builtin.theme.options.dim_inactive = true
+-- lvim.builtin.theme.options.style = "storm"
+
 -- Use which-key to add extra bindings with the leader-key prefix
 -- Use which-key to add extra bindings with the leader-key prefix
 -- lvim.builtin.which_key.mappings["P"] = { "<cmd>Telescope projects<CR>", "Projects" }
 -- lvim.builtin.which_key.mappings["P"] = { "<cmd>Telescope projects<CR>", "Projects" }
 -- lvim.builtin.which_key.mappings["t"] = {
 -- lvim.builtin.which_key.mappings["t"] = {
@@ -82,13 +86,13 @@ lvim.builtin.treesitter.ensure_installed = {
 }
 }
 
 
 lvim.builtin.treesitter.ignore_install = { "haskell" }
 lvim.builtin.treesitter.ignore_install = { "haskell" }
-lvim.builtin.treesitter.highlight.enabled = true
+lvim.builtin.treesitter.highlight.enable = true
 
 
 -- generic LSP settings
 -- generic LSP settings
 
 
 -- -- make sure server will always be installed even if the server is in skipped_servers list
 -- -- make sure server will always be installed even if the server is in skipped_servers list
 -- lvim.lsp.installer.setup.ensure_installed = {
 -- lvim.lsp.installer.setup.ensure_installed = {
---     "sumeko_lua",
+--     "sumneko_lua",
 --     "jsonls",
 --     "jsonls",
 -- }
 -- }
 -- -- change UI setting of `LspInstallInfo`
 -- -- change UI setting of `LspInstallInfo`
@@ -161,7 +165,6 @@ lvim.builtin.treesitter.highlight.enabled = true
 
 
 -- Additional Plugins
 -- Additional Plugins
 -- lvim.plugins = {
 -- lvim.plugins = {
---     {"folke/tokyonight.nvim"},
 --     {
 --     {
 --       "folke/trouble.nvim",
 --       "folke/trouble.nvim",
 --       cmd = "TroubleToggle",
 --       cmd = "TroubleToggle",

+ 7 - 4
utils/installer/config_win.example.lua

@@ -28,7 +28,7 @@ vim.g.clipboard = {
 -- general
 -- general
 lvim.log.level = "warn"
 lvim.log.level = "warn"
 lvim.format_on_save = true
 lvim.format_on_save = true
-lvim.colorscheme = "onedarker"
+lvim.colorscheme = "tokyonight"
 -- to disable icons and use a minimalist setup, uncomment the following
 -- to disable icons and use a minimalist setup, uncomment the following
 -- lvim.use_icons = false
 -- lvim.use_icons = false
 
 
@@ -61,6 +61,10 @@ lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
 --   },
 --   },
 -- }
 -- }
 
 
+-- Change theme settings
+-- lvim.builtin.theme.options.dim_inactive = true
+-- lvim.builtin.theme.options.style = "storm"
+
 -- Use which-key to add extra bindings with the leader-key prefix
 -- Use which-key to add extra bindings with the leader-key prefix
 -- lvim.builtin.which_key.mappings["P"] = { "<cmd>Telescope projects<CR>", "Projects" }
 -- lvim.builtin.which_key.mappings["P"] = { "<cmd>Telescope projects<CR>", "Projects" }
 -- lvim.builtin.which_key.mappings["t"] = {
 -- lvim.builtin.which_key.mappings["t"] = {
@@ -97,13 +101,13 @@ lvim.builtin.treesitter.ensure_installed = {
 }
 }
 
 
 lvim.builtin.treesitter.ignore_install = { "haskell" }
 lvim.builtin.treesitter.ignore_install = { "haskell" }
-lvim.builtin.treesitter.highlight.enabled = true
+lvim.builtin.treesitter.highlight.enable = true
 
 
 -- generic LSP settings
 -- generic LSP settings
 
 
 -- -- make sure server will always be installed even if the server is in skipped_servers list
 -- -- make sure server will always be installed even if the server is in skipped_servers list
 -- lvim.lsp.installer.setup.ensure_installed = {
 -- lvim.lsp.installer.setup.ensure_installed = {
---     "sumeko_lua",
+--     "sumneko_lua",
 --     "jsonls",
 --     "jsonls",
 -- }
 -- }
 -- -- change UI setting of `LspInstallInfo`
 -- -- change UI setting of `LspInstallInfo`
@@ -176,7 +180,6 @@ lvim.builtin.treesitter.highlight.enabled = true
 
 
 -- Additional Plugins
 -- Additional Plugins
 -- lvim.plugins = {
 -- lvim.plugins = {
---     {"folke/tokyonight.nvim"},
 --     {
 --     {
 --       "folke/trouble.nvim",
 --       "folke/trouble.nvim",
 --       cmd = "TroubleToggle",
 --       cmd = "TroubleToggle",

+ 34 - 17
utils/installer/install.sh

@@ -2,20 +2,20 @@
 set -eo pipefail
 set -eo pipefail
 
 
 #Set branch to master unless specified by the user
 #Set branch to master unless specified by the user
-declare LV_BRANCH="${LV_BRANCH:-"master"}"
-declare -r LV_REMOTE="${LV_REMOTE:-lunarvim/lunarvim.git}"
-declare -r INSTALL_PREFIX="${INSTALL_PREFIX:-"$HOME/.local"}"
+declare -x LV_BRANCH="${LV_BRANCH:-"master"}"
+declare -xr LV_REMOTE="${LV_REMOTE:-lunarvim/lunarvim.git}"
+declare -xr INSTALL_PREFIX="${INSTALL_PREFIX:-"$HOME/.local"}"
 
 
-declare -r XDG_DATA_HOME="${XDG_DATA_HOME:-"$HOME/.local/share"}"
-declare -r XDG_CACHE_HOME="${XDG_CACHE_HOME:-"$HOME/.cache"}"
-declare -r XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-"$HOME/.config"}"
+declare -xr XDG_DATA_HOME="${XDG_DATA_HOME:-"$HOME/.local/share"}"
+declare -xr XDG_CACHE_HOME="${XDG_CACHE_HOME:-"$HOME/.cache"}"
+declare -xr XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-"$HOME/.config"}"
 
 
-declare -r LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-"$XDG_DATA_HOME/lunarvim"}"
-declare -r LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-"$XDG_CONFIG_HOME/lvim"}"
-declare -r LUNARVIM_CACHE_DIR="${LUNARVIM_CACHE_DIR:-"$XDG_CACHE_HOME/lvim"}"
-declare -r LUNARVIM_BASE_DIR="${LUNARVIM_BASE_DIR:-"$LUNARVIM_RUNTIME_DIR/lvim"}"
+declare -xr LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-"$XDG_DATA_HOME/lunarvim"}"
+declare -xr LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-"$XDG_CONFIG_HOME/lvim"}"
+declare -xr LUNARVIM_CACHE_DIR="${LUNARVIM_CACHE_DIR:-"$XDG_CACHE_HOME/lvim"}"
+declare -xr LUNARVIM_BASE_DIR="${LUNARVIM_BASE_DIR:-"$LUNARVIM_RUNTIME_DIR/lvim"}"
 
 
-declare -r LUNARVIM_LOG_LEVEL="${LUNARVIM_LOG_LEVEL:-warn}"
+declare -xr LUNARVIM_LOG_LEVEL="${LUNARVIM_LOG_LEVEL:-warn}"
 
 
 declare BASEDIR
 declare BASEDIR
 BASEDIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
 BASEDIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
@@ -51,7 +51,7 @@ function usage() {
   echo "    -l, --local                              Install local copy of LunarVim"
   echo "    -l, --local                              Install local copy of LunarVim"
   echo "    -y, --yes                                Disable confirmation prompts (answer yes to all questions)"
   echo "    -y, --yes                                Disable confirmation prompts (answer yes to all questions)"
   echo "    --overwrite                              Overwrite previous LunarVim configuration (a backup is always performed first)"
   echo "    --overwrite                              Overwrite previous LunarVim configuration (a backup is always performed first)"
-  echo "    --[no]-install-dependencies              Whether to automatically install external dependencies (will prompt by default)"
+  echo "    --[no-]install-dependencies              Whether to automatically install external dependencies (will prompt by default)"
 }
 }
 
 
 function parse_arguments() {
 function parse_arguments() {
@@ -201,11 +201,11 @@ function print_missing_dep_msg() {
 }
 }
 
 
 function check_neovim_min_version() {
 function check_neovim_min_version() {
-  local verify_version_cmd='if !has("nvim-0.7") | cquit | else | quit | endif'
+  local verify_version_cmd='if !has("nvim-0.8") | cquit | else | quit | endif'
 
 
   # exit with an error if min_version not found
   # exit with an error if min_version not found
   if ! nvim --headless -u NONE -c "$verify_version_cmd"; then
   if ! nvim --headless -u NONE -c "$verify_version_cmd"; then
-    echo "[ERROR]: LunarVim requires at least Neovim v0.7 or higher"
+    echo "[ERROR]: LunarVim requires at least Neovim v0.8 or higher"
     exit 1
     exit 1
   fi
   fi
 }
 }
@@ -395,7 +395,7 @@ function backup_old_config() {
 function clone_lvim() {
 function clone_lvim() {
   msg "Cloning LunarVim configuration"
   msg "Cloning LunarVim configuration"
   if ! git clone --branch "$LV_BRANCH" \
   if ! git clone --branch "$LV_BRANCH" \
-    --depth 1 "https://github.com/${LV_REMOTE}" "$LUNARVIM_BASE_DIR"; then
+    "https://github.com/${LV_REMOTE}" "$LUNARVIM_BASE_DIR"; then
     echo "Failed to clone repository. Installation failed."
     echo "Failed to clone repository. Installation failed."
     exit 1
     exit 1
   fi
   fi
@@ -439,12 +439,14 @@ function setup_lvim() {
 
 
   setup_shim
   setup_shim
 
 
-  cp "$LUNARVIM_BASE_DIR/utils/installer/config.example.lua" "$LUNARVIM_CONFIG_DIR/config.lua"
+  create_desktop_file
+
+  [ ! -f "$LUNARVIM_CONFIG_DIR/config.lua" ] \
+    && cp "$LUNARVIM_BASE_DIR/utils/installer/config.example.lua" "$LUNARVIM_CONFIG_DIR/config.lua"
 
 
   echo "Preparing Packer setup"
   echo "Preparing Packer setup"
 
 
   "$INSTALL_PREFIX/bin/lvim" --headless \
   "$INSTALL_PREFIX/bin/lvim" --headless \
-    -c "lua require('lvim.core.log'):set_level([[$LUNARVIM_LOG_LEVEL]])" \
     -c 'autocmd User PackerComplete quitall' \
     -c 'autocmd User PackerComplete quitall' \
     -c 'PackerSync'
     -c 'PackerSync'
 
 
@@ -453,6 +455,21 @@ function setup_lvim() {
   verify_core_plugins
   verify_core_plugins
 }
 }
 
 
+function create_desktop_file() {
+  OS="$(uname -s)"
+  # TODO: Any other OSes that use desktop files?
+  ([ "$OS" != "Linux" ] || ! command -v xdg-desktop-menu &>/dev/null) && return
+  echo "Creating desktop file"
+
+  for d in "$LUNARVIM_BASE_DIR"/utils/desktop/*/; do
+    size_folder=$(basename "$d")
+    mkdir -p "$XDG_DATA_HOME/icons/hicolor/$size_folder/apps/"
+    cp "$LUNARVIM_BASE_DIR/utils/desktop/$size_folder/lvim.svg" "$XDG_DATA_HOME/icons/hicolor/$size_folder/apps"
+  done
+
+  xdg-desktop-menu install --novendor "$LUNARVIM_BASE_DIR/utils/desktop/lvim.desktop"
+}
+
 function print_logo() {
 function print_logo() {
   cat <<'EOF'
   cat <<'EOF'
 
 

+ 2 - 1
utils/installer/install_bin.sh

@@ -26,7 +26,8 @@ function setup_shim() {
 
 
   sed -e s"#RUNTIME_DIR_VAR#\"${LUNARVIM_RUNTIME_DIR}\"#"g \
   sed -e s"#RUNTIME_DIR_VAR#\"${LUNARVIM_RUNTIME_DIR}\"#"g \
     -e s"#CONFIG_DIR_VAR#\"${LUNARVIM_CONFIG_DIR}\"#"g \
     -e s"#CONFIG_DIR_VAR#\"${LUNARVIM_CONFIG_DIR}\"#"g \
-    -e s"#CACHE_DIR_VAR#\"${LUNARVIM_CACHE_DIR}\"#"g "$src" \
+    -e s"#CACHE_DIR_VAR#\"${LUNARVIM_CACHE_DIR}\"#"g \
+    -e s"#BASE_DIR_VAR#\"${LUNARVIM_BASE_DIR}\"#"g "$src" \
     | tee "$dst" >/dev/null
     | tee "$dst" >/dev/null
 
 
   chmod u+x "$dst"
   chmod u+x "$dst"

+ 11 - 0
utils/installer/uninstall.sh

@@ -60,12 +60,23 @@ function remove_lvim_bin() {
   rm -f "$lvim_bin"
   rm -f "$lvim_bin"
 }
 }
 
 
+function remove_desktop_file() {
+  OS="$(uname -s)"
+  # TODO: Any other OSes that use desktop files?
+  ([ "$OS" != "Linux" ] || ! command -v xdg-desktop-menu &>/dev/null) && return
+  echo "Removing desktop file..."
+
+  find "$XDG_DATA_HOME/icons/hicolor" -name "lvim.svg" -type f -delete
+  xdg-desktop-menu uninstall lvim.desktop
+}
+
 function main() {
 function main() {
   parse_arguments "$@"
   parse_arguments "$@"
   echo "Removing LunarVim binary..."
   echo "Removing LunarVim binary..."
   remove_lvim_bin
   remove_lvim_bin
   echo "Removing LunarVim directories..."
   echo "Removing LunarVim directories..."
   remove_lvim_dirs
   remove_lvim_dirs
+  remove_desktop_file
   echo "Uninstalled LunarVim!"
   echo "Uninstalled LunarVim!"
 }
 }