Browse Source

Merge branch 'rolling' of github.com:ChristianChiarulli/LunarVim

christianchiarulli 3 years ago
parent
commit
83013c0d4f
58 changed files with 1927 additions and 852 deletions
  1. 2 2
      .github/ISSUE_TEMPLATE/lsp-issue-form.yaml
  2. 2 1
      .github/workflows/install.yaml
  3. 19 19
      .luacheckrc
  4. 3 3
      CONTRIBUTING.md
  5. 59 33
      README.md
  6. 1 0
      ftdetect/plaintex.lua
  7. 1 1
      ftplugin/elixir.lua
  8. 1 1
      ftplugin/euphoria3.lua
  9. 1 0
      ftplugin/gdscript.lua
  10. 1 0
      ftplugin/haskell.lua
  11. 3 0
      ftplugin/ps1.lua
  12. 1 0
      ftplugin/toml.lua
  13. 26 6
      init.lua
  14. 11 5
      lua/core/autocmds.lua
  15. 4 1
      lua/core/autopairs.lua
  16. 20 2
      lua/core/bufferline.lua
  17. 2 0
      lua/core/commands.lua
  18. 37 28
      lua/core/compe.lua
  19. 3 1
      lua/core/dap.lua
  20. 4 5
      lua/core/dashboard.lua
  21. 6 6
      lua/core/galaxyline.lua
  22. 2 1
      lua/core/gitsigns.lua
  23. 222 0
      lua/core/info.lua
  24. 29 0
      lua/core/log.lua
  25. 47 7
      lua/core/nvimtree.lua
  26. 15 0
      lua/core/rooter.lua
  27. 6 4
      lua/core/telescope.lua
  28. 46 4
      lua/core/terminal.lua
  29. 2 0
      lua/core/treesitter.lua
  30. 36 4
      lua/core/which-key.lua
  31. 377 161
      lua/default-config.lua
  32. 159 102
      lua/keymappings.lua
  33. 43 1
      lua/lsp/handlers.lua
  34. 125 35
      lua/lsp/init.lua
  35. 0 27
      lua/lsp/keybinds.lua
  36. 0 33
      lua/lsp/kind.lua
  37. 119 43
      lua/lsp/null-ls.lua
  38. 140 0
      lua/lsp/peek.lua
  39. 0 122
      lua/lsp/service.lua
  40. 0 20
      lua/lsp/signs.lua
  41. 8 5
      lua/plugins.lua
  42. 16 9
      lua/spacegray/LSP.lua
  43. 16 16
      lua/spacegray/Treesitter.lua
  44. 2 2
      lua/spacegray/Whichkey.lua
  45. 29 29
      lua/spacegray/highlights.lua
  46. 13 0
      lua/spacegray/init.lua
  47. 25 18
      lua/spacegray/palette.lua
  48. 47 0
      lua/utils/ft.lua
  49. 46 34
      lua/utils/init.lua
  50. 1 1
      utils/bin/lvim
  51. 11 0
      utils/docker/Dockerfile
  52. 23 0
      utils/docker/script.sh
  53. 33 19
      utils/installer/config.example-no-ts.lua
  54. 34 31
      utils/installer/config.example.lua
  55. 38 5
      utils/installer/install.sh
  56. 2 2
      utils/installer/install_stylua.sh
  57. 8 2
      utils/installer/uninstall.sh
  58. 0 1
      utils/lush-template/lua/lush_theme/lush_template.lua

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

@@ -31,9 +31,9 @@ body:
         required: true
       - label: I restarted Neovim after running :LspInstall
         required: true
-      - label: I have a valid language configuration (~/.config/nvim/ftplugin/)
+      - label: I have a valid language configuration (~/.config/lvim/ftplugin/)
         required: true
-      - label: I checked the options (~/.config/nvim/lv-config.lua)
+      - label: I checked the options (~/.config/lvim/config.lua)
         required: true
       - label: The programs specified by the config are installed
   - type: input

+ 2 - 1
.github/workflows/install.yaml

@@ -30,13 +30,14 @@ jobs:
           sudo apt-get update
           sudo apt-get install neovim -y
 
-      - name: Installl dependencies for OSX
+      - name: Install dependencies for OSX
         if: matrix.os == 'osx'
         run: |
           brew update >/dev/null
           brew install neovim
 
       - name: Install LunarVim
+        timeout-minutes: 4
         run: |
           bash ./utils/installer/install.sh --testing
 

+ 19 - 19
.luacheckrc

@@ -1,31 +1,31 @@
 -- vim: ft=lua tw=80
 
 stds.nvim = {
-	globals = {
-		"lvim",
-		vim = { fields = { "g" } },
-		"CONFIG_PATH",
-		"CACHE_PATH",
-		"DATA_PATH",
-		"TERMINAL",
-		"USER",
+  globals = {
+    "lvim",
+    vim = { fields = { "g" } },
+    "CONFIG_PATH",
+    "CACHE_PATH",
+    "DATA_PATH",
+    "TERMINAL",
+    "USER",
     "C",
     "Config",
     "WORKSPACE_PATH",
     "JAVA_LS_EXECUTABLE",
     "MUtils",
-    os = {fields = {"capture"}}
-	},
-	read_globals = {
-		"jit",
-		"os",
-		"vim",
-		-- vim = { fields = { "cmd", "api", "fn", "o" } },
-	},
+    "USER_CONFIG_PATH",
+    os = { fields = { "capture" } },
+  },
+  read_globals = {
+    "jit",
+    "os",
+    "vim",
+    -- vim = { fields = { "cmd", "api", "fn", "o" } },
+  },
 }
 std = "lua51+nvim"
 
-
 -- Don't report unused self arguments of methods.
 self = false
 
@@ -33,6 +33,6 @@ self = false
 cache = true
 
 ignore = {
-	"631", -- max_line_length
-	"212/_.*", -- unused argument, for vars with "_" prefix
+  "631", -- max_line_length
+  "212/_.*", -- unused argument, for vars with "_" prefix
 }

+ 3 - 3
CONTRIBUTING.md

@@ -1,6 +1,6 @@
 # Contributing to LunarVim
 
-Welcome to the LunarVim contributing guide. We are excited about the prospect of you joining our [community](https://github.com/ChristianChiarulli/LunarVim/graphs/contributors)!
+Welcome to the LunarVim contributing guide. We are excited about the prospect of you joining our [community](https://github.com/lunarvim/LunarVim/graphs/contributors)!
 
 There are many opportunities to contributing to the project at any level. Every contribution is highly valued and no contribution is too small.
 
@@ -11,8 +11,8 @@ 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/ChristianChiarulli/LunarVim/wiki/Installation) guide
-3. Link your fork with the repository `git remote add upstream https://github.com/ChristianChiarulli/LunarVim.git`
+2. Follow the [Installation](https://github.com/lunarvim/LunarVim/wiki/Installation) 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.
 
 ## Setting up development tools

+ 59 - 33
README.md

@@ -1,14 +1,14 @@
 ![LunarVim Demo](./utils/media/lunarvim_logo_dark.png)
 
 <div align="center"><p>
-    <a href="https://github.com/ChristianChiarulli/LunarVim/releases/latest">
-      <img alt="Latest release" src="https://img.shields.io/github/v/release/ChristianChiarulli/LunarVim" />
+    <a href="https://github.com/lunarvim/LunarVim/releases/latest">
+      <img alt="Latest release" src="https://img.shields.io/github/v/release/lunarvim/LunarVim" />
     </a>
-    <a href="https://github.com/ChristianChiarulli/LunarVim/pulse">
-      <img alt="Last commit" src="https://img.shields.io/github/last-commit/ChristianChiarulli/LunarVim"/>
+    <a href="https://github.com/lunarvim/LunarVim/pulse">
+      <img alt="Last commit" src="https://img.shields.io/github/last-commit/lunarvim/LunarVim"/>
     </a>
-    <a href="https://github.com/ChristianChiarulli/LunarVim/blob/main/LICENSE">
-      <img src="https://img.shields.io/github/license/siduck76/NvChad?style=flat-square&logo=GNU&label=License" alt="License"
+    <a href="https://github.com/lunarvim/LunarVim/blob/main/LICENSE">
+      <img src="https://img.shields.io/github/license/lunarvim/lunarvim?style=flat-square&logo=GNU&label=License" alt="License"
     />
     <a href="https://patreon.com/chrisatmachine" title="Donate to this project using Patreon">
       <img src="https://img.shields.io/badge/patreon-donate-yellow.svg" alt="Patreon donate button" />
@@ -25,22 +25,26 @@
 Make sure you have the newest version of Neovim (0.5).
 
 ``` bash
-bash <(curl -s https://raw.githubusercontent.com/ChristianChiarulli/lunarvim/master/utils/installer/install.sh)
+bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh)
 ```
 
 ### Installing
 The following command installs LunarVim.  Change `LVBRANCH` to the branch you'd like to install.  `master` for the stable branch and `rolling` for the latest changes.
 ``` bash
-LVBRANCH=rolling bash <(curl -s https://raw.githubusercontent.com/ChristianChiarulli/lunarvim/rolling/utils/installer/install.sh)
+LVBRANCH=rolling bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/rolling/utils/installer/install.sh)
 ```
 
 ### BREAKING CHANGE on rolling and master branches
-* The latest changes to LunarVim require you to [remove it completely](https://github.com/ChristianChiarulli/LunarVim/wiki/Uninstalling-LunarVim) before upgrading
+* 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 (`lv-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.
+* 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 `lv-config.lua` have been renamed.  For details [look here](https://github.com/ChristianChiarulli/LunarVim/wiki/Breaking-changes-in-rolling)
+* 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, \
@@ -51,7 +55,7 @@ you can run the script with `--overwrite` but be warned this will remove the fol
 - `~/.local/share/lunarvim`               #Removed only on Rolling Branch
 - `~/.config/lvim`                        #Removed only on Rolling Branch
 ```bash
-curl -s https://raw.githubusercontent.com/ChristianChiarulli/lunarvim/rolling/utils/installer/install.sh | LVBRANCH=rolling bash -s -- --overwrite
+curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/rolling/utils/installer/install.sh | LVBRANCH=rolling bash -s -- --overwrite
 ```
 then run nvim and wait for treesitter to finish the installation
 
@@ -60,13 +64,13 @@ then run nvim and wait for treesitter to finish the installation
 
 Just enter `:LspInstall` followed by `<TAB>` to see your options
 
-**NOTE** I recommend installing `lua` for autocomplete in `lv-config.lua`
+**NOTE** I recommend installing `lua` for autocomplete in `config.lua`
 
-For the julia language server look [here](https://github.com/ChristianChiarulli/LunarVim/wiki/Enabling-a-language-server#julia-support)
+For the julia language server look [here](https://github.com/lunarvim/LunarVim/wiki/Enabling-a-language-server#julia-support)
 
 ## 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/lv-config.lua`) on rolling
+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
 
 Example:
 
@@ -78,8 +82,28 @@ lvim.colorscheme = "spacegray"
 
 lvim.builtin.compe.autocomplete = true
 
--- keymappings
+-- keymappings [view all the defaults by pressing <leader>Lk]
 lvim.leader = "space"
+-- add your own keymapping
+lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
+-- unmap a default keymapping
+-- lvim.keys.normal_mode["<C-Up>"] = ""
+-- edit a default keymapping
+-- lvim.keys.normal_mode["<C-q>"] = ":q<cr>"
+-- set keymap with custom opts
+-- lvim.keys.insert_mode["po"] = {'<ESC>', { noremap = true }}
+
+-- Use which-key to add extra bindings with the leader-key prefix
+-- lvim.builtin.which_key.mappings["P"] = { "<cmd>lua require'telescope'.extensions.project.project{}<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
 lvim.builtin.dashboard.active = true
@@ -90,11 +114,24 @@ lvim.builtin.treesitter.ensure_installed = "maintained"
 lvim.builtin.treesitter.ignore_install = { "haskell" }
 lvim.builtin.treesitter.highlight.enabled = true
 
-lvim.lang.python.formatter.exe = "black"
-lvim.lang.python.linters = ""
-
 lvim.lsp.diagnostics.virtual_text = false
 
+-- set a formatter if you want to override the default lsp one (if it exists)
+lvim.lang.python.formatters = {
+  {
+    exe = "black",
+    args = {}
+  }
+}
+-- set an additional linter
+lvim.lang.python.linters = {
+  {
+    exe = "flake8",
+    args = {}
+  }
+}
+
+
 -- Additional Plugins
 lvim.plugins = {
     {"lunarvim/colorschemes"},
@@ -110,17 +147,6 @@ lvim.plugins = {
 --   { "BufWinEnter", "*.lua", "setlocal ts=8 sw=8" },
 -- }
 
--- Additional Leader bindings for WhichKey
--- lvim.builtin.which_key.mappings["P"] = { "<cmd>lua require'telescope'.extensions.project.project{}<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" },
--- }
 
 ```
 
@@ -149,7 +175,7 @@ cd ~/.local/share/lunarvim/lvim && git pull
 :PackerSync
 ```
 
-To update Neovim use your package manager or [compile from source](https://github.com/ChristianChiarulli/LunarVim/wiki/Installation#get-the-latest-version-of-neovim)
+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
 
@@ -165,7 +191,7 @@ To update Neovim use your package manager or [compile from source](https://githu
     - 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 openning a filetype for the first time
+    - 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
@@ -178,7 +204,7 @@ To update Neovim use your package manager or [compile from source](https://githu
 
 - [YouTube](https://www.youtube.com/channel/UCS97tchJDq17Qms3cux8wcA)
 
-- [Wiki](https://github.com/ChristianChiarulli/LunarVim/wiki)
+- [Documentation](https://www.lunarvim.org)
 
 - [Discord](https://discord.gg/Xb9B4Ny)
 

+ 1 - 0
ftdetect/plaintex.lua

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

+ 1 - 1
ftplugin/elixir.lua

@@ -1,7 +1,7 @@
 require("lsp").setup "elixir"
 
 -- TODO: do we need this?
--- needed for the LSP to recognize elixir files (alternativly just use elixir-editors/vim-elixir)
+-- 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

+ 1 - 1
ftplugin/euphoria3.lua

@@ -1,7 +1,7 @@
 require("lsp").setup "erlang"
 
 -- TODO: do we need this?
--- needed for the LSP to recognize elixir files (alternativly just use elixir-editors/vim-elixir)
+-- 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

+ 1 - 0
ftplugin/gdscript.lua

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

+ 1 - 0
ftplugin/haskell.lua

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

+ 3 - 0
ftplugin/ps1.lua

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

+ 1 - 0
ftplugin/toml.lua

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

+ 26 - 6
init.lua

@@ -11,18 +11,36 @@ vim.cmd [[
   set runtimepath^=~/.local/share/lunarvim/lvim/after
 ]]
 -- vim.opt.rtp:append() instead of vim.cmd ?
+
+local function file_exists(name)
+  local f = io.open(name, "r")
+  if f ~= nil then
+    io.close(f)
+    return true
+  else
+    return false
+  end
+end
+
+local lvim_path = os.getenv "HOME" .. "/.config/lvim/"
+USER_CONFIG_PATH = lvim_path .. "config.lua"
+local config_exist = file_exists(USER_CONFIG_PATH)
+if not config_exist then
+  USER_CONFIG_PATH = lvim_path .. "lv-config.lua"
+  print "Rename ~/.config/lvim/lv-config.lua to config.lua"
+end
+
 require "default-config"
+local autocmds = require "core.autocmds"
 require("settings").load_options()
-local status_ok, error = pcall(vim.cmd, "luafile ~/.config/lvim/lv-config.lua")
+
+local status_ok, error = pcall(vim.cmd, "luafile " .. USER_CONFIG_PATH)
 if not status_ok then
-  print "something is wrong with your lv-config"
+  print("something is wrong with your " .. USER_CONFIG_PATH)
   print(error)
 end
 require("settings").load_commands()
-require("core.autocmds").define_augroups(lvim.autocommands)
-
-require "keymappings"
--- require("lsp").setup_default_bindings()
+autocmds.define_augroups(lvim.autocommands)
 
 local plugins = require "plugins"
 local plugin_loader = require("plugin-loader").init()
@@ -50,6 +68,8 @@ if lsp_settings_status_ok then
   }
 end
 
+require("keymappings").setup()
+
 -- TODO: these guys need to be in language files
 -- if lvim.lang.emmet.active then
 --   require "lsp.emmet-ls"

+ 11 - 5
lua/core/autocmds.lua

@@ -2,6 +2,11 @@ local autocommands = {}
 
 lvim.autocommands = {
   _general_settings = {
+    {
+      "Filetype",
+      "*",
+      "lua require('utils.ft').do_filetype(vim.fn.expand(\"<amatch>\"))",
+    },
     {
       "TextYankPost",
       "*",
@@ -27,7 +32,7 @@ lvim.autocommands = {
       "*",
       "setlocal formatoptions-=c formatoptions-=r formatoptions-=o",
     },
-    { "BufWritePost", "lv-config.lua", "lua require('utils').reload_lv_config()" },
+    { "BufWritePost", USER_CONFIG_PATH, "lua require('utils').reload_lv_config()" },
     {
       "FileType",
       "qf",
@@ -51,13 +56,14 @@ lvim.autocommands = {
   --     {'BufWinEnter', '.gmi', 'setlocal filetype=markdown'}, {'BufRead', '*.gmi', 'setlocal filetype=markdown'},
   --     {'BufNewFile', '*.gmi', 'setlocal filetype=markdown'}
   -- },
+  _git = {
+    { "FileType", "gitcommit", "setlocal wrap" },
+    { "FileType", "gitcommit", "setlocal spell" },
+  },
   _markdown = {
     { "FileType", "markdown", "setlocal wrap" },
     { "FileType", "markdown", "setlocal spell" },
   },
-  _tab_bindings = {
-    { "FileType", "*", "lua require'core.compe'.set_tab_keybindings()" },
-  },
   _buffer_bindings = {
     { "FileType", "floaterm", "nnoremap <silent> <buffer> q :q<CR>" },
   },
@@ -66,7 +72,7 @@ lvim.autocommands = {
     { "VimResized", "*", "wincmd =" },
   },
   _packer_compile = {
-    -- will cause split windows to be resized evenly if main window is resized
+    -- will run PackerCompile after writing plugins.lua
     { "BufWritePost", "plugins.lua", "PackerCompile" },
   },
   _general_lsp = {

+ 4 - 1
lua/core/autopairs.lua

@@ -1,8 +1,10 @@
 -- if not package.loaded['nvim-autopairs'] then
 --   return
 -- end
+local Log = require "core.log"
 local status_ok, _ = pcall(require, "nvim-autopairs")
 if not status_ok then
+  Log:get_default().error "Failed to load autopairs"
   return
 end
 local npairs = require "nvim-autopairs"
@@ -25,9 +27,10 @@ MUtils.completion_confirm = function()
 end
 
 if package.loaded["compe"] then
+  local map_complete_optional = vim.bo.filetype ~= "tex"
   require("nvim-autopairs.completion.compe").setup {
     map_cr = true, --  map <CR> on insert mode
-    map_complete = true, -- it will auto insert `(` after select function or method item
+    map_complete = map_complete_optional, -- it will auto insert `(` after select function or method item
   }
 end
 

+ 20 - 2
lua/core/bufferline.lua

@@ -1,2 +1,20 @@
-vim.api.nvim_set_keymap("n", "<S-l>", ":BufferNext<CR>", { noremap = true, silent = true })
-vim.api.nvim_set_keymap("n", "<S-h>", ":BufferPrevious<CR>", { noremap = true, silent = true })
+local M = {}
+
+M.config = function()
+  lvim.builtin.bufferline = {
+    active = true,
+    keymap = {
+      normal_mode = {
+        ["<S-l>"] = ":BufferNext<CR>",
+        ["<S-h>"] = ":BufferPrevious<CR>",
+      },
+    },
+  }
+end
+
+M.setup = function()
+  local keymap = require "keymappings"
+  keymap.append_to_defaults(lvim.builtin.bufferline.keymap)
+end
+
+return M

+ 2 - 0
lua/core/commands.lua

@@ -10,6 +10,8 @@ M.defaults = {
     endif
   endfunction
   ]],
+  -- :LvimInfo
+  [[command! LvimInfo lua require('core.info').toggle_popup(vim.bo.filetype)]],
 }
 
 M.load = function(commands)

+ 37 - 28
lua/core/compe.lua

@@ -1,4 +1,5 @@
 local M = {}
+local Log = require "core.log"
 M.config = function()
   lvim.builtin.compe = {
     enabled = true,
@@ -12,7 +13,15 @@ M.config = function()
     max_abbr_width = 100,
     max_kind_width = 100,
     max_menu_width = 100,
-    documentation = true,
+    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)" },
@@ -30,8 +39,22 @@ M.config = function()
       emoji = { kind = " ﲃ  (Emoji)", filetypes = { "markdown", "text" } },
       -- for emoji press : (idk if that in compe tho)
     },
-    -- FileTypes in this list won't trigger auto-complete when TAB is pressed.  Hitting TAB will insert a tab character
-    exclude_filetypes = { "md", "markdown", "mdown", "mkd", "mkdn", "mdwn", "text", "txt" },
+
+    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
 
@@ -40,6 +63,7 @@ M.setup = function()
 
   local status_ok, compe = pcall(require, "compe")
   if not status_ok then
+    Log:get_default().error "Failed to load compe"
     return
   end
 
@@ -64,12 +88,13 @@ M.setup = function()
   _G.tab_complete = function()
     if vim.fn.pumvisible() == 1 then
       return t "<C-n>"
-    elseif vim.fn.call("vsnip#available", { 1 }) == 1 then
-      return t "<Plug>(vsnip-expand-or-jump)"
+    elseif vim.fn.call("vsnip#jumpable", { 1 }) == 1 then
+      return t "<Plug>(vsnip-jump-next)"
     elseif check_back_space() then
       return t "<Tab>"
     else
-      return vim.fn["compe#complete"]()
+      -- return vim.fn["compe#complete"]() -- < use this if you want <tab> to always offer completion
+      return t "<Tab>"
     end
   end
 
@@ -83,29 +108,13 @@ M.setup = function()
     end
   end
 
-  vim.api.nvim_set_keymap("i", "<C-Space>", "compe#complete()", { noremap = true, silent = true, expr = true })
-  -- vim.api.nvim_set_keymap("i", "<CR>", "compe#confirm('<CR>')", { noremap = true, silent = true, expr = true })
-  vim.api.nvim_set_keymap("i", "<C-e>", "compe#close('<C-e>')", { noremap = true, silent = true, expr = true })
-  vim.api.nvim_set_keymap("i", "<C-f>", "compe#scroll({ 'delta': +4 })", { noremap = true, silent = true, expr = true })
-  vim.api.nvim_set_keymap("i", "<C-d>", "compe#scroll({ 'delta': -4 })", { noremap = true, silent = true, expr = true })
-end
+  local keymap = require "keymappings"
+  keymap.load(lvim.builtin.compe.keymap.values, lvim.builtin.compe.keymap.opts)
 
-local is_excluded = function(file_type)
-  for _, type in ipairs(lvim.builtin.compe.exclude_filetypes) do
-    if type == file_type then
-      return true
-    end
-  end
-  return false
+  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 })
 end
 
-M.set_tab_keybindings = function()
-  local file_type = vim.fn.expand "%:e"
-  if is_excluded(file_type) == false then
-    vim.api.nvim_buf_set_keymap(0, "i", "<Tab>", "v:lua.tab_complete()", { expr = true })
-    vim.api.nvim_buf_set_keymap(0, "s", "<Tab>", "v:lua.tab_complete()", { expr = true })
-    vim.api.nvim_buf_set_keymap(0, "i", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true })
-    vim.api.nvim_buf_set_keymap(0, "s", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true })
-  end
-end
 return M

+ 3 - 1
lua/core/dap.lua

@@ -1,4 +1,5 @@
 local M = {}
+local Log = require "core.log"
 M.config = function()
   lvim.builtin.dap = {
     active = false,
@@ -14,6 +15,7 @@ end
 M.setup = function()
   local status_ok, dap = pcall(require, "dap")
   if not status_ok then
+    Log:get_default().error "Failed to load dap"
     return
   end
 
@@ -34,7 +36,7 @@ M.setup = function()
     p = { "<cmd>lua require'dap'.pause.toggle()<cr>", "Pause" },
     r = { "<cmd>lua require'dap'.repl.toggle()<cr>", "Toggle Repl" },
     s = { "<cmd>lua require'dap'.continue()<cr>", "Start" },
-    q = { "<cmd>lua require'dap'.stop()<cr>", "Quit" },
+    q = { "<cmd>lua require'dap'.close()<cr>", "Quit" },
   }
 end
 

+ 4 - 5
lua/core/dashboard.lua

@@ -43,12 +43,11 @@ M.config = function()
       },
       d = {
         description = { "  Settings           " },
-        -- command = ":e " .. CONFIG_PATH .. "/lv-config.lua",
-        command = ":e ~/.config/lvim/lv-config.lua",
+        command = ":e " .. USER_CONFIG_PATH,
       },
     },
 
-    footer = { "chrisatmachine.com" },
+    footer = { "lunarvim.org" },
   }
 end
 
@@ -73,7 +72,7 @@ M.setup = function()
 
   vim.api.nvim_exec(
     [[
-    let g:dashboard_custom_footer = ['LunarVim loaded '..packages..' plugins ']
+    let g:dashboard_custom_footer = ['LunarVim loaded '..packages..' plugins  ']
 ]],
     false
   )
@@ -85,7 +84,7 @@ M.setup = function()
 
   require("core.autocmds").define_augroups {
     _dashboard = {
-      -- seems to be nobuflisted that makes my stuff disapear will do more testing
+      -- seems to be nobuflisted that makes my stuff disappear will do more testing
       {
         "FileType",
         "dashboard",

+ 6 - 6
lua/core/galaxyline.lua

@@ -1,8 +1,10 @@
 -- if not package.loaded['galaxyline'] then
 --   return
 -- end
+local Log = require "core.log"
 local status_ok, gl = pcall(require, "galaxyline")
 if not status_ok then
+  Log:get_default().error "Failed to load galaxyline"
   return
 end
 
@@ -202,21 +204,19 @@ table.insert(gls.right, {
 
 local function get_attached_provider_name(msg)
   msg = msg or "LSP Inactive"
-
-  local buf_ft = vim.bo.filetype
   local buf_clients = vim.lsp.buf_get_clients()
   if next(buf_clients) == nil then
     return msg
   end
+  local buf_ft = vim.bo.filetype
   local buf_client_names = {}
+  local null_ls_providers = require("lsp.null-ls").get_registered_providers_by_filetype(buf_ft)
   for _, client in pairs(buf_clients) do
-    if client.name == "null-ls" then
-      table.insert(buf_client_names, lvim.lang[buf_ft].linters[1])
-      table.insert(buf_client_names, lvim.lang[buf_ft].formatter.exe)
-    else
+    if client.name ~= "null-ls" then
       table.insert(buf_client_names, client.name)
     end
   end
+  vim.list_extend(buf_client_names, null_ls_providers)
   return table.concat(buf_client_names, ", ")
 end
 

+ 2 - 1
lua/core/gitsigns.lua

@@ -1,4 +1,5 @@
 local M = {}
+local Log = require "core.log"
 M.config = function()
   lvim.builtin.gitsigns = {
     signs = {
@@ -44,13 +45,13 @@ M.config = function()
     sign_priority = 6,
     update_debounce = 200,
     status_formatter = nil, -- Use default
-    use_decoration_api = false,
   }
 end
 
 M.setup = function()
   local status_ok, gitsigns = pcall(require, "gitsigns")
   if not status_ok then
+    Log:get_default().error "Failed to load gitsigns"
     return
   end
   gitsigns.setup(lvim.builtin.gitsigns)

+ 222 - 0
lua/core/info.lua

@@ -0,0 +1,222 @@
+local M = {}
+local u = require "utils"
+local null_ls_handler = require "lsp.null-ls"
+local indent = "  "
+
+M.banner = {
+  " ",
+  indent
+    .. "⠀⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀   ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀  ⠀⠀     ⠀⠀⠀   ⠀⠀ ⣺⡿⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀",
+  indent
+    .. "⠀⣿⠇⠀⠀⠀⠀⠀⣤⡄⠀⠀⢠⣤⡄⠀.⣠⣤⣤⣤⡀⠀⠀⢀⣤⣤⣤⣤⡄⠀⠀⠀⣤⣄⣤⣤⣤⠀⠀ ⣿⣯  ⣿⡟⠀   ⣤⣤⠀⠀⠀⠀⣠⣤⣤⣤⣄⣤⣤",
+  indent
+    .. "⢠⣿⠀⠀⠀⠀⠀⠀⣿⠃⠀⠀⣸⣿⠁⠀⣿⣿⠉⠀⠈⣿⡇⠀⠀⠛⠋⠀⠀⢹⣿⠀⠀⠀⣿⠏⠀⠸⠿⠃⠀⣿⣿⠀⣰⡟⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⣿⡟⢸⣿⡇⢀⣿",
+  indent
+    .. "⣸⡇⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⣿⡟⠀⢠⣿⡇⠀⠀⢰⣿⡇⠀⣰⣾⠟⠛⠛⣻⡇⠀⠀⢸⡿⠀⠀⠀⠀⠀⠀⢻⣿⢰⣿⠀⠀⠀⠀⠀⠀⣾⡇⠀⠀⠀⢸⣿⠇⢸⣿⠀⢸⡏",
+  indent
+    .. "⣿⣧⣤⣤⣤⡄⠀⠘⣿⣤⣤⡤⣿⠇⠀⢸⣿⠁⠀⠀⣼⣿⠀⠀⢿⣿⣤⣤⠔⣿⠃⠀⠀⣾⡇⠀⠀⠀⠀⠀⠀⢸⣿⣿⠋⠀⠀⠀⢠⣤⣤⣿⣥⣤⡄⠀⣼⣿⠀⣸⡏⠀⣿⠃",
+  indent
+    .. "⠉⠉⠉⠉⠉⠁⠀⠀⠈⠉⠉⠀⠉⠀⠀⠈⠉⠀⠀⠀⠉⠉⠀⠀⠀⠉⠉⠁⠈⠉⠀⠀⠀⠉⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠀⠀⠀⠀⠈⠉⠉⠉⠉⠉⠁⠀⠉⠁⠀⠉⠁⠀⠉⠀",
+  "",
+}
+
+local function str_list(list)
+  return "[ " .. table.concat(list, ", ") .. " ]"
+end
+
+local function get_formatter_suggestion_msg(ft)
+  local supported_formatters = u.get_supported_formatters_by_filetype(ft)
+  return {
+    indent
+      .. "───────────────────────────────────────────────────────────────────",
+    "",
+    indent .. " HINT ",
+    "",
+    indent .. "* List of supported formatters: " .. str_list(supported_formatters),
+    indent .. "* Configured formatter needs to be installed and executable.",
+    indent .. "* Enable installed formatter(s) with following config in ~/.config/lvim/config.lua",
+    "",
+    indent .. "  lvim.lang." .. tostring(ft) .. [[.formatting = { { exe = ']] .. table.concat(
+      supported_formatters,
+      "│"
+    ) .. [[' } }]],
+    "",
+  }
+end
+
+local function get_linter_suggestion_msg(ft)
+  local supported_linters = u.get_supported_linters_by_filetype(ft)
+  return {
+    indent
+      .. "───────────────────────────────────────────────────────────────────",
+    "",
+    indent .. " HINT ",
+    "",
+    indent .. "* List of supported linters: " .. str_list(supported_linters),
+    indent .. "* Configured linter needs to be installed and executable.",
+    indent .. "* Enable installed linter(s) with following config in ~/.config/lvim/config.lua",
+    "",
+    indent
+      .. "  lvim.lang."
+      .. tostring(ft)
+      .. [[.linters = { { exe = ']]
+      .. table.concat(supported_linters, "│")
+      .. [[' } }]],
+    "",
+  }
+end
+
+---creates an average size popup
+---@param buf_lines a list of lines to print
+---@param callback could be used to set syntax highlighting rules for example
+---@return bufnr buffer number of the created buffer
+---@return win_id window ID of the created popup
+function M.create_simple_popup(buf_lines, callback)
+  -- runtime/lua/vim/lsp/util.lua
+  local bufnr = vim.api.nvim_create_buf(false, true)
+  local height_percentage = 0.9
+  local width_percentage = 0.8
+  local row_start_percentage = (1 - height_percentage) / 2
+  local col_start_percentage = (1 - width_percentage) / 2
+  local opts = {}
+  opts.relative = "editor"
+  opts.height = math.min(math.ceil(vim.o.lines * height_percentage), #buf_lines)
+  opts.row = math.ceil(vim.o.lines * row_start_percentage)
+  opts.col = math.floor(vim.o.columns * col_start_percentage)
+  opts.width = math.floor(vim.o.columns * width_percentage)
+  opts.style = "minimal"
+  opts.border = "rounded"
+  --[[
+  opts.border = {
+    lvim.builtin.telescope.defaults.borderchars[5], -- "┌",
+    lvim.builtin.telescope.defaults.borderchars[3], -- "-",
+    lvim.builtin.telescope.defaults.borderchars[6], -- "┐",
+    lvim.builtin.telescope.defaults.borderchars[2], -- "|",
+    lvim.builtin.telescope.defaults.borderchars[7], -- "┘",
+    lvim.builtin.telescope.defaults.borderchars[3], -- "-",
+    lvim.builtin.telescope.defaults.borderchars[8], -- "└",
+    lvim.builtin.telescope.defaults.borderchars[4], -- "|",
+  }
+  --]]
+
+  local win_id = vim.api.nvim_open_win(bufnr, true, opts)
+
+  vim.api.nvim_win_set_buf(win_id, bufnr)
+  -- this needs to be window option!
+  vim.api.nvim_win_set_option(win_id, "number", false)
+  vim.cmd "setlocal nocursorcolumn"
+  vim.cmd "setlocal wrap"
+  -- set buffer options
+  vim.api.nvim_buf_set_option(bufnr, "filetype", "lspinfo")
+  vim.lsp.util.close_preview_autocmd({ "BufHidden", "BufLeave" }, win_id)
+  buf_lines = vim.lsp.util._trim(buf_lines, {})
+  vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, buf_lines)
+  vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
+  if type(callback) == "function" then
+    callback()
+  end
+  return bufnr, win_id
+end
+
+local function tbl_set_highlight(terms, highlight_group)
+  if type(terms) ~= "table" then
+    return
+  end
+
+  for _, v in pairs(terms) do
+    vim.cmd('let m=matchadd("' .. highlight_group .. '", "' .. v .. '")')
+  end
+end
+
+function M.toggle_popup(ft)
+  local client = u.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
+  local missing_linters = {}
+  local missing_formatters = {}
+  local num_caps = 0
+  local null_ls_providers = null_ls_handler.get_registered_providers_by_filetype(ft)
+  if client ~= nil then
+    is_client_active = not client.is_stopped()
+    client_enabled_caps = require("lsp").get_ls_capabilities(client.id)
+    num_caps = vim.tbl_count(client_enabled_caps)
+    client_name = client.name
+    client_id = client.id
+    document_formatting = client.resolved_capabilities.document_formatting
+  end
+  if lvim.lang[ft] ~= nil then
+    missing_linters = lvim.lang[ft].linters._failed_requests or {}
+    missing_formatters = lvim.lang[ft].formatters._failed_requests or {}
+  end
+
+  local buf_lines = {}
+  vim.list_extend(buf_lines, M.banner)
+
+  local header = {
+    indent .. "Detected filetype:     " .. tostring(ft),
+    indent .. "Treesitter active:     " .. tostring(next(vim.treesitter.highlighter.active) ~= nil),
+    "",
+  }
+  vim.list_extend(buf_lines, header)
+
+  local lsp_info = {
+    indent .. "Language Server Protocol (LSP) info",
+    indent .. "* Associated server:   " .. client_name,
+    indent .. "* Active:              " .. tostring(is_client_active) .. " (id: " .. tostring(client_id) .. ")",
+    indent .. "* Supports formatting: " .. tostring(document_formatting),
+    indent .. "* Capabilities list:   " .. table.concat(vim.list_slice(client_enabled_caps, 1, num_caps / 2), ", "),
+    indent .. indent .. indent .. table.concat(vim.list_slice(client_enabled_caps, ((num_caps / 2) + 1)), ", "),
+    "",
+  }
+  vim.list_extend(buf_lines, lsp_info)
+
+  local null_ls_info = {
+    indent .. "Formatters and linters",
+    indent .. "* Configured providers: " .. table.concat(null_ls_providers, "  , ") .. "  ",
+  }
+  vim.list_extend(buf_lines, null_ls_info)
+
+  local missing_formatters_status
+  if vim.tbl_count(missing_formatters) > 0 then
+    missing_formatters_status = {
+      indent .. "* Missing formatters:   " .. table.concat(missing_formatters, "  , ") .. "  ",
+    }
+    vim.list_extend(buf_lines, missing_formatters_status)
+  end
+
+  local missing_linters_status
+  if vim.tbl_count(missing_linters) > 0 then
+    missing_linters_status = {
+      indent .. "* Missing linters:      " .. table.concat(missing_linters, "  , ") .. "  ",
+    }
+    vim.list_extend(buf_lines, missing_linters_status)
+  end
+
+  vim.list_extend(buf_lines, { "" })
+
+  vim.list_extend(buf_lines, get_formatter_suggestion_msg(ft))
+
+  vim.list_extend(buf_lines, get_linter_suggestion_msg(ft))
+
+  local function set_syntax_hl()
+    vim.cmd [[highlight LvimInfoIdentifier gui=bold]]
+    vim.cmd [[highlight link LvimInfoHeader Type]]
+    vim.cmd [[let m=matchadd("DashboardHeader", "Language Server Protocol (LSP) info")]]
+    vim.cmd [[let m=matchadd("DashboardHeader", "Formatters and linters")]]
+    vim.cmd('let m=matchadd("LvimInfoIdentifier", " ' .. ft .. '$")')
+    vim.cmd 'let m=matchadd("string", "true")'
+    vim.cmd 'let m=matchadd("error", "false")'
+    tbl_set_highlight(null_ls_providers, "LvimInfoIdentifier")
+    tbl_set_highlight(missing_formatters, "LvimInfoIdentifier")
+    tbl_set_highlight(missing_linters, "LvimInfoIdentifier")
+    -- tbl_set_highlight(u.get_supported_formatters_by_filetype(ft), "LvimInfoIdentifier")
+    -- tbl_set_highlight(u.get_supported_linters_by_filetype(ft), "LvimInfoIdentifier")
+    vim.cmd('let m=matchadd("LvimInfoIdentifier", "' .. client_name .. '")')
+  end
+
+  return M.create_simple_popup(buf_lines, set_syntax_hl)
+end
+return M

+ 29 - 0
lua/core/log.lua

@@ -0,0 +1,29 @@
+local Log = {}
+
+--- Creates a log handle based on Plenary.log
+---@param opts these are passed verbatim to Plenary.log
+---@return log handle
+function Log:new(opts)
+  local status_ok, _ = pcall(require, "plenary.log")
+  if not status_ok then
+    return nil
+  end
+
+  local obj = require("plenary.log").new(opts)
+  local path = string.format("%s/%s.log", vim.api.nvim_call_function("stdpath", { "cache" }), opts.plugin)
+
+  obj.get_path = function()
+    return path
+  end
+
+  return obj
+end
+
+--- Creates or retrieves a log handle for the default logfile
+--- based on Plenary.log
+---@return log handle
+function Log:get_default()
+  return Log:new { plugin = "lunarvim", level = lvim.log.level }
+end
+
+return Log

+ 47 - 7
lua/core/nvimtree.lua

@@ -1,8 +1,10 @@
 local M = {}
+local Log = require "core.log"
 --
 M.config = function()
   lvim.builtin.nvimtree = {
     side = "left",
+    width = 30,
     show_icons = {
       git = 1,
       folders = 1,
@@ -48,6 +50,7 @@ end
 M.setup = function()
   local status_ok, nvim_tree_config = pcall(require, "nvim-tree.config")
   if not status_ok then
+    Log:get_default().error "Failed to load nvim-tree.config"
     return
   end
   local g = vim.g
@@ -58,13 +61,44 @@ M.setup = function()
 
   local tree_cb = nvim_tree_config.nvim_tree_callback
 
-  g.nvim_tree_bindings = {
-    { key = { "l", "<CR>", "o" }, cb = tree_cb "edit" },
-    { key = "h", cb = tree_cb "close_node" },
-    { key = "v", cb = tree_cb "vsplit" },
-  }
+  if not g.nvim_tree_bindings then
+    g.nvim_tree_bindings = {
+      { key = { "l", "<CR>", "o" }, cb = tree_cb "edit" },
+      { key = "h", cb = tree_cb "close_node" },
+      { key = "v", cb = tree_cb "vsplit" },
+    }
+  end
 end
 --
+M.focus_or_close = function()
+  local view_status_ok, view = pcall(require, "nvim-tree.view")
+  if not view_status_ok then
+    return
+  end
+  local a = vim.api
+
+  local curwin = a.nvim_get_current_win()
+  local curbuf = a.nvim_win_get_buf(curwin)
+  local bufnr = view.View.bufnr
+  local winnr = view.get_winnr()
+
+  if view.win_open() then
+    if curwin == winnr and curbuf == bufnr then
+      view.close()
+      if package.loaded["bufferline.state"] then
+        require("bufferline.state").set_offset(0)
+      end
+    else
+      view.focus()
+    end
+  else
+    view.open()
+    if package.loaded["bufferline.state"] and lvim.builtin.nvimtree.side == "left" then
+      -- require'bufferline.state'.set_offset(lvim.builtin.nvimtree.width + 1, 'File Explorer')
+      require("bufferline.state").set_offset(lvim.builtin.nvimtree.width + 1, "")
+    end
+  end
+end
 --
 M.toggle_tree = function()
   local view_status_ok, view = pcall(require, "nvim-tree.view")
@@ -78,11 +112,17 @@ M.toggle_tree = function()
     end
   else
     if package.loaded["bufferline.state"] and lvim.builtin.nvimtree.side == "left" then
-      -- require'bufferline.state'.set_offset(31, 'File Explorer')
-      require("bufferline.state").set_offset(31, "")
+      -- require'bufferline.state'.set_offset(lvim.builtin.nvimtree.width + 1, 'File Explorer')
+      require("bufferline.state").set_offset(lvim.builtin.nvimtree.width + 1, "")
     end
     require("nvim-tree").toggle()
   end
 end
 --
+function M.change_tree_dir(dir)
+  if vim.g.loaded_tree then
+    require("nvim-tree.lib").change_dir(dir)
+  end
+end
+--
 return M

+ 15 - 0
lua/core/rooter.lua

@@ -0,0 +1,15 @@
+local M = {}
+function M.config()
+  lvim.builtin.rooter = {
+    --- This is on by default since it's currently the expected behavior.
+    ---@usage set to false to disable vim-rooter.
+    active = true,
+    silent_chdir = 1,
+    manual_only = 0,
+  }
+end
+function M.setup()
+  vim.g.rooter_silent_chdir = lvim.builtin.rooter.silent_chdir
+  vim.g.rooter_manual_only = lvim.builtin.rooter.manual_only
+end
+return M

+ 6 - 4
lua/core/telescope.lua

@@ -1,4 +1,5 @@
 local M = {}
+local Log = require "core.log"
 M.config = function()
   local status_ok, actions = pcall(require, "telescope.actions")
   if not status_ok then
@@ -40,11 +41,11 @@ M.config = function()
       -- buffer_previewer_maker = require("telescope.previewers").buffer_previewer_maker,
       mappings = {
         i = {
-          ["<C-n>"] = actions.cycle_history_next,
-          ["<C-p>"] = actions.cycle_history_prev,
+          ["<C-n>"] = actions.move_selection_next,
+          ["<C-p>"] = actions.move_selection_previous,
           ["<C-c>"] = actions.close,
-          ["<C-j>"] = actions.move_selection_next,
-          ["<C-k>"] = actions.move_selection_previous,
+          ["<C-j>"] = actions.cycle_history_next,
+          ["<C-k>"] = actions.cycle_history_prev,
           ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,
           ["<CR>"] = actions.select_default + actions.center,
           -- To disable a keymap, put [map] = false
@@ -79,6 +80,7 @@ end
 M.setup = function()
   local status_ok, telescope = pcall(require, "telescope")
   if not status_ok then
+    Log:get_default().error "Failed to load telescope"
     return
   end
   telescope.setup(lvim.builtin.telescope)

+ 46 - 4
lua/core/terminal.lua

@@ -1,8 +1,11 @@
 local M = {}
+local Log = require "core.log"
+local utils = require "utils"
+
 M.config = function()
   lvim.builtin["terminal"] = {
     -- size can be a number or function which is passed the current terminal
-    size = 5,
+    size = 20,
     -- open_mapping = [[<c-\>]],
     open_mapping = [[<c-t>]],
     hide_numbers = true, -- hide the number column in toggleterm buffers
@@ -11,7 +14,7 @@ M.config = function()
     shading_factor = 2, -- the degree by which to darken to terminal colour, default: 1 for dark backgrounds, 3 for light
     start_in_insert = true,
     insert_mappings = true, -- whether or not the open mapping applies in insert mode
-    persist_size = true,
+    persist_size = false,
     -- direction = 'vertical' | 'horizontal' | 'window' | 'float',
     direction = "float",
     close_on_exit = true, -- close the terminal window when the process exits
@@ -32,17 +35,20 @@ M.config = function()
         background = "Normal",
       },
     },
-    -- Add executables on the lv-config file
+    -- Add executables on the config.lua
     -- { exec, keymap, name}
     -- lvim.builtin.terminal.execs = {{}} to overwrite
     -- lvim.builtin.terminal.execs[#lvim.builtin.terminal.execs+1] = {"gdb", "tg", "GNU Debugger"}
-    execs = { { "lazygit", "gg", "LazyGit" } },
+    execs = {
+      { "lazygit", "gg", "LazyGit" },
+    },
   }
 end
 
 M.setup = function()
   local status_ok, terminal = pcall(require, "toggleterm")
   if not status_ok then
+    Log:get_default().error "Failed to load toggleterm"
     print(terminal)
     return
   end
@@ -88,4 +94,40 @@ 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
+  end
+  local term_opts = vim.tbl_deep_extend("force", lvim.builtin.terminal, {
+    cmd = lvim.log.viewer.cmd .. " " .. logfile,
+    open_mapping = lvim.log.viewer.layout_config.open_mapping,
+    direction = lvim.log.viewer.layout_config.direction,
+    -- TODO: this might not be working as expected
+    size = lvim.log.viewer.layout_config.size,
+    float_opts = lvim.log.viewer.layout_config.float_opts,
+  })
+
+  local Terminal = require("toggleterm.terminal").Terminal
+  local log_view = Terminal:new(term_opts)
+  -- require("core.log"):get_default().debug("term", vim.inspect(term_opts))
+  log_view:toggle()
+end
+
 return M

+ 2 - 0
lua/core/treesitter.lua

@@ -1,4 +1,5 @@
 local M = {}
+local Log = require "core.log"
 M.config = function()
   lvim.builtin.treesitter = {
     ensure_installed = {}, -- one of "all", "maintained" (parsers with maintainers), or a list of languages
@@ -64,6 +65,7 @@ end
 M.setup = function()
   local status_ok, treesitter_configs = pcall(require, "nvim-treesitter.configs")
   if not status_ok then
+    Log:get_default().error "Failed to load nvim-treesitter.configs"
     return
   end
 

+ 36 - 4
lua/core/which-key.lua

@@ -1,4 +1,5 @@
 local M = {}
+local Log = require "core.log"
 M.config = function()
   lvim.builtin.which_key = {
     active = false,
@@ -67,7 +68,7 @@ M.config = function()
       ["c"] = { "<cmd>BufferClose!<CR>", "Close Buffer" },
       ["e"] = { "<cmd>lua require'core.nvimtree'.toggle_tree()<CR>", "Explorer" },
       ["f"] = { "<cmd>Telescope find_files<CR>", "Find File" },
-      ["h"] = { '<cmd>let @/=""<CR>', "No Highlight" },
+      ["h"] = { "<cmd>nohlsearch<CR>", "No Highlight" },
       b = {
         name = "Buffers",
         j = { "<cmd>BufferPick<cr>", "jump to buffer" },
@@ -97,6 +98,7 @@ M.config = function()
         i = { "<cmd>PackerInstall<cr>", "Install" },
         r = { "<cmd>lua require('utils').reload_lv_config()<cr>", "Reload" },
         s = { "<cmd>PackerSync<cr>", "Sync" },
+        S = { "<cmd>PackerStatus<cr>", "Status" },
         u = { "<cmd>PackerUpdate<cr>", "Update" },
       },
 
@@ -151,8 +153,13 @@ M.config = function()
           "<cmd>lua vim.lsp.diagnostic.goto_prev({popup_opts = {border = lvim.lsp.popup_border}})<cr>",
           "Prev Diagnostic",
         },
-        l = { "<cmd>silent lua require('lint').try_lint()<cr>", "Lint" },
-        q = { "<cmd>Telescope quickfix<cr>", "Quickfix" },
+        p = {
+          name = "Peek",
+          d = { "<cmd>lua require('lsp.peek').Peek('definition')<cr>", "Definition" },
+          t = { "<cmd>lua require('lsp.peek').Peek('typeDefinition')<cr>", "Type Definition" },
+          i = { "<cmd>lua require('lsp.peek').Peek('implementation')<cr>", "Implementation" },
+        },
+        q = { "<cmd>lua vim.lsp.diagnostic.set_loclist()<cr>", "Quickfix" },
         r = { "<cmd>lua vim.lsp.buf.rename()<cr>", "Rename" },
         s = { "<cmd>Telescope lsp_document_symbols<cr>", "Document Symbols" },
         S = {
@@ -160,7 +167,31 @@ M.config = function()
           "Workspace Symbols",
         },
       },
-
+      L = {
+        name = "+LunarVim",
+        k = { "<cmd>lua require('keymappings').print()<cr>", "View LunarVim's default keymappings" },
+        i = {
+          "<cmd>lua require('core.info').toggle_popup(vim.bo.filetype)<cr>",
+          "Toggle LunarVim Info",
+        },
+        l = {
+          name = "+logs",
+          d = {
+            "<cmd>lua require('core.terminal').toggle_log_view('lunarvim')<cr>",
+            "view default log",
+          },
+          D = { "<cmd>edit ~/.cache/nvim/lunarvim.log<cr>", "Open the default logfile" },
+          n = { "<cmd>lua require('core.terminal').toggle_log_view('lsp')<cr>", "view lsp log" },
+          N = { "<cmd>edit ~/.cache/nvim/log<cr>", "Open the Neovim logfile" },
+          l = { "<cmd>lua require('core.terminal').toggle_log_view('nvim')<cr>", "view neovim log" },
+          L = { "<cmd>edit ~/.cache/nvim/lsp.log<cr>", "Open the LSP logfile" },
+          p = {
+            "<cmd>lua require('core.terminal').toggle_log_view('packer.nvim')<cr>",
+            "view packer log",
+          },
+          P = { "<cmd>edit ~/.cache/nvim/packer.nvim.log<cr>", "Open the Packer logfile" },
+        },
+      },
       s = {
         name = "Search",
         b = { "<cmd>Telescope git_branches<cr>", "Checkout branch" },
@@ -192,6 +223,7 @@ M.setup = function()
   -- end
   local status_ok, which_key = pcall(require, "which-key")
   if not status_ok then
+    Log:get_default "Failed to load whichkey"
     return
   end
 

File diff suppressed because it is too large
+ 377 - 161
lua/default-config.lua


+ 159 - 102
lua/keymappings.lua

@@ -1,115 +1,172 @@
-local utils = require "utils"
-
-local opts = {
-  nnoremap = { noremap = true, silent = true },
-  inoremap = { noremap = true, silent = true },
-  vnoremap = { noremap = true, silent = true },
-  xnoremap = { noremap = true, silent = true },
-  generic = { silent = true },
+local M = {}
+local Log = require "core.log"
+
+local generic_opts_any = { noremap = true, silent = true }
+
+local generic_opts = {
+  insert_mode = generic_opts_any,
+  normal_mode = generic_opts_any,
+  visual_mode = generic_opts_any,
+  visual_block_mode = generic_opts_any,
+  term_mode = { silent = true },
 }
 
-local default_keys = {
-  insert_mode = {
-    -- I hate escape
-    { "jk", "<ESC>" },
-    { "kj", "<ESC>" },
-    { "jj", "<ESC>" },
-    -- Move current line / block with Alt-j/k ala vscode.
-    { "<A-j>", "<Esc>:m .+1<CR>==gi" },
-    { "<A-k>", "<Esc>:m .-2<CR>==gi" },
-    -- navigation
-    { "<A-Up>", "<C-\\><C-N><C-w>k" },
-    { "<A-Down>", "<C-\\><C-N><C-w>j" },
-    { "<A-Left>", "<C-\\><C-N><C-w>h" },
-    { "<A-Right>", "<C-\\><C-N><C-w>l" },
-  },
-
-  normal_mode = {
-    -- Better window movement
-    { "<C-h>", "<C-w>h" },
-    { "<C-j>", "<C-w>j" },
-    { "<C-k>", "<C-w>k" },
-    { "<C-l>", "<C-w>l" },
-
-    -- Resize with arrows
-    { "<C-Up>", ":resize -2<CR>" },
-    { "<C-Down>", ":resize +2<CR>" },
-    { "<C-Left>", ":vertical resize -2<CR>" },
-    { "<C-Right>", ":vertical resize +2<CR>" },
-
-    -- Tab switch buffer
-    -- { "<TAB>", ":bnext<CR>" },
-    -- { "<S-TAB>", ":bprevious<CR>" },
-
-    -- Move current line / block with Alt-j/k a la vscode.
-    { "<A-j>", ":m .+1<CR>==" },
-    { "<A-k>", ":m .-2<CR>==" },
-
-    -- QuickFix
-    { "]q", ":cnext<CR>" },
-    { "[q", ":cprev<CR>" },
-    { "<C-q>", ":call QuickFixToggle()<CR>" },
-
-    -- {'<C-TAB>', 'compe#complete()', {noremap = true, silent = true, expr = true}},
-  },
-
-  term_mode = {
-    -- Terminal window navigation
-    { "<C-h>", "<C-\\><C-N><C-w>h" },
-    { "<C-j>", "<C-\\><C-N><C-w>j" },
-    { "<C-k>", "<C-\\><C-N><C-w>k" },
-    { "<C-l>", "<C-\\><C-N><C-w>l" },
-  },
-
-  visual_mode = {
-    -- Better indenting
-    { "<", "<gv" },
-    { ">", ">gv" },
-
-    -- { "p", '"0p', { silent = true } },
-    -- { "P", '"0P', { silent = true } },
-  },
-
-  visual_block_mode = {
-    -- Move selected line / block of text in visual mode
-    { "K", ":move '<-2<CR>gv-gv" },
-    { "J", ":move '>+1<CR>gv-gv" },
-
-    -- Move current line / block with Alt-j/k ala vscode.
-    { "<A-j>", ":m '>+1<CR>gv-gv" },
-    { "<A-k>", ":m '<-2<CR>gv-gv" },
-  },
+local mode_adapters = {
+  insert_mode = "i",
+  normal_mode = "n",
+  term_mode = "t",
+  visual_mode = "v",
+  visual_block_mode = "x",
 }
 
-if vim.fn.has "mac" == 1 then
-  -- TODO: fix this
-  default_keys.normal_mode[5][1] = "<A-Up>"
-  default_keys.normal_mode[6][1] = "<A-Down>"
-  default_keys.normal_mode[7][1] = "<A-Left>"
-  default_keys.normal_mode[8][1] = "<A-Right>"
+-- Append key mappings to lunarvim's defaults for a given mode
+-- @param keymaps The table of key mappings containing a list per mode (normal_mode, insert_mode, ..)
+function M.append_to_defaults(keymaps)
+  for mode, mappings in pairs(keymaps) do
+    for k, v in ipairs(mappings) do
+      lvim.keys[mode][k] = v
+    end
+  end
+end
+
+-- Set key mappings individually
+-- @param mode The keymap mode, can be one of the keys of mode_adapters
+-- @param key The key of keymap
+-- @param val Can be form as a mapping or tuple of mapping and user defined opt
+function M.set_keymaps(mode, key, val)
+  local opt = generic_opts[mode] and generic_opts[mode] or generic_opts_any
+  if type(val) == "table" then
+    opt = val[2]
+    val = val[1]
+  end
+  vim.api.nvim_set_keymap(mode, key, val, opt)
+end
+
+-- Load key mappings for a given mode
+-- @param mode The keymap mode, can be one of the keys of mode_adapters
+-- @param keymaps The list of key mappings
+function M.load_mode(mode, keymaps)
+  mode = mode_adapters[mode] and mode_adapters[mode] or mode
+  for k, v in pairs(keymaps) do
+    M.set_keymaps(mode, k, v)
+  end
 end
 
-if lvim.leader == " " or lvim.leader == "space" then
-  vim.g.mapleader = " "
-else
-  vim.g.mapleader = lvim.leader
+-- Load key mappings for all provided modes
+-- @param keymaps A list of key mappings for each mode
+function M.load(keymaps)
+  for mode, mapping in pairs(keymaps) do
+    M.load_mode(mode, mapping)
+  end
 end
 
-local function get_user_keys(mode)
-  if lvim.keys[mode] == nil then
-    return default_keys[mode]
+function M.config()
+  lvim.keys = {
+    ---@usage change or add keymappings for insert mode
+    insert_mode = {
+      -- 'jk' for quitting insert mode
+      ["jk"] = "<ESC>",
+      -- 'kj' for quitting insert mode
+      ["kj"] = "<ESC>",
+      -- 'jj' for quitting insert mode
+      ["jj"] = "<ESC>",
+      -- Move current line / block with Alt-j/k ala vscode.
+      ["<A-j>"] = "<Esc>:m .+1<CR>==gi",
+      -- Move current line / block with Alt-j/k ala vscode.
+      ["<A-k>"] = "<Esc>:m .-2<CR>==gi",
+      -- navigation
+      ["<A-Up>"] = "<C-\\><C-N><C-w>k",
+      ["<A-Down>"] = "<C-\\><C-N><C-w>j",
+      ["<A-Left>"] = "<C-\\><C-N><C-w>h",
+      ["<A-Right>"] = "<C-\\><C-N><C-w>l",
+      -- navigate tab completion with <c-j> and <c-k>
+      -- runs conditionally
+      ["<C-j>"] = { 'pumvisible() ? "\\<C-n>" : "\\<C-j>"', { expr = true, noremap = true } },
+      ["<C-k>"] = { 'pumvisible() ? "\\<C-p>" : "\\<C-k>"', { expr = true, noremap = true } },
+    },
+
+    ---@usage change or add keymappings for normal mode
+    normal_mode = {
+      -- Better window movement
+      ["<C-h>"] = "<C-w>h",
+      ["<C-j>"] = "<C-w>j",
+      ["<C-k>"] = "<C-w>k",
+      ["<C-l>"] = "<C-w>l",
+
+      -- Resize with arrows
+      ["<C-Up>"] = ":resize -2<CR>",
+      ["<C-Down>"] = ":resize +2<CR>",
+      ["<C-Left>"] = ":vertical resize -2<CR>",
+      ["<C-Right>"] = ":vertical resize +2<CR>",
+
+      -- Tab switch buffer
+      ["<S-l>"] = ":BufferNext<CR>",
+      ["<S-h>"] = ":BufferPrevious<CR>",
+
+      -- Move current line / block with Alt-j/k a la vscode.
+      ["<A-j>"] = ":m .+1<CR>==",
+      ["<A-k>"] = ":m .-2<CR>==",
+
+      -- QuickFix
+      ["]q"] = ":cnext<CR>",
+      ["[q"] = ":cprev<CR>",
+      ["<C-q>"] = ":call QuickFixToggle()<CR>",
+    },
+
+    ---@usage change or add keymappings for terminal mode
+    term_mode = {
+      -- Terminal window navigation
+      ["<C-h>"] = "<C-\\><C-N><C-w>h",
+      ["<C-j>"] = "<C-\\><C-N><C-w>j",
+      ["<C-k>"] = "<C-\\><C-N><C-w>k",
+      ["<C-l>"] = "<C-\\><C-N><C-w>l",
+    },
+
+    ---@usage change or add keymappings for visual mode
+    visual_mode = {
+      -- Better indenting
+      ["<"] = "<gv",
+      [">"] = ">gv",
+
+      -- ["p"] = '"0p',
+      -- ["P"] = '"0P',
+    },
+
+    ---@usage change or add keymappings for visual block mode
+    visual_block_mode = {
+      -- Move selected line / block of text in visual mode
+      ["K"] = ":move '<-2<CR>gv-gv",
+      ["J"] = ":move '>+1<CR>gv-gv",
+
+      -- Move current line / block with Alt-j/k ala vscode.
+      ["<A-j>"] = ":m '>+1<CR>gv-gv",
+      ["<A-k>"] = ":m '<-2<CR>gv-gv",
+    },
+  }
+
+  if vim.fn.has "mac" == 1 then
+    lvim.keys.normal_mode["<A-Up>"] = lvim.keys.normal_mode["<C-Up>"]
+    lvim.keys.normal_mode["<A-Down>"] = lvim.keys.normal_mode["<C-Down>"]
+    lvim.keys.normal_mode["<A-Left>"] = lvim.keys.normal_mode["<C-Left>"]
+    lvim.keys.normal_mode["<A-Right>"] = lvim.keys.normal_mode["<C-Right>"]
+    if Log:get_default() then
+      Log:get_default().info "Activated mac keymappings"
+    end
+  end
+end
+
+function M.print(mode)
+  print "List of LunarVim's default keymappings (not including which-key)"
+  if mode then
+    print(vim.inspect(lvim.keys[mode]))
   else
-    return lvim.keys[mode]
+    print(vim.inspect(lvim.keys))
   end
 end
 
-utils.add_keymap_normal_mode(opts.nnoremap, get_user_keys "normal_mode")
-utils.add_keymap_insert_mode(opts.inoremap, get_user_keys "insert_mode")
-utils.add_keymap_visual_mode(opts.vnoremap, get_user_keys "visual_mode")
-utils.add_keymap_visual_block_mode(opts.xnoremap, get_user_keys "visual_block_mode")
-utils.add_keymap_term_mode(opts.generic, get_user_keys "term_mode")
+function M.setup()
+  vim.g.mapleader = (lvim.leader == "space" and " ") or lvim.leader
+  M.load(lvim.keys)
+end
 
--- navigate tab completion with <c-j> and <c-k>
--- runs conditionally
-vim.cmd 'inoremap <expr> <C-j> pumvisible() ? "\\<C-n>" : "\\<C-j>"'
-vim.cmd 'inoremap <expr> <C-k> pumvisible() ? "\\<C-p>" : "\\<C-k>"'
+return M

+ 43 - 1
lua/lsp/handlers.lua

@@ -5,10 +5,52 @@ local M = {}
 function M.setup()
   vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, {
     virtual_text = lvim.lsp.diagnostics.virtual_text,
-    signs = lvim.lsp.diagnostics.signs,
+    signs = lvim.lsp.diagnostics.signs.active,
     underline = lvim.lsp.document_highlight,
   })
 
+  vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, _, params, client_id, _)
+    local config = { -- your config
+      virtual_text = lvim.lsp.diagnostics.virtual_text,
+      signs = lvim.lsp.diagnostics.signs,
+      underline = lvim.lsp.diagnostics.underline,
+      update_in_insert = lvim.lsp.diagnostics.update_in_insert,
+      severity_sort = lvim.lsp.diagnostics.severity_sort,
+    }
+    local uri = params.uri
+    local bufnr = vim.uri_to_bufnr(uri)
+
+    if not bufnr then
+      return
+    end
+
+    local diagnostics = params.diagnostics
+
+    for i, v in ipairs(diagnostics) do
+      local source = v.source
+      if source then
+        if string.find(source, "/") then
+          source = string.sub(v.source, string.find(v.source, "([%w-_]+)$"))
+        end
+        diagnostics[i].message = string.format("%s: %s", source, v.message)
+      else
+        diagnostics[i].message = string.format("%s", v.message)
+      end
+
+      if vim.tbl_contains(vim.tbl_keys(v), "code") then
+        diagnostics[i].message = diagnostics[i].message .. string.format(" [%s]", v.code)
+      end
+    end
+
+    vim.lsp.diagnostic.save(diagnostics, bufnr, client_id)
+
+    if not vim.api.nvim_buf_is_loaded(bufnr) then
+      return
+    end
+
+    vim.lsp.diagnostic.display(diagnostics, bufnr, client_id, config)
+  end
+
   vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, {
     border = lvim.lsp.popup_border,
   })

+ 125 - 35
lua/lsp/init.lua

@@ -1,59 +1,149 @@
-local utils = require "utils"
-local service = require "lsp.service"
-local null_ls = require "lsp.null-ls"
 local M = {}
-
+local Log = require "core.log"
 function M.config()
-  require("lsp.kind").setup()
+  vim.lsp.protocol.CompletionItemKind = lvim.lsp.completion.item_kind
+
+  for _, sign in ipairs(lvim.lsp.diagnostics.signs.values) do
+    vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name })
+  end
+
   require("lsp.handlers").setup()
-  require("lsp.signs").setup()
-  require("lsp.keybinds").setup()
 end
 
-function M.setup(lang)
-  local lang_server = lvim.lang[lang].lsp
-  local provider = lang_server.provider
-  if utils.check_lsp_client_active(provider) then
-    return
+local function lsp_highlight_document(client)
+  if lvim.lsp.document_highlight == false then
+    return -- we don't need further
+  end
+  -- Set autocommands conditional on server_capabilities
+  if client.resolved_capabilities.document_highlight then
+    vim.api.nvim_exec(
+      [[
+      hi LspReferenceRead cterm=bold ctermbg=red guibg=#464646
+      hi LspReferenceText cterm=bold ctermbg=red guibg=#464646
+      hi LspReferenceWrite cterm=bold ctermbg=red guibg=#464646
+      augroup lsp_document_highlight
+        autocmd! * <buffer>
+        autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()
+        autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references()
+      augroup END
+    ]],
+      false
+    )
   end
+end
 
-  local overrides = lvim.lsp.override
+local function add_lsp_buffer_keybindings(bufnr)
+  local wk = require "which-key"
+  local keys = {
+    ["K"] = { "<cmd>lua vim.lsp.buf.hover()<CR>", "Show hover" },
+    ["gd"] = { "<cmd>lua vim.lsp.buf.definition()<CR>", "Goto Definition" },
+    ["gD"] = { "<cmd>lua vim.lsp.buf.declaration()<CR>", "Goto declaration" },
+    ["gr"] = { "<cmd>lua vim.lsp.buf.references()<CR>", "Goto references" },
+    ["gi"] = { "<cmd>lua vim.lsp.buf.implementation()<CR>", "Goto implementation" },
+    ["gs"] = { "<cmd>lua vim.lsp.buf.signature_help()<CR>", "show signature help" },
+    ["gp"] = { "<cmd>lua require'lsp.peek'.Peek('definition')<CR>", "Peek definition" },
+    ["gl"] = {
+      "<cmd>lua vim.lsp.diagnostic.show_line_diagnostics({ show_header = false, border = 'single' })<CR>",
+      "Show line diagnostics",
+    },
+  }
+  wk.register(keys, { mode = "n", buffer = bufnr })
+end
 
-  if utils.is_table(overrides) then
-    if utils.has_value(overrides, lang) then
-      return
-    end
+local function set_smart_cwd(client)
+  local proj_dir = client.config.root_dir
+  if lvim.lsp.smart_cwd and proj_dir ~= "/" then
+    vim.api.nvim_set_current_dir(proj_dir)
+    require("core.nvimtree").change_tree_dir(proj_dir)
   end
+end
 
-  if utils.is_string(overrides) then
-    if overrides == lang then
-      return
+function M.common_capabilities()
+  local capabilities = vim.lsp.protocol.make_client_capabilities()
+  capabilities.textDocument.completion.completionItem.snippetSupport = true
+  capabilities.textDocument.completion.completionItem.resolveSupport = {
+    properties = {
+      "documentation",
+      "detail",
+      "additionalTextEdits",
+    },
+  }
+  return capabilities
+end
+
+function M.get_ls_capabilities(client_id)
+  local client
+  if not client_id then
+    local buf_clients = vim.lsp.buf_get_clients()
+    for _, buf_client in ipairs(buf_clients) do
+      if buf_client.name ~= "null-ls" then
+        client_id = buf_client.id
+        break
+      end
     end
   end
-  local sources = null_ls.setup(lang)
+  if not client_id then
+    error "Unable to determine client_id"
+  end
 
-  for _, source in pairs(sources) do
-    local method = source.method
-    local format_method = "NULL_LS_FORMATTING"
+  client = vim.lsp.get_client_by_id(tonumber(client_id))
 
-    if utils.is_table(method) then
-      if utils.has_value(method, format_method) then
-        lang_server.setup.on_attach = service.no_formatter_on_attach
-      end
-    end
+  local enabled_caps = {}
 
-    if utils.is_string(method) then
-      if method == format_method then
-        lang_server.setup.on_attach = service.no_formatter_on_attach
-      end
+  for k, v in pairs(client.resolved_capabilities) do
+    if v == true then
+      table.insert(enabled_caps, k)
     end
   end
 
-  if provider == "" or provider == nil then
+  return enabled_caps
+end
+
+function M.common_on_init(client, bufnr)
+  if lvim.lsp.on_init_callback then
+    lvim.lsp.on_init_callback(client, bufnr)
+    Log:get_default().info "Called lsp.on_init_callback"
+    return
+  end
+
+  local formatters = lvim.lang[vim.bo.filetype].formatters
+  if not vim.tbl_isempty(formatters) and formatters[1]["exe"] ~= nil and formatters[1].exe ~= "" then
+    client.resolved_capabilities.document_formatting = false
+    Log:get_default().info(
+      string.format("Overriding language server [%s] with format provider [%s]", client.name, formatters[1].exe)
+    )
+  end
+end
+
+function M.common_on_attach(client, bufnr)
+  if lvim.lsp.on_attach_callback then
+    lvim.lsp.on_attach_callback(client, bufnr)
+    Log:get_default().info "Called lsp.on_init_callback"
+  end
+  lsp_highlight_document(client)
+  add_lsp_buffer_keybindings(bufnr)
+  set_smart_cwd(client)
+  require("lsp.null-ls").setup(vim.bo.filetype)
+end
+
+function M.setup(lang)
+  local lsp = lvim.lang[lang].lsp
+  if require("utils").check_lsp_client_active(lsp.provider) then
     return
   end
 
-  require("lspconfig")[provider].setup(lang_server.setup)
+  local overrides = lvim.lsp.override
+
+  if type(overrides) == "table" then
+    if vim.tbl_contains(overrides, lang) then
+      return
+    end
+  end
+
+  if lsp.provider ~= nil and lsp.provider ~= "" then
+    local lspconfig = require "lspconfig"
+    lspconfig[lsp.provider].setup(lsp.setup)
+  end
 end
 
 return M

+ 0 - 27
lua/lsp/keybinds.lua

@@ -1,27 +0,0 @@
-local M = {}
-
-function M.setup()
-  if lvim.lsp.default_keybinds then
-    vim.cmd "nnoremap <silent> gd <cmd>lua vim.lsp.buf.definition()<CR>"
-    vim.cmd "nnoremap <silent> gD <cmd>lua vim.lsp.buf.declaration()<CR>"
-    vim.cmd "nnoremap <silent> gr <cmd>lua vim.lsp.buf.references()<CR>"
-    vim.cmd "nnoremap <silent> gi <cmd>lua vim.lsp.buf.implementation()<CR>"
-    vim.api.nvim_set_keymap(
-      "n",
-      "gl",
-      '<cmd>lua vim.lsp.diagnostic.show_line_diagnostics({ show_header = false, border = "single" })<CR>',
-      { noremap = true, silent = true }
-    )
-
-    vim.cmd "nnoremap <silent> gp <cmd>lua require'lsp.utils'.PeekDefinition()<CR>"
-    vim.cmd "nnoremap <silent> K :lua vim.lsp.buf.hover()<CR>"
-    vim.cmd "nnoremap <silent> <C-p> :lua vim.lsp.diagnostic.goto_prev({popup_opts = {border = lvim.lsp.popup_border}})<CR>"
-    vim.cmd "nnoremap <silent> <C-n> :lua vim.lsp.diagnostic.goto_next({popup_opts = {border = lvim.lsp.popup_border}})<CR>"
-    -- vim.cmd "nnoremap <silent> gs <cmd>lua vim.lsp.buf.signature_help()<CR>"
-    -- scroll down hover doc or scroll in definition preview
-    -- scroll up hover doc
-    -- vim.cmd 'command! -nargs=0 LspVirtualTextToggle lua require("lsp/virtual_text").toggle()'
-  end
-end
-
-return M

+ 0 - 33
lua/lsp/kind.lua

@@ -1,33 +0,0 @@
-local M = {}
-
-function M.setup()
-  vim.lsp.protocol.CompletionItemKind = {
-    -- symbols for autocomplete
-    "   (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)",
-  }
-end
-return M

+ 119 - 43
lua/lsp/null-ls.lua

@@ -1,66 +1,142 @@
 local M = {}
+local Log = require "core.log"
 
-local _, null_ls = pcall(require, "null-ls")
-local utils = require "utils"
-local sources = {}
+local null_ls = require "null-ls"
 
-local local_executables = { "prettier", "prettierd", "prettier_d_slim", "eslint_d", "eslint" }
+local nodejs_local_providers = { "prettier", "prettierd", "prettier_d_slim", "eslint_d", "eslint" }
 
-local find_local_exe = function(exe)
-  vim.cmd "let root_dir = FindRootDirectory()"
-  local root_dir = vim.api.nvim_get_var "root_dir"
-  local local_exe = root_dir .. "/node_modules/.bin/" .. exe
-  return local_exe
-end
+M.requested_providers = {}
 
-local function setup_ls(exe, type)
-  if utils.has_value(local_executables, exe) then
-    local smart_executable = null_ls.builtins[type][exe]
-    local local_executable = find_local_exe(exe)
-    if vim.fn.executable(local_executable) == 1 then
-      smart_executable._opts.command = local_executable
-      table.insert(sources, smart_executable)
-    else
-      if vim.fn.executable(exe) == 1 then
-        table.insert(sources, smart_executable)
+function M.get_registered_providers_by_filetype(ft)
+  local matches = {}
+  for _, provider in pairs(M.requested_providers) do
+    if vim.tbl_contains(provider.filetypes, ft) then
+      local provider_name = provider.name
+      -- special case: show "eslint_d" instead of eslint
+      -- https://github.com/jose-elias-alvarez/null-ls.nvim/blob/9b8458bd1648e84169a7e8638091ba15c2f20fc0/doc/BUILTINS.md#eslint
+      if string.find(provider._opts.command, "eslint_d") then
+        provider_name = "eslint_d"
       end
+      table.insert(matches, provider_name)
+    end
+  end
+
+  return matches
+end
+
+function M.get_missing_providers_by_filetype(ft)
+  local matches = {}
+  for _, provider in pairs(M.requested_providers) do
+    if vim.tbl_contains(provider.filetypes, ft) then
+      local provider_name = provider.name
+
+      table.insert(matches, provider_name)
     end
+  end
+
+  return matches
+end
+
+local function register_failed_request(ft, provider, operation)
+  if not lvim.lang[ft][operation]._failed_requests then
+    lvim.lang[ft][operation]._failed_requests = {}
+  end
+  table.insert(lvim.lang[ft][operation]._failed_requests, provider)
+end
+
+local function validate_nodejs_provider(provider)
+  local command_path
+  local root_dir
+  if lvim.builtin.rooter.active then
+    --- use vim-rooter to set root_dir
+    vim.cmd "let root_dir = FindRootDirectory()"
+    root_dir = vim.api.nvim_get_var "root_dir"
   else
-    if null_ls.builtins[type][exe] and vim.fn.executable(null_ls.builtins[type][exe]._opts.command) then
-      table.insert(sources, null_ls.builtins[type][exe])
+    --- use LSP to set root_dir
+    local ts_client = require("utils").get_active_client_by_ft "typescript"
+    if ts_client == nil then
+      Log:get_default().error "Unable to determine root directory since tsserver didn't start correctly"
+      return
     end
+    root_dir = ts_client.config.root_dir
   end
-  null_ls.register { sources = sources }
+  local local_nodejs_command = root_dir .. "/node_modules/.bin/" .. provider._opts.command
+  Log:get_default().debug("checking for local node module: ", vim.inspect(provider))
+
+  if vim.fn.executable(local_nodejs_command) == 1 then
+    command_path = local_nodejs_command
+  elseif vim.fn.executable(provider._opts.command) == 1 then
+    Log:get_default().debug("checking in global path instead for node module", provider._opts.command)
+    command_path = provider._opts.command
+  else
+    Log:get_default().debug("Unable to find node module", provider._opts.command)
+  end
+  return command_path
 end
 
--- TODO: for linters and formatters with spaces and '-' replace with '_'
-local function setup(filetype, type)
-  local executables = nil
-  if type == "diagnostics" then
-    executables = lvim.lang[filetype].linters
+local function validate_provider_request(provider)
+  if provider == "" or provider == nil then
+    return
   end
-  if type == "formatting" then
-    executables = lvim.lang[filetype].formatter.exe
+  -- NOTE: we can't use provider.name because eslint_d uses eslint name
+  if vim.tbl_contains(nodejs_local_providers, provider._opts.command) then
+    return validate_nodejs_provider(provider)
   end
+  if vim.fn.executable(provider._opts.command) ~= 1 then
+    Log:get_default().debug("Unable to find the path for", vim.inspect(provider))
+    Log:get_default().warn("Unable to find the path for ", provider._opts.command)
+    return
+  end
+  return provider._opts.command
+end
 
-  if utils.is_table(executables) then
-    for _, exe in pairs(executables) do
-      if exe ~= "" then
-        setup_ls(exe, type)
+-- TODO: for linters and formatters with spaces and '-' replace with '_'
+function M.setup(filetype)
+  for _, formatter in pairs(lvim.lang[filetype].formatters) do
+    Log:get_default().debug("validating format provider: ", formatter.exe)
+    local builtin_formatter = null_ls.builtins.formatting[formatter.exe]
+    if not vim.tbl_contains(M.requested_providers, builtin_formatter) then
+      -- FIXME: why doesn't this work?
+      -- builtin_formatter._opts.args = formatter.args or builtin_formatter._opts.args
+      -- builtin_formatter._opts.to_stdin = formatter.stdin or builtin_formatter._opts.to_stdin
+      local resolved_path = validate_provider_request(builtin_formatter)
+      if resolved_path then
+        builtin_formatter._opts.command = resolved_path
+        table.insert(M.requested_providers, builtin_formatter)
+        Log:get_default().info("Using format provider", builtin_formatter.name)
+      else
+        -- mark it here to avoid re-doing the lookup again
+        register_failed_request(filetype, formatter.exe, "formatters")
       end
     end
   end
-  if utils.is_string(executables) and executables ~= "" then
-    setup_ls(executables, type)
+
+  for _, linter in pairs(lvim.lang[filetype].linters) do
+    local builtin_diagnoser = null_ls.builtins.diagnostics[linter.exe]
+    Log:get_default().debug("validating lint provider: ", linter.exe)
+    -- special case: fallback to "eslint"
+    -- https://github.com/jose-elias-alvarez/null-ls.nvim/blob/9b8458bd1648e84169a7e8638091ba15c2f20fc0/doc/BUILTINS.md#eslint
+    -- if provider.exe
+    if linter.exe == "eslint_d" then
+      builtin_diagnoser = null_ls.builtins.diagnostics.eslint.with { command = "eslint_d" }
+    end
+    if not vim.tbl_contains(M.requested_providers, builtin_diagnoser) then
+      -- FIXME: why doesn't this work?
+      -- builtin_diagnoser._opts.args = linter.args or builtin_diagnoser._opts.args
+      -- builtin_diagnoser._opts.to_stdin = linter.stdin or builtin_diagnoser._opts.to_stdin
+      local resolved_path = validate_provider_request(builtin_diagnoser)
+      if resolved_path then
+        builtin_diagnoser._opts.command = resolved_path
+        table.insert(M.requested_providers, builtin_diagnoser)
+        Log:get_default().info("Using linter provider", builtin_diagnoser.name)
+      else
+        -- mark it here to avoid re-doing the lookup again
+        register_failed_request(filetype, linter.exe, "linters")
+      end
+    end
   end
-end
 
--- TODO: return the formatter if one was registered, then turn off the builtin formatter
-function M.setup(filetype)
-  setup(filetype, "formatting")
-  setup(filetype, "diagnostics")
-  lvim.sources = sources
-  return sources
+  null_ls.register { sources = M.requested_providers }
 end
 
 return M

+ 140 - 0
lua/lsp/peek.lua

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

+ 0 - 122
lua/lsp/service.lua

@@ -1,122 +0,0 @@
-local M = {}
-
-local function lsp_highlight_document(client)
-  if lvim.lsp.document_highlight == false then
-    return -- we don't need further
-  end
-  -- Set autocommands conditional on server_capabilities
-  if client.resolved_capabilities.document_highlight then
-    vim.api.nvim_exec(
-      [[
-      hi LspReferenceRead cterm=bold ctermbg=red guibg=#464646
-      hi LspReferenceText cterm=bold ctermbg=red guibg=#464646
-      hi LspReferenceWrite cterm=bold ctermbg=red guibg=#464646
-      augroup lsp_document_highlight
-        autocmd! * <buffer>
-        autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()
-        autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references()
-      augroup END
-    ]],
-      false
-    )
-  end
-end
-
-function M.lsp_highlight_document(client)
-  lsp_highlight_document(client)
-end
-
--- Taken from https://www.reddit.com/r/neovim/comments/gyb077/nvimlsp_peek_defination_javascript_ttserver/
-function M.preview_location(location, context, before_context)
-  -- location may be LocationLink or Location (more useful for the former)
-  context = context or 15
-  before_context = before_context or 0
-  local uri = location.targetUri or location.uri
-  if uri == nil then
-    return
-  end
-  local bufnr = vim.uri_to_bufnr(uri)
-  if not vim.api.nvim_buf_is_loaded(bufnr) then
-    vim.fn.bufload(bufnr)
-  end
-
-  local range = location.targetRange or location.range
-  local contents = vim.api.nvim_buf_get_lines(
-    bufnr,
-    range.start.line - before_context,
-    range["end"].line + 1 + context,
-    false
-  )
-  local filetype = vim.api.nvim_buf_get_option(bufnr, "filetype")
-  return vim.lsp.util.open_floating_preview(contents, filetype, { border = lvim.lsp.popup_border })
-end
-
-function M.preview_location_callback(_, method, result)
-  local context = 15
-  if result == nil or vim.tbl_isempty(result) then
-    print("No location found: " .. method)
-    return nil
-  end
-  if vim.tbl_islist(result) then
-    M.floating_buf, M.floating_win = M.preview_location(result[1], context)
-  else
-    M.floating_buf, M.floating_win = M.preview_location(result, context)
-  end
-end
-
-function M.PeekDefinition()
-  if vim.tbl_contains(vim.api.nvim_list_wins(), M.floating_win) then
-    vim.api.nvim_set_current_win(M.floating_win)
-  else
-    local params = vim.lsp.util.make_position_params()
-    return vim.lsp.buf_request(0, "textDocument/definition", params, M.preview_location_callback)
-  end
-end
-
-function M.PeekTypeDefinition()
-  if vim.tbl_contains(vim.api.nvim_list_wins(), M.floating_win) then
-    vim.api.nvim_set_current_win(M.floating_win)
-  else
-    local params = vim.lsp.util.make_position_params()
-    return vim.lsp.buf_request(0, "textDocument/typeDefinition", params, M.preview_location_callback)
-  end
-end
-
-function M.PeekImplementation()
-  if vim.tbl_contains(vim.api.nvim_list_wins(), M.floating_win) then
-    vim.api.nvim_set_current_win(M.floating_win)
-  else
-    local params = vim.lsp.util.make_position_params()
-    return vim.lsp.buf_request(0, "textDocument/implementation", params, M.preview_location_callback)
-  end
-end
-
-function M.common_on_attach(client, bufnr)
-  if lvim.lsp.on_attach_callback then
-    lvim.lsp.on_attach_callback(client, bufnr)
-  end
-  lsp_highlight_document(client)
-end
-
-function M.no_formatter_on_attach(client, bufnr)
-  if lvim.lsp.on_attach_callback then
-    lvim.lsp.on_attach_callback(client, bufnr)
-  end
-  lsp_highlight_document(client)
-  client.resolved_capabilities.document_formatting = false
-end
-
-function M.common_capabilities()
-  local capabilities = vim.lsp.protocol.make_client_capabilities()
-  capabilities.textDocument.completion.completionItem.snippetSupport = true
-  capabilities.textDocument.completion.completionItem.resolveSupport = {
-    properties = {
-      "documentation",
-      "detail",
-      "additionalTextEdits",
-    },
-  }
-  return capabilities
-end
-
-return M

+ 0 - 20
lua/lsp/signs.lua

@@ -1,20 +0,0 @@
-local M = {}
-function M.setup()
-  vim.fn.sign_define(
-    "LspDiagnosticsSignError",
-    { texthl = "LspDiagnosticsSignError", text = "", numhl = "LspDiagnosticsSignError" }
-  )
-  vim.fn.sign_define(
-    "LspDiagnosticsSignWarning",
-    { texthl = "LspDiagnosticsSignWarning", text = "", numhl = "LspDiagnosticsSignWarning" }
-  )
-  vim.fn.sign_define(
-    "LspDiagnosticsSignHint",
-    { texthl = "LspDiagnosticsSignHint", text = "", numhl = "LspDiagnosticsSignHint" }
-  )
-  vim.fn.sign_define(
-    "LspDiagnosticsSignInformation",
-    { texthl = "LspDiagnosticsSignInformation", text = "", numhl = "LspDiagnosticsSignInformation" }
-  )
-end
-return M

+ 8 - 5
lua/plugins.lua

@@ -18,8 +18,6 @@ return {
 
   { "nvim-lua/popup.nvim" },
   { "nvim-lua/plenary.nvim" },
-  { "tjdevries/astronauta.nvim", commit = "e69d7bdc4183047c4700427922c4a3cc1e3258c6" },
-
   -- Telescope
   {
     "nvim-telescope/telescope.nvim",
@@ -57,7 +55,7 @@ return {
   {
     "hrsh7th/vim-vsnip",
     -- wants = "friendly-snippets",
-    event = "InsertCharPre",
+    event = "InsertEnter",
   },
   {
     "rafamadriz/friendly-snippets",
@@ -135,6 +133,8 @@ return {
     config = function()
       local status_ok, nvim_comment = pcall(require, "nvim_comment")
       if not status_ok then
+        local Log = require "core.log"
+        Log:get_default().error "Failed to load nvim-comment"
         return
       end
       nvim_comment.setup()
@@ -147,12 +147,14 @@ return {
   -- vim-rooter
   {
     "airblade/vim-rooter",
+    -- event = "BufReadPre",
     config = function()
-      vim.g.rooter_silent_chdir = 1
+      require("core.rooter").setup()
       if lvim.builtin.rooter.on_config_done then
         lvim.builtin.rooter.on_config_done()
       end
     end,
+    disable = not lvim.builtin.rooter.active,
   },
 
   -- Icons
@@ -174,12 +176,13 @@ return {
   {
     "romgrk/barbar.nvim",
     config = function()
-      require "core.bufferline"
+      require("core.bufferline").setup()
       if lvim.builtin.bufferline.on_config_done then
         lvim.builtin.bufferline.on_config_done()
       end
     end,
     event = "BufWinEnter",
+    disable = not lvim.builtin.bufferline.active,
   },
 
   -- Debugging

+ 16 - 9
lua/spacegray/LSP.lua

@@ -19,15 +19,15 @@ local LSP = {
   LspDiagnosticsWarning = { fg = C.warning_orange },
   LspDiagnosticsInformation = { fg = C.info_yellow },
   LspDiagnosticsHint = { fg = C.hint_blue },
-  LspDiagnosticsUnderlineError = { fg = C.error_red },
-  LspDiagnosticsUnderlineWarning = { fg = C.warning_orange },
-  LspDiagnosticsUnderlineInformation = { fg = C.info_yellow },
-  LspDiagnosticsUnderlineHint = { fg = C.hint_blue },
-  QuickScopePrimary = { fg = C.cyan_test, style = "underline" },
-  QuickScopeSecondary = { fg = C.purple_test, style = "underline" },
+  LspDiagnosticsUnderlineError = { style = "underline" },
+  LspDiagnosticsUnderlineWarning = { style = "underline" },
+  LspDiagnosticsUnderlineInformation = { style = "underline" },
+  LspDiagnosticsUnderlineHint = { style = "underline" },
+  QuickScopePrimary = { fg = C.purple_test, style = "underline" },
+  QuickScopeSecondary = { fg = C.cyan_test, style = "underline" },
   TelescopeSelection = { fg = C.hint_blue },
   TelescopeMatching = { fg = C.info_yellow, style = "bold" },
-  TelescopeBorder = { fg = C.cyan, bg = C.bg },
+  TelescopeBorder = { fg = C.cyan, bg = Config.transparent_background and "NONE" or C.bg },
   NvimTreeFolderIcon = { fg = C.blue },
   NvimTreeIndentMarker = { fg = C.gray },
   NvimTreeNormal = { fg = C.light_gray, bg = C.alt_bg },
@@ -45,6 +45,10 @@ local LSP = {
   NvimTreeSymlink = { fg = C.cyan },
   NvimTreeRootFolder = { fg = C.fg, style = "bold" },
   NvimTreeExecFile = { fg = C.green },
+  LirFloatNormal = { fg = C.light_gray, bg = C.alt_bg },
+  LirDir = { fg = C.blue },
+  LirSymLink = { fg = C.cyan },
+  LirEmptyDirText = { fg = C.blue },
   BufferCurrent = { fg = C.fg, bg = C.bg },
   BufferCurrentIndex = { fg = C.fg, bg = C.bg },
   BufferCurrentMod = { fg = C.info_yellow, bg = C.bg },
@@ -53,7 +57,7 @@ local LSP = {
   BufferVisible = { fg = C.fg, bg = C.bg },
   BufferVisibleIndex = { fg = C.fg, bg = C.bg },
   BufferVisibleMod = { fg = C.info_yellow, bg = C.bg },
-  BufferVisibleSign = { fg = C.hint_blue, bg = C.bg },
+  BufferVisibleSign = { fg = C.gray, bg = C.bg },
   BufferVisibleTarget = { fg = C.red, bg = C.bg, style = "bold" },
   BufferInactive = { fg = C.gray, bg = C.alt_bg },
   BufferInactiveIndex = { fg = C.gray, bg = C.alt_bg },
@@ -65,11 +69,14 @@ local LSP = {
   StatusLineSeparator = { fg = C.alt_bg },
   StatusLineTerm = { fg = C.alt_bg },
   StatusLineTermNC = { fg = C.alt_bg },
-  CodiVirtualText = { fg = C.pale_purple },
+  CodiVirtualText = { fg = C.hint_blue },
   IndentBlanklineContextChar = { fg = C.accent },
   DashboardHeader = { fg = C.blue },
   DashboardCenter = { fg = C.purple },
   DashboardFooter = { fg = C.cyan },
+  xmlTag = { fg = C.cyan },
+  xmlTagName = { fg = C.cyan },
+  xmlEndTag = { fg = C.cyan },
   CompeDocumentation = { bg = C.alt_bg },
   DiffViewNormal = { fg = C.gray, bg = C.alt_bg },
   DiffviewStatusAdded = { fg = C.sign_add },

+ 16 - 16
lua/spacegray/Treesitter.lua

@@ -14,7 +14,7 @@ local Treesitter = {
   TSNamespace = { fg = C.blue },
   TSRepeat = { fg = C.blue },
   TSConstant = { fg = C.orange },
-  TSConstBuiltin = { fg = C.orange },
+  TSConstBuiltin = { fg = C.red },
   TSFloat = { fg = C.red },
   TSNumber = { fg = C.red },
   TSBoolean = { fg = C.red },
@@ -24,32 +24,32 @@ local Treesitter = {
   TSFuncBuiltin = { fg = C.yellow },
   TSMethod = { fg = C.yellow },
   TSConstMacro = { fg = C.cyan },
-  TSFuncMacro = { fg = C.cyan },
-  TSVariable = { fg = C.white },
-  TSVariableBuiltin = { fg = C.cyan },
-  TSProperty = { fg = C.cyan },
-  TSOperator = { fg = C.gray_blue },
-  TSField = { fg = C.white },
-  TSParameter = { fg = C.white },
-  TSParameterReference = { fg = C.white },
-  TSSymbol = { fg = C.white },
+  TSFuncMacro = { fg = C.yellow },
+  TSVariable = { fg = C.light_blue },
+  TSVariableBuiltin = { fg = C.light_blue },
+  TSProperty = { fg = C.light_blue },
+  TSOperator = { fg = C.gray },
+  TSField = { fg = C.light_blue },
+  TSParameter = { fg = C.light_blue },
+  TSParameterReference = { fg = C.light_blue },
+  TSSymbol = { fg = C.light_blue },
   TSText = { fg = C.fg },
   TSPunctDelimiter = { fg = C.gray },
   TSTagDelimiter = { fg = C.gray },
   TSPunctBracket = { fg = C.gray },
   TSPunctSpecial = { fg = C.gray },
   TSString = { fg = C.green },
-  TSStringRegex = { fg = C.light_green },
-  TSStringEscape = { fg = C.light_green },
+  TSStringRegex = { fg = C.yellow_orange },
+  TSStringEscape = { fg = C.yellow_orange },
   TSTag = { fg = C.blue },
   TSEmphasis = { style = "italic" },
   TSUnderline = { style = "underline" },
   TSTitle = { fg = C.blue, style = "bold" },
-  TSLiteral = { fg = C.green },
-  TSURI = { fg = C.cyan, style = "underline" },
+  TSLiteral = { fg = C.yellow_orange },
+  TSURI = { fg = C.yellow_orange, style = "underline" },
   TSKeywordOperator = { fg = C.blue },
-  TSStructure = { fg = C.purple_test },
-  TSStrong = { fg = C.yellow },
+  TSStructure = { fg = C.light_blue },
+  TSStrong = { fg = C.yellow_orange },
   TSQueryLinterError = { fg = C.warning_orange },
 }
 

+ 2 - 2
lua/spacegray/Whichkey.lua

@@ -2,8 +2,8 @@ local Whichkey = {
   WhichKey = { fg = C.purple },
   WhichKeySeperator = { fg = C.green },
   WhichKeyGroup = { fg = C.blue },
-  WhichKeyDesc = { fg = C.cyan },
-  WhichKeyFloat = { bg = C.alt_bg },
+  WhichKeyDesc = { fg = C.light_blue },
+  WhichKeyFloat = { bg = C.dark },
 }
 
 return Whichkey

+ 29 - 29
lua/spacegray/highlights.lua

@@ -1,15 +1,15 @@
 local highlights = {
   Normal = { fg = C.fg, bg = Config.transparent_background and "NONE" or C.bg },
   SignColumn = { bg = C.bg },
-  MsgArea = { fg = C.fg, bg = C.bg },
+  MsgArea = { fg = C.fg, bg = Config.transparent_background and "NONE" or C.bg },
   ModeMsg = { fg = C.fg, bg = C.bg },
   MsgSeparator = { fg = C.fg, bg = C.bg },
   SpellBad = { fg = C.error_red, style = "underline" },
   SpellCap = { fg = C.yellow, style = "underline" },
   SpellLocal = { fg = C.green, style = "underline" },
   SpellRare = { fg = C.purple, style = "underline" },
-  NormalNC = { fg = C.fg, bg = C.bg },
-  Pmenu = { fg = C.white, bg = C.accent },
+  NormalNC = { fg = C.fg, bg = Config.transparent_background and "NONE" or C.bg },
+  Pmenu = { fg = C.light_gray, bg = C.popup_back },
   PmenuSel = { fg = C.alt_bg, bg = C.blue },
   WildMenu = { fg = C.alt_bg, bg = C.blue },
   CursorLineNr = { fg = C.light_gray, style = "bold" },
@@ -17,24 +17,24 @@ local highlights = {
   Folded = { fg = C.accent, bg = C.alt_bg },
   FoldColumn = { fg = C.accent, bg = C.alt_bg },
   LineNr = { fg = C.gray },
-  FloatBorder = { fg = C.gray, bg = C.alt_bg },
-  Whitespace = { fg = C.gray },
-  VertSplit = { fg = C.bg, bg = C.accent },
-  CursorLine = { bg = C.alt_bg },
-  CursorColumn = { bg = C.alt_bg },
-  ColorColumn = { bg = C.alt_bg },
-  NormalFloat = { bg = C.alt_bg },
-  Visual = { bg = C.alt_bg },
+  FloatBoder = { fg = C.gray, bg = C.alt_bg },
+  Whitespace = { fg = C.bg },
+  VertSplit = { fg = C.bg, bg = C.fg },
+  CursorLine = { bg = C.dark },
+  CursorColumn = { bg = C.dark },
+  ColorColumn = { bg = C.dark },
+  NormalFloat = { bg = C.dark },
+  Visual = { bg = C.ui_blue },
   VisualNOS = { bg = C.alt_bg },
-  WarningMsg = { fg = C.warning_orange, bg = C.bg },
+  WarningMsg = { fg = C.error_red, bg = C.bg },
   DiffAdd = { fg = C.alt_bg, bg = C.sign_add },
   DiffChange = { fg = C.alt_bg, bg = C.sign_change, style = "underline" },
   DiffDelete = { fg = C.alt_bg, bg = C.sign_delete },
   QuickFixLine = { bg = C.accent },
   PmenuSbar = { bg = C.alt_bg },
-  PmenuThumb = { bg = C.white },
+  PmenuThumb = { bg = C.gray },
   MatchWord = { style = "underline" },
-  MatchParen = { fg = C.pale_purple, bg = C.bg, style = "underline" },
+  MatchParen = { fg = C.hint_blue, bg = C.bg, style = "underline" },
   MatchWordCur = { style = "underline" },
   MatchParenCur = { style = "underline" },
   Cursor = { fg = C.cursor_fg, bg = C.cursor_bg },
@@ -47,23 +47,23 @@ local highlights = {
   SpecialKey = { fg = C.blue, style = "bold" },
   Title = { fg = C.blue, style = "bold" },
   ErrorMsg = { fg = C.error_red, bg = C.bg, style = "bold" },
-  Search = { fg = C.hint_blue, bg = C.alt_bg },
-  IncSearch = { fg = C.hint_blue, bg = C.alt_bg },
-  Substitute = { fg = C.alt_bg, bg = C.gray_blue },
-  MoreMsg = { fg = C.cyan },
-  Question = { fg = C.cyan },
+  Search = { fg = C.light_gray, bg = C.search_blue },
+  IncSearch = { fg = C.light_gray, bg = C.search_blue },
+  Substitute = { fg = C.light_gray, bg = C.search_orange },
+  MoreMsg = { fg = C.orange },
+  Question = { fg = C.orange },
   EndOfBuffer = { fg = C.bg },
   NonText = { fg = C.bg },
-  Variable = { fg = C.white },
+  Variable = { fg = C.light_blue },
   String = { fg = C.green },
   Character = { fg = C.light_green },
-  Constant = { fg = C.orange },
+  Constant = { fg = C.blue },
   Number = { fg = C.red },
   Boolean = { fg = C.red },
   Float = { fg = C.red },
-  Identifier = { fg = C.white },
+  Identifier = { fg = C.light_blue },
   Function = { fg = C.yellow },
-  Operator = { fg = C.gray_blue },
+  Operator = { fg = C.gray },
   Type = { fg = C.purple },
   StorageClass = { fg = C.purple },
   Structure = { fg = C.purple },
@@ -75,12 +75,12 @@ local highlights = {
   Label = { fg = C.blue },
   Exception = { fg = C.blue },
   Include = { fg = C.blue },
-  PreProc = { fg = C.cyan },
-  Define = { fg = C.cyan },
-  Macro = { fg = C.cyan },
-  PreCondit = { fg = C.cyan },
+  PreProc = { fg = C.purple },
+  Define = { fg = C.purple },
+  Macro = { fg = C.purple },
+  PreCondit = { fg = C.purple },
   Special = { fg = C.orange },
-  SpecialChar = { fg = C.orange },
+  SpecialChar = { fg = C.white },
   Tag = { fg = C.blue },
   Debug = { fg = C.red },
   Delimiter = { fg = C.gray },
@@ -91,7 +91,7 @@ local highlights = {
   Ignore = { fg = C.cyan, bg = C.bg, style = "bold" },
   Todo = { fg = C.red, bg = C.bg, style = "bold" },
   Error = { fg = C.error_red, bg = C.bg, style = "bold" },
-  TabLine = { fg = C.white, bg = C.alt_bg },
+  TabLine = { fg = C.light_gray, bg = C.alt_bg },
   TabLineSel = { fg = C.white, bg = C.alt_bg },
   TabLineFill = { fg = C.white, bg = C.alt_bg },
 }

+ 13 - 0
lua/spacegray/init.lua

@@ -9,6 +9,17 @@ vim.g.colors_name = "spacegray"
 local util = require "spacegray.util"
 Config = require "spacegray.config"
 C = require "spacegray.palette"
+
+local async
+async = vim.loop.new_async(vim.schedule_wrap(function()
+  local skeletons = {}
+  for _, skeleton in ipairs(skeletons) do
+    util.initialise(skeleton)
+  end
+
+  async:close()
+end))
+
 local highlights = require "spacegray.highlights"
 local Treesitter = require "spacegray.Treesitter"
 local markdown = require "spacegray.markdown"
@@ -28,3 +39,5 @@ local skeletons = {
 for _, skeleton in ipairs(skeletons) do
   util.initialise(skeleton)
 end
+
+async:send()

+ 25 - 18
lua/spacegray/palette.lua

@@ -1,21 +1,27 @@
 local colors = {
-  fg = "#c8c9d1",
-  bg = "#212121",
-  alt_bg = "#2a2a2a",
-  accent = "#383d45",
-  white = "#c8c9d1",
-  gray = "#858585",
+  fg = "#ABB2BF",
+  bg = "#202020",
+  alt_bg = "#262626",
+  dark = "#222222",
+  accent = "#AAAAAA",
+  popup_back = "#2D2D30",
+  search_orange = "#613214",
+  search_blue = "#5e81ac",
+  white = "#D8DEE9",
+  gray = "#9BA1AB",
   light_gray = "#c8c9c1",
-  blue = "#5486c0",
-  gray_blue = "#66899d",
-  cyan = "#65a7c5",
-  red = "#b04b57",
-  green = "#87b379",
-  light_green = "#b2d77c",
-  yellow = "#eeba5a",
-  orange = "#c6735a",
-  purple = "#bf83c1",
-  pale_purple = "#7199ee",
+  blue = "#5f8ccd",
+  dark_blue = "#223E55",
+  light_blue = "#8dc0d5",
+  green = "#83ba8b",
+  cyan = "#4EC9B0",
+  light_green = "#B5CEA8",
+  red = "#D16969",
+  orange = "#D1866B",
+  light_red = "#CA535F",
+  yellow = "#ECCC8E",
+  yellow_orange = "#D7BA7D",
+  purple = "#BF82B4",
   magenta = "#D16D9E",
   cursor_fg = "#515052",
   cursor_bg = "#AEAFAD",
@@ -26,8 +32,9 @@ local colors = {
   warning_orange = "#ff8800",
   info_yellow = "#FFCC66",
   hint_blue = "#4FC1FF",
-  purple_test = "#ff00ff",
-  cyan_test = "#00ffff",
+  purple_test = "#ff007c",
+  cyan_test = "#00dfff",
+  ui_blue = "#264F78",
 }
 
 return colors

+ 47 - 0
lua/utils/ft.lua

@@ -0,0 +1,47 @@
+-- Here be dragons
+-- Opening files with telescope will not start LSP without this
+local ft = {}
+
+ft.find_lua_ftplugins = function(filetype)
+  local patterns = {
+    string.format("ftplugin/%s.lua", filetype),
+
+    -- Looks like we don't need this, because the first one works
+    -- string.format("after/ftplugin/%s.lua", filetype),
+  }
+
+  local result = {}
+  for _, pat in ipairs(patterns) do
+    vim.list_extend(result, vim.api.nvim_get_runtime_file(pat, true))
+  end
+
+  return result
+end
+
+ft.do_filetype = function(filetype)
+  local ftplugins = ft.find_lua_ftplugins(filetype)
+
+  local f_env = setmetatable({
+    -- Override print, so the prints still go through, otherwise it's confusing for people
+    print = vim.schedule_wrap(print),
+  }, {
+    -- Buf default back read/write to whatever is going on in the global landscape
+    __index = _G,
+    __newindex = _G,
+  })
+
+  for _, file in ipairs(ftplugins) do
+    local f = loadfile(file)
+    if not f then
+      vim.api.nvim_err_writeln("Unable to load file: " .. file)
+    else
+      local ok, msg = pcall(setfenv(f, f_env))
+
+      if not ok then
+        vim.api.nvim_err_writeln("Error while processing file: " .. file .. "\n" .. msg)
+      end
+    end
+  end
+end
+
+return ft

+ 46 - 34
lua/utils/init.lua

@@ -1,4 +1,6 @@
 local utils = {}
+local Log = require "core.log"
+local uv = vim.loop
 
 -- recursive Print (structure, limit, separator)
 local function r_inspect_settings(structure, limit, separator)
@@ -16,7 +18,7 @@ local function r_inspect_settings(structure, limit, separator)
 
   if ts == "table" then
     for k, v in pairs(structure) do
-      -- replace non alpha keys wih ["key"]
+      -- replace non alpha keys with ["key"]
       if tostring(k):match "[^%a_]" then
         k = '["' .. tostring(k) .. '"]'
       end
@@ -68,6 +70,9 @@ function utils.toggle_autoformat()
         },
       },
     }
+    if Log:get_default() then
+      Log:get_default().info "Format on save active"
+    end
   end
 
   if not lvim.format_on_save then
@@ -76,12 +81,16 @@ function utils.toggle_autoformat()
         :autocmd! autoformat
       endif
     ]]
+    if Log:get_default() then
+      Log:get_default().info "Format on save off"
+    end
   end
 end
 
 function utils.reload_lv_config()
   vim.cmd "source ~/.local/share/lunarvim/lvim/lua/settings.lua"
-  vim.cmd "source ~/.config/lvim/lv-config.lua"
+  vim.cmd("source " .. USER_CONFIG_PATH)
+  require("keymappings").setup() -- this should be done before loading the plugins
   vim.cmd "source ~/.local/share/lunarvim/lvim/lua/plugins.lua"
   local plugins = require "plugins"
   local plugin_loader = require("plugin-loader").init()
@@ -90,6 +99,7 @@ function utils.reload_lv_config()
   vim.cmd ":PackerCompile"
   vim.cmd ":PackerInstall"
   -- vim.cmd ":PackerClean"
+  Log:get_default().info "Reloaded configuration"
 end
 
 function utils.check_lsp_client_active(name)
@@ -102,48 +112,42 @@ function utils.check_lsp_client_active(name)
   return false
 end
 
-function utils.is_table(t)
-  return type(t) == "table"
+function utils.get_active_client_by_ft(filetype)
+  local clients = vim.lsp.get_active_clients()
+  for _, client in pairs(clients) do
+    if client.name == lvim.lang[filetype].lsp.provider then
+      return client
+    end
+  end
+  return nil
 end
 
-function utils.is_string(t)
-  return type(t) == "string"
-end
+-- TODO: consider porting this logic to null-ls instead
+function utils.get_supported_linters_by_filetype(filetype)
+  local null_ls = require "null-ls"
+  local matches = {}
+  for _, provider in pairs(null_ls.builtins.diagnostics) do
+    if vim.tbl_contains(provider.filetypes, filetype) then
+      local provider_name = provider.name
 
-function utils.has_value(tab, val)
-  for _, value in ipairs(tab) do
-    if value == val then
-      return true
+      table.insert(matches, provider_name)
     end
   end
 
-  return false
+  return matches
 end
 
-function utils.add_keymap(mode, opts, keymaps)
-  for _, keymap in ipairs(keymaps) do
-    vim.api.nvim_set_keymap(mode, keymap[1], keymap[2], opts)
+function utils.get_supported_formatters_by_filetype(filetype)
+  local null_ls = require "null-ls"
+  local matches = {}
+  for _, provider in pairs(null_ls.builtins.formatting) do
+    if provider.filetypes and vim.tbl_contains(provider.filetypes, filetype) then
+      -- table.insert(matches, { provider.name, ft })
+      table.insert(matches, provider.name)
+    end
   end
-end
 
-function utils.add_keymap_normal_mode(opts, keymaps)
-  utils.add_keymap("n", opts, keymaps)
-end
-
-function utils.add_keymap_visual_mode(opts, keymaps)
-  utils.add_keymap("v", opts, keymaps)
-end
-
-function utils.add_keymap_visual_block_mode(opts, keymaps)
-  utils.add_keymap("x", opts, keymaps)
-end
-
-function utils.add_keymap_insert_mode(opts, keymaps)
-  utils.add_keymap("i", opts, keymaps)
-end
-
-function utils.add_keymap_term_mode(opts, keymaps)
-  utils.add_keymap("t", opts, keymaps)
+  return matches
 end
 
 function utils.unrequire(m)
@@ -162,6 +166,14 @@ function utils.gsub_args(args)
   return args
 end
 
+--- Checks whether a given path exists and is a file.
+--@param filename (string) path to check
+--@returns (bool)
+function utils.is_file(filename)
+  local stat = uv.fs_stat(filename)
+  return stat and stat.type == "file" or false
+end
+
 return utils
 
 -- TODO: find a new home for these autocommands

+ 1 - 1
utils/bin/lvim

@@ -1,3 +1,3 @@
 #!/bin/sh
 
-nvim -u ~/.local/share/lunarvim/lvim/init.lua --cmd "set runtimepath+=~/.local/share/lunarvim/lvim" "$@"
+exec nvim -u ~/.local/share/lunarvim/lvim/init.lua --cmd "set runtimepath+=~/.local/share/lunarvim/lvim" "$@"

+ 11 - 0
utils/docker/Dockerfile

@@ -0,0 +1,11 @@
+FROM python:3
+
+SHELL ["/bin/bash", "-c"]
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+COPY script.sh /tmp/script.sh
+
+RUN bash -c "/tmp/script.sh"
+
+ENTRYPOINT ["/bin/bash"]

+ 23 - 0
utils/docker/script.sh

@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# Updating the package list
+apt-get update
+
+# Installing dependencies
+apt-get -y install tzdata sudo git nodejs npm git ripgrep fzf ranger curl fonts-hack-ttf
+
+pip3 install ueberzug neovim-remote
+npm install tree-sitter-cli neovim
+
+# Installing Neovim
+mkdir -p /tmp/neovim
+cd /tmp/neovim || exit
+curl -L -o nvim.appimage https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage
+chmod u+x nvim.appimage
+./nvim.appimage --appimage-extract
+mv squashfs-root /usr/local/neovim
+ln -s /usr/local/neovim/usr/bin/nvim /usr/bin/nvim
+rm ./nvim.appimage
+
+# Installing LunarVim
+LVBRANCH=master bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/rolling/utils/installer/install.sh)

+ 33 - 19
utils/installer/lv-config.example-no-ts.lua → utils/installer/config.example-no-ts.lua

@@ -5,25 +5,26 @@ lvim.format_on_save = true
 lvim.lint_on_save = true
 lvim.colorscheme = "spacegray"
 
--- keymappings
+-- keymappings [view all the defaults by pressing <leader>Lk]
 lvim.leader = "space"
--- overwrite the key-mappings provided by LunarVim for any mode, or leave it empty to keep them
--- lvim.keys.normal_mode = {
---   Page down/up
---   {'[d', '<PageUp>'},
---   {']d', '<PageDown>'},
---
---   Navigate buffers
---   {'<Tab>', ':bnext<CR>'},
---   {'<S-Tab>', ':bprevious<CR>'},
+-- add your own keymapping
+lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
+-- unmap a default keymapping
+-- lvim.keys.normal_mode["<C-Up>"] = ""
+-- edit a default keymapping
+-- lvim.keys.normal_mode["<C-q>"] = ":q<cr>"
+
+-- Use which-key to add extra bindings with the leader-key prefix
+-- lvim.builtin.which_key.mappings["P"] = { "<cmd>lua require'telescope'.extensions.project.project{}<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" },
 -- }
--- if you just want to augment the existing ones then use the utility function
--- require("utils").add_keymap_insert_mode({ silent = true }, {
--- { "<C-s>", ":w<cr>" },
--- { "<C-c>", "<ESC>" },
--- })
--- you can also use the native vim way directly
--- vim.api.nvim_set_keymap("i", "<C-Space>", "compe#complete()", { noremap = true, silent = true, expr = true })
 
 -- TODO: User Config for predefined plugins
 -- After changing plugin config exit and reopen LunarVim, Run :PackerInstall :PackerCompile
@@ -48,6 +49,21 @@ lvim.builtin.treesitter.highlight.enabled = true
 --   buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc")
 -- end
 
+-- set a formatter if you want to override the default lsp one (if it exists)
+-- lvim.lang.python.formatters = {
+--   {
+--     exe = "black",
+--     args = {}
+--   }
+-- }
+-- set an additional linter
+-- lvim.lang.python.linters = {
+--   {
+--     exe = "flake8",
+--     args = {}
+--   }
+-- }
+
 -- Additional Plugins
 -- lvim.plugins = {
 --     {"folke/tokyonight.nvim"}, {
@@ -61,5 +77,3 @@ lvim.builtin.treesitter.highlight.enabled = true
 -- lvim.autocommands.custom_groups = {
 --   { "BufWinEnter", "*.lua", "setlocal ts=8 sw=8" },
 -- }
-
--- Additional Leader bindings for WhichKey

+ 34 - 31
utils/installer/lv-config.example.lua → utils/installer/config.example.lua

@@ -9,29 +9,31 @@ an executable
 -- THESE ARE EXAMPLE CONFIGS FEEL FREE TO CHANGE TO WHATEVER YOU WANT
 
 -- general
-
+lvim.log.level = "warn"
 lvim.format_on_save = true
 lvim.lint_on_save = true
 lvim.colorscheme = "spacegray"
--- keymappings
+
+-- keymappings [view all the defaults by pressing <leader>Lk]
 lvim.leader = "space"
--- overwrite the key-mappings provided by LunarVim for any mode, or leave it empty to keep them
--- lvim.keys.normal_mode = {
---   Page down/up
---   {'[d', '<PageUp>'},
---   {']d', '<PageDown>'},
---
---   Navigate buffers
---   {'<Tab>', ':bnext<CR>'},
---   {'<S-Tab>', ':bprevious<CR>'},
+-- add your own keymapping
+lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
+-- unmap a default keymapping
+-- lvim.keys.normal_mode["<C-Up>"] = ""
+-- edit a default keymapping
+-- lvim.keys.normal_mode["<C-q>"] = ":q<cr>"
+
+-- Use which-key to add extra bindings with the leader-key prefix
+-- lvim.builtin.which_key.mappings["P"] = { "<cmd>lua require'telescope'.extensions.project.project{}<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" },
 -- }
--- if you just want to augment the existing ones then use the utility function
--- require("utils").add_keymap_insert_mode({ silent = true }, {
--- { "<C-s>", ":w<cr>" },
--- { "<C-c>", "<ESC>" },
--- })
--- you can also use the native vim way directly
--- vim.api.nvim_set_keymap("i", "<C-Space>", "compe#complete()", { noremap = true, silent = true, expr = true })
 
 -- TODO: User Config for predefined plugins
 -- After changing plugin config exit and reopen LunarVim, Run :PackerInstall :PackerCompile
@@ -56,7 +58,20 @@ lvim.builtin.treesitter.highlight.enabled = true
 --   buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc")
 -- end
 
--- python
+-- set a formatter if you want to override the default lsp one (if it exists)
+-- lvim.lang.python.formatters = {
+--   {
+--     exe = "black",
+--     args = {}
+--   }
+-- }
+-- set an additional linter
+-- lvim.lang.python.linters = {
+--   {
+--     exe = "flake8",
+--     args = {}
+--   }
+-- }
 
 -- Additional Plugins
 -- lvim.plugins = {
@@ -71,15 +86,3 @@ lvim.builtin.treesitter.highlight.enabled = true
 -- lvim.autocommands.custom_groups = {
 --   { "BufWinEnter", "*.lua", "setlocal ts=8 sw=8" },
 -- }
-
--- Additional Leader bindings for WhichKey
--- lvim.builtin.which_key.mappings["P"] = { "<cmd>lua require'telescope'.extensions.project.project{}<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" },
--- }

+ 38 - 5
utils/installer/install.sh

@@ -1,6 +1,7 @@
 #!/bin/sh
 #Set Variable to master is not set differently
 LVBRANCH="${LVBRANCH:-master}"
+USER_BIN_DIR="/usr/local/bin"
 set -o nounset # error when referencing undefined variable
 set -o errexit # exit when command fails
 
@@ -15,6 +16,10 @@ installnodeubuntu() {
 	sudo apt install npm
 }
 
+installnodetermux() {
+	apt install nodejs
+}
+
 moveoldlvim() {
 	echo "Not installing LunarVim"
 	echo "Please move your ~/.local/share/lunarvim folder before installing"
@@ -49,6 +54,7 @@ installnode() {
 	[ -f "/etc/artix-release" ] && installnodearch
 	[ -f "/etc/fedora-release" ] && installnodefedora
 	[ -f "/etc/gentoo-release" ] && installnodegentoo
+	[ -d "/data/data/com.termux" ] && installnodetermux
 	[ "$(uname -s | cut -c 1-10)" = "MINGW64_NT" ] && echo "Windows not currently supported"
 	sudo npm i -g neovim
 }
@@ -63,6 +69,10 @@ installpiponubuntu() {
 	sudo apt install python3-pip >/dev/null
 }
 
+installpipontermux() {
+	apt install python
+}
+
 installpiponarch() {
 	sudo pacman -S python-pip
 }
@@ -82,6 +92,7 @@ installpip() {
 	[ -f "/etc/arch-release" ] && installpiponarch
 	[ -f "/etc/fedora-release" ] && installpiponfedora
 	[ -f "/etc/gentoo-release" ] && installpipongentoo
+	[ -d "/data/data/com.termux" ] && installpipontermux
 	[ "$(uname -s | cut -c 1-10)" = "MINGW64_NT" ] && echo "Windows not currently supported"
 }
 
@@ -100,6 +111,12 @@ installpacker() {
 }
 
 cloneconfig() {
+	if [ -d "/data/data/com.termux" ]; then
+		sudo() {
+			eval "$@"
+		}
+		USER_BIN_DIR="$HOME/../usr/bin"
+	fi
 	echo "Cloning LunarVim configuration"
 	mkdir -p ~/.local/share/lunarvim
 	case "$@" in
@@ -108,12 +125,13 @@ cloneconfig() {
 		cp -r "$(pwd)" ~/.local/share/lunarvim/lvim
 		;;
 	*)
-		git clone --branch "$LVBRANCH" https://github.com/ChristianChiarulli/lunarvim.git ~/.local/share/lunarvim/lvim
+		git clone --branch "$LVBRANCH" https://github.com/lunarvim/lunarvim.git ~/.local/share/lunarvim/lvim
 		;;
 	esac
 	mkdir -p "$HOME/.config/lvim"
-	sudo cp "$HOME/.local/share/lunarvim/lvim/utils/bin/lvim" "/usr/local/bin"
-	cp "$HOME/.local/share/lunarvim/lvim/utils/installer/lv-config.example-no-ts.lua" "$HOME/.config/lvim/lv-config.lua"
+	sudo cp "$HOME/.local/share/lunarvim/lvim/utils/bin/lvim" "$USER_BIN_DIR"
+	sudo chmod a+rx "$USER_BIN_DIR"/lvim
+	cp "$HOME/.local/share/lunarvim/lvim/utils/installer/config.example-no-ts.lua" "$HOME/.config/lvim/config.lua"
 
 	nvim -u ~/.local/share/lunarvim/lvim/init.lua --cmd "set runtimepath+=~/.local/share/lunarvim/lvim" --headless \
 		+'autocmd User PackerComplete sleep 100m | qall' \
@@ -126,9 +144,9 @@ cloneconfig() {
 	printf "\nCompile Complete\n"
 
 	if [ -e "$HOME/.local/share/lunarvim/lvim/init.lua" ]; then
-		echo 'lv-config already present'
+		echo 'config.lua already present'
 	else
-		cp "$HOME/.local/share/lunarvim/lvim/utils/installer/lv-config.example.lua" "$HOME/.config/lvim/lv-config.lua"
+		cp "$HOME/.local/share/lunarvim/lvim/utils/installer/config.example.lua" "$HOME/.config/lvim/config.lua"
 	fi
 
 }
@@ -140,6 +158,11 @@ asktoinstallnode() {
 	[ "$answer" != "${answer#[Yy]}" ] && installnode
 }
 
+asktoinstallgit() {
+	echo "git not found, please install git"
+	exit
+}
+
 asktoinstallpip() {
 	# echo "pip not found"
 	# echo -n "Would you like to install pip now (y/n)? "
@@ -161,6 +184,12 @@ installonubuntu() {
 	npm install -g tree-sitter-cli
 }
 
+installtermux() {
+	apt install ripgrep fzf
+	pip install neovim-remote
+	npm install -g tree-sitter-cli
+}
+
 installonarch() {
 	sudo pacman -S ripgrep fzf
 	pip3 install neovim-remote
@@ -184,6 +213,7 @@ installextrapackages() {
 	[ -f "/etc/artix-release" ] && installonarch
 	[ -f "/etc/fedora-release" ] && installonfedora
 	[ -f "/etc/gentoo-release" ] && installongentoo
+	[ -d "/data/data/com.termux" ] && installtermux
 	[ "$(uname -s | cut -c 1-10)" = "MINGW64_NT" ] && echo "Windows not currently supported"
 }
 
@@ -202,6 +232,9 @@ esac
 # move old lvim directory if it exists
 [ -d "$HOME/.local/share/lunarvim" ] && moveoldlvim
 
+# install node and neovim support
+(command -v git >/dev/null && echo "git installed, moving on...") || asktoinstallgit
+
 # install pip
 (command -v pip3 >/dev/null && echo "pip installed, moving on...") || asktoinstallpip
 

+ 2 - 2
utils/installer/install_stylua.sh

@@ -30,7 +30,7 @@ function download_stylua() {
 		exit 1
 	fi
 
-	echo "Installtion in progress.."
+	echo "Installation in progress.."
 	unzip -q "$DOWNLOAD_DIR/$FILENAME.zip" -d "$DOWNLOAD_DIR"
 
 	if [ -f "$DOWNLOAD_DIR/stylua" ]; then
@@ -43,7 +43,7 @@ function download_stylua() {
 }
 
 function verify_install() {
-	echo "Verifying installtion.."
+	echo "Verifying installation.."
 	local DOWNLOADED_VER
 	DOWNLOADED_VER="$("$INSTALL_DIR/stylua" -V | awk '{ print $2 }')"
 	if [ "$DOWNLOADED_VER" != "$RELEASE" ]; then

+ 8 - 2
utils/installer/uninstall.sh

@@ -1,5 +1,11 @@
 #!/bin/sh
-
+USER_BIN_DIR="/usr/local/bin"
+if [ -d "/data/data/com.termux" ]; then
+	sudo() {
+		eval "$@"
+	}
+	USER_BIN_DIR="$HOME/../usr/bin"
+fi
 rm -rf ~/.local/share/lunarvim
-sudo rm /usr/local/bin/lvim
+sudo rm "$USER_BIN_DIR"/lvim
 rm -rf ~/.local/share/applications/lvim.desktop

+ 0 - 1
utils/lush-template/lua/lush_theme/lush_template.lua

@@ -43,7 +43,6 @@
 --  `:lua require('lush').ify()`
 
 local lush = require "lush"
-local hsl = lush.hsl
 
 local theme = lush(function()
   return {

Some files were not shown because too many files changed in this diff