Просмотр исходного кода

Merge remote-tracking branch 'origin/rolling'

kylo252 3 лет назад
Родитель
Сommit
caf62bcfed
100 измененных файлов с 1106 добавлено и 1785 удалено
  1. 1 1
      .github/ISSUE_TEMPLATE/config.yml
  2. 34 0
      .github/workflows/commitlint.config.js
  3. 15 0
      .github/workflows/commitlint.yml
  4. 12 15
      .github/workflows/format.yaml
  5. 8 13
      .github/workflows/install.yaml
  6. 12 12
      .github/workflows/lint.yaml
  7. 7 3
      .luacheckrc
  8. 9 4
      .pre-commit-config.yaml
  9. 60 16
      CONTRIBUTING.md
  10. 33 0
      Makefile
  11. 30 118
      README.md
  12. 13 0
      colors/onedarker.vim
  13. 0 2
      colors/spacegray.vim
  14. 3 0
      ftdetect/bicep.lua
  15. 3 0
      ftdetect/json.lua
  16. 3 0
      ftdetect/sol.lua
  17. 0 1
      ftplugin/asm.lua
  18. 0 1
      ftplugin/beancount.lua
  19. 0 4
      ftplugin/c.lua
  20. 0 1
      ftplugin/clojure.lua
  21. 0 1
      ftplugin/cmake.lua
  22. 0 1
      ftplugin/cpp.lua
  23. 0 1
      ftplugin/crystal.lua
  24. 0 1
      ftplugin/cs.lua
  25. 0 1
      ftplugin/css.lua
  26. 0 1
      ftplugin/d.lua
  27. 0 1
      ftplugin/dart.lua
  28. 0 1
      ftplugin/dockerfile.lua
  29. 0 10
      ftplugin/elixir.lua
  30. 0 1
      ftplugin/elm.lua
  31. 0 1
      ftplugin/erlang.lua
  32. 0 9
      ftplugin/euphoria3.lua
  33. 0 1
      ftplugin/fish.lua
  34. 0 1
      ftplugin/fortran.lua
  35. 0 1
      ftplugin/gdscript.lua
  36. 0 1
      ftplugin/go.lua
  37. 0 1
      ftplugin/graphql.lua
  38. 0 1
      ftplugin/haskell.lua
  39. 0 1
      ftplugin/html.lua
  40. 0 1
      ftplugin/java.lua
  41. 0 1
      ftplugin/javascript.lua
  42. 0 1
      ftplugin/javascriptreact.lua
  43. 0 1
      ftplugin/json.lua
  44. 0 1
      ftplugin/julia.lua
  45. 0 1
      ftplugin/kotlin.lua
  46. 0 1
      ftplugin/less.lua
  47. 0 1
      ftplugin/lua.lua
  48. 0 2
      ftplugin/netrw.lua
  49. 0 1
      ftplugin/nix.lua
  50. 0 1
      ftplugin/perl.lua
  51. 0 1
      ftplugin/php.lua
  52. 0 3
      ftplugin/ps1.lua
  53. 0 1
      ftplugin/puppet.lua
  54. 0 3
      ftplugin/python.lua
  55. 0 2
      ftplugin/r.lua
  56. 0 1
      ftplugin/rmd.lua
  57. 0 2
      ftplugin/ruby.lua
  58. 0 4
      ftplugin/rust.lua
  59. 0 1
      ftplugin/sass.lua
  60. 0 1
      ftplugin/sbt.lua
  61. 0 1
      ftplugin/scala.lua
  62. 0 1
      ftplugin/scss.lua
  63. 0 1
      ftplugin/sh.lua
  64. 0 1
      ftplugin/sql.lua
  65. 0 1
      ftplugin/svelte.lua
  66. 0 1
      ftplugin/swift.lua
  67. 0 1
      ftplugin/terraform.lua
  68. 0 1
      ftplugin/tex.lua
  69. 0 0
      ftplugin/thing.pp
  70. 0 1
      ftplugin/toml.lua
  71. 0 1
      ftplugin/typescript.lua
  72. 0 1
      ftplugin/typescriptreact.lua
  73. 0 1
      ftplugin/vim.lua
  74. 0 1
      ftplugin/vue.lua
  75. 0 1
      ftplugin/yaml.lua
  76. 0 1
      ftplugin/zig.lua
  77. 0 1
      ftplugin/zsh.lua
  78. 9 44
      init.lua
  79. 193 0
      lua/bootstrap.lua
  80. 5 1131
      lua/config/defaults.lua
  81. 131 10
      lua/config/init.lua
  82. 3 3
      lua/config/settings.lua
  83. 5 0
      lua/core/autocmds.lua
  84. 37 25
      lua/core/autopairs.lua
  85. 1 2
      lua/core/builtins/init.lua
  86. 260 0
      lua/core/cmp.lua
  87. 3 1
      lua/core/commands.lua
  88. 0 133
      lua/core/compe.lua
  89. 15 0
      lua/core/dap.lua
  90. 18 9
      lua/core/dashboard.lua
  91. 1 1
      lua/core/gitsigns.lua
  92. 40 51
      lua/core/info.lua
  93. 1 0
      lua/core/log.lua
  94. 0 19
      lua/core/lspinstall.lua
  95. 29 27
      lua/core/lualine/components.lua
  96. 6 6
      lua/core/lualine/styles.lua
  97. 26 15
      lua/core/nvimtree.lua
  98. 1 1
      lua/core/project.lua
  99. 71 10
      lua/core/telescope.lua
  100. 8 23
      lua/core/terminal.lua

+ 1 - 1
.github/ISSUE_TEMPLATE/config.yml

@@ -2,7 +2,7 @@ blank_issues_enabled: true
 
 contact_links:
   - name: Matrix community
-    url: https://matrix.to/#/+atmachine:matrix
+    url: https://matrix.to/#/#atmachine-neovim:matrix.org
     about: Please ask and answer questions on Matrix.
   - name: Discord community
     url: https://discord.gg/Xb9B4Ny

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

@@ -0,0 +1,34 @@
+module.exports = {
+  rules: {
+    "body-leading-blank": [1, "always"],
+    "body-max-line-length": [2, "always", 100],
+    "footer-leading-blank": [1, "always"],
+    "footer-max-line-length": [2, "always", 100],
+    "header-max-length": [2, "always", 72],
+    "scope-case": [2, "always", "lower-case"],
+    "subject-case": [
+      2,
+      "never",
+      ["upper-case", "pascal-case", "sentence-case", "start-case"],
+    ],
+    "subject-empty": [2, "never"],
+    "subject-full-stop": [2, "never", "."],
+    "type-case": [2, "always", "lower-case"],
+    "type-empty": [2, "never"],
+    "type-enum": [
+      2,
+      "always",
+      [
+        "build",
+        "ci",
+        "docs",
+        "feat",
+        "fix",
+        "perf",
+        "refactor",
+        "revert",
+        "test",
+      ],
+    ],
+  },
+};

+ 15 - 0
.github/workflows/commitlint.yml

@@ -0,0 +1,15 @@
+name: "Commit Linter"
+on: pull_request
+jobs:
+  lint-commits:
+    runs-on: ubuntu-latest
+    env:
+      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+    steps:
+      - uses: actions/checkout@v2.3.1
+        with:
+          fetch-depth: 0
+      - uses: wagoid/commitlint-github-action@v4
+        with:
+          configFile: .github/workflows/commitlint.config.js
+          helpURL: https://github.com/LunarVim/LunarVim/blob/rolling/CONTRIBUTING.md#commit-messages

+ 12 - 15
.github/workflows/format.yaml

@@ -1,11 +1,11 @@
 name: format
 on:
   push:
-    branches: '**'
+    branches: "**"
   pull_request:
     branches:
-      - 'master'
-      - 'rolling'
+      - "master"
+      - "rolling"
 
 jobs:
   stylua-check:
@@ -14,14 +14,13 @@ jobs:
     steps:
       - uses: actions/checkout@v2
 
-      - name: Prepare dependencies
-        run: |
-          sudo apt install -y curl unzip --no-install-recommends
-          bash ./utils/installer/install_stylua.sh
+      - name: Lint with stylua
+        uses: JohnnyMorganz/stylua-action@1.0.0
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          # CLI arguments
+          args: --check .
 
-      - name: Check formatting
-        run: |
-          ./utils/stylua --config-path .stylua.toml -c .
   shfmt-check:
     name: "Formatting check with shfmt"
     runs-on: ubuntu-20.04
@@ -31,14 +30,12 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.16'
-      
+          go-version: "1.16"
+
       - name: Use shfmt
         run: |
           GO111MODULE=on go get mvdan.cc/sh/v3/cmd/shfmt
 
       # https://google.github.io/styleguide/shellguide.html
       - name: Check formatting
-        run: |
-          shfmt -f . | grep -v jdtls | xargs shfmt -i 2 -ci -l -d
-    
+        run: make style-sh

+ 8 - 13
.github/workflows/install.yaml

@@ -1,7 +1,7 @@
 name: install
 on:
   push:
-    branches: "**"
+    branches: ["**"]
   pull_request:
     branches:
       - "master"
@@ -23,31 +23,26 @@ jobs:
     steps:
       - uses: actions/checkout@v2
 
-      # sha256sum is not available by default
-      - name: Installl dependencies for OSX
-        if: matrix.os == 'osx'
-        run: |
-          echo "HOMEBREW_NO_AUTO_UPDATE=1" >> $GITHUB_ENV
-          echo "$HOME/.local/bin" >> $GITHUB_PATH
-          brew install coreutils
-
       - name: Install neovim binary
         run: |
+          echo "$HOME/.local/bin" >> $GITHUB_PATH
           bash ./utils/installer/install-neovim-from-release
 
       - name: Install LunarVim
         timeout-minutes: 4
         run: |
-          mkdir -p "$HOME"/.local/share/lunarvim/lvim
-          mkdir -p "$HOME"/.config/lvim
-          ln -s "$PWD"/* "$HOME"/.local/share/lunarvim/lvim/.
-          bash ./utils/installer/install.sh
+          ./utils/installer/install.sh --local --no-install-dependencies
 
       - name: Test LunarVim PackerCompile
         run: if "$HOME"/.local/bin/lvim --headless +PackerCompile -c ':qall' 2>&1|grep -q 'Error'; then false; fi
 
       - name: Test LunarVim Health
         run: if "$HOME"/.local/bin/lvim --headless +checkhealth -c ':qall' 2>&1|grep -q 'Error'; then false; fi
+
+      - name: Run unit-tests
+        # NOTE: make sure to adjust the timeout if you start adding a lot of tests
+        timeout-minutes: 4
+        run: make test
 #   freebsd:
 #     runs-on: macos-latest
 #     if: github.event.pull_request.draft == false

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

@@ -1,11 +1,11 @@
 name: lint
 on:
   push:
-    branches: '**'
+    branches: "**"
   pull_request:
     branches:
-      - 'master'
-      - 'rolling'
+      - "master"
+      - "rolling"
 
 jobs:
   lua-linter:
@@ -13,23 +13,23 @@ jobs:
     runs-on: ubuntu-20.04
     steps:
       - uses: actions/checkout@v2
-      
+
       - uses: leafo/gh-actions-lua@v8
       - uses: leafo/gh-actions-luarocks@v4
 
       - name: Use luacheck
         run: luarocks install luacheck
-      
+
       - name: Run luacheck
-        run: luacheck *.lua lua/
+        run: make lint-lua
 
   shellcheck:
     name: Shellcheck
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v2
-    - name: Run ShellCheck
-      uses: ludeeus/action-shellcheck@master
-      with:
-       scandir: './utils'
-       ignore: 'bin'
+      - uses: actions/checkout@v2
+      - name: Run ShellCheck
+        uses: ludeeus/action-shellcheck@master
+        with:
+          scandir: "./utils"
+          ignore: "bin"

+ 7 - 3
.luacheckrc

@@ -4,9 +4,6 @@ stds.nvim = {
   globals = {
     "lvim",
     vim = { fields = { "g" } },
-    "CONFIG_PATH",
-    "CACHE_PATH",
-    "DATA_PATH",
     "TERMINAL",
     "USER",
     "C",
@@ -21,11 +18,18 @@ stds.nvim = {
     "jit",
     "os",
     "vim",
+    "join_paths",
+    "get_runtime_dir",
+    "get_config_dir",
+    "get_cache_dir",
+    "get_version",
     -- vim = { fields = { "cmd", "api", "fn", "o" } },
   },
 }
 std = "lua51+nvim"
 
+files["tests/*_spec.lua"].std = "lua51+nvim+busted"
+
 -- Don't report unused self arguments of methods.
 self = false
 

+ 9 - 4
.pre-commit-config.yaml

@@ -7,23 +7,28 @@ repos:
         language: system
         types: [shell]
         entry: bash
-        args: [-c, "shfmt -f $(git rev-parse --show-toplevel) | grep -v jdtls | xargs shfmt -i=2 -ci -w"]
+        args: [-c, make lint-sh]
       - id: shellcheck
         name: shellcheck
         language: system
         types: [shell]
         entry: bash
-        args:
-          [-c, "shfmt -f $(git rev-parse --show-toplevel) | grep -v jdtls | xargs shellcheck"]
+        args: [-c, make style-sh]
       - id: stylua
         name: StyLua
         language: rust
         entry: stylua
         types: [lua]
-        args: ['-']
+        args: ["-"]
       - id: luacheck
         name: luacheck
         language: system
         entry: luacheck
         types: [lua]
         args: [.]
+      - id: commitlint
+        name: commitlint
+        language: system
+        entry: bash
+        args: [./utils/ci/run_commitlint.sh]
+        stages: [commit-msg]

+ 60 - 16
CONTRIBUTING.md

@@ -11,10 +11,12 @@ One of the best ways to begin contributing in a meaningful way is by helping fin
 ## Getting Started
 
 1. Backup your ~/.config/nvim
-2. Follow the [Installation](https://github.com/lunarvim/LunarVim/wiki/Installation) guide
+2. Follow the [Installation](https://www.lunarvim.org/01-installing.html) guide
 3. Link your fork with the repository `git remote add upstream https://github.com/lunarvim/LunarVim.git`
 4. That's it ! You can now `git fetch upstream` and `git rebase [-i] upstream/rolling` to update your branches with the latest contributions.
 
+<br />
+
 ## Setting up development tools
 
 ### For editing Lua files
@@ -31,21 +33,9 @@ One of the best ways to begin contributing in a meaningful way is by helping fin
 
 Install [pre-commit](https://github.com/pre-commit/pre-commit) which will run all linters and formatters for you as a pre-commit-hook.
 
-## Some Guidelines
-
-### Git Commit Messages
-
-* Use the present tense ("Add feature" not "Added feature")
-* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
-* Limit the first line to 72 characters or less
-* Reference issues and pull requests liberally after the first line
+<br />
 
-### Git Branch Naming
-
-* Name your branches meaningfully,
-ex: (feature|bugfix|hotfix)/what-my-pr-does
-
-### Code 
+## Code Conventions
 
 All lua code is formatted with [Stylua](https://github.com/JohnnyMorganz/StyLua).
 * Use snake_case
@@ -60,10 +50,64 @@ All shell code is formatted according to [Google Shell Style Guide](https://goog
 shfmt -i 2 -ci -l -d .
 ```
 
+<br />
+
+## Pull Requests (PRs)
+
+To avoid duplicate work, create a draft pull request.
+
+### Commit Messages
+* Commit header is limited to 72 characters.
+* Commit body and footer is limited to 100 characters per line.
+
+**Commit header format:**
+```
+<type>(<scope>?): <summary>
+  │       │           │
+  │       │           └─> Present tense.     'add something...'(O) vs 'added something...'(X)
+  │       │               Imperative mood.   'move cursor to...'(O) vs 'moves cursor to...'(X)
+  │       │               Not capitalized. 
+  │       │               No period at the end.
+  │       │
+  │       └─> Commit Scope is optional, but strongly recommended.
+  │           Use lower case.
+  │           'plugin', 'file', or 'directory' name is suggested, but not limited.
+  │
+  └─> Commit Type: build|ci|docs|feat|fix|perf|refactor|test
+```
+
+##### Commit Type Guideline
+
+* **build**: changes that affect the build system or external dependencies (example scopes: npm, pip, rg)
+* **ci**: changes to CI configuration files and scripts (example scopes: format, lint, issue_templates)
+* **docs**: changes to the documentation only
+* **feat**: a new feature for the user
+* **fix**: a bug fix
+* **perf**: a performance improvement
+* **refactor**: a code change that neither fixes a bug nor adds a feature
+* **test**: Adding missing tests or correcting existing tests
+
+**Real world examples:**
+```
+feat(quickfix): add 'q' binding to quit quickfix window when focused 
+```
+```
+fix(installer): add missing "HOME" variable 
+```
+
+
+### Branch Naming
+
+Name your branches meaningfully.
+
+ex)
+```(feature|bugfix|hotfix)/what-my-pr-does```
+
+<br />
 
 ## Communication
 
 Members of the community have multiple ways to collaborate on the project.
 We encourage you to join the community:
 - [Discord server](https://discord.gg/Xb9B4Ny)
-- [Matrix server](https://matrix.to/#/+atmachine:matrix)
+- [Matrix server](https://matrix.to/#/#atmachine-neovim:matrix.org)

+ 33 - 0
Makefile

@@ -0,0 +1,33 @@
+SHELL := /bin/bash
+
+install:
+	@echo Starting LunarVim Installer
+	bash ./utils/installer/install.sh
+
+install-neovim-binary:
+	@echo Installing Neovim from github releases
+	bash ./utils/installer/install-neovim-from-release
+
+uninstall:
+	@echo TODO: this is currently not supported
+
+lint: lint-lua lint-sh
+
+lint-lua:
+	luacheck *.lua lua/* tests/*
+
+lint-sh:
+	shfmt -f . | grep -v jdtls | xargs shellcheck
+
+style: style-lua style-sh
+
+style-lua:
+	stylua --config-path .stylua.toml --check .
+
+style-sh:
+	shfmt -f . | grep -v jdtls | xargs shfmt -i 2 -ci -l -d
+
+test:
+	bash ./utils/bin/test_runner.sh "$(TEST)"
+
+.PHONY: install install-neovim-binary uninstall lint style test

+ 30 - 118
README.md

@@ -16,83 +16,45 @@
     <a href="https://twitter.com/intent/follow?screen_name=chrisatmachine">
       <img src="https://img.shields.io/twitter/follow/chrisatmachine?style=social&logo=twitter" alt="follow on Twitter">
     </a>
-</p>	
+</p>
 
 </div>
 
-## Install In One Command!
-
-Make sure you have the newest version of Neovim (0.5).
+## Documentation
 
-``` bash
-bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh)
-```
+You can find all the documentation for LunarVim at [lunarvim.org](https://www.lunarvim.org)
 
-### Customizing the installation
-
-The following options are supported by setting environment variables:
-- `"$LV_REMOTE"`            Select a different LunarVim remote [default: 'lunarvim/lunarvim.git']
-- `"$LV_BRANCH"`            Select LunarVim's branch [default: 'rolling']
-- `"$INSTALL_PREFIX"`       Select LunarVim's install prefix [default: `'$HOME/.local'`]
-- `"$LUNARVIM_RUNTIME_DIR"` Select LunarVim's runtime directory [default: `'$HOME/.local/share/lunarvim'`]
-- `"$LUNARVIM_CONFIG_DIR"`  Select LunarVim's configuration directory [default: `'$HOME/.config/lvim'`]
-
-Putting it all together
+## Install In One Command!
 
-``` bash
-curl -LSs https://raw.githubusercontent.com/lunarvim/lunarvim/rolling/utils/installer/install.sh -O install.sh
-INSTALL_PREFIX=/tmp/t1 LUNARVIM_CONFIG_DIR=/tmp/t2 LUNARVIM_RUNTIME_DIR=/tmp/t3 bash ./install.sh
-```
+Make sure you have the release version of Neovim (0.5).
 
-### BREAKING CHANGE on rolling and master branches
-* The latest changes to LunarVim require you to [remove it completely](https://github.com/lunarvim/LunarVim/wiki/Uninstalling-LunarVim) before upgrading
-* Going forward LunarVim will no longer reside in the nvim configuration folder.  LunarVim has been moved to `~/.local/share/lunarvim`.  
-* To launch Lunarvim use the new `lvim` command.  `nvim` will only launch standard neovim.  
-* Your personal configuration file (`config.lua`) can now be found in `~/.config/lvim`.  You can initialize this folder as a git repository to track changes to your configuration files.
-* If you want to keep launching LunarVim with the `nvim` command, add an alias entry to your shell's config file:  `alias nvim=lvim`.  To temporarily revert to the default `nvim` prefix it with a backslash `\nvim`.
-* Many options formerly available in `config.lua` have been renamed.  For details [look here](https://github.com/lunarvim/LunarVim/wiki/Breaking-changes-in-rolling)
-
-### Debugging LunarVim's configuration
-* To turn on debugging add these settings `lvim.log.level = debug` and use `<leader>Ll` to see the options of viewing the logfiles
-* You can also use install [lnav](https://github.com/tstack/lnav) and use it in a floating terminal. Make sure to set `lvim.builtin.terminal.active = true`.
-
-### Fixing installation problems
-If your installation is stuck on `Ok to remove? [y/N]`, it means there are some leftovers, \
-you can run the script with `--overwrite` but be warned this will remove the following folders:
-- `~/.cache/nvim`
-- `~/.config/nvim`                        #Removed only on Master Branch
-- `~/.local/share/nvim/site/pack/packer`  #Removed only on Master Branch
-- `~/.local/share/lunarvim`               #Removed only on Rolling Branch
-- `~/.config/lvim`                        #Removed only on Rolling Branch
 ```bash
-curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/rolling/utils/installer/install.sh | LVBRANCH=rolling bash -s -- --overwrite
+bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh)
 ```
-then run nvim and wait for treesitter to finish the installation
 
+## Install Language support
 
-## Installing LSP for your language
+- Enter `:LspInstall` followed by `<TAB>` to see your options for LSP
 
-Just enter `:LspInstall` followed by `<TAB>` to see your options
+- Enter `:TSInstall` followed by `<TAB>` to see your options for syntax highlighting
 
 **NOTE** I recommend installing `lua` for autocomplete in `config.lua`
 
-For the julia language server look [here](https://github.com/lunarvim/LunarVim/wiki/Enabling-a-language-server#julia-support)
+![Demo1](./utils/media/demo1.png)
+![Demo2](./utils/media/demo2.png)
+![Demo3](./utils/media/demo3.png)
 
 ## Configuration file
 
-To activate other plugins and language features use the `lv-config.lua` file provided in the `nvim` folder (`~/.config/nvim/lv-config.lua`) in the master branch or (`~/.config/lvim/config.lua`) on rolling
+To install plugins configure LunarVim use the `config.lua` located here: `~/.config/lvim/config.lua`
 
 Example:
 
 ```lua
 -- general
 lvim.format_on_save = true
-lvim.lint_on_save = true
-lvim.colorscheme = "spacegray"
+lvim.colorscheme = "onedarker"
 
-lvim.builtin.compe.autocomplete = true
-
--- keymappings [view all the defaults by pressing <leader>Lk]
 lvim.leader = "space"
 -- add your own keymapping
 lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
@@ -105,25 +67,16 @@ lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
 
 -- 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["t"] = {
---   name = "+Trouble",
---   r = { "<cmd>Trouble lsp_references<cr>", "References" },
---   f = { "<cmd>Trouble lsp_definitions<cr>", "Definitions" },
---   d = { "<cmd>Trouble lsp_document_diagnostics<cr>", "Diagnosticss" },
---   q = { "<cmd>Trouble quickfix<cr>", "QuickFix" },
---   l = { "<cmd>Trouble loclist<cr>", "LocationList" },
---   w = { "<cmd>Trouble lsp_workspace_diagnostics<cr>", "Diagnosticss" },
--- }
-
--- After changing plugin config exit and reopen LunarVim, Run :PackerInstall :PackerCompile
+
+-- Configure builtin plugins
 lvim.builtin.dashboard.active = true
 lvim.builtin.terminal.active = true
 
--- if you don't want all the parsers change this to a table of the ones you want
+-- 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.ignore_install = { "haskell" }
-lvim.builtin.treesitter.highlight.enabled = true
 
+-- Disable virtual text
 lvim.lsp.diagnostics.virtual_text = false
 
 -- set a formatter if you want to override the default lsp one (if it exists)
@@ -148,74 +101,31 @@ lvim.plugins = {
     {"folke/tokyonight.nvim"}, {
         "ray-x/lsp_signature.nvim",
         config = function() require"lsp_signature".on_attach() end,
-        event = "InsertEnter"
+        event = "BufRead"
     }
 }
-
--- Autocommands (https://neovim.io/doc/user/autocmd.html)
--- lvim.autocommands.custom_groups = {
---   { "BufWinEnter", "*.lua", "setlocal ts=8 sw=8" },
--- }
-
-
 ```
 
-In case you want to see all the settings inside LunarVim, run the following:
-
-```bash
-cd /tmp
-lvim --headless +'lua require("utils").generate_settings()' +qa && sort -o lv-settings.lua{,}
-```
-and then inspect `/tmp/lv-settings.lua` file
-
 ## Updating LunarVim
 
-In order to update you should be aware of three things `Plugins`, `LunarVim` and `Neovim`
+- inside LunarVim `:LvimUpdate`
+- from the command-line `lvim +LvimUpdate +q`
 
-To update plugins:
+### Update the plugins
 
-```
-:PackerUpdate
-```
+- inside LunarVim `:PackerUpdate`
 
-To update LunarVim:
+## Breaking changes
 
-```bash
-cd ~/.local/share/lunarvim/lvim && git pull
-:PackerSync
-```
-
-To update Neovim use your package manager or [compile from source](https://github.com/lunarvim/LunarVim/wiki/Installation#get-the-latest-version-of-neovim)
-
-## Project Goals
-
-1. Provide basic functionalities required from an IDE
-    - LSP
-    - Formatting/Linting
-    - Debugging
-    - Treesitter
-    - Colorschemes
-2. Be as fast and lean as possible 
-    - Lazy loading
-    - Not a single extra plugin
-    - User configurable lang/feature enable/disable
-3. Provide a [simple and easy](https://github.com/LunarVim/LunarVimCommunity) way for users to share their own configuration or use others. 
-4. Hot reload of configurations
-    - Hot install of lsp/treesitter/formatter required upon opening a filetype for the first time
-5. Provide a stable & maintainable error free configuration layer over neovim 
-    - With the help of the community behind it
-    - Github workflow testing
-    - Freezing plugin versions
-6. Provide detailed documentation
-    - Video series on how to configure LunarVim as an IDE for each lang
-7. Valhalla
+- `lvim.lang.FOO.lsp` is no longer supported after #1584.
+  You can either use `:NlspConfig` for most of the settings you might need, or override the setup by adding an entry to `lvim.lsp.override = { "FOO" }`.
 
 ## Resources
 
-- [YouTube](https://www.youtube.com/channel/UCS97tchJDq17Qms3cux8wcA)
-
 - [Documentation](https://www.lunarvim.org)
 
+- [YouTube](https://www.youtube.com/channel/UCS97tchJDq17Qms3cux8wcA)
+
 - [Discord](https://discord.gg/Xb9B4Ny)
 
 - [Twitter](https://twitter.com/chrisatmachine)
@@ -223,9 +133,11 @@ To update Neovim use your package manager or [compile from source](https://githu
 ## Testimonials
 
 > "I have the processing power of a potato with 4 gb of ram and LunarVim runs perfectly."
+>
 > - @juanCortelezzi, LunarVim user.
 
 > "My minimal config with a good amount less code than LunarVim loads 40ms slower. Time to switch."
+>
 > - @mvllow, Potential LunarVim user.
 
 <div align="center" id="madewithlua">

+ 13 - 0
colors/onedarker.vim

@@ -0,0 +1,13 @@
+" Author: Christian Chiarulli <chrisatmachine@gmail.com>
+
+lua << EOF
+package.loaded['onedarker'] = nil
+package.loaded['onedarker.highlights'] = nil
+package.loaded['onedarker.Treesitter'] = nil
+package.loaded['onedarker.markdown'] = nil
+package.loaded['onedarker.Whichkey'] = nil
+package.loaded['onedarker.Git'] = nil
+package.loaded['onedarker.LSP'] = nil
+
+require("onedarker")
+EOF

+ 0 - 2
colors/spacegray.vim

@@ -1,2 +0,0 @@
-" Author: Christian Chiarulli <chrisatmachine@gmail.com>
-lua require("spacegray")

+ 3 - 0
ftdetect/bicep.lua

@@ -0,0 +1,3 @@
+vim.cmd [[
+ au BufRead,BufNewFile *.bicep set filetype=bicep
+]]

+ 3 - 0
ftdetect/json.lua

@@ -0,0 +1,3 @@
+vim.cmd [[
+ au BufRead,BufNewFile tsconfig.json set filetype=jsonc
+]]

+ 3 - 0
ftdetect/sol.lua

@@ -0,0 +1,3 @@
+vim.cmd [[
+ au BufRead,BufNewFile *.sol set filetype=solidity
+]]

+ 0 - 1
ftplugin/asm.lua

@@ -1 +0,0 @@
-require("lsp").setup "asm"

+ 0 - 1
ftplugin/beancount.lua

@@ -1 +0,0 @@
-require("lsp").setup "beancount"

+ 0 - 4
ftplugin/c.lua

@@ -1,4 +0,0 @@
-require("lsp").setup "c"
-
--- TODO get from dap
--- require("lang.c").dap()

+ 0 - 1
ftplugin/clojure.lua

@@ -1 +0,0 @@
-require("lsp").setup "clojure"

+ 0 - 1
ftplugin/cmake.lua

@@ -1 +0,0 @@
-require("lsp").setup "cmake"

+ 0 - 1
ftplugin/cpp.lua

@@ -1 +0,0 @@
-require("lsp").setup "cpp"

+ 0 - 1
ftplugin/crystal.lua

@@ -1 +0,0 @@
-require("lsp").setup "crystal"

+ 0 - 1
ftplugin/cs.lua

@@ -1 +0,0 @@
-require("lsp").setup "cs"

+ 0 - 1
ftplugin/css.lua

@@ -1 +0,0 @@
-require("lsp").setup "css"

+ 0 - 1
ftplugin/d.lua

@@ -1 +0,0 @@
-require("lsp").setup "d"

+ 0 - 1
ftplugin/dart.lua

@@ -1 +0,0 @@
-require("lsp").setup "dart"

+ 0 - 1
ftplugin/dockerfile.lua

@@ -1 +0,0 @@
-require("lsp").setup "docker"

+ 0 - 10
ftplugin/elixir.lua

@@ -1,10 +0,0 @@
-require("lsp").setup "elixir"
-vim.api.nvim_buf_set_option(0, "commentstring", "# %s")
-
--- TODO: do we need this?
--- needed for the LSP to recognize elixir files (alternatively just use elixir-editors/vim-elixir)
--- vim.cmd [[
---   au BufRead,BufNewFile *.ex,*.exs set filetype=elixir
---   au BufRead,BufNewFile *.eex,*.leex,*.sface set filetype=eelixir
---   au BufRead,BufNewFile mix.lock set filetype=elixir
--- ]]

+ 0 - 1
ftplugin/elm.lua

@@ -1 +0,0 @@
-require("lsp").setup "elm"

+ 0 - 1
ftplugin/erlang.lua

@@ -1 +0,0 @@
-require("lsp").setup "erlang"

+ 0 - 9
ftplugin/euphoria3.lua

@@ -1,9 +0,0 @@
-require("lsp").setup "erlang"
-
--- TODO: do we need this?
--- needed for the LSP to recognize elixir files (alternatively just use elixir-editors/vim-elixir)
--- vim.cmd [[
---   au BufRead,BufNewFile *.ex,*.exs set filetype=elixir
---   au BufRead,BufNewFile *.eex,*.leex,*.sface set filetype=eelixir
---   au BufRead,BufNewFile mix.lock set filetype=elixir
--- ]]

+ 0 - 1
ftplugin/fish.lua

@@ -1 +0,0 @@
-require("lsp").setup "fish"

+ 0 - 1
ftplugin/fortran.lua

@@ -1 +0,0 @@
-require("lsp").setup "fortran"

+ 0 - 1
ftplugin/gdscript.lua

@@ -1 +0,0 @@
-require("lsp").setup "gdscript"

+ 0 - 1
ftplugin/go.lua

@@ -1 +0,0 @@
-require("lsp").setup "go"

+ 0 - 1
ftplugin/graphql.lua

@@ -1 +0,0 @@
-require("lsp").setup "graphql"

+ 0 - 1
ftplugin/haskell.lua

@@ -1 +0,0 @@
-require("lsp").setup "haskell"

+ 0 - 1
ftplugin/html.lua

@@ -1 +0,0 @@
-require("lsp").setup "html"

+ 0 - 1
ftplugin/java.lua

@@ -1 +0,0 @@
-require("lsp").setup "java"

+ 0 - 1
ftplugin/javascript.lua

@@ -1 +0,0 @@
-require("lsp").setup "javascript"

+ 0 - 1
ftplugin/javascriptreact.lua

@@ -1 +0,0 @@
-require("lsp").setup "javascriptreact"

+ 0 - 1
ftplugin/json.lua

@@ -1 +0,0 @@
-require("lsp").setup "json"

+ 0 - 1
ftplugin/julia.lua

@@ -1 +0,0 @@
-require("lsp").setup "julia"

+ 0 - 1
ftplugin/kotlin.lua

@@ -1 +0,0 @@
-require("lsp").setup "kotlin"

+ 0 - 1
ftplugin/less.lua

@@ -1 +0,0 @@
-css.lua

+ 0 - 1
ftplugin/lua.lua

@@ -1 +0,0 @@
-require("lsp").setup "lua"

+ 0 - 2
ftplugin/netrw.lua

@@ -1,2 +0,0 @@
-vim.cmd [[nmap <buffer> h -]]
-vim.cmd [[nmap <buffer> l <cr>]]

+ 0 - 1
ftplugin/nix.lua

@@ -1 +0,0 @@
-require("lsp").setup "nix"

+ 0 - 1
ftplugin/perl.lua

@@ -1 +0,0 @@
-require("lsp").setup "perl"

+ 0 - 1
ftplugin/php.lua

@@ -1 +0,0 @@
-require("lsp").setup "php"

+ 0 - 3
ftplugin/ps1.lua

@@ -1,3 +0,0 @@
-require("lsp").setup "ps1"
-
-vim.cmd [[setlocal ts=4 sw=4]]

+ 0 - 1
ftplugin/puppet.lua

@@ -1 +0,0 @@
-require("lsp").setup "puppet"

+ 0 - 3
ftplugin/python.lua

@@ -1,3 +0,0 @@
-require("lsp").setup "python"
--- TODO get from dap
--- require("lang.python").dap()

+ 0 - 2
ftplugin/r.lua

@@ -1,2 +0,0 @@
--- R -e 'install.packages("languageserver",repos = "http://cran.us.r-project.org")'
-require("lsp").setup "r"

+ 0 - 1
ftplugin/rmd.lua

@@ -1 +0,0 @@
-r.lua

+ 0 - 2
ftplugin/ruby.lua

@@ -1,2 +0,0 @@
--- also support sorbet
-require("lsp").setup "ruby"

+ 0 - 4
ftplugin/rust.lua

@@ -1,4 +0,0 @@
-require("lsp").setup "rust"
-
--- TODO get from dap
--- require("lang.rust").dap()

+ 0 - 1
ftplugin/sass.lua

@@ -1 +0,0 @@
-css.lua

+ 0 - 1
ftplugin/sbt.lua

@@ -1 +0,0 @@
-scala.lua

+ 0 - 1
ftplugin/scala.lua

@@ -1 +0,0 @@
-require("lsp").setup "scala"

+ 0 - 1
ftplugin/scss.lua

@@ -1 +0,0 @@
-css.lua

+ 0 - 1
ftplugin/sh.lua

@@ -1 +0,0 @@
-require("lsp").setup "sh"

+ 0 - 1
ftplugin/sql.lua

@@ -1 +0,0 @@
-require("lsp").setup "sql"

+ 0 - 1
ftplugin/svelte.lua

@@ -1 +0,0 @@
-require("lsp").setup "svelte"

+ 0 - 1
ftplugin/swift.lua

@@ -1 +0,0 @@
-require("lsp").setup "swift"

+ 0 - 1
ftplugin/terraform.lua

@@ -1 +0,0 @@
-require("lsp").setup "terraform"

+ 0 - 1
ftplugin/tex.lua

@@ -1 +0,0 @@
-require("lsp").setup "tex"

+ 0 - 0
ftplugin/thing.pp


+ 0 - 1
ftplugin/toml.lua

@@ -1 +0,0 @@
-vim.cmd [[setlocal commentstring=#%s]]

+ 0 - 1
ftplugin/typescript.lua

@@ -1 +0,0 @@
-require("lsp").setup "typescript"

+ 0 - 1
ftplugin/typescriptreact.lua

@@ -1 +0,0 @@
-require("lsp").setup "typescript"

+ 0 - 1
ftplugin/vim.lua

@@ -1 +0,0 @@
-require("lsp").setup "vim"

+ 0 - 1
ftplugin/vue.lua

@@ -1 +0,0 @@
-require("lsp").setup "vue"

+ 0 - 1
ftplugin/yaml.lua

@@ -1 +0,0 @@
-require("lsp").setup "yaml"

+ 0 - 1
ftplugin/zig.lua

@@ -1 +0,0 @@
-require("lsp").setup "zig"

+ 0 - 1
ftplugin/zsh.lua

@@ -1 +0,0 @@
-require("lsp").setup "sh"

+ 9 - 44
init.lua

@@ -1,61 +1,26 @@
--- {{{ Bootstrap
-local home_dir = vim.loop.os_homedir()
-
-vim.opt.rtp:append(home_dir .. "/.local/share/lunarvim/lvim")
-
-vim.opt.rtp:remove(home_dir .. "/.config/nvim")
-vim.opt.rtp:remove(home_dir .. "/.config/nvim/after")
-vim.opt.rtp:append(home_dir .. "/.config/lvim")
-vim.opt.rtp:append(home_dir .. "/.config/lvim/after")
-
-vim.opt.rtp:remove(home_dir .. "/.local/share/nvim/site")
-vim.opt.rtp:remove(home_dir .. "/.local/share/nvim/site/after")
-vim.opt.rtp:append(home_dir .. "/.local/share/lunarvim/site")
-vim.opt.rtp:append(home_dir .. "/.local/share/lunarvim/site/after")
+if os.getenv "LUNARVIM_RUNTIME_DIR" then
+  local path_sep = vim.loop.os_uname().version:match "Windows" and "\\" or "/"
+  vim.opt.rtp:append(os.getenv "LUNARVIM_RUNTIME_DIR" .. path_sep .. "lvim")
+end
 
--- TODO: we need something like this: vim.opt.packpath = vim.opt.rtp
-vim.cmd [[let &packpath = &runtimepath]]
--- }}}
+require("bootstrap"):init()
 
 local config = require "config"
-config:init()
+-- config:init()
 config:load()
 
 local plugins = require "plugins"
-local plugin_loader = require("plugin-loader").init()
-plugin_loader:load { plugins, lvim.plugins }
+require("plugin-loader"):load { plugins, lvim.plugins }
 
 local Log = require "core.log"
-Log:info "Starting LunarVim"
+Log:debug "Starting LunarVim"
 
 vim.g.colors_name = lvim.colorscheme -- Colorscheme must get called after plugins are loaded or it will break new installs.
 vim.cmd("colorscheme " .. lvim.colorscheme)
 
-local utils = require "utils"
-utils.toggle_autoformat()
 local commands = require "core.commands"
 commands.load(commands.defaults)
 
-require("lsp").config()
-
-local null_status_ok, null_ls = pcall(require, "null-ls")
-if null_status_ok then
-  null_ls.config {}
-  require("lspconfig")["null-ls"].setup(lvim.lsp.null_ls.setup)
-end
-
-local lsp_settings_status_ok, lsp_settings = pcall(require, "nlspsettings")
-if lsp_settings_status_ok then
-  lsp_settings.setup {
-    config_home = home_dir .. "/.config/lvim/lsp-settings",
-  }
-end
-
 require("keymappings").setup()
 
--- TODO: these guys need to be in language files
--- if lvim.lang.emmet.active then
---   require "lsp.emmet-ls"
--- end
--- if lvim.lang.tailwindcss.active then
---   require "lsp.tailwind
+require("lsp").setup()

+ 193 - 0
lua/bootstrap.lua

@@ -0,0 +1,193 @@
+local M = {}
+
+package.loaded["utils.hooks"] = nil
+local _, hooks = pcall(require, "utils.hooks")
+
+---Join path segments that were passed as input
+---@return string
+function _G.join_paths(...)
+  local uv = vim.loop
+  local path_sep = uv.os_uname().version:match "Windows" and "\\" or "/"
+  local result = table.concat({ ... }, path_sep)
+  return result
+end
+
+---Get the full path to `$LUNARVIM_RUNTIME_DIR`
+---@return string
+function _G.get_runtime_dir()
+  local lvim_runtime_dir = os.getenv "LUNARVIM_RUNTIME_DIR"
+  if not lvim_runtime_dir then
+    -- when nvim is used directly
+    return vim.fn.stdpath "config"
+  end
+  return lvim_runtime_dir
+end
+
+---Get the full path to `$LUNARVIM_CONFIG_DIR`
+---@return string
+function _G.get_config_dir()
+  local lvim_config_dir = os.getenv "LUNARVIM_CONFIG_DIR"
+  if not lvim_config_dir then
+    return vim.fn.stdpath "config"
+  end
+  return lvim_config_dir
+end
+
+---Get the full path to `$LUNARVIM_CACHE_DIR`
+---@return string
+function _G.get_cache_dir()
+  local lvim_cache_dir = os.getenv "LUNARVIM_CACHE_DIR"
+  if not lvim_cache_dir then
+    return vim.fn.stdpath "cache"
+  end
+  return lvim_cache_dir
+end
+
+---Get the full path to the currently installed lunarvim repo
+---@return string
+local function get_install_path()
+  local lvim_runtime_dir = os.getenv "LUNARVIM_RUNTIME_DIR"
+  if not lvim_runtime_dir then
+    -- when nvim is used directly
+    return vim.fn.stdpath "config"
+  end
+  return join_paths(lvim_runtime_dir, "lvim")
+end
+
+---Get currently installed version of LunarVim
+---@param type string can be "short"
+---@return string
+function _G.get_version(type)
+  type = type or ""
+  local lvim_full_ver = vim.fn.system("git -C " .. get_install_path() .. " describe --tags")
+
+  if string.match(lvim_full_ver, "%d") == nil then
+    return nil
+  end
+  if type == "short" then
+    return vim.fn.split(lvim_full_ver, "-")[1]
+  else
+    return string.sub(lvim_full_ver, 1, #lvim_full_ver - 1)
+  end
+end
+
+---Initialize the `&runtimepath` variables and prepare for startup
+---@return table
+function M:init()
+  self.runtime_dir = get_runtime_dir()
+  self.config_dir = get_config_dir()
+  self.cache_path = get_cache_dir()
+  self.install_path = get_install_path()
+
+  self.pack_dir = join_paths(self.runtime_dir, "site", "pack")
+  self.packer_install_dir = join_paths(self.runtime_dir, "site", "pack", "packer", "start", "packer.nvim")
+  self.packer_cache_path = join_paths(self.config_dir, "plugin", "packer_compiled.lua")
+
+  if os.getenv "LUNARVIM_RUNTIME_DIR" then
+    vim.opt.rtp:remove(join_paths(vim.fn.stdpath "data", "site"))
+    vim.opt.rtp:remove(join_paths(vim.fn.stdpath "data", "site", "after"))
+    vim.opt.rtp:prepend(join_paths(self.runtime_dir, "site"))
+    vim.opt.rtp:append(join_paths(self.runtime_dir, "site", "after"))
+
+    vim.opt.rtp:remove(vim.fn.stdpath "config")
+    vim.opt.rtp:remove(join_paths(vim.fn.stdpath "config", "after"))
+    vim.opt.rtp:prepend(self.config_dir)
+    vim.opt.rtp:append(join_paths(self.config_dir, "after"))
+    -- TODO: we need something like this: vim.opt.packpath = vim.opt.rtp
+
+    vim.cmd [[let &packpath = &runtimepath]]
+    vim.cmd("set spellfile=" .. join_paths(self.config_dir, "spell", "en.utf-8.add"))
+  end
+
+  vim.fn.mkdir(vim.fn.stdpath "cache", "p")
+
+  -- FIXME: currently unreliable in unit-tests
+  if not os.getenv "LVIM_TEST_ENV" then
+    require("impatient").setup {
+      path = vim.fn.stdpath "cache" .. "/lvim_cache",
+      enable_profiling = true,
+    }
+  end
+
+  local config = require "config"
+  config:init {
+    path = join_paths(self.config_dir, "config.lua"),
+  }
+
+  require("plugin-loader"):init {
+    package_root = self.pack_dir,
+    install_path = self.packer_install_dir,
+  }
+
+  return self
+end
+
+---Update LunarVim
+---pulls the latest changes from github and, resets the startup cache
+function M:update()
+  hooks.run_pre_update()
+  M:update_repo()
+  hooks.run_post_update()
+end
+
+local function git_cmd(subcmd)
+  local Job = require "plenary.job"
+  local Log = require "core.log"
+  local args = { "-C", get_install_path() }
+  vim.list_extend(args, subcmd)
+
+  local stderr = {}
+  local stdout, ret = Job
+    :new({
+      command = "git",
+      args = args,
+      cwd = get_install_path(),
+      on_stderr = function(_, data)
+        table.insert(stderr, data)
+      end,
+    })
+    :sync()
+
+  if not vim.tbl_isempty(stderr) then
+    Log:debug(stderr)
+  end
+
+  if not vim.tbl_isempty(stdout) then
+    Log:debug(stdout)
+  end
+
+  return ret
+end
+
+---pulls the latest changes from github
+function M:update_repo()
+  local Log = require "core.log"
+  local sub_commands = {
+    fetch = { "fetch" },
+    diff = { "diff", "--quiet", "@{upstream}" },
+    merge = { "merge", "--ff-only", "--progress" },
+  }
+  Log:info "Checking for updates"
+
+  local ret = git_cmd(sub_commands.fetch)
+  if ret ~= 0 then
+    Log:error "Update failed! Check the log for further information"
+    return
+  end
+
+  ret = git_cmd(sub_commands.diff)
+
+  if ret == 0 then
+    Log:info "LunarVim is already up-to-date"
+    return
+  end
+
+  ret = git_cmd(sub_commands.merge)
+
+  if ret ~= 0 then
+    Log:error "Update failed! Please pull the changes manually instead."
+    return
+  end
+end
+
+return M

+ 5 - 1131
lua/config/defaults.lua

@@ -1,19 +1,14 @@
 local home_dir = vim.loop.os_homedir()
-CONFIG_PATH = home_dir .. "/.local/share/lunarvim/lvim"
-DATA_PATH = vim.fn.stdpath "data"
-CACHE_PATH = vim.fn.stdpath "cache"
-TERMINAL = vim.fn.expand "$TERMINAL"
-USER = vim.fn.expand "$USER"
-vim.cmd [[ set spellfile=~/.config/lvim/spell/en.utf-8.add ]]
+local utils = require "utils"
 
 lvim = {
   leader = "space",
-  colorscheme = "spacegray",
+  colorscheme = "onedarker",
   line_wrap_cursor_movement = true,
   transparent_window = false,
   format_on_save = true,
-  vsnip_dir = home_dir .. "/.config/snippets",
-  database = { save_location = "~/.config/lunarvim_db", auto_execute = 1 },
+  vsnip_dir = utils.join_paths(home_dir, ".config", "snippets"),
+  database = { save_location = utils.join_paths(home_dir, ".config", "lunarvim_db"), auto_execute = 1 },
   keys = {},
 
   builtin = {},
@@ -33,1131 +28,10 @@ lvim = {
       },
     },
   },
-
-  lsp = {
-    completion = {
-      item_kind = {
-        "   (Text) ",
-        "   (Method)",
-        "   (Function)",
-        "   (Constructor)",
-        " ﴲ  (Field)",
-        "[] (Variable)",
-        "   (Class)",
-        " ﰮ  (Interface)",
-        "   (Module)",
-        " 襁 (Property)",
-        "   (Unit)",
-        "   (Value)",
-        " 練 (Enum)",
-        "   (Keyword)",
-        "   (Snippet)",
-        "   (Color)",
-        "   (File)",
-        "   (Reference)",
-        "   (Folder)",
-        "   (EnumMember)",
-        " ﲀ  (Constant)",
-        " ﳤ  (Struct)",
-        "   (Event)",
-        "   (Operator)",
-        "   (TypeParameter)",
-      },
-    },
-    diagnostics = {
-      signs = {
-        active = true,
-        values = {
-          { name = "LspDiagnosticsSignError", text = "" },
-          { name = "LspDiagnosticsSignWarning", text = "" },
-          { name = "LspDiagnosticsSignHint", text = "" },
-          { name = "LspDiagnosticsSignInformation", text = "" },
-        },
-      },
-      virtual_text = {
-        prefix = "",
-        spacing = 0,
-      },
-      underline = true,
-      severity_sort = true,
-    },
-    override = {},
-    document_highlight = true,
-    popup_border = "single",
-    on_attach_callback = nil,
-    on_init_callback = nil,
-    null_ls = {
-      setup = {},
-    },
-  },
-
   plugins = {
     -- use config.lua for this not put here
   },
 
   autocommands = {},
-}
-
-local schemas = nil
-local status_ok, jsonls_settings = pcall(require, "nlspsettings.jsonls")
-if status_ok then
-  schemas = jsonls_settings.get_default_schemas()
-end
-
--- TODO move all of this into lang specific files, only require when using
-lvim.lang = {
-  asm = {
-    formatters = {
-      -- {
-      --   exe = "asmfmt",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "",
-      setup = {},
-    },
-  },
-  beancount = {
-    formatters = {
-      -- {
-      --   exe = "bean_format",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "beancount",
-      setup = {
-        cmd = { "beancount-langserver" },
-      },
-    },
-  },
-  c = {
-    formatters = {
-      -- {
-      --   exe = "clang_format",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "uncrustify",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "clangd",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/cpp/clangd/bin/clangd",
-          "--background-index",
-          "--header-insertion=never",
-          "--cross-file-rename",
-          "--clang-tidy",
-          "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*",
-        },
-      },
-    },
-  },
-  cpp = {
-    formatters = {
-      -- {
-      --   exe = "clang_format",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "uncrustify",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "clangd",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/cpp/clangd/bin/clangd",
-          "--background-index",
-          "--header-insertion=never",
-          "--cross-file-rename",
-          "--clang-tidy",
-          "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*",
-        },
-      },
-    },
-  },
-  crystal = {
-    formatters = {
-      -- {
-      --   exe = "crystal_format",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "crystalline",
-      setup = {
-        cmd = { "crystalline" },
-      },
-    },
-  },
-  cs = {
-    formatters = {
-      -- {
-      --   exe = "clang_format ",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "uncrustify",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "omnisharp",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/csharp/omnisharp/run",
-          "--languageserver",
-          "--hostPID",
-          tostring(vim.fn.getpid()),
-        },
-      },
-    },
-  },
-  cmake = {
-    formatters = {
-      -- {
-      --   exe = "cmake_format",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "cmake",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/cmake/venv/bin/cmake-language-server",
-        },
-      },
-    },
-  },
-  clojure = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "clojure_lsp",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/clojure/clojure-lsp",
-        },
-      },
-    },
-  },
-  css = {
-    formatters = {
-      -- {
-      --   exe = "prettier",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettierd",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "cssls",
-      setup = {
-        cmd = {
-          "node",
-          DATA_PATH .. "/lspinstall/css/vscode-css/css-language-features/server/dist/node/cssServerMain.js",
-          "--stdio",
-        },
-      },
-    },
-  },
-  less = {
-    formatters = {
-      -- {
-      --   exe = "prettier",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettierd",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "cssls",
-      setup = {
-        cmd = {
-          "node",
-          DATA_PATH .. "/lspinstall/css/vscode-css/css-language-features/server/dist/node/cssServerMain.js",
-          "--stdio",
-        },
-      },
-    },
-  },
-  d = {
-    formatters = {
-      -- {
-      --   exe = "dfmt",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "serve_d",
-      setup = {
-        cmd = { "serve-d" },
-      },
-    },
-  },
-  dart = {
-    formatters = {
-      -- {
-      --   exe = "dart_format",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "dartls",
-      setup = {
-        cmd = {
-          "dart",
-          "/usr/lib/dart/bin/snapshots/analysis_server.dart.snapshot",
-          "--lsp",
-        },
-      },
-    },
-  },
-  docker = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "dockerls",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/dockerfile/node_modules/.bin/docker-langserver",
-          "--stdio",
-        },
-      },
-    },
-  },
-  elixir = {
-    formatters = {
-      -- {
-      --   exe = "mix",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "elixirls",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/elixir/elixir-ls/language_server.sh",
-        },
-      },
-    },
-  },
-  elm = {
-    formatters = {
-      -- {
-      --   exe = "elm_format",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "elmls",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-language-server",
-        },
-        -- init_options = {
-        -- elmAnalyseTrigger = "change",
-        -- elmFormatPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-format",
-        -- elmPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/",
-        -- elmTestPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-test",
-        -- },
-      },
-    },
-  },
-  erlang = {
-    formatters = {
-      -- {
-      --   exe = "erlfmt",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "erlangls",
-      setup = {
-        cmd = {
-          "erlang_ls",
-        },
-      },
-    },
-  },
-  emmet = { active = false },
-  fish = {
-    formatters = {
-      -- {
-      --   exe = "fish_indent",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "",
-      setup = {},
-    },
-  },
-  fortran = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "fortls",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/fortran/venv/bin/fortls",
-        },
-      },
-    },
-  },
-  go = {
-    formatters = {
-      -- {
-      --   exe = "gofmt",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "goimports",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "gofumpt",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "gopls",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/go/gopls",
-        },
-      },
-    },
-  },
-  graphql = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "graphql",
-      setup = {
-        cmd = {
-          "graphql-lsp",
-          "server",
-          "-m",
-          "stream",
-        },
-      },
-    },
-  },
-  haskell = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "hls",
-      setup = {
-        cmd = { DATA_PATH .. "/lspinstall/haskell/hls" },
-      },
-    },
-  },
-  html = {
-    formatters = {
-      -- {
-      --   exe = "prettier",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettierd",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "html",
-      setup = {
-        cmd = {
-          "node",
-          DATA_PATH .. "/lspinstall/html/vscode-html/html-language-features/server/dist/node/htmlServerMain.js",
-          "--stdio",
-        },
-      },
-    },
-  },
-  java = {
-    formatters = {
-      -- {
-      --   exe = "clang_format",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "uncrustify",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "jdtls",
-      setup = {
-        cmd = { DATA_PATH .. "/lspinstall/java/jdtls.sh" },
-      },
-    },
-  },
-  json = {
-    formatters = {
-      -- {
-      --   exe = "json_tool",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettier",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettierd",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "jsonls",
-      setup = {
-        cmd = {
-          "node",
-          DATA_PATH .. "/lspinstall/json/vscode-json/json-language-features/server/dist/node/jsonServerMain.js",
-          "--stdio",
-        },
-        settings = {
-          json = {
-            schemas = schemas,
-            --   = {
-            --   {
-            --     fileMatch = { "package.json" },
-            --     url = "https://json.schemastore.org/package.json",
-            --   },
-            -- },
-          },
-        },
-        commands = {
-          Format = {
-            function()
-              vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 })
-            end,
-          },
-        },
-      },
-    },
-  },
-  julia = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "julials",
-      setup = {
-        {
-          "julia",
-          "--startup-file=no",
-          "--history-file=no",
-          -- vim.fn.expand "~/.config/nvim/lua/lsp/julia/run.jl",
-          CONFIG_PATH .. "/utils/julia/run.jl",
-        },
-      },
-    },
-  },
-  kotlin = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "kotlin_language_server",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/kotlin/server/bin/kotlin-language-server",
-        },
-        root_dir = function(fname)
-          local util = require "lspconfig/util"
-
-          local root_files = {
-            "settings.gradle", -- Gradle (multi-project)
-            "settings.gradle.kts", -- Gradle (multi-project)
-            "build.xml", -- Ant
-            "pom.xml", -- Maven
-          }
-
-          local fallback_root_files = {
-            "build.gradle", -- Gradle
-            "build.gradle.kts", -- Gradle
-          }
-          return util.root_pattern(unpack(root_files))(fname) or util.root_pattern(unpack(fallback_root_files))(fname)
-        end,
-      },
-    },
-  },
-  lua = {
-    formatters = {
-      -- {
-      --   exe = "stylua",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "lua_format",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "sumneko_lua",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/lua/sumneko-lua-language-server",
-          "-E",
-          DATA_PATH .. "/lspinstall/lua/main.lua",
-        },
-        settings = {
-          Lua = {
-            runtime = {
-              -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim)
-              version = "LuaJIT",
-              -- Setup your lua path
-              path = vim.split(package.path, ";"),
-            },
-            diagnostics = {
-              -- Get the language server to recognize the `vim` global
-              globals = { "vim", "lvim" },
-            },
-            workspace = {
-              -- Make the server aware of Neovim runtime files
-              library = {
-                [vim.fn.expand "~/.local/share/lunarvim/lvim/lua"] = true,
-                [vim.fn.expand "$VIMRUNTIME/lua"] = true,
-                [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true,
-              },
-              maxPreload = 100000,
-              preloadFileSize = 1000,
-            },
-          },
-        },
-      },
-    },
-  },
-  nginx = {
-    formatters = {
-      -- {
-      --   exe = "nginx_beautifier",
-      --   args = {
-      --     provider = "",
-      --     setup = {},
-      --   },
-      -- },
-    },
-    linters = {},
-    lsp = {},
-  },
-  perl = {
-    formatters = {
-      -- {
-      --   exe = "perltidy",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "",
-      setup = {},
-    },
-  },
-  sql = {
-    formatters = {
-      -- {
-      --   exe = "sqlformat",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "sqls",
-      setup = {
-        cmd = { "sqls" },
-      },
-    },
-  },
-  php = {
-    formatters = {
-      -- {
-      --   exe = "phpcbf",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "intelephense",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/php/node_modules/.bin/intelephense",
-          "--stdio",
-        },
-        filetypes = { "php", "phtml" },
-        settings = {
-          intelephense = {
-            environment = {
-              phpVersion = "7.4",
-            },
-          },
-        },
-      },
-    },
-  },
-  puppet = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "puppet",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/puppet/puppet-editor-services/puppet-languageserver",
-          "--stdio",
-        },
-      },
-    },
-  },
-  javascript = {
-    formatters = {
-      -- {
-      --   exe = "prettier",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettier_d_slim",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettierd",
-      --   args = {},
-      -- },
-    },
-    -- @usage can be {"eslint"} or {"eslint_d"}
-    linters = {},
-    lsp = {
-      provider = "tsserver",
-      setup = {
-        cmd = {
-          -- TODO:
-          DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",
-          "--stdio",
-        },
-      },
-    },
-  },
-  javascriptreact = {
-    formatters = {
-      -- {
-      --   exe = "prettier",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettier_d_slim",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettierd",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "tsserver",
-      setup = {
-        cmd = {
-          -- TODO:
-          DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",
-          "--stdio",
-        },
-      },
-    },
-  },
-  python = {
-    formatters = {
-      -- {
-      --   exe = "yapf",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "isort",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "pyright",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/python/node_modules/.bin/pyright-langserver",
-          "--stdio",
-        },
-      },
-    },
-  },
-  -- R -e 'install.packages("formatR",repos = "http://cran.us.r-project.org")'
-  -- R -e 'install.packages("readr",repos = "http://cran.us.r-project.org")'
-  r = {
-    formatters = {
-      -- {
-      --   exe = "format_r",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "r_language_server",
-      setup = {
-        cmd = {
-          "R",
-          "--slave",
-          "-e",
-          "languageserver::run()",
-        },
-      },
-    },
-  },
-  ruby = {
-    formatters = {
-      -- {
-      --   exe = "rufo",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "solargraph",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/ruby/solargraph/solargraph",
-          "stdio",
-        },
-        filetypes = { "ruby" },
-        init_options = {
-          formatting = true,
-        },
-        root_dir = function(fname)
-          local util = require("lspconfig").util
-          return util.root_pattern("Gemfile", ".git")(fname)
-        end,
-        settings = {
-          solargraph = {
-            diagnostics = true,
-          },
-        },
-      },
-    },
-  },
-  rust = {
-    formatters = {
-      -- {
-      --   exe = "rustfmt",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "rust_analyzer",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/rust/rust-analyzer",
-        },
-      },
-    },
-  },
-  scala = {
-    formatters = {
-      -- {
-      --   exe = "scalafmt",
-      --   args = {},
-      -- },
-    },
-    linters = { "" },
-    lsp = {
-      provider = "metals",
-      setup = {},
-    },
-  },
-  sh = {
-    formatters = {
-      -- {
-      --   exe = "shfmt",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "bashls",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/bash/node_modules/.bin/bash-language-server",
-          "start",
-        },
-      },
-    },
-  },
-  svelte = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "svelte",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/svelte/node_modules/.bin/svelteserver",
-          "--stdio",
-        },
-      },
-    },
-  },
-  swift = {
-    formatters = {
-      -- {
-      --   exe = "swiftformat",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "sourcekit",
-      setup = {
-        cmd = {
-          "xcrun",
-          "sourcekit-lsp",
-        },
-      },
-    },
-  },
-  tailwindcss = {
-    active = false,
-    filetypes = {
-      "html",
-      "css",
-      "scss",
-      "javascript",
-      "javascriptreact",
-      "typescript",
-      "typescriptreact",
-    },
-  },
-  terraform = {
-    formatters = {
-      -- {
-      --   exe = "terraform_fmt",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "terraformls",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/terraform/terraform-ls",
-          "serve",
-        },
-      },
-    },
-  },
-  tex = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "texlab",
-      setup = {
-        cmd = { DATA_PATH .. "/lspinstall/latex/texlab" },
-      },
-    },
-  },
-  typescript = {
-    formatters = {
-      -- {
-      --   exe = "prettier",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettierd",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettier_d_slim",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "tsserver",
-      setup = {
-        cmd = {
-          -- TODO:
-          DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",
-          "--stdio",
-        },
-      },
-    },
-  },
-  typescriptreact = {
-    formatters = {
-      -- {
-      --   exe = "prettier",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettierd",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettier_d_slim",
-      --   args = {},
-      -- },
-    },
-    -- @usage can be {"eslint"} or {"eslint_d"}
-    linters = {},
-    lsp = {
-      provider = "tsserver",
-      setup = {
-        cmd = {
-          -- TODO:
-          DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",
-          "--stdio",
-        },
-      },
-    },
-  },
-  vim = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "vimls",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/vim/node_modules/.bin/vim-language-server",
-          "--stdio",
-        },
-      },
-    },
-  },
-  vue = {
-    formatters = {
-      -- {
-      --   exe = "prettier",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettierd",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettier_d_slim",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "vuels",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/vue/node_modules/.bin/vls",
-        },
-      },
-    },
-  },
-  yaml = {
-    formatters = {
-      -- {
-      --   exe = "prettier",
-      --   args = {},
-      -- },
-      -- {
-      --   exe = "prettierd",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "yamlls",
-      setup = {
-        cmd = {
-          DATA_PATH .. "/lspinstall/yaml/node_modules/.bin/yaml-language-server",
-          "--stdio",
-        },
-      },
-    },
-  },
-  zig = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "zls",
-      setup = {
-        cmd = {
-          "zls",
-        },
-      },
-    },
-  },
-  gdscript = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "gdscript",
-      setup = {
-        cmd = {
-          "nc",
-          "localhost",
-          "6008",
-        },
-      },
-    },
-  },
-  ps1 = {
-    formatters = {},
-    linters = {},
-    lsp = {
-      provider = "powershell_es",
-      setup = {
-        bundle_path = "",
-      },
-    },
-  },
-  nix = {
-    formatters = {
-      -- {
-      --   exe = "nixfmt",
-      --   args = {},
-      -- },
-    },
-    linters = {},
-    lsp = {
-      provider = "rnix",
-      setup = {
-        cmd = { "rnix-lsp" },
-        filetypes = { "nix" },
-        init_options = {},
-        settings = {},
-        root_dir = function(fname)
-          local util = require "lspconfig/util"
-          return util.root_pattern ".git"(fname) or vim.fn.getcwd()
-        end,
-      },
-    },
-  },
+  lang = {},
 }

+ 131 - 10
lua/config/init.lua

@@ -1,27 +1,146 @@
-local home_dir = vim.loop.os_homedir()
-local M = {
-  path = string.format("%s/.config/lvim/config.lua", home_dir),
-}
+local M = {}
 
 --- Initialize lvim default configuration
 -- Define lvim global variable
-function M:init()
+function M:init(opts)
+  opts = opts or {}
+  self.path = opts.path
   local utils = require "utils"
 
   require "config.defaults"
 
+  -- Fallback config.lua to lv-config.lua
+  if not utils.is_file(self.path) then
+    local lv_config = self.path:gsub("config.lua$", "lv-config.lua")
+    print(self.path, "not found, falling back to", lv_config)
+
+    self.path = lv_config
+  end
+
   local builtins = require "core.builtins"
   builtins.config(self)
 
   local settings = require "config.settings"
   settings.load_options()
 
-  -- Fallback config.lua to lv-config.lua
-  if not utils.is_file(self.path) then
-    local lv_config = self.path:gsub("config.lua$", "lv-config.lua")
-    print(self.path, "not found, falling back to", lv_config)
+  local lvim_lsp_config = require "lsp.config"
+  lvim.lsp = vim.deepcopy(lvim_lsp_config)
 
-    self.path = lv_config
+  local supported_languages = {
+    "asm",
+    "bash",
+    "beancount",
+    "bibtex",
+    "bicep",
+    "c",
+    "c_sharp",
+    "clojure",
+    "cmake",
+    "comment",
+    "commonlisp",
+    "cpp",
+    "crystal",
+    "cs",
+    "css",
+    "cuda",
+    "d",
+    "dart",
+    "dockerfile",
+    "dot",
+    "elixir",
+    "elm",
+    "emmet",
+    "erlang",
+    "fennel",
+    "fish",
+    "fortran",
+    "gdscript",
+    "glimmer",
+    "go",
+    "gomod",
+    "graphql",
+    "haskell",
+    "hcl",
+    "heex",
+    "html",
+    "java",
+    "javascript",
+    "javascriptreact",
+    "jsdoc",
+    "json",
+    "json5",
+    "jsonc",
+    "julia",
+    "kotlin",
+    "latex",
+    "ledger",
+    "less",
+    "lua",
+    "markdown",
+    "nginx",
+    "nix",
+    "ocaml",
+    "ocaml_interface",
+    "perl",
+    "php",
+    "pioasm",
+    "ps1",
+    "puppet",
+    "python",
+    "ql",
+    "query",
+    "r",
+    "regex",
+    "rst",
+    "ruby",
+    "rust",
+    "scala",
+    "scss",
+    "sh",
+    "solidity",
+    "sparql",
+    "sql",
+    "supercollider",
+    "surface",
+    "svelte",
+    "swift",
+    "tailwindcss",
+    "terraform",
+    "tex",
+    "tlaplus",
+    "toml",
+    "tsx",
+    "turtle",
+    "typescript",
+    "typescriptreact",
+    "verilog",
+    "vim",
+    "vue",
+    "yaml",
+    "yang",
+    "zig",
+  }
+
+  require("lsp.manager").init_defaults(supported_languages)
+end
+
+local function deprecation_notice()
+  local in_headless = #vim.api.nvim_list_uis() == 0
+  if in_headless then
+    return
+  end
+
+  for lang, entry in pairs(lvim.lang) do
+    local deprecated_config = entry["lsp"] or {}
+    if not vim.tbl_isempty(deprecated_config) then
+      local msg = string.format(
+        "Deprecation notice: [lvim.lang.%s.lsp] setting is no longer supported. See https://github.com/LunarVim/LunarVim#breaking-changes",
+        lang
+      )
+      vim.schedule(function()
+        vim.notify(msg, vim.log.levels.WARN)
+      end)
+    end
   end
 end
 
@@ -38,6 +157,8 @@ function M:load(config_path)
     return
   end
 
+  deprecation_notice()
+
   self.path = config_path
 
   autocmds.define_augroups(lvim.autocommands)

+ 3 - 3
lua/config/settings.lua

@@ -1,5 +1,5 @@
 local M = {}
-
+local utils = require "utils"
 M.load_options = function()
   local default_options = {
     backup = false, -- creates a backup file
@@ -28,7 +28,7 @@ M.load_options = function()
     timeoutlen = 100, -- time to wait for a mapped sequence to complete (in milliseconds)
     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
-    undodir = CACHE_PATH .. "/undo", -- set an undo directory
+    undodir = utils.join_paths(get_cache_dir(), "undo"), -- set an undo directory
     undofile = true, -- enable persistent undo
     updatetime = 300, -- 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
@@ -45,7 +45,7 @@ M.load_options = function()
     spelllang = "en",
     scrolloff = 8, -- is one of my fav
     sidescrolloff = 8,
-  } ---  VIM ONLY COMMANDS  ---cmd "filetype plugin on"cmd('let &titleold="' .. TERMINAL .. '"')cmd "set inccommand=split"cmd "set iskeyword+=-"
+  }
 
   ---  SETTINGS  ---
 

+ 5 - 0
lua/core/autocmds.lua

@@ -13,6 +13,11 @@ lvim.autocommands = {
       "qf",
       "nnoremap <silent> <buffer> q :q<CR>",
     },
+    {
+      "FileType",
+      "lsp-installer",
+      "nnoremap <silent> <buffer> q :q<CR>",
+    },
     {
       "TextYankPost",
       "*",

+ 37 - 25
lua/core/autopairs.lua

@@ -4,11 +4,13 @@ function M.config()
   lvim.builtin.autopairs = {
     active = true,
     on_config_done = nil,
-    ---@usage  map <CR> on insert mode
-    map_cr = true,
     ---@usage auto insert after select function or method item
-    -- NOTE: This should be wrapped into a function so that it is re-evaluated when opening new files
-    map_complete = vim.bo.filetype ~= "tex",
+    map_complete = true,
+    ---@usage  -- modifies the function or method delimiter by filetypes
+    map_char = {
+      all = "(",
+      tex = "{",
+    },
     ---@usage check treesitter
     check_ts = true,
     ts_config = {
@@ -20,36 +22,46 @@ function M.config()
 end
 
 M.setup = function()
-  -- skip it, if you use another global object
-  _G.MUtils = {}
   local autopairs = require "nvim-autopairs"
   local Rule = require "nvim-autopairs.rule"
+  local cond = require "nvim-autopairs.conds"
 
-  vim.g.completion_confirm_key = ""
-  MUtils.completion_confirm = function()
-    if vim.fn.pumvisible() ~= 0 then
-      if vim.fn.complete_info()["selected"] ~= -1 then
-        return vim.fn["compe#confirm"](autopairs.esc "<cr>")
-      else
-        return autopairs.esc "<cr>"
+  autopairs.setup {
+    check_ts = lvim.builtin.autopairs.check_ts,
+    ts_config = lvim.builtin.autopairs.ts_config,
+  }
+
+  -- vim.g.completion_confirm_key = ""
+
+  autopairs.add_rule(Rule("$$", "$$", "tex"))
+  autopairs.add_rules {
+    Rule("$", "$", { "tex", "latex" }) -- don't add a pair if the next character is %
+      :with_pair(cond.not_after_regex_check "%%") -- don't add a pair if  the previous character is xxx
+      :with_pair(cond.not_before_regex_check("xxx", 3)) -- don't move right when repeat character
+      :with_move(cond.none()) -- don't delete if the next character is xx
+      :with_del(cond.not_after_regex_check "xx") -- disable  add newline when press <cr>
+      :with_cr(cond.none()),
+  }
+  autopairs.add_rules {
+    Rule("$$", "$$", "tex"):with_pair(function(opts)
+      print(vim.inspect(opts))
+      if opts.line == "aa $$" then
+        -- don't add pair on that line
+        return false
       end
-    else
-      return autopairs.autopairs_cr()
-    end
-  end
+    end),
+  }
 
-  if package.loaded["compe"] then
-    require("nvim-autopairs.completion.compe").setup {
-      map_cr = lvim.builtin.autopairs.map_cr,
+  if package.loaded["cmp"] then
+    require("nvim-autopairs.completion.cmp").setup {
+      map_cr = false,
       map_complete = lvim.builtin.autopairs.map_complete,
+      map_char = lvim.builtin.autopairs.map_char,
     }
+    -- we map CR explicitly in cmp.lua but we still need to setup the autopairs CR keymap
+    vim.api.nvim_set_keymap("i", "<CR>", "v:lua.MPairs.autopairs_cr()", { expr = true, noremap = true })
   end
 
-  autopairs.setup {
-    check_ts = lvim.builtin.autopairs.check_ts,
-    ts_config = lvim.builtin.autopairs.ts_config,
-  }
-
   require("nvim-treesitter.configs").setup { autopairs = { enable = true } }
 
   local ts_conds = require "nvim-autopairs.ts-conds"

+ 1 - 2
lua/core/builtins/init.lua

@@ -4,7 +4,7 @@ local builtins = {
   "keymappings",
   "core.which-key",
   "core.gitsigns",
-  "core.compe",
+  "core.cmp",
   "core.dashboard",
   "core.dap",
   "core.terminal",
@@ -15,7 +15,6 @@ local builtins = {
   "core.bufferline",
   "core.autopairs",
   "core.comment",
-  "core.lspinstall",
   "core.lualine",
 }
 

+ 260 - 0
lua/core/cmp.lua

@@ -0,0 +1,260 @@
+local M = {}
+
+local check_backspace = function()
+  local col = vim.fn.col "." - 1
+  return col == 0 or vim.fn.getline("."):sub(col, col):match "%s"
+end
+
+local function T(str)
+  return vim.api.nvim_replace_termcodes(str, true, true, true)
+end
+
+local is_emmet_active = function()
+  local clients = vim.lsp.buf_get_clients()
+
+  for _, client in pairs(clients) do
+    if client.name == "emmet_ls" then
+      return true
+    end
+  end
+  return false
+end
+
+M.config = function()
+  local status_cmp_ok, cmp = pcall(require, "cmp")
+  if not status_cmp_ok then
+    return
+  end
+  local status_luasnip_ok, luasnip = pcall(require, "luasnip")
+  if not status_luasnip_ok then
+    return
+  end
+  local win_get_cursor = vim.api.nvim_win_get_cursor
+  local get_current_buf = vim.api.nvim_get_current_buf
+
+  local function inside_snippet()
+    -- for outdated versions of luasnip
+    if not luasnip.session.current_nodes then
+      return false
+    end
+
+    local node = luasnip.session.current_nodes[get_current_buf()]
+    if not node then
+      return false
+    end
+
+    local snip_begin_pos, snip_end_pos = node.parent.snippet.mark:pos_begin_end()
+    local pos = win_get_cursor(0)
+    pos[1] = pos[1] - 1 -- LuaSnip is 0-based not 1-based like nvim for rows
+    return pos[1] >= snip_begin_pos[1] and pos[1] <= snip_end_pos[1]
+  end
+
+  ---sets the current buffer's luasnip to the one nearest the cursor
+  ---@return boolean true if a node is found, false otherwise
+  local function seek_luasnip_cursor_node()
+    -- for outdated versions of luasnip
+    if not luasnip.session.current_nodes then
+      return false
+    end
+
+    local pos = win_get_cursor(0)
+    pos[1] = pos[1] - 1
+    local node = luasnip.session.current_nodes[get_current_buf()]
+    if not node then
+      return false
+    end
+
+    local snippet = node.parent.snippet
+    local exit_node = snippet.insert_nodes[0]
+
+    -- exit early if we're past the exit node
+    if exit_node then
+      local exit_pos_end = exit_node.mark:pos_end()
+      if (pos[1] > exit_pos_end[1]) or (pos[1] == exit_pos_end[1] and pos[2] > exit_pos_end[2]) then
+        snippet:remove_from_jumplist()
+        luasnip.session.current_nodes[get_current_buf()] = nil
+
+        return false
+      end
+    end
+
+    node = snippet.inner_first:jump_into(1, true)
+    while node ~= nil and node.next ~= nil and node ~= snippet do
+      local n_next = node.next
+      local next_pos = n_next and n_next.mark:pos_begin()
+      local candidate = n_next ~= snippet and next_pos and (pos[1] < next_pos[1])
+        or (pos[1] == next_pos[1] and pos[2] < next_pos[2])
+
+      -- Past unmarked exit node, exit early
+      if n_next == nil or n_next == snippet.next then
+        snippet:remove_from_jumplist()
+        luasnip.session.current_nodes[get_current_buf()] = nil
+
+        return false
+      end
+
+      if candidate then
+        luasnip.session.current_nodes[get_current_buf()] = node
+        return true
+      end
+
+      local ok
+      ok, node = pcall(node.jump_from, node, 1, true) -- no_move until last stop
+      if not ok then
+        snippet:remove_from_jumplist()
+        luasnip.session.current_nodes[get_current_buf()] = nil
+
+        return false
+      end
+    end
+
+    -- No candidate, but have an exit node
+    if exit_node then
+      -- to jump to the exit node, seek to snippet
+      luasnip.session.current_nodes[get_current_buf()] = snippet
+      return true
+    end
+
+    -- No exit node, exit from snippet
+    snippet:remove_from_jumplist()
+    luasnip.session.current_nodes[get_current_buf()] = nil
+    return false
+  end
+
+  lvim.builtin.cmp = {
+    confirm_opts = {
+      behavior = cmp.ConfirmBehavior.Replace,
+      select = false,
+    },
+    experimental = {
+      ghost_text = true,
+      native_menu = false,
+    },
+    formatting = {
+      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 = " ",
+      },
+      format = function(entry, vim_item)
+        vim_item.kind = lvim.builtin.cmp.formatting.kind_icons[vim_item.kind]
+        vim_item.menu = ({
+          nvim_lsp = "(LSP)",
+          emoji = "(Emoji)",
+          path = "(Path)",
+          calc = "(Calc)",
+          cmp_tabnine = "(Tabnine)",
+          vsnip = "(Snippet)",
+          luasnip = "(Snippet)",
+          buffer = "(Buffer)",
+        })[entry.source.name]
+        vim_item.dup = ({
+          buffer = 1,
+          path = 1,
+          nvim_lsp = 0,
+        })[entry.source.name] or 0
+        return vim_item
+      end,
+    },
+    snippet = {
+      expand = function(args)
+        require("luasnip").lsp_expand(args.body)
+      end,
+    },
+    documentation = {
+      border = { "╭", "─", "╮", "│", "╯", "─", "╰", "│" },
+    },
+    sources = {
+      { name = "nvim_lsp" },
+      { name = "path" },
+      { name = "luasnip" },
+      { name = "cmp_tabnine" },
+      { name = "nvim_lua" },
+      { name = "buffer" },
+      { name = "calc" },
+      { name = "emoji" },
+      { name = "treesitter" },
+      { name = "crates" },
+    },
+    mapping = {
+      ["<C-d>"] = cmp.mapping.scroll_docs(-4),
+      ["<C-f>"] = cmp.mapping.scroll_docs(4),
+      -- TODO: potentially fix emmet nonsense
+      ["<Tab>"] = cmp.mapping(function()
+        if cmp.visible() then
+          cmp.select_next_item()
+        elseif luasnip.expandable() then
+          luasnip.expand()
+        elseif inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable() then
+          luasnip.jump(1)
+        elseif check_backspace() then
+          vim.fn.feedkeys(T "<Tab>", "n")
+        elseif is_emmet_active() then
+          return vim.fn["cmp#complete"]()
+        else
+          vim.fn.feedkeys(T "<Tab>", "n")
+        end
+      end, {
+        "i",
+        "s",
+      }),
+      ["<S-Tab>"] = cmp.mapping(function(fallback)
+        if cmp.visible() then
+          cmp.select_prev_item()
+        elseif inside_snippet() and luasnip.jumpable(-1) then
+          luasnip.jump(-1)
+        else
+          fallback()
+        end
+      end, {
+        "i",
+        "s",
+      }),
+
+      ["<C-Space>"] = cmp.mapping.complete(),
+      ["<C-e>"] = cmp.mapping.close(),
+      ["<CR>"] = cmp.mapping(function(fallback)
+        if cmp.visible() and cmp.confirm(lvim.builtin.cmp.confirm_opts) then
+          return
+        end
+
+        if inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable() then
+          if not luasnip.jump(1) then
+            fallback()
+          end
+        else
+          fallback()
+        end
+      end),
+    },
+  }
+end
+
+M.setup = function()
+  require("luasnip/loaders/from_vscode").lazy_load()
+  require("cmp").setup(lvim.builtin.cmp)
+end
+
+return M

+ 3 - 1
lua/core/commands.lua

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

+ 0 - 133
lua/core/compe.lua

@@ -1,133 +0,0 @@
-local M = {}
-
-M.config = function()
-  lvim.builtin.compe = {
-    active = true,
-    on_config_done = nil,
-    autocomplete = true,
-    debug = false,
-    min_length = 1,
-    preselect = "enable",
-    throttle_time = 80,
-    source_timeout = 200,
-    incomplete_delay = 400,
-    max_abbr_width = 100,
-    max_kind_width = 100,
-    max_menu_width = 100,
-    documentation = {
-      border = "single",
-      winhighlight = "NormalFloat:CompeDocumentation,FloatBorder:CompeDocumentationBorder",
-      max_width = 120,
-      min_width = 60,
-      max_height = math.floor(vim.o.lines * 0.3),
-      min_height = 1,
-    },
-    -- documentation = true,
-
-    source = {
-      path = { kind = "   (Path)" },
-      buffer = { kind = "   (Buffer)" },
-      calc = { kind = "   (Calc)" },
-      vsnip = { kind = "   (Snippet)" },
-      nvim_lsp = { kind = "   (LSP)" },
-      nvim_lua = false,
-      spell = { kind = "   (Spell)" },
-      tags = false,
-      vim_dadbod_completion = false,
-      snippets_nvim = false,
-      ultisnips = false,
-      treesitter = false,
-      emoji = { kind = " ﲃ  (Emoji)", filetypes = { "markdown", "text" } },
-      -- for emoji press : (idk if that in compe tho)
-    },
-
-    keymap = {
-      values = {
-        insert_mode = {
-          -- ["<Tab>"] = { 'pumvisible() ? "<C-n>" : "<Tab>"', { silent = true, noremap = true, expr = true } },
-          -- ["<S-Tab>"] = { 'pumvisible() ? "<C-p>" : "<S-Tab>"', { silent = true, noremap = true, expr = true } },
-          ["<C-Space>"] = { "compe#complete()", { silent = true, noremap = true, expr = true } },
-          ["<C-e>"] = { "compe#close('<C-e>')", { silent = true, noremap = true, expr = true } },
-          ["<C-f>"] = { "compe#scroll({ 'delta': +4 })", { silent = true, noremap = true, expr = true } },
-          ["<C-d>"] = { "compe#scroll({ 'delta': -4 })", { silent = true, noremap = true, expr = true } },
-        },
-      },
-      opts = {
-        insert_mode = { noremap = true, silent = true, expr = true },
-      },
-    },
-  }
-end
-
-M.setup = function()
-  vim.g.vsnip_snippet_dir = lvim.vsnip_dir
-
-  local compe = require "compe"
-
-  compe.setup(lvim.builtin.compe)
-
-  local t = function(str)
-    return vim.api.nvim_replace_termcodes(str, true, true, true)
-  end
-
-  local check_back_space = function()
-    local col = vim.fn.col "." - 1
-    if col == 0 or vim.fn.getline("."):sub(col, col):match "%s" then
-      return true
-    else
-      return false
-    end
-  end
-
-  local is_emmet_active = function()
-    local clients = vim.lsp.buf_get_clients()
-
-    for _, client in pairs(clients) do
-      if client.name == "emmet_ls" then
-        return true
-      end
-    end
-    return false
-  end
-
-  -- Use (s-)tab to:
-  --- move to prev/next item in completion menuone
-  --- jump to prev/next snippet's placeholder
-  _G.tab_complete = function()
-    if vim.fn.pumvisible() == 1 then
-      return t "<C-n>"
-    elseif vim.fn.call("vsnip#jumpable", { 1 }) == 1 then
-      return t "<Plug>(vsnip-jump-next)"
-    elseif check_back_space() then
-      return t "<Tab>"
-    elseif is_emmet_active() then
-      return vim.fn["compe#complete"]()
-    else
-      return t "<Tab>"
-    end
-  end
-
-  _G.s_tab_complete = function()
-    if vim.fn.pumvisible() == 1 then
-      return t "<C-p>"
-    elseif vim.fn.call("vsnip#jumpable", { -1 }) == 1 then
-      return t "<Plug>(vsnip-jump-prev)"
-    else
-      return t "<S-Tab>"
-    end
-  end
-
-  local keymap = require "keymappings"
-  keymap.load(lvim.builtin.compe.keymap.values, lvim.builtin.compe.keymap.opts)
-
-  vim.api.nvim_set_keymap("i", "<Tab>", "v:lua.tab_complete()", { expr = true })
-  vim.api.nvim_set_keymap("s", "<Tab>", "v:lua.tab_complete()", { expr = true })
-  vim.api.nvim_set_keymap("i", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true })
-  vim.api.nvim_set_keymap("s", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true })
-
-  if lvim.builtin.compe.on_config_done then
-    lvim.builtin.compe.on_config_done(compe)
-  end
-end
-
-return M

+ 15 - 0
lua/core/dap.lua

@@ -10,6 +10,18 @@ M.config = function()
       linehl = "",
       numhl = "",
     },
+    breakpoint_rejected = {
+      text = "",
+      texthl = "LspDiagnosticsSignHint",
+      linehl = "",
+      numhl = "",
+    },
+    stopped = {
+      text = "",
+      texthl = "LspDiagnosticsSignInformation",
+      linehl = "DiagnosticUnderlineInfo",
+      numhl = "LspDiagnosticsSignInformation",
+    },
   }
 end
 
@@ -17,6 +29,9 @@ M.setup = function()
   local dap = require "dap"
 
   vim.fn.sign_define("DapBreakpoint", lvim.builtin.dap.breakpoint)
+  vim.fn.sign_define("DapBreakpointRejected", lvim.builtin.dap.breakpoint_rejected)
+  vim.fn.sign_define("DapStopped", lvim.builtin.dap.stopped)
+
   dap.defaults.fallback.terminal_win_cmd = "50vsplit new"
 
   lvim.builtin.which_key.mappings["d"] = {

+ 18 - 9
lua/core/dashboard.lua

@@ -1,5 +1,5 @@
 local M = {}
-local home_dir = vim.loop.os_homedir()
+local utils = require "utils"
 
 M.config = function(config)
   lvim.builtin.dashboard = {
@@ -7,7 +7,7 @@ M.config = function(config)
     on_config_done = nil,
     search_handler = "telescope",
     disable_at_vim_enter = 0,
-    session_directory = home_dir .. "/.cache/lvim/sessions",
+    session_directory = utils.join_paths(get_cache_dir(), "sessions"),
     custom_header = {
       "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣀⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
       "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣶⣾⠿⠿⠟⠛⠛⠛⠛⠿⠿⣿⣷⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
@@ -69,14 +69,23 @@ M.setup = function()
 
   vim.g.dashboard_session_directory = lvim.builtin.dashboard.session_directory
 
-  vim.cmd "let packages = len(globpath('~/.local/share/lunarvim/site/pack/packer/start', '*', 0, 1))"
+  local lvim_site = "lunarvim.org"
+  local lvim_version = get_version "short"
+  local num_plugins_loaded = #vim.fn.globpath(get_runtime_dir() .. "/site/pack/packer/start", "*", 0, 1)
 
-  vim.api.nvim_exec(
-    [[
-    let g:dashboard_custom_footer = ['LunarVim loaded '..packages..' plugins  ']
-]],
-    false
-  )
+  local footer = {
+    "LunarVim loaded " .. num_plugins_loaded .. " plugins ",
+    "",
+    lvim_site,
+  }
+
+  if lvim_version then
+    table.insert(footer, 2, "")
+    table.insert(footer, 3, "v" .. lvim_version)
+  end
+
+  local text = require "interface.text"
+  vim.g.dashboard_custom_footer = text.align_center({ width = 0 }, footer, 0.49) -- Use 0.49 as  counts for 2 characters
 
   require("core.autocmds").define_augroups {
     _dashboard = {

+ 1 - 1
lua/core/gitsigns.lua

@@ -44,7 +44,7 @@ M.config = function()
         noremap = true,
         buffer = true,
       },
-      watch_index = { interval = 1000 },
+      watch_gitdir = { interval = 1000 },
       sign_priority = 6,
       update_debounce = 200,
       status_formatter = nil, -- Use default

+ 40 - 51
lua/core/info.lua

@@ -10,6 +10,8 @@ local M = {
 }
 
 local fmt = string.format
+local text = require "interface.text"
+local lsp_utils = require "lsp.utils"
 
 local function str_list(list)
   return fmt("[ %s ]", table.concat(list, ", "))
@@ -65,44 +67,54 @@ local function tbl_set_highlight(terms, highlight_group)
   end
 end
 
-function M.toggle_popup(ft)
-  local lsp_utils = require "lsp.utils"
-  local client = lsp_utils.get_active_client_by_ft(ft)
-  local is_client_active = false
-  local client_enabled_caps = {}
-  local client_name = ""
-  local client_id = 0
-  local document_formatting = false
-  if client ~= nil then
-    is_client_active = not client.is_stopped()
-    client_enabled_caps = require("lsp").get_ls_capabilities(client.id)
-    client_name = client.name
-    client_id = client.id
-    document_formatting = client.resolved_capabilities.document_formatting
+local function make_client_info(client)
+  local client_enabled_caps = lsp_utils.get_client_capabilities(client.id)
+  local name = client.name
+  local id = client.id
+  local document_formatting = client.resolved_capabilities.document_formatting
+  local client_info = {
+    fmt("* Name:                 %s", name),
+    fmt("* Id:                   %s", tostring(id)),
+    fmt("* Supports formatting:  %s", tostring(document_formatting)),
+  }
+  if not vim.tbl_isempty(client_enabled_caps) then
+    local caps_text = "* Capabilities list:    "
+    local caps_text_len = caps_text:len()
+    local enabled_caps = text.format_table(client_enabled_caps, 3, " | ")
+    enabled_caps = text.shift_right(enabled_caps, caps_text_len)
+    enabled_caps[1] = fmt("%s%s", caps_text, enabled_caps[1]:sub(caps_text_len + 1))
+    vim.list_extend(client_info, enabled_caps)
   end
 
+  return client_info
+end
+
+function M.toggle_popup(ft)
+  local clients = lsp_utils.get_active_clients_by_ft(ft)
+  local client_names = {}
+
   local header = {
     fmt("Detected filetype:      %s", ft),
     fmt("Treesitter active:      %s", tostring(next(vim.treesitter.highlighter.active) ~= nil)),
   }
 
-  local text = require "interface.text"
   local lsp_info = {
     "Language Server Protocol (LSP) info",
-    fmt("* Associated server:    %s", client_name),
-    fmt("* Active:               %s (id: %d)", tostring(is_client_active), client_id),
-    fmt("* Supports formatting:  %s", tostring(document_formatting)),
+    fmt "* Associated server(s):",
   }
-  if not vim.tbl_isempty(client_enabled_caps) then
-    local caps_text = "* Capabilities list:    "
-    local caps_text_len = caps_text:len()
-    local enabled_caps = text.format_table(client_enabled_caps, 3, " | ")
-    enabled_caps = text.shift_left(enabled_caps, caps_text_len)
-    enabled_caps[1] = fmt("%s%s", caps_text, enabled_caps[1]:sub(caps_text_len + 1))
-    vim.list_extend(lsp_info, enabled_caps)
+
+  for _, client in pairs(clients) do
+    vim.list_extend(lsp_info, make_client_info(client))
+    table.insert(client_names, client.name)
   end
-  local null_ls = require "lsp.null-ls"
-  local registered_providers = null_ls.list_supported_provider_names(ft)
+
+  local null_formatters = require "lsp.null-ls.formatters"
+  local null_linters = require "lsp.null-ls.linters"
+  local registered_formatters = null_formatters.list_supported_names(ft)
+  local registered_linters = null_linters.list_supported_names(ft)
+  local registered_providers = {}
+  vim.list_extend(registered_providers, registered_formatters)
+  vim.list_extend(registered_providers, registered_linters)
   local registered_count = vim.tbl_count(registered_providers)
   local null_ls_info = {
     "Formatters and linters",
@@ -113,24 +125,6 @@ function M.toggle_popup(ft)
     ),
   }
 
-  local null_formatters = require "lsp.null-ls.formatters"
-  local missing_formatters = null_formatters.list_unsupported_names(ft)
-  local missing_formatters_status = {}
-  if not vim.tbl_isempty(missing_formatters) then
-    missing_formatters_status = {
-      fmt("* Missing formatters:   %s", table.concat(missing_formatters, "  , ") .. "  "),
-    }
-  end
-
-  local null_linters = require "lsp.null-ls.linters"
-  local missing_linters = null_linters.list_unsupported_names(ft)
-  local missing_linters_status = {}
-  if not vim.tbl_isempty(missing_linters) then
-    missing_linters_status = {
-      fmt("* Missing linters:      %s", table.concat(missing_linters, "  , ") .. "  "),
-    }
-  end
-
   local content_provider = function(popup)
     local content = {}
 
@@ -143,8 +137,6 @@ function M.toggle_popup(ft)
       lsp_info,
       { "" },
       null_ls_info,
-      missing_formatters_status,
-      missing_linters_status,
       { "" },
       { "" },
       get_formatter_suggestion_msg(ft),
@@ -155,7 +147,7 @@ function M.toggle_popup(ft)
       vim.list_extend(content, section)
     end
 
-    return text.align(popup, content, 0.5)
+    return text.align_left(popup, content, 0.5)
   end
 
   local function set_syntax_hl()
@@ -167,11 +159,8 @@ function M.toggle_popup(ft)
     vim.cmd 'let m=matchadd("string", "true")'
     vim.cmd 'let m=matchadd("error", "false")'
     tbl_set_highlight(registered_providers, "LvimInfoIdentifier")
-    tbl_set_highlight(missing_formatters, "LvimInfoIdentifier")
-    tbl_set_highlight(missing_linters, "LvimInfoIdentifier")
     -- tbl_set_highlight(require("lsp.null-ls.formatters").list_available(ft), "LvimInfoIdentifier")
     -- tbl_set_highlight(require("lsp.null-ls.linters").list_available(ft), "LvimInfoIdentifier")
-    vim.cmd('let m=matchadd("LvimInfoIdentifier", "' .. client_name .. '")')
   end
 
   local Popup = require("interface.popup"):new {

+ 1 - 0
lua/core/log.lua

@@ -8,6 +8,7 @@ function Log:add_entry(msg, level)
   if self.__handle then
     -- plenary uses lower-case log levels
     self.__handle[level:lower()](msg)
+    return
   end
   local status_ok, plenary = pcall(require, "plenary")
   if status_ok then

+ 0 - 19
lua/core/lspinstall.lua

@@ -1,19 +0,0 @@
-local M = {}
-
-M.config = function()
-  lvim.builtin.lspinstall = {
-    active = true,
-    on_config_done = nil,
-  }
-end
-
-M.setup = function()
-  local lspinstall = require "lspinstall"
-  lspinstall.setup()
-
-  if lvim.builtin.lspinstall.on_config_done then
-    lvim.builtin.lspinstall.on_config_done(lspinstall)
-  end
-end
-
-return M

+ 29 - 27
lua/core/lualine/components.lua

@@ -17,31 +17,32 @@ return {
     function()
       return " "
     end,
-    left_padding = 0,
-    right_padding = 0,
+    padding = { left = 0, right = 0 },
     color = {},
-    condition = nil,
+    cond = nil,
   },
   branch = {
     "b:gitsigns_head",
     icon = " ",
     color = { gui = "bold" },
-    condition = conditions.hide_in_width,
+    cond = conditions.hide_in_width,
   },
   filename = {
     "filename",
     color = {},
-    condition = nil,
+    cond = nil,
   },
   diff = {
     "diff",
     source = diff_source,
     symbols = { added = "  ", modified = "柳", removed = " " },
-    color_added = { fg = colors.green },
-    color_modified = { fg = colors.yellow },
-    color_removed = { fg = colors.red },
+    diff_color = {
+      added = { fg = colors.green },
+      modified = { fg = colors.yellow },
+      removed = { fg = colors.red },
+    },
     color = {},
-    condition = nil,
+    cond = nil,
   },
   python_env = {
     function()
@@ -60,44 +61,46 @@ return {
       return ""
     end,
     color = { fg = colors.green },
-    condition = conditions.hide_in_width,
+    cond = conditions.hide_in_width,
   },
   diagnostics = {
     "diagnostics",
     sources = { "nvim_lsp" },
     symbols = { error = " ", warn = " ", info = " ", hint = " " },
     color = {},
-    condition = conditions.hide_in_width,
+    cond = conditions.hide_in_width,
   },
   treesitter = {
     function()
-      if next(vim.treesitter.highlighter.active) then
+      local b = vim.api.nvim_get_current_buf()
+      if next(vim.treesitter.highlighter.active[b]) then
         return "  "
       end
       return ""
     end,
     color = { fg = colors.green },
-    condition = conditions.hide_in_width,
+    cond = conditions.hide_in_width,
   },
   lsp = {
     function(msg)
-      msg = msg or "LSP Inactive"
+      msg = msg or "LS Inactive"
       local buf_clients = vim.lsp.buf_get_clients()
       if next(buf_clients) == nil then
+        -- TODO: clean up this if statement
+        if type(msg) == "boolean" or #msg == 0 then
+          return "LS Inactive"
+        end
         return msg
       end
       local buf_ft = vim.bo.filetype
       local buf_client_names = {}
 
       -- add client
-      local utils = require "lsp.utils"
-      local active_client = utils.get_active_client_by_ft(buf_ft)
       for _, client in pairs(buf_clients) do
         if client.name ~= "null-ls" then
           table.insert(buf_client_names, client.name)
         end
       end
-      vim.list_extend(buf_client_names, active_client or {})
 
       -- add formatter
       local formatters = require "lsp.null-ls.formatters"
@@ -113,10 +116,10 @@ return {
     end,
     icon = " ",
     color = { gui = "bold" },
-    condition = conditions.hide_in_width,
+    cond = conditions.hide_in_width,
   },
-  location = { "location", condition = conditions.hide_in_width, color = {} },
-  progress = { "progress", condition = conditions.hide_in_width, color = {} },
+  location = { "location", cond = conditions.hide_in_width, color = {} },
+  progress = { "progress", cond = conditions.hide_in_width, color = {} },
   spaces = {
     function()
       local label = "Spaces: "
@@ -125,16 +128,16 @@ return {
       end
       return label .. vim.api.nvim_buf_get_option(0, "shiftwidth") .. " "
     end,
-    condition = conditions.hide_in_width,
+    cond = conditions.hide_in_width,
     color = {},
   },
   encoding = {
     "o:encoding",
-    upper = true,
+    fmt = string.upper,
     color = {},
-    condition = conditions.hide_in_width,
+    cond = conditions.hide_in_width,
   },
-  filetype = { "filetype", condition = conditions.hide_in_width, color = {} },
+  filetype = { "filetype", cond = conditions.hide_in_width, color = {} },
   scrollbar = {
     function()
       local current_line = vim.fn.line "."
@@ -144,9 +147,8 @@ return {
       local index = math.ceil(line_ratio * #chars)
       return chars[index]
     end,
-    left_padding = 0,
-    right_padding = 0,
+    padding = { left = 0, right = 0 },
     color = { fg = colors.yellow, bg = colors.bg },
-    condition = nil,
+    cond = nil,
   },
 }

+ 6 - 6
lua/core/lualine/styles.lua

@@ -11,8 +11,8 @@ styles.none = {
   style = "none",
   options = {
     icons_enabled = true,
-    component_separators = "",
-    section_separators = "",
+    component_separators = { left = "", right = "" },
+    section_separators = { left = "", right = "" },
     disabled_filetypes = {},
   },
   sections = {
@@ -39,8 +39,8 @@ styles.default = {
   style = "default",
   options = {
     icons_enabled = true,
-    component_separators = { "", "" },
-    section_separators = { "", "" },
+    component_separators = { left = "", right = "" },
+    section_separators = { left = "", right = "" },
     disabled_filetypes = {},
   },
   sections = {
@@ -67,8 +67,8 @@ styles.lvim = {
   style = "lvim",
   options = {
     icons_enabled = true,
-    component_separators = "",
-    section_separators = "",
+    component_separators = { left = "", right = "" },
+    section_separators = { left = "", right = "" },
     disabled_filetypes = { "dashboard", "NvimTree", "Outline" },
   },
   sections = {

+ 26 - 15
lua/core/nvimtree.lua

@@ -5,8 +5,23 @@ function M.config()
   lvim.builtin.nvimtree = {
     active = true,
     on_config_done = nil,
-    side = "left",
-    width = 30,
+    setup = {
+      open_on_setup = 0,
+      auto_close = 1,
+      open_on_tab = 0,
+      update_focused_file = {
+        enable = 1,
+      },
+      lsp_diagnostics = 1,
+      view = {
+        width = 30,
+        side = "left",
+        auto_resize = false,
+        mappings = {
+          custom_only = false,
+        },
+      },
+    },
     show_icons = {
       git = 1,
       folders = 1,
@@ -15,16 +30,11 @@ function M.config()
       tree_width = 30,
     },
     ignore = { ".git", "node_modules", ".cache" },
-    auto_open = 0,
-    auto_close = 1,
     quit_on_open = 0,
-    follow = 1,
     hide_dotfiles = 1,
     git_hl = 1,
     root_folder_modifier = ":t",
-    tab_open = 0,
     allow_resize = 1,
-    lsp_diagnostics = 1,
     auto_ignore_ft = { "startify", "dashboard" },
     icons = {
       default = "",
@@ -63,17 +73,17 @@ function M.setup()
 
   -- Implicitly update nvim-tree when project module is active
   if lvim.builtin.project.active then
-    vim.g.nvim_tree_update_cwd = 1
-    vim.g.nvim_tree_respect_buf_cwd = 1
-    vim.g.nvim_tree_disable_netrw = 0
-    vim.g.nvim_tree_hijack_netrw = 0
+    lvim.builtin.nvimtree.respect_buf_cwd = 1
+    lvim.builtin.nvimtree.setup.update_cwd = 1
+    lvim.builtin.nvimtree.setup.disable_netrw = 0
+    lvim.builtin.nvimtree.setup.hijack_netrw = 0
     vim.g.netrw_banner = 0
   end
 
   local tree_cb = nvim_tree_config.nvim_tree_callback
 
-  if not g.nvim_tree_bindings then
-    g.nvim_tree_bindings = {
+  if not lvim.builtin.nvimtree.setup.view.mappings.list then
+    lvim.builtin.nvimtree.setup.view.mappings.list = {
       { key = { "l", "<CR>", "o" }, cb = tree_cb "edit" },
       { key = "h", cb = tree_cb "close_node" },
       { key = "v", cb = tree_cb "vsplit" },
@@ -96,11 +106,12 @@ function M.setup()
   if lvim.builtin.nvimtree.on_config_done then
     lvim.builtin.nvimtree.on_config_done(nvim_tree_config)
   end
+  require("nvim-tree").setup(lvim.builtin.nvimtree.setup)
 end
 
 function M.on_open()
-  if package.loaded["bufferline.state"] and lvim.builtin.nvimtree.side == "left" then
-    require("bufferline.state").set_offset(lvim.builtin.nvimtree.width + 1, "")
+  if package.loaded["bufferline.state"] and lvim.builtin.nvimtree.setup.view.side == "left" then
+    require("bufferline.state").set_offset(lvim.builtin.nvimtree.setup.view.width + 1, "")
   end
 end
 

+ 1 - 1
lua/core/project.lua

@@ -35,7 +35,7 @@ function M.config()
 
     ---@type string
     ---@usage path to store the project history for use in telescope
-    datapath = CACHE_PATH,
+    datapath = get_cache_dir(),
   }
 end
 

+ 71 - 10
lua/core/telescope.lua

@@ -1,5 +1,7 @@
 local M = {}
 
+local utils = require "utils"
+
 function M.config()
   -- Define this minimal config so that it's available if telescope is not yet available.
   lvim.builtin.telescope = {
@@ -24,7 +26,6 @@ function M.config()
       layout_strategy = "horizontal",
       layout_config = {
         width = 0.75,
-        prompt_position = "bottom",
         preview_cutoff = 120,
         horizontal = { mirror = false },
         vertical = { mirror = false },
@@ -87,16 +88,11 @@ function M.find_lunarvim_files(opts)
   opts = opts or {}
   local themes = require "telescope.themes"
   local theme_opts = themes.get_ivy {
-    previewer = false,
     sorting_strategy = "ascending",
     layout_strategy = "bottom_pane",
-    layout_config = {
-      height = 5,
-      width = 0.5,
-    },
-    prompt = ">> ",
+    prompt_prefix = ">> ",
     prompt_title = "~ LunarVim files ~",
-    cwd = CONFIG_PATH,
+    cwd = utils.join_paths(get_runtime_dir(), "lvim"),
     find_command = { "git", "ls-files" },
   }
   opts = vim.tbl_deep_extend("force", theme_opts, opts)
@@ -109,14 +105,79 @@ function M.grep_lunarvim_files(opts)
   local theme_opts = themes.get_ivy {
     sorting_strategy = "ascending",
     layout_strategy = "bottom_pane",
-    prompt = ">> ",
+    prompt_prefix = ">> ",
     prompt_title = "~ search LunarVim ~",
-    cwd = CONFIG_PATH,
+    cwd = utils.join_paths(get_runtime_dir(), "lvim"),
   }
   opts = vim.tbl_deep_extend("force", theme_opts, opts)
   require("telescope.builtin").live_grep(opts)
 end
 
+function M.view_lunarvim_changelog()
+  local finders = require "telescope.finders"
+  local make_entry = require "telescope.make_entry"
+  local pickers = require "telescope.pickers"
+  local previewers = require "telescope.previewers"
+  local actions = require "telescope.actions"
+  local opts = {}
+
+  local conf = require("telescope.config").values
+  opts.entry_maker = make_entry.gen_from_git_commits(opts)
+
+  pickers.new(opts, {
+    prompt_title = "LunarVim changelog",
+
+    finder = finders.new_oneshot_job(
+      vim.tbl_flatten {
+        "git",
+        "log",
+        "--pretty=oneline",
+        "--abbrev-commit",
+        "--",
+        ".",
+      },
+      opts
+    ),
+    previewer = {
+      previewers.git_commit_diff_to_parent.new(opts),
+      previewers.git_commit_diff_to_head.new(opts),
+      previewers.git_commit_diff_as_was.new(opts),
+      previewers.git_commit_message.new(opts),
+    },
+
+    --TODO: consider opening a diff view when pressing enter
+    attach_mappings = function(_, map)
+      map("i", "<enter>", actions._close)
+      map("n", "<enter>", actions._close)
+      map("i", "<esc>", actions._close)
+      map("n", "<esc>", actions._close)
+      map("n", "q", actions._close)
+      return true
+    end,
+    sorter = conf.file_sorter(opts),
+  }):find()
+end
+
+function M.code_actions()
+  local opts = {
+    winblend = 15,
+    layout_config = {
+      prompt_position = "top",
+      width = 80,
+      height = 12,
+    },
+    borderchars = {
+      prompt = { "─", "│", " ", "│", "╭", "╮", "│", "│" },
+      results = { "─", "│", "─", "│", "├", "┤", "╯", "╰" },
+      preview = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" },
+    },
+    border = {},
+    previewer = false,
+    shorten_path = false,
+  }
+  require("telescope.builtin").lsp_code_actions(require("telescope.themes").get_dropdown(opts))
+end
+
 function M.setup()
   local telescope = require "telescope"
 

+ 8 - 23
lua/core/terminal.lua

@@ -1,5 +1,5 @@
 local M = {}
-local utils = require "utils"
+local Log = require "core.log"
 
 M.config = function()
   lvim.builtin["terminal"] = {
@@ -81,7 +81,6 @@ end
 M._exec_toggle = function(exec)
   local binary = M._split(exec)[1]
   if vim.fn.executable(binary) ~= 1 then
-    local Log = require "core.log"
     Log:error("Unable to run executable " .. binary .. ". Please make sure it is installed properly.")
     return
   end
@@ -90,29 +89,16 @@ M._exec_toggle = function(exec)
   exec_term:toggle()
 end
 
-local function get_log_path(name)
-  --handle custom paths not managed by Plenary.log
-  local logger = require "core.log"
-  local file
-  if name == "nvim" then
-    file = CACHE_PATH .. "/log"
-  else
-    file = logger:new({ plugin = name }):get_path()
-  end
-  if utils.is_file(file) then
-    return file
-  end
-end
-
 ---Toggles a log viewer according to log.viewer.layout_config
----@param name can be the name of any of the managed logs, e,g. "lunarvim" or the default ones {"nvim", "lsp", "packer.nvim"}
-M.toggle_log_view = function(name)
-  local logfile = get_log_path(name)
-  if not logfile then
-    return
+---@param logfile string the fullpath to the logfile
+M.toggle_log_view = function(logfile)
+  local log_viewer = lvim.log.viewer.cmd
+  if vim.fn.executable(log_viewer) ~= 1 then
+    log_viewer = "less +F"
   end
+  log_viewer = log_viewer .. " " .. logfile
   local term_opts = vim.tbl_deep_extend("force", lvim.builtin.terminal, {
-    cmd = lvim.log.viewer.cmd .. " " .. logfile,
+    cmd = log_viewer,
     open_mapping = lvim.log.viewer.layout_config.open_mapping,
     direction = lvim.log.viewer.layout_config.direction,
     -- TODO: this might not be working as expected
@@ -122,7 +108,6 @@ M.toggle_log_view = function(name)
 
   local Terminal = require("toggleterm.terminal").Terminal
   local log_view = Terminal:new(term_opts)
-  -- require("core.log"):debug("term", vim.inspect(term_opts))
   log_view:toggle()
 end
 

Некоторые файлы не были показаны из-за большого количества измененных файлов