summaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua')
-rw-r--r--lua/bootstrap.lua193
-rw-r--r--lua/config/defaults.lua1136
-rw-r--r--lua/config/init.lua141
-rw-r--r--lua/config/settings.lua6
-rw-r--r--lua/core/autocmds.lua5
-rw-r--r--lua/core/autopairs.lua62
-rw-r--r--lua/core/builtins/init.lua3
-rw-r--r--lua/core/cmp.lua260
-rw-r--r--lua/core/commands.lua4
-rw-r--r--lua/core/compe.lua133
-rw-r--r--lua/core/dap.lua15
-rw-r--r--lua/core/dashboard.lua27
-rw-r--r--lua/core/gitsigns.lua2
-rw-r--r--lua/core/info.lua91
-rw-r--r--lua/core/log.lua1
-rw-r--r--lua/core/lspinstall.lua19
-rw-r--r--lua/core/lualine/components.lua56
-rw-r--r--lua/core/lualine/styles.lua12
-rw-r--r--lua/core/nvimtree.lua41
-rw-r--r--lua/core/project.lua2
-rw-r--r--lua/core/telescope.lua81
-rw-r--r--lua/core/terminal.lua31
-rw-r--r--lua/core/which-key.lua51
-rw-r--r--lua/impatient.lua360
-rw-r--r--lua/impatient/profile.lua145
-rw-r--r--lua/interface/text.lua24
-rw-r--r--lua/keymappings.lua4
-rw-r--r--lua/lsp/config.lua45
-rw-r--r--lua/lsp/handlers.lua178
-rw-r--r--lua/lsp/init.lua177
-rw-r--r--lua/lsp/manager.lua86
-rw-r--r--lua/lsp/null-ls/formatters.lua52
-rw-r--r--lua/lsp/null-ls/init.lua60
-rw-r--r--lua/lsp/null-ls/linters.lua52
-rw-r--r--lua/lsp/null-ls/services.lua20
-rw-r--r--lua/lsp/peek.lua18
-rw-r--r--lua/lsp/providers/jsonls.lua197
-rw-r--r--lua/lsp/providers/sumneko_lua.lua19
-rw-r--r--lua/lsp/providers/vuels.lua26
-rw-r--r--lua/lsp/providers/yamlls.lua30
-rw-r--r--lua/lsp/templates.lua98
-rw-r--r--lua/lsp/utils.lua58
-rw-r--r--lua/lualine/themes/onedarker.lua35
-rw-r--r--lua/onedarker/Git.lua (renamed from lua/spacegray/Git.lua)0
-rw-r--r--lua/onedarker/LSP.lua (renamed from lua/spacegray/LSP.lua)30
-rw-r--r--lua/onedarker/Treesitter.lua66
-rw-r--r--lua/onedarker/Whichkey.lua (renamed from lua/spacegray/Whichkey.lua)4
-rw-r--r--lua/onedarker/config.lua (renamed from lua/spacegray/config.lua)0
-rw-r--r--lua/onedarker/diff.lua12
-rw-r--r--lua/onedarker/highlights.lua (renamed from lua/spacegray/highlights.lua)60
-rw-r--r--lua/onedarker/init.lua32
-rw-r--r--lua/onedarker/markdown.lua (renamed from lua/spacegray/markdown.lua)2
-rw-r--r--lua/onedarker/palette.lua45
-rw-r--r--lua/onedarker/util.lua (renamed from lua/spacegray/util.lua)0
-rw-r--r--lua/plugin-loader.lua43
-rw-r--r--lua/plugins.lua60
-rw-r--r--lua/spacegray/Treesitter.lua56
-rw-r--r--lua/spacegray/init.lua43
-rw-r--r--lua/spacegray/palette.lua40
-rw-r--r--lua/utils/hooks.lua33
-rw-r--r--lua/utils/init.lua121
-rw-r--r--lua/utils/table.lua24
62 files changed, 2774 insertions, 1953 deletions
diff --git a/lua/bootstrap.lua b/lua/bootstrap.lua
new file mode 100644
index 00000000..866403b7
--- /dev/null
+++ b/lua/bootstrap.lua
@@ -0,0 +1,193 @@
+local M = {}
+
+package.loaded["utils.hooks"] = nil
+local _, hooks = pcall(require, "utils.hooks")
+
+---Join path segments that were passed as input
+---@return string
+function _G.join_paths(...)
+ local uv = vim.loop
+ local path_sep = uv.os_uname().version:match "Windows" and "\\" or "/"
+ local result = table.concat({ ... }, path_sep)
+ return result
+end
+
+---Get the full path to `$LUNARVIM_RUNTIME_DIR`
+---@return string
+function _G.get_runtime_dir()
+ local lvim_runtime_dir = os.getenv "LUNARVIM_RUNTIME_DIR"
+ if not lvim_runtime_dir then
+ -- when nvim is used directly
+ return vim.fn.stdpath "config"
+ end
+ return lvim_runtime_dir
+end
+
+---Get the full path to `$LUNARVIM_CONFIG_DIR`
+---@return string
+function _G.get_config_dir()
+ local lvim_config_dir = os.getenv "LUNARVIM_CONFIG_DIR"
+ if not lvim_config_dir then
+ return vim.fn.stdpath "config"
+ end
+ return lvim_config_dir
+end
+
+---Get the full path to `$LUNARVIM_CACHE_DIR`
+---@return string
+function _G.get_cache_dir()
+ local lvim_cache_dir = os.getenv "LUNARVIM_CACHE_DIR"
+ if not lvim_cache_dir then
+ return vim.fn.stdpath "cache"
+ end
+ return lvim_cache_dir
+end
+
+---Get the full path to the currently installed lunarvim repo
+---@return string
+local function get_install_path()
+ local lvim_runtime_dir = os.getenv "LUNARVIM_RUNTIME_DIR"
+ if not lvim_runtime_dir then
+ -- when nvim is used directly
+ return vim.fn.stdpath "config"
+ end
+ return join_paths(lvim_runtime_dir, "lvim")
+end
+
+---Get currently installed version of LunarVim
+---@param type string can be "short"
+---@return string
+function _G.get_version(type)
+ type = type or ""
+ local lvim_full_ver = vim.fn.system("git -C " .. get_install_path() .. " describe --tags")
+
+ if string.match(lvim_full_ver, "%d") == nil then
+ return nil
+ end
+ if type == "short" then
+ return vim.fn.split(lvim_full_ver, "-")[1]
+ else
+ return string.sub(lvim_full_ver, 1, #lvim_full_ver - 1)
+ end
+end
+
+---Initialize the `&runtimepath` variables and prepare for startup
+---@return table
+function M:init()
+ self.runtime_dir = get_runtime_dir()
+ self.config_dir = get_config_dir()
+ self.cache_path = get_cache_dir()
+ self.install_path = get_install_path()
+
+ self.pack_dir = join_paths(self.runtime_dir, "site", "pack")
+ self.packer_install_dir = join_paths(self.runtime_dir, "site", "pack", "packer", "start", "packer.nvim")
+ self.packer_cache_path = join_paths(self.config_dir, "plugin", "packer_compiled.lua")
+
+ if os.getenv "LUNARVIM_RUNTIME_DIR" then
+ vim.opt.rtp:remove(join_paths(vim.fn.stdpath "data", "site"))
+ vim.opt.rtp:remove(join_paths(vim.fn.stdpath "data", "site", "after"))
+ vim.opt.rtp:prepend(join_paths(self.runtime_dir, "site"))
+ vim.opt.rtp:append(join_paths(self.runtime_dir, "site", "after"))
+
+ vim.opt.rtp:remove(vim.fn.stdpath "config")
+ vim.opt.rtp:remove(join_paths(vim.fn.stdpath "config", "after"))
+ vim.opt.rtp:prepend(self.config_dir)
+ vim.opt.rtp:append(join_paths(self.config_dir, "after"))
+ -- TODO: we need something like this: vim.opt.packpath = vim.opt.rtp
+
+ vim.cmd [[let &packpath = &runtimepath]]
+ vim.cmd("set spellfile=" .. join_paths(self.config_dir, "spell", "en.utf-8.add"))
+ end
+
+ vim.fn.mkdir(vim.fn.stdpath "cache", "p")
+
+ -- FIXME: currently unreliable in unit-tests
+ if not os.getenv "LVIM_TEST_ENV" then
+ require("impatient").setup {
+ path = vim.fn.stdpath "cache" .. "/lvim_cache",
+ enable_profiling = true,
+ }
+ end
+
+ local config = require "config"
+ config:init {
+ path = join_paths(self.config_dir, "config.lua"),
+ }
+
+ require("plugin-loader"):init {
+ package_root = self.pack_dir,
+ install_path = self.packer_install_dir,
+ }
+
+ return self
+end
+
+---Update LunarVim
+---pulls the latest changes from github and, resets the startup cache
+function M:update()
+ hooks.run_pre_update()
+ M:update_repo()
+ hooks.run_post_update()
+end
+
+local function git_cmd(subcmd)
+ local Job = require "plenary.job"
+ local Log = require "core.log"
+ local args = { "-C", get_install_path() }
+ vim.list_extend(args, subcmd)
+
+ local stderr = {}
+ local stdout, ret = Job
+ :new({
+ command = "git",
+ args = args,
+ cwd = get_install_path(),
+ on_stderr = function(_, data)
+ table.insert(stderr, data)
+ end,
+ })
+ :sync()
+
+ if not vim.tbl_isempty(stderr) then
+ Log:debug(stderr)
+ end
+
+ if not vim.tbl_isempty(stdout) then
+ Log:debug(stdout)
+ end
+
+ return ret
+end
+
+---pulls the latest changes from github
+function M:update_repo()
+ local Log = require "core.log"
+ local sub_commands = {
+ fetch = { "fetch" },
+ diff = { "diff", "--quiet", "@{upstream}" },
+ merge = { "merge", "--ff-only", "--progress" },
+ }
+ Log:info "Checking for updates"
+
+ local ret = git_cmd(sub_commands.fetch)
+ if ret ~= 0 then
+ Log:error "Update failed! Check the log for further information"
+ return
+ end
+
+ ret = git_cmd(sub_commands.diff)
+
+ if ret == 0 then
+ Log:info "LunarVim is already up-to-date"
+ return
+ end
+
+ ret = git_cmd(sub_commands.merge)
+
+ if ret ~= 0 then
+ Log:error "Update failed! Please pull the changes manually instead."
+ return
+ end
+end
+
+return M
diff --git a/lua/config/defaults.lua b/lua/config/defaults.lua
index 9bd1bdd8..f030234d 100644
--- a/lua/config/defaults.lua
+++ b/lua/config/defaults.lua
@@ -1,19 +1,14 @@
local home_dir = vim.loop.os_homedir()
-CONFIG_PATH = home_dir .. "/.local/share/lunarvim/lvim"
-DATA_PATH = vim.fn.stdpath "data"
-CACHE_PATH = vim.fn.stdpath "cache"
-TERMINAL = vim.fn.expand "$TERMINAL"
-USER = vim.fn.expand "$USER"
-vim.cmd [[ set spellfile=~/.config/lvim/spell/en.utf-8.add ]]
+local utils = require "utils"
lvim = {
leader = "space",
- colorscheme = "spacegray",
+ colorscheme = "onedarker",
line_wrap_cursor_movement = true,
transparent_window = false,
format_on_save = true,
- vsnip_dir = home_dir .. "/.config/snippets",
- database = { save_location = "~/.config/lunarvim_db", auto_execute = 1 },
+ vsnip_dir = utils.join_paths(home_dir, ".config", "snippets"),
+ database = { save_location = utils.join_paths(home_dir, ".config", "lunarvim_db"), auto_execute = 1 },
keys = {},
builtin = {},
@@ -33,1131 +28,10 @@ lvim = {
},
},
},
-
- lsp = {
- completion = {
- item_kind = {
- "  (Text) ",
- "  (Method)",
- "  (Function)",
- "  (Constructor)",
- " ﴲ (Field)",
- "[] (Variable)",
- "  (Class)",
- " ﰮ (Interface)",
- "  (Module)",
- " 襁 (Property)",
- "  (Unit)",
- "  (Value)",
- " 練 (Enum)",
- "  (Keyword)",
- "  (Snippet)",
- "  (Color)",
- "  (File)",
- "  (Reference)",
- "  (Folder)",
- "  (EnumMember)",
- " ﲀ (Constant)",
- " ﳤ (Struct)",
- "  (Event)",
- "  (Operator)",
- "  (TypeParameter)",
- },
- },
- diagnostics = {
- signs = {
- active = true,
- values = {
- { name = "LspDiagnosticsSignError", text = "" },
- { name = "LspDiagnosticsSignWarning", text = "" },
- { name = "LspDiagnosticsSignHint", text = "" },
- { name = "LspDiagnosticsSignInformation", text = "" },
- },
- },
- virtual_text = {
- prefix = "",
- spacing = 0,
- },
- underline = true,
- severity_sort = true,
- },
- override = {},
- document_highlight = true,
- popup_border = "single",
- on_attach_callback = nil,
- on_init_callback = nil,
- null_ls = {
- setup = {},
- },
- },
-
plugins = {
-- use config.lua for this not put here
},
autocommands = {},
-}
-
-local schemas = nil
-local status_ok, jsonls_settings = pcall(require, "nlspsettings.jsonls")
-if status_ok then
- schemas = jsonls_settings.get_default_schemas()
-end
-
--- TODO move all of this into lang specific files, only require when using
-lvim.lang = {
- asm = {
- formatters = {
- -- {
- -- exe = "asmfmt",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "",
- setup = {},
- },
- },
- beancount = {
- formatters = {
- -- {
- -- exe = "bean_format",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "beancount",
- setup = {
- cmd = { "beancount-langserver" },
- },
- },
- },
- c = {
- formatters = {
- -- {
- -- exe = "clang_format",
- -- args = {},
- -- },
- -- {
- -- exe = "uncrustify",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "clangd",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/cpp/clangd/bin/clangd",
- "--background-index",
- "--header-insertion=never",
- "--cross-file-rename",
- "--clang-tidy",
- "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*",
- },
- },
- },
- },
- cpp = {
- formatters = {
- -- {
- -- exe = "clang_format",
- -- args = {},
- -- },
- -- {
- -- exe = "uncrustify",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "clangd",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/cpp/clangd/bin/clangd",
- "--background-index",
- "--header-insertion=never",
- "--cross-file-rename",
- "--clang-tidy",
- "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*",
- },
- },
- },
- },
- crystal = {
- formatters = {
- -- {
- -- exe = "crystal_format",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "crystalline",
- setup = {
- cmd = { "crystalline" },
- },
- },
- },
- cs = {
- formatters = {
- -- {
- -- exe = "clang_format ",
- -- args = {},
- -- },
- -- {
- -- exe = "uncrustify",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "omnisharp",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/csharp/omnisharp/run",
- "--languageserver",
- "--hostPID",
- tostring(vim.fn.getpid()),
- },
- },
- },
- },
- cmake = {
- formatters = {
- -- {
- -- exe = "cmake_format",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "cmake",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/cmake/venv/bin/cmake-language-server",
- },
- },
- },
- },
- clojure = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "clojure_lsp",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/clojure/clojure-lsp",
- },
- },
- },
- },
- css = {
- formatters = {
- -- {
- -- exe = "prettier",
- -- args = {},
- -- },
- -- {
- -- exe = "prettierd",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "cssls",
- setup = {
- cmd = {
- "node",
- DATA_PATH .. "/lspinstall/css/vscode-css/css-language-features/server/dist/node/cssServerMain.js",
- "--stdio",
- },
- },
- },
- },
- less = {
- formatters = {
- -- {
- -- exe = "prettier",
- -- args = {},
- -- },
- -- {
- -- exe = "prettierd",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "cssls",
- setup = {
- cmd = {
- "node",
- DATA_PATH .. "/lspinstall/css/vscode-css/css-language-features/server/dist/node/cssServerMain.js",
- "--stdio",
- },
- },
- },
- },
- d = {
- formatters = {
- -- {
- -- exe = "dfmt",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "serve_d",
- setup = {
- cmd = { "serve-d" },
- },
- },
- },
- dart = {
- formatters = {
- -- {
- -- exe = "dart_format",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "dartls",
- setup = {
- cmd = {
- "dart",
- "/usr/lib/dart/bin/snapshots/analysis_server.dart.snapshot",
- "--lsp",
- },
- },
- },
- },
- docker = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "dockerls",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/dockerfile/node_modules/.bin/docker-langserver",
- "--stdio",
- },
- },
- },
- },
- elixir = {
- formatters = {
- -- {
- -- exe = "mix",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "elixirls",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/elixir/elixir-ls/language_server.sh",
- },
- },
- },
- },
- elm = {
- formatters = {
- -- {
- -- exe = "elm_format",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "elmls",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-language-server",
- },
- -- init_options = {
- -- elmAnalyseTrigger = "change",
- -- elmFormatPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-format",
- -- elmPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/",
- -- elmTestPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-test",
- -- },
- },
- },
- },
- erlang = {
- formatters = {
- -- {
- -- exe = "erlfmt",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "erlangls",
- setup = {
- cmd = {
- "erlang_ls",
- },
- },
- },
- },
- emmet = { active = false },
- fish = {
- formatters = {
- -- {
- -- exe = "fish_indent",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "",
- setup = {},
- },
- },
- fortran = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "fortls",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/fortran/venv/bin/fortls",
- },
- },
- },
- },
- go = {
- formatters = {
- -- {
- -- exe = "gofmt",
- -- args = {},
- -- },
- -- {
- -- exe = "goimports",
- -- args = {},
- -- },
- -- {
- -- exe = "gofumpt",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "gopls",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/go/gopls",
- },
- },
- },
- },
- graphql = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "graphql",
- setup = {
- cmd = {
- "graphql-lsp",
- "server",
- "-m",
- "stream",
- },
- },
- },
- },
- haskell = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "hls",
- setup = {
- cmd = { DATA_PATH .. "/lspinstall/haskell/hls" },
- },
- },
- },
- html = {
- formatters = {
- -- {
- -- exe = "prettier",
- -- args = {},
- -- },
- -- {
- -- exe = "prettierd",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "html",
- setup = {
- cmd = {
- "node",
- DATA_PATH .. "/lspinstall/html/vscode-html/html-language-features/server/dist/node/htmlServerMain.js",
- "--stdio",
- },
- },
- },
- },
- java = {
- formatters = {
- -- {
- -- exe = "clang_format",
- -- args = {},
- -- },
- -- {
- -- exe = "uncrustify",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "jdtls",
- setup = {
- cmd = { DATA_PATH .. "/lspinstall/java/jdtls.sh" },
- },
- },
- },
- json = {
- formatters = {
- -- {
- -- exe = "json_tool",
- -- args = {},
- -- },
- -- {
- -- exe = "prettier",
- -- args = {},
- -- },
- -- {
- -- exe = "prettierd",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "jsonls",
- setup = {
- cmd = {
- "node",
- DATA_PATH .. "/lspinstall/json/vscode-json/json-language-features/server/dist/node/jsonServerMain.js",
- "--stdio",
- },
- settings = {
- json = {
- schemas = schemas,
- -- = {
- -- {
- -- fileMatch = { "package.json" },
- -- url = "https://json.schemastore.org/package.json",
- -- },
- -- },
- },
- },
- commands = {
- Format = {
- function()
- vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 })
- end,
- },
- },
- },
- },
- },
- julia = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "julials",
- setup = {
- {
- "julia",
- "--startup-file=no",
- "--history-file=no",
- -- vim.fn.expand "~/.config/nvim/lua/lsp/julia/run.jl",
- CONFIG_PATH .. "/utils/julia/run.jl",
- },
- },
- },
- },
- kotlin = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "kotlin_language_server",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/kotlin/server/bin/kotlin-language-server",
- },
- root_dir = function(fname)
- local util = require "lspconfig/util"
-
- local root_files = {
- "settings.gradle", -- Gradle (multi-project)
- "settings.gradle.kts", -- Gradle (multi-project)
- "build.xml", -- Ant
- "pom.xml", -- Maven
- }
-
- local fallback_root_files = {
- "build.gradle", -- Gradle
- "build.gradle.kts", -- Gradle
- }
- return util.root_pattern(unpack(root_files))(fname) or util.root_pattern(unpack(fallback_root_files))(fname)
- end,
- },
- },
- },
- lua = {
- formatters = {
- -- {
- -- exe = "stylua",
- -- args = {},
- -- },
- -- {
- -- exe = "lua_format",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "sumneko_lua",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/lua/sumneko-lua-language-server",
- "-E",
- DATA_PATH .. "/lspinstall/lua/main.lua",
- },
- settings = {
- Lua = {
- runtime = {
- -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim)
- version = "LuaJIT",
- -- Setup your lua path
- path = vim.split(package.path, ";"),
- },
- diagnostics = {
- -- Get the language server to recognize the `vim` global
- globals = { "vim", "lvim" },
- },
- workspace = {
- -- Make the server aware of Neovim runtime files
- library = {
- [vim.fn.expand "~/.local/share/lunarvim/lvim/lua"] = true,
- [vim.fn.expand "$VIMRUNTIME/lua"] = true,
- [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true,
- },
- maxPreload = 100000,
- preloadFileSize = 1000,
- },
- },
- },
- },
- },
- },
- nginx = {
- formatters = {
- -- {
- -- exe = "nginx_beautifier",
- -- args = {
- -- provider = "",
- -- setup = {},
- -- },
- -- },
- },
- linters = {},
- lsp = {},
- },
- perl = {
- formatters = {
- -- {
- -- exe = "perltidy",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "",
- setup = {},
- },
- },
- sql = {
- formatters = {
- -- {
- -- exe = "sqlformat",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "sqls",
- setup = {
- cmd = { "sqls" },
- },
- },
- },
- php = {
- formatters = {
- -- {
- -- exe = "phpcbf",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "intelephense",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/php/node_modules/.bin/intelephense",
- "--stdio",
- },
- filetypes = { "php", "phtml" },
- settings = {
- intelephense = {
- environment = {
- phpVersion = "7.4",
- },
- },
- },
- },
- },
- },
- puppet = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "puppet",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/puppet/puppet-editor-services/puppet-languageserver",
- "--stdio",
- },
- },
- },
- },
- javascript = {
- formatters = {
- -- {
- -- exe = "prettier",
- -- args = {},
- -- },
- -- {
- -- exe = "prettier_d_slim",
- -- args = {},
- -- },
- -- {
- -- exe = "prettierd",
- -- args = {},
- -- },
- },
- -- @usage can be {"eslint"} or {"eslint_d"}
- linters = {},
- lsp = {
- provider = "tsserver",
- setup = {
- cmd = {
- -- TODO:
- DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",
- "--stdio",
- },
- },
- },
- },
- javascriptreact = {
- formatters = {
- -- {
- -- exe = "prettier",
- -- args = {},
- -- },
- -- {
- -- exe = "prettier_d_slim",
- -- args = {},
- -- },
- -- {
- -- exe = "prettierd",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "tsserver",
- setup = {
- cmd = {
- -- TODO:
- DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",
- "--stdio",
- },
- },
- },
- },
- python = {
- formatters = {
- -- {
- -- exe = "yapf",
- -- args = {},
- -- },
- -- {
- -- exe = "isort",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "pyright",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/python/node_modules/.bin/pyright-langserver",
- "--stdio",
- },
- },
- },
- },
- -- R -e 'install.packages("formatR",repos = "http://cran.us.r-project.org")'
- -- R -e 'install.packages("readr",repos = "http://cran.us.r-project.org")'
- r = {
- formatters = {
- -- {
- -- exe = "format_r",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "r_language_server",
- setup = {
- cmd = {
- "R",
- "--slave",
- "-e",
- "languageserver::run()",
- },
- },
- },
- },
- ruby = {
- formatters = {
- -- {
- -- exe = "rufo",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "solargraph",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/ruby/solargraph/solargraph",
- "stdio",
- },
- filetypes = { "ruby" },
- init_options = {
- formatting = true,
- },
- root_dir = function(fname)
- local util = require("lspconfig").util
- return util.root_pattern("Gemfile", ".git")(fname)
- end,
- settings = {
- solargraph = {
- diagnostics = true,
- },
- },
- },
- },
- },
- rust = {
- formatters = {
- -- {
- -- exe = "rustfmt",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "rust_analyzer",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/rust/rust-analyzer",
- },
- },
- },
- },
- scala = {
- formatters = {
- -- {
- -- exe = "scalafmt",
- -- args = {},
- -- },
- },
- linters = { "" },
- lsp = {
- provider = "metals",
- setup = {},
- },
- },
- sh = {
- formatters = {
- -- {
- -- exe = "shfmt",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "bashls",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/bash/node_modules/.bin/bash-language-server",
- "start",
- },
- },
- },
- },
- svelte = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "svelte",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/svelte/node_modules/.bin/svelteserver",
- "--stdio",
- },
- },
- },
- },
- swift = {
- formatters = {
- -- {
- -- exe = "swiftformat",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "sourcekit",
- setup = {
- cmd = {
- "xcrun",
- "sourcekit-lsp",
- },
- },
- },
- },
- tailwindcss = {
- active = false,
- filetypes = {
- "html",
- "css",
- "scss",
- "javascript",
- "javascriptreact",
- "typescript",
- "typescriptreact",
- },
- },
- terraform = {
- formatters = {
- -- {
- -- exe = "terraform_fmt",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "terraformls",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/terraform/terraform-ls",
- "serve",
- },
- },
- },
- },
- tex = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "texlab",
- setup = {
- cmd = { DATA_PATH .. "/lspinstall/latex/texlab" },
- },
- },
- },
- typescript = {
- formatters = {
- -- {
- -- exe = "prettier",
- -- args = {},
- -- },
- -- {
- -- exe = "prettierd",
- -- args = {},
- -- },
- -- {
- -- exe = "prettier_d_slim",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "tsserver",
- setup = {
- cmd = {
- -- TODO:
- DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",
- "--stdio",
- },
- },
- },
- },
- typescriptreact = {
- formatters = {
- -- {
- -- exe = "prettier",
- -- args = {},
- -- },
- -- {
- -- exe = "prettierd",
- -- args = {},
- -- },
- -- {
- -- exe = "prettier_d_slim",
- -- args = {},
- -- },
- },
- -- @usage can be {"eslint"} or {"eslint_d"}
- linters = {},
- lsp = {
- provider = "tsserver",
- setup = {
- cmd = {
- -- TODO:
- DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",
- "--stdio",
- },
- },
- },
- },
- vim = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "vimls",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/vim/node_modules/.bin/vim-language-server",
- "--stdio",
- },
- },
- },
- },
- vue = {
- formatters = {
- -- {
- -- exe = "prettier",
- -- args = {},
- -- },
- -- {
- -- exe = "prettierd",
- -- args = {},
- -- },
- -- {
- -- exe = "prettier_d_slim",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "vuels",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/vue/node_modules/.bin/vls",
- },
- },
- },
- },
- yaml = {
- formatters = {
- -- {
- -- exe = "prettier",
- -- args = {},
- -- },
- -- {
- -- exe = "prettierd",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "yamlls",
- setup = {
- cmd = {
- DATA_PATH .. "/lspinstall/yaml/node_modules/.bin/yaml-language-server",
- "--stdio",
- },
- },
- },
- },
- zig = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "zls",
- setup = {
- cmd = {
- "zls",
- },
- },
- },
- },
- gdscript = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "gdscript",
- setup = {
- cmd = {
- "nc",
- "localhost",
- "6008",
- },
- },
- },
- },
- ps1 = {
- formatters = {},
- linters = {},
- lsp = {
- provider = "powershell_es",
- setup = {
- bundle_path = "",
- },
- },
- },
- nix = {
- formatters = {
- -- {
- -- exe = "nixfmt",
- -- args = {},
- -- },
- },
- linters = {},
- lsp = {
- provider = "rnix",
- setup = {
- cmd = { "rnix-lsp" },
- filetypes = { "nix" },
- init_options = {},
- settings = {},
- root_dir = function(fname)
- local util = require "lspconfig/util"
- return util.root_pattern ".git"(fname) or vim.fn.getcwd()
- end,
- },
- },
- },
+ lang = {},
}
diff --git a/lua/config/init.lua b/lua/config/init.lua
index 332460d3..411f7a93 100644
--- a/lua/config/init.lua
+++ b/lua/config/init.lua
@@ -1,27 +1,146 @@
-local home_dir = vim.loop.os_homedir()
-local M = {
- path = string.format("%s/.config/lvim/config.lua", home_dir),
-}
+local M = {}
--- Initialize lvim default configuration
-- Define lvim global variable
-function M:init()
+function M:init(opts)
+ opts = opts or {}
+ self.path = opts.path
local utils = require "utils"
require "config.defaults"
+ -- Fallback config.lua to lv-config.lua
+ if not utils.is_file(self.path) then
+ local lv_config = self.path:gsub("config.lua$", "lv-config.lua")
+ print(self.path, "not found, falling back to", lv_config)
+
+ self.path = lv_config
+ end
+
local builtins = require "core.builtins"
builtins.config(self)
local settings = require "config.settings"
settings.load_options()
- -- Fallback config.lua to lv-config.lua
- if not utils.is_file(self.path) then
- local lv_config = self.path:gsub("config.lua$", "lv-config.lua")
- print(self.path, "not found, falling back to", lv_config)
+ local lvim_lsp_config = require "lsp.config"
+ lvim.lsp = vim.deepcopy(lvim_lsp_config)
- self.path = lv_config
+ local supported_languages = {
+ "asm",
+ "bash",
+ "beancount",
+ "bibtex",
+ "bicep",
+ "c",
+ "c_sharp",
+ "clojure",
+ "cmake",
+ "comment",
+ "commonlisp",
+ "cpp",
+ "crystal",
+ "cs",
+ "css",
+ "cuda",
+ "d",
+ "dart",
+ "dockerfile",
+ "dot",
+ "elixir",
+ "elm",
+ "emmet",
+ "erlang",
+ "fennel",
+ "fish",
+ "fortran",
+ "gdscript",
+ "glimmer",
+ "go",
+ "gomod",
+ "graphql",
+ "haskell",
+ "hcl",
+ "heex",
+ "html",
+ "java",
+ "javascript",
+ "javascriptreact",
+ "jsdoc",
+ "json",
+ "json5",
+ "jsonc",
+ "julia",
+ "kotlin",
+ "latex",
+ "ledger",
+ "less",
+ "lua",
+ "markdown",
+ "nginx",
+ "nix",
+ "ocaml",
+ "ocaml_interface",
+ "perl",
+ "php",
+ "pioasm",
+ "ps1",
+ "puppet",
+ "python",
+ "ql",
+ "query",
+ "r",
+ "regex",
+ "rst",
+ "ruby",
+ "rust",
+ "scala",
+ "scss",
+ "sh",
+ "solidity",
+ "sparql",
+ "sql",
+ "supercollider",
+ "surface",
+ "svelte",
+ "swift",
+ "tailwindcss",
+ "terraform",
+ "tex",
+ "tlaplus",
+ "toml",
+ "tsx",
+ "turtle",
+ "typescript",
+ "typescriptreact",
+ "verilog",
+ "vim",
+ "vue",
+ "yaml",
+ "yang",
+ "zig",
+ }
+
+ require("lsp.manager").init_defaults(supported_languages)
+end
+
+local function deprecation_notice()
+ local in_headless = #vim.api.nvim_list_uis() == 0
+ if in_headless then
+ return
+ end
+
+ for lang, entry in pairs(lvim.lang) do
+ local deprecated_config = entry["lsp"] or {}
+ if not vim.tbl_isempty(deprecated_config) then
+ local msg = string.format(
+ "Deprecation notice: [lvim.lang.%s.lsp] setting is no longer supported. See https://github.com/LunarVim/LunarVim#breaking-changes",
+ lang
+ )
+ vim.schedule(function()
+ vim.notify(msg, vim.log.levels.WARN)
+ end)
+ end
end
end
@@ -38,6 +157,8 @@ function M:load(config_path)
return
end
+ deprecation_notice()
+
self.path = config_path
autocmds.define_augroups(lvim.autocommands)
diff --git a/lua/config/settings.lua b/lua/config/settings.lua
index ba71a922..90042c4f 100644
--- a/lua/config/settings.lua
+++ b/lua/config/settings.lua
@@ -1,5 +1,5 @@
local M = {}
-
+local utils = require "utils"
M.load_options = function()
local default_options = {
backup = false, -- creates a backup file
@@ -28,7 +28,7 @@ M.load_options = function()
timeoutlen = 100, -- time to wait for a mapped sequence to complete (in milliseconds)
title = true, -- set the title of window to the value of the titlestring
-- opt.titlestring = "%<%F%=%l/%L - nvim" -- what the title of the window will be set to
- undodir = CACHE_PATH .. "/undo", -- set an undo directory
+ undodir = utils.join_paths(get_cache_dir(), "undo"), -- set an undo directory
undofile = true, -- enable persistent undo
updatetime = 300, -- faster completion
writebackup = false, -- if a file is being edited by another program (or was written to file while editing with another program), it is not allowed to be edited
@@ -45,7 +45,7 @@ M.load_options = function()
spelllang = "en",
scrolloff = 8, -- is one of my fav
sidescrolloff = 8,
- } --- VIM ONLY COMMANDS ---cmd "filetype plugin on"cmd('let &titleold="' .. TERMINAL .. '"')cmd "set inccommand=split"cmd "set iskeyword+=-"
+ }
--- SETTINGS ---
diff --git a/lua/core/autocmds.lua b/lua/core/autocmds.lua
index 041926e5..662afcfa 100644
--- a/lua/core/autocmds.lua
+++ b/lua/core/autocmds.lua
@@ -14,6 +14,11 @@ lvim.autocommands = {
"nnoremap <silent> <buffer> q :q<CR>",
},
{
+ "FileType",
+ "lsp-installer",
+ "nnoremap <silent> <buffer> q :q<CR>",
+ },
+ {
"TextYankPost",
"*",
"lua require('vim.highlight').on_yank({higroup = 'Search', timeout = 200})",
diff --git a/lua/core/autopairs.lua b/lua/core/autopairs.lua
index 24aa1875..eb080fb1 100644
--- a/lua/core/autopairs.lua
+++ b/lua/core/autopairs.lua
@@ -4,11 +4,13 @@ function M.config()
lvim.builtin.autopairs = {
active = true,
on_config_done = nil,
- ---@usage map <CR> on insert mode
- map_cr = true,
---@usage auto insert after select function or method item
- -- NOTE: This should be wrapped into a function so that it is re-evaluated when opening new files
- map_complete = vim.bo.filetype ~= "tex",
+ map_complete = true,
+ ---@usage -- modifies the function or method delimiter by filetypes
+ map_char = {
+ all = "(",
+ tex = "{",
+ },
---@usage check treesitter
check_ts = true,
ts_config = {
@@ -20,36 +22,46 @@ function M.config()
end
M.setup = function()
- -- skip it, if you use another global object
- _G.MUtils = {}
local autopairs = require "nvim-autopairs"
local Rule = require "nvim-autopairs.rule"
+ local cond = require "nvim-autopairs.conds"
- vim.g.completion_confirm_key = ""
- MUtils.completion_confirm = function()
- if vim.fn.pumvisible() ~= 0 then
- if vim.fn.complete_info()["selected"] ~= -1 then
- return vim.fn["compe#confirm"](autopairs.esc "<cr>")
- else
- return autopairs.esc "<cr>"
+ autopairs.setup {
+ check_ts = lvim.builtin.autopairs.check_ts,
+ ts_config = lvim.builtin.autopairs.ts_config,
+ }
+
+ -- vim.g.completion_confirm_key = ""
+
+ autopairs.add_rule(Rule("$$", "$$", "tex"))
+ autopairs.add_rules {
+ Rule("$", "$", { "tex", "latex" }) -- don't add a pair if the next character is %
+ :with_pair(cond.not_after_regex_check "%%") -- don't add a pair if the previous character is xxx
+ :with_pair(cond.not_before_regex_check("xxx", 3)) -- don't move right when repeat character
+ :with_move(cond.none()) -- don't delete if the next character is xx
+ :with_del(cond.not_after_regex_check "xx") -- disable add newline when press <cr>
+ :with_cr(cond.none()),
+ }
+ autopairs.add_rules {
+ Rule("$$", "$$", "tex"):with_pair(function(opts)
+ print(vim.inspect(opts))
+ if opts.line == "aa $$" then
+ -- don't add pair on that line
+ return false
end
- else
- return autopairs.autopairs_cr()
- end
- end
+ end),
+ }
- if package.loaded["compe"] then
- require("nvim-autopairs.completion.compe").setup {
- map_cr = lvim.builtin.autopairs.map_cr,
+ if package.loaded["cmp"] then
+ require("nvim-autopairs.completion.cmp").setup {
+ map_cr = false,
map_complete = lvim.builtin.autopairs.map_complete,
+ map_char = lvim.builtin.autopairs.map_char,
}
+ -- we map CR explicitly in cmp.lua but we still need to setup the autopairs CR keymap
+ vim.api.nvim_set_keymap("i", "<CR>", "v:lua.MPairs.autopairs_cr()", { expr = true, noremap = true })
end
- autopairs.setup {
- check_ts = lvim.builtin.autopairs.check_ts,
- ts_config = lvim.builtin.autopairs.ts_config,
- }
-
require("nvim-treesitter.configs").setup { autopairs = { enable = true } }
local ts_conds = require "nvim-autopairs.ts-conds"
diff --git a/lua/core/builtins/init.lua b/lua/core/builtins/init.lua
index 32f96af5..c3b3618f 100644
--- a/lua/core/builtins/init.lua
+++ b/lua/core/builtins/init.lua
@@ -4,7 +4,7 @@ local builtins = {
"keymappings",
"core.which-key",
"core.gitsigns",
- "core.compe",
+ "core.cmp",
"core.dashboard",
"core.dap",
"core.terminal",
@@ -15,7 +15,6 @@ local builtins = {
"core.bufferline",
"core.autopairs",
"core.comment",
- "core.lspinstall",
"core.lualine",
}
diff --git a/lua/core/cmp.lua b/lua/core/cmp.lua
new file mode 100644
index 00000000..d5d92314
--- /dev/null
+++ b/lua/core/cmp.lua
@@ -0,0 +1,260 @@
+local M = {}
+
+local check_backspace = function()
+ local col = vim.fn.col "." - 1
+ return col == 0 or vim.fn.getline("."):sub(col, col):match "%s"
+end
+
+local function T(str)
+ return vim.api.nvim_replace_termcodes(str, true, true, true)
+end
+
+local is_emmet_active = function()
+ local clients = vim.lsp.buf_get_clients()
+
+ for _, client in pairs(clients) do
+ if client.name == "emmet_ls" then
+ return true
+ end
+ end
+ return false
+end
+
+M.config = function()
+ local status_cmp_ok, cmp = pcall(require, "cmp")
+ if not status_cmp_ok then
+ return
+ end
+ local status_luasnip_ok, luasnip = pcall(require, "luasnip")
+ if not status_luasnip_ok then
+ return
+ end
+ local win_get_cursor = vim.api.nvim_win_get_cursor
+ local get_current_buf = vim.api.nvim_get_current_buf
+
+ local function inside_snippet()
+ -- for outdated versions of luasnip
+ if not luasnip.session.current_nodes then
+ return false
+ end
+
+ local node = luasnip.session.current_nodes[get_current_buf()]
+ if not node then
+ return false
+ end
+
+ local snip_begin_pos, snip_end_pos = node.parent.snippet.mark:pos_begin_end()
+ local pos = win_get_cursor(0)
+ pos[1] = pos[1] - 1 -- LuaSnip is 0-based not 1-based like nvim for rows
+ return pos[1] >= snip_begin_pos[1] and pos[1] <= snip_end_pos[1]
+ end
+
+ ---sets the current buffer's luasnip to the one nearest the cursor
+ ---@return boolean true if a node is found, false otherwise
+ local function seek_luasnip_cursor_node()
+ -- for outdated versions of luasnip
+ if not luasnip.session.current_nodes then
+ return false
+ end
+
+ local pos = win_get_cursor(0)
+ pos[1] = pos[1] - 1
+ local node = luasnip.session.current_nodes[get_current_buf()]
+ if not node then
+ return false
+ end
+
+ local snippet = node.parent.snippet
+ local exit_node = snippet.insert_nodes[0]
+
+ -- exit early if we're past the exit node
+ if exit_node then
+ local exit_pos_end = exit_node.mark:pos_end()
+ if (pos[1] > exit_pos_end[1]) or (pos[1] == exit_pos_end[1] and pos[2] > exit_pos_end[2]) then
+ snippet:remove_from_jumplist()
+ luasnip.session.current_nodes[get_current_buf()] = nil
+
+ return false
+ end
+ end
+
+ node = snippet.inner_first:jump_into(1, true)
+ while node ~= nil and node.next ~= nil and node ~= snippet do
+ local n_next = node.next
+ local next_pos = n_next and n_next.mark:pos_begin()
+ local candidate = n_next ~= snippet and next_pos and (pos[1] < next_pos[1])
+ or (pos[1] == next_pos[1] and pos[2] < next_pos[2])
+
+ -- Past unmarked exit node, exit early
+ if n_next == nil or n_next == snippet.next then
+ snippet:remove_from_jumplist()
+ luasnip.session.current_nodes[get_current_buf()] = nil
+
+ return false
+ end
+
+ if candidate then
+ luasnip.session.current_nodes[get_current_buf()] = node
+ return true
+ end
+
+ local ok
+ ok, node = pcall(node.jump_from, node, 1, true) -- no_move until last stop
+ if not ok then
+ snippet:remove_from_jumplist()
+ luasnip.session.current_nodes[get_current_buf()] = nil
+
+ return false
+ end
+ end
+
+ -- No candidate, but have an exit node
+ if exit_node then
+ -- to jump to the exit node, seek to snippet
+ luasnip.session.current_nodes[get_current_buf()] = snippet
+ return true
+ end
+
+ -- No exit node, exit from snippet
+ snippet:remove_from_jumplist()
+ luasnip.session.current_nodes[get_current_buf()] = nil
+ return false
+ end
+
+ lvim.builtin.cmp = {
+ confirm_opts = {
+ behavior = cmp.ConfirmBehavior.Replace,
+ select = false,
+ },
+ experimental = {
+ ghost_text = true,
+ native_menu = false,
+ },
+ formatting = {
+ kind_icons = {
+ Class = " ",
+ Color = " ",
+ Constant = "ﲀ ",
+ Constructor = " ",
+ Enum = "練",
+ EnumMember = " ",
+ Event = " ",
+ Field = " ",
+ File = "",
+ Folder = " ",
+ Function = " ",
+ Interface = "ﰮ ",
+ Keyword = " ",
+ Method = " ",
+ Module = " ",
+ Operator = "",
+ Property = " ",
+ Reference = " ",
+ Snippet = " ",
+ Struct = " ",
+ Text = " ",
+ TypeParameter = " ",
+ Unit = "塞",
+ Value = " ",
+ Variable = " ",
+ },
+ format = function(entry, vim_item)
+ vim_item.kind = lvim.builtin.cmp.formatting.kind_icons[vim_item.kind]
+ vim_item.menu = ({
+ nvim_lsp = "(LSP)",
+ emoji = "(Emoji)",
+ path = "(Path)",
+ calc = "(Calc)",
+ cmp_tabnine = "(Tabnine)",
+ vsnip = "(Snippet)",
+ luasnip = "(Snippet)",
+ buffer = "(Buffer)",
+ })[entry.source.name]
+ vim_item.dup = ({
+ buffer = 1,
+ path = 1,
+ nvim_lsp = 0,
+ })[entry.source.name] or 0
+ return vim_item
+ end,
+ },
+ snippet = {
+ expand = function(args)
+ require("luasnip").lsp_expand(args.body)
+ end,
+ },
+ documentation = {
+ border = { "╭", "─", "╮", "│", "╯", "─", "╰", "│" },
+ },
+ sources = {
+ { name = "nvim_lsp" },
+ { name = "path" },
+ { name = "luasnip" },
+ { name = "cmp_tabnine" },
+ { name = "nvim_lua" },
+ { name = "buffer" },
+ { name = "calc" },
+ { name = "emoji" },
+ { name = "treesitter" },
+ { name = "crates" },
+ },
+ mapping = {
+ ["<C-d>"] = cmp.mapping.scroll_docs(-4),
+ ["<C-f>"] = cmp.mapping.scroll_docs(4),
+ -- TODO: potentially fix emmet nonsense
+ ["<Tab>"] = cmp.mapping(function()
+ if cmp.visible() then
+ cmp.select_next_item()
+ elseif luasnip.expandable() then
+ luasnip.expand()
+ elseif inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable() then
+ luasnip.jump(1)
+ elseif check_backspace() then
+ vim.fn.feedkeys(T "<Tab>", "n")
+ elseif is_emmet_active() then
+ return vim.fn["cmp#complete"]()
+ else
+ vim.fn.feedkeys(T "<Tab>", "n")
+ end
+ end, {
+ "i",
+ "s",
+ }),
+ ["<S-Tab>"] = cmp.mapping(function(fallback)
+ if cmp.visible() then
+ cmp.select_prev_item()
+ elseif inside_snippet() and luasnip.jumpable(-1) then
+ luasnip.jump(-1)
+ else
+ fallback()
+ end
+ end, {
+ "i",
+ "s",
+ }),
+
+ ["<C-Space>"] = cmp.mapping.complete(),
+ ["<C-e>"] = cmp.mapping.close(),
+ ["<CR>"] = cmp.mapping(function(fallback)
+ if cmp.visible() and cmp.confirm(lvim.builtin.cmp.confirm_opts) then
+ return
+ end
+
+ if inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable() then
+ if not luasnip.jump(1) then
+ fallback()
+ end
+ else
+ fallback()
+ end
+ end),
+ },
+ }
+end
+
+M.setup = function()
+ require("luasnip/loaders/from_vscode").lazy_load()
+ require("cmp").setup(lvim.builtin.cmp)
+end
+
+return M
diff --git a/lua/core/commands.lua b/lua/core/commands.lua
index 22170c85..6ceeaaff 100644
--- a/lua/core/commands.lua
+++ b/lua/core/commands.lua
@@ -11,7 +11,9 @@ M.defaults = {
endfunction
]],
-- :LvimInfo
- [[command! LvimInfo lua require('core.info').toggle_popup(vim.bo.filetype)]],
+ [[ command! LvimInfo lua require('core.info').toggle_popup(vim.bo.filetype) ]],
+ [[ command! LvimCacheReset lua require('utils.hooks').reset_cache() ]],
+ [[ command! LvimUpdate lua require('bootstrap').update() ]],
}
M.load = function(commands)
diff --git a/lua/core/compe.lua b/lua/core/compe.lua
deleted file mode 100644
index 9eb3dcfa..00000000
--- a/lua/core/compe.lua
+++ /dev/null
@@ -1,133 +0,0 @@
-local M = {}
-
-M.config = function()
- lvim.builtin.compe = {
- active = true,
- on_config_done = nil,
- autocomplete = true,
- debug = false,
- min_length = 1,
- preselect = "enable",
- throttle_time = 80,
- source_timeout = 200,
- incomplete_delay = 400,
- max_abbr_width = 100,
- max_kind_width = 100,
- max_menu_width = 100,
- documentation = {
- border = "single",
- winhighlight = "NormalFloat:CompeDocumentation,FloatBorder:CompeDocumentationBorder",
- max_width = 120,
- min_width = 60,
- max_height = math.floor(vim.o.lines * 0.3),
- min_height = 1,
- },
- -- documentation = true,
-
- source = {
- path = { kind = "  (Path)" },
- buffer = { kind = "  (Buffer)" },
- calc = { kind = "  (Calc)" },
- vsnip = { kind = "  (Snippet)" },
- nvim_lsp = { kind = "  (LSP)" },
- nvim_lua = false,
- spell = { kind = "  (Spell)" },
- tags = false,
- vim_dadbod_completion = false,
- snippets_nvim = false,
- ultisnips = false,
- treesitter = false,
- emoji = { kind = " ﲃ (Emoji)", filetypes = { "markdown", "text" } },
- -- for emoji press : (idk if that in compe tho)
- },
-
- keymap = {
- values = {
- insert_mode = {
- -- ["<Tab>"] = { 'pumvisible() ? "<C-n>" : "<Tab>"', { silent = true, noremap = true, expr = true } },
- -- ["<S-Tab>"] = { 'pumvisible() ? "<C-p>" : "<S-Tab>"', { silent = true, noremap = true, expr = true } },
- ["<C-Space>"] = { "compe#complete()", { silent = true, noremap = true, expr = true } },
- ["<C-e>"] = { "compe#close('<C-e>')", { silent = true, noremap = true, expr = true } },
- ["<C-f>"] = { "compe#scroll({ 'delta': +4 })", { silent = true, noremap = true, expr = true } },
- ["<C-d>"] = { "compe#scroll({ 'delta': -4 })", { silent = true, noremap = true, expr = true } },
- },
- },
- opts = {
- insert_mode = { noremap = true, silent = true, expr = true },
- },
- },
- }
-end
-
-M.setup = function()
- vim.g.vsnip_snippet_dir = lvim.vsnip_dir
-
- local compe = require "compe"
-
- compe.setup(lvim.builtin.compe)
-
- local t = function(str)
- return vim.api.nvim_replace_termcodes(str, true, true, true)
- end
-
- local check_back_space = function()
- local col = vim.fn.col "." - 1
- if col == 0 or vim.fn.getline("."):sub(col, col):match "%s" then
- return true
- else
- return false
- end
- end
-
- local is_emmet_active = function()
- local clients = vim.lsp.buf_get_clients()
-
- for _, client in pairs(clients) do
- if client.name == "emmet_ls" then
- return true
- end
- end
- return false
- end
-
- -- Use (s-)tab to:
- --- move to prev/next item in completion menuone
- --- jump to prev/next snippet's placeholder
- _G.tab_complete = function()
- if vim.fn.pumvisible() == 1 then
- return t "<C-n>"
- elseif vim.fn.call("vsnip#jumpable", { 1 }) == 1 then
- return t "<Plug>(vsnip-jump-next)"
- elseif check_back_space() then
- return t "<Tab>"
- elseif is_emmet_active() then
- return vim.fn["compe#complete"]()
- else
- return t "<Tab>"
- end
- end
-
- _G.s_tab_complete = function()
- if vim.fn.pumvisible() == 1 then
- return t "<C-p>"
- elseif vim.fn.call("vsnip#jumpable", { -1 }) == 1 then
- return t "<Plug>(vsnip-jump-prev)"
- else
- return t "<S-Tab>"
- end
- end
-
- local keymap = require "keymappings"
- keymap.load(lvim.builtin.compe.keymap.values, lvim.builtin.compe.keymap.opts)
-
- vim.api.nvim_set_keymap("i", "<Tab>", "v:lua.tab_complete()", { expr = true })
- vim.api.nvim_set_keymap("s", "<Tab>", "v:lua.tab_complete()", { expr = true })
- vim.api.nvim_set_keymap("i", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true })
- vim.api.nvim_set_keymap("s", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true })
-
- if lvim.builtin.compe.on_config_done then
- lvim.builtin.compe.on_config_done(compe)
- end
-end
-
-return M
diff --git a/lua/core/dap.lua b/lua/core/dap.lua
index 5de3b7c4..d9b59641 100644
--- a/lua/core/dap.lua
+++ b/lua/core/dap.lua
@@ -10,6 +10,18 @@ M.config = function()
linehl = "",
numhl = "",
},
+ breakpoint_rejected = {
+ text = "",
+ texthl = "LspDiagnosticsSignHint",
+ linehl = "",
+ numhl = "",
+ },
+ stopped = {
+ text = "",
+ texthl = "LspDiagnosticsSignInformation",
+ linehl = "DiagnosticUnderlineInfo",
+ numhl = "LspDiagnosticsSignInformation",
+ },
}
end
@@ -17,6 +29,9 @@ M.setup = function()
local dap = require "dap"
vim.fn.sign_define("DapBreakpoint", lvim.builtin.dap.breakpoint)
+ vim.fn.sign_define("DapBreakpointRejected", lvim.builtin.dap.breakpoint_rejected)
+ vim.fn.sign_define("DapStopped", lvim.builtin.dap.stopped)
+
dap.defaults.fallback.terminal_win_cmd = "50vsplit new"
lvim.builtin.which_key.mappings["d"] = {
diff --git a/lua/core/dashboard.lua b/lua/core/dashboard.lua
index a613921f..505350cb 100644
--- a/lua/core/dashboard.lua
+++ b/lua/core/dashboard.lua
@@ -1,5 +1,5 @@
local M = {}
-local home_dir = vim.loop.os_homedir()
+local utils = require "utils"
M.config = function(config)
lvim.builtin.dashboard = {
@@ -7,7 +7,7 @@ M.config = function(config)
on_config_done = nil,
search_handler = "telescope",
disable_at_vim_enter = 0,
- session_directory = home_dir .. "/.cache/lvim/sessions",
+ session_directory = utils.join_paths(get_cache_dir(), "sessions"),
custom_header = {
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣀⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣶⣾⠿⠿⠟⠛⠛⠛⠛⠿⠿⣿⣷⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
@@ -69,14 +69,23 @@ M.setup = function()
vim.g.dashboard_session_directory = lvim.builtin.dashboard.session_directory
- vim.cmd "let packages = len(globpath('~/.local/share/lunarvim/site/pack/packer/start', '*', 0, 1))"
+ local lvim_site = "lunarvim.org"
+ local lvim_version = get_version "short"
+ local num_plugins_loaded = #vim.fn.globpath(get_runtime_dir() .. "/site/pack/packer/start", "*", 0, 1)
- vim.api.nvim_exec(
- [[
- let g:dashboard_custom_footer = ['LunarVim loaded '..packages..' plugins  ']
-]],
- false
- )
+ local footer = {
+ "LunarVim loaded " .. num_plugins_loaded .. " plugins ",
+ "",
+ lvim_site,
+ }
+
+ if lvim_version then
+ table.insert(footer, 2, "")
+ table.insert(footer, 3, "v" .. lvim_version)
+ end
+
+ local text = require "interface.text"
+ vim.g.dashboard_custom_footer = text.align_center({ width = 0 }, footer, 0.49) -- Use 0.49 as  counts for 2 characters
require("core.autocmds").define_augroups {
_dashboard = {
diff --git a/lua/core/gitsigns.lua b/lua/core/gitsigns.lua
index bb9d088b..cc6387dc 100644
--- a/lua/core/gitsigns.lua
+++ b/lua/core/gitsigns.lua
@@ -44,7 +44,7 @@ M.config = function()
noremap = true,
buffer = true,
},
- watch_index = { interval = 1000 },
+ watch_gitdir = { interval = 1000 },
sign_priority = 6,
update_debounce = 200,
status_formatter = nil, -- Use default
diff --git a/lua/core/info.lua b/lua/core/info.lua
index 67e45d1c..16001d07 100644
--- a/lua/core/info.lua
+++ b/lua/core/info.lua
@@ -10,6 +10,8 @@ local M = {
}
local fmt = string.format
+local text = require "interface.text"
+local lsp_utils = require "lsp.utils"
local function str_list(list)
return fmt("[ %s ]", table.concat(list, ", "))
@@ -65,44 +67,54 @@ local function tbl_set_highlight(terms, highlight_group)
end
end
-function M.toggle_popup(ft)
- local lsp_utils = require "lsp.utils"
- local client = lsp_utils.get_active_client_by_ft(ft)
- local is_client_active = false
- local client_enabled_caps = {}
- local client_name = ""
- local client_id = 0
- local document_formatting = false
- if client ~= nil then
- is_client_active = not client.is_stopped()
- client_enabled_caps = require("lsp").get_ls_capabilities(client.id)
- client_name = client.name
- client_id = client.id
- document_formatting = client.resolved_capabilities.document_formatting
+local function make_client_info(client)
+ local client_enabled_caps = lsp_utils.get_client_capabilities(client.id)
+ local name = client.name
+ local id = client.id
+ local document_formatting = client.resolved_capabilities.document_formatting
+ local client_info = {
+ fmt("* Name: %s", name),
+ fmt("* Id: %s", tostring(id)),
+ fmt("* Supports formatting: %s", tostring(document_formatting)),
+ }
+ if not vim.tbl_isempty(client_enabled_caps) then
+ local caps_text = "* Capabilities list: "
+ local caps_text_len = caps_text:len()
+ local enabled_caps = text.format_table(client_enabled_caps, 3, " | ")
+ enabled_caps = text.shift_right(enabled_caps, caps_text_len)
+ enabled_caps[1] = fmt("%s%s", caps_text, enabled_caps[1]:sub(caps_text_len + 1))
+ vim.list_extend(client_info, enabled_caps)
end
+ return client_info
+end
+
+function M.toggle_popup(ft)
+ local clients = lsp_utils.get_active_clients_by_ft(ft)
+ local client_names = {}
+
local header = {
fmt("Detected filetype: %s", ft),
fmt("Treesitter active: %s", tostring(next(vim.treesitter.highlighter.active) ~= nil)),
}
- local text = require "interface.text"
local lsp_info = {
"Language Server Protocol (LSP) info",
- fmt("* Associated server: %s", client_name),
- fmt("* Active: %s (id: %d)", tostring(is_client_active), client_id),
- fmt("* Supports formatting: %s", tostring(document_formatting)),
+ fmt "* Associated server(s):",
}
- if not vim.tbl_isempty(client_enabled_caps) then
- local caps_text = "* Capabilities list: "
- local caps_text_len = caps_text:len()
- local enabled_caps = text.format_table(client_enabled_caps, 3, " | ")
- enabled_caps = text.shift_left(enabled_caps, caps_text_len)
- enabled_caps[1] = fmt("%s%s", caps_text, enabled_caps[1]:sub(caps_text_len + 1))
- vim.list_extend(lsp_info, enabled_caps)
+
+ for _, client in pairs(clients) do
+ vim.list_extend(lsp_info, make_client_info(client))
+ table.insert(client_names, client.name)
end
- local null_ls = require "lsp.null-ls"
- local registered_providers = null_ls.list_supported_provider_names(ft)
+
+ local null_formatters = require "lsp.null-ls.formatters"
+ local null_linters = require "lsp.null-ls.linters"
+ local registered_formatters = null_formatters.list_supported_names(ft)
+ local registered_linters = null_linters.list_supported_names(ft)
+ local registered_providers = {}
+ vim.list_extend(registered_providers, registered_formatters)
+ vim.list_extend(registered_providers, registered_linters)
local registered_count = vim.tbl_count(registered_providers)
local null_ls_info = {
"Formatters and linters",
@@ -113,24 +125,6 @@ function M.toggle_popup(ft)
),
}
- local null_formatters = require "lsp.null-ls.formatters"
- local missing_formatters = null_formatters.list_unsupported_names(ft)
- local missing_formatters_status = {}
- if not vim.tbl_isempty(missing_formatters) then
- missing_formatters_status = {
- fmt("* Missing formatters: %s", table.concat(missing_formatters, "  , ") .. "  "),
- }
- end
-
- local null_linters = require "lsp.null-ls.linters"
- local missing_linters = null_linters.list_unsupported_names(ft)
- local missing_linters_status = {}
- if not vim.tbl_isempty(missing_linters) then
- missing_linters_status = {
- fmt("* Missing linters: %s", table.concat(missing_linters, "  , ") .. "  "),
- }
- end
-
local content_provider = function(popup)
local content = {}
@@ -143,8 +137,6 @@ function M.toggle_popup(ft)
lsp_info,
{ "" },
null_ls_info,
- missing_formatters_status,
- missing_linters_status,
{ "" },
{ "" },
get_formatter_suggestion_msg(ft),
@@ -155,7 +147,7 @@ function M.toggle_popup(ft)
vim.list_extend(content, section)
end
- return text.align(popup, content, 0.5)
+ return text.align_left(popup, content, 0.5)
end
local function set_syntax_hl()
@@ -167,11 +159,8 @@ function M.toggle_popup(ft)
vim.cmd 'let m=matchadd("string", "true")'
vim.cmd 'let m=matchadd("error", "false")'
tbl_set_highlight(registered_providers, "LvimInfoIdentifier")
- tbl_set_highlight(missing_formatters, "LvimInfoIdentifier")
- tbl_set_highlight(missing_linters, "LvimInfoIdentifier")
-- tbl_set_highlight(require("lsp.null-ls.formatters").list_available(ft), "LvimInfoIdentifier")
-- tbl_set_highlight(require("lsp.null-ls.linters").list_available(ft), "LvimInfoIdentifier")
- vim.cmd('let m=matchadd("LvimInfoIdentifier", "' .. client_name .. '")')
end
local Popup = require("interface.popup"):new {
diff --git a/lua/core/log.lua b/lua/core/log.lua
index 1eb786ba..fca1fcb4 100644
--- a/lua/core/log.lua
+++ b/lua/core/log.lua
@@ -8,6 +8,7 @@ function Log:add_entry(msg, level)
if self.__handle then
-- plenary uses lower-case log levels
self.__handle[level:lower()](msg)
+ return
end
local status_ok, plenary = pcall(require, "plenary")
if status_ok then
diff --git a/lua/core/lspinstall.lua b/lua/core/lspinstall.lua
deleted file mode 100644
index 0bb59e0e..00000000
--- a/lua/core/lspinstall.lua
+++ /dev/null
@@ -1,19 +0,0 @@
-local M = {}
-
-M.config = function()
- lvim.builtin.lspinstall = {
- active = true,
- on_config_done = nil,
- }
-end
-
-M.setup = function()
- local lspinstall = require "lspinstall"
- lspinstall.setup()
-
- if lvim.builtin.lspinstall.on_config_done then
- lvim.builtin.lspinstall.on_config_done(lspinstall)
- end
-end
-
-return M
diff --git a/lua/core/lualine/components.lua b/lua/core/lualine/components.lua
index 894d9e9b..3ee2fdf8 100644
--- a/lua/core/lualine/components.lua
+++ b/lua/core/lualine/components.lua
@@ -17,31 +17,32 @@ return {
function()
return " "
end,
- left_padding = 0,
- right_padding = 0,
+ padding = { left = 0, right = 0 },
color = {},
- condition = nil,
+ cond = nil,
},
branch = {
"b:gitsigns_head",
icon = " ",
color = { gui = "bold" },
- condition = conditions.hide_in_width,
+ cond = conditions.hide_in_width,
},
filename = {
"filename",
color = {},
- condition = nil,
+ cond = nil,
},
diff = {
"diff",
source = diff_source,
symbols = { added = "  ", modified = "柳", removed = " " },
- color_added = { fg = colors.green },
- color_modified = { fg = colors.yellow },
- color_removed = { fg = colors.red },
+ diff_color = {
+ added = { fg = colors.green },
+ modified = { fg = colors.yellow },
+ removed = { fg = colors.red },
+ },
color = {},
- condition = nil,
+ cond = nil,
},
python_env = {
function()
@@ -60,44 +61,46 @@ return {
return ""
end,
color = { fg = colors.green },
- condition = conditions.hide_in_width,
+ cond = conditions.hide_in_width,
},
diagnostics = {
"diagnostics",
sources = { "nvim_lsp" },
symbols = { error = " ", warn = " ", info = " ", hint = " " },
color = {},
- condition = conditions.hide_in_width,
+ cond = conditions.hide_in_width,
},
treesitter = {
function()
- if next(vim.treesitter.highlighter.active) then
+ local b = vim.api.nvim_get_current_buf()
+ if next(vim.treesitter.highlighter.active[b]) then
return "  "
end
return ""
end,
color = { fg = colors.green },
- condition = conditions.hide_in_width,
+ cond = conditions.hide_in_width,
},
lsp = {
function(msg)
- msg = msg or "LSP Inactive"
+ msg = msg or "LS Inactive"
local buf_clients = vim.lsp.buf_get_clients()
if next(buf_clients) == nil then
+ -- TODO: clean up this if statement
+ if type(msg) == "boolean" or #msg == 0 then
+ return "LS Inactive"
+ end
return msg
end
local buf_ft = vim.bo.filetype
local buf_client_names = {}
-- add client
- local utils = require "lsp.utils"
- local active_client = utils.get_active_client_by_ft(buf_ft)
for _, client in pairs(buf_clients) do
if client.name ~= "null-ls" then
table.insert(buf_client_names, client.name)
end
end
- vim.list_extend(buf_client_names, active_client or {})
-- add formatter
local formatters = require "lsp.null-ls.formatters"
@@ -113,10 +116,10 @@ return {
end,
icon = " ",
color = { gui = "bold" },
- condition = conditions.hide_in_width,
+ cond = conditions.hide_in_width,
},
- location = { "location", condition = conditions.hide_in_width, color = {} },
- progress = { "progress", condition = conditions.hide_in_width, color = {} },
+ location = { "location", cond = conditions.hide_in_width, color = {} },
+ progress = { "progress", cond = conditions.hide_in_width, color = {} },
spaces = {
function()
local label = "Spaces: "
@@ -125,16 +128,16 @@ return {
end
return label .. vim.api.nvim_buf_get_option(0, "shiftwidth") .. " "
end,
- condition = conditions.hide_in_width,
+ cond = conditions.hide_in_width,
color = {},
},
encoding = {
"o:encoding",
- upper = true,
+ fmt = string.upper,
color = {},
- condition = conditions.hide_in_width,
+ cond = conditions.hide_in_width,
},
- filetype = { "filetype", condition = conditions.hide_in_width, color = {} },
+ filetype = { "filetype", cond = conditions.hide_in_width, color = {} },
scrollbar = {
function()
local current_line = vim.fn.line "."
@@ -144,9 +147,8 @@ return {
local index = math.ceil(line_ratio * #chars)
return chars[index]
end,
- left_padding = 0,
- right_padding = 0,
+ padding = { left = 0, right = 0 },
color = { fg = colors.yellow, bg = colors.bg },
- condition = nil,
+ cond = nil,
},
}
diff --git a/lua/core/lualine/styles.lua b/lua/core/lualine/styles.lua
index 3595e5e3..19097424 100644
--- a/lua/core/lualine/styles.lua
+++ b/lua/core/lualine/styles.lua
@@ -11,8 +11,8 @@ styles.none = {
style = "none",
options = {
icons_enabled = true,
- component_separators = "",
- section_separators = "",
+ component_separators = { left = "", right = "" },
+ section_separators = { left = "", right = "" },
disabled_filetypes = {},
},
sections = {
@@ -39,8 +39,8 @@ styles.default = {
style = "default",
options = {
icons_enabled = true,
- component_separators = { "", "" },
- section_separators = { "", "" },
+ component_separators = { left = "", right = "" },
+ section_separators = { left = "", right = "" },
disabled_filetypes = {},
},
sections = {
@@ -67,8 +67,8 @@ styles.lvim = {
style = "lvim",
options = {
icons_enabled = true,
- component_separators = "",
- section_separators = "",
+ component_separators = { left = "", right = "" },
+ section_separators = { left = "", right = "" },
disabled_filetypes = { "dashboard", "NvimTree", "Outline" },
},
sections = {
diff --git a/lua/core/nvimtree.lua b/lua/core/nvimtree.lua
index 6aa5401d..55cc6175 100644
--- a/lua/core/nvimtree.lua
+++ b/lua/core/nvimtree.lua
@@ -5,8 +5,23 @@ function M.config()
lvim.builtin.nvimtree = {
active = true,
on_config_done = nil,
- side = "left",
- width = 30,
+ setup = {
+ open_on_setup = 0,
+ auto_close = 1,
+ open_on_tab = 0,
+ update_focused_file = {
+ enable = 1,
+ },
+ lsp_diagnostics = 1,
+ view = {
+ width = 30,
+ side = "left",
+ auto_resize = false,
+ mappings = {
+ custom_only = false,
+ },
+ },
+ },
show_icons = {
git = 1,
folders = 1,
@@ -15,16 +30,11 @@ function M.config()
tree_width = 30,
},
ignore = { ".git", "node_modules", ".cache" },
- auto_open = 0,
- auto_close = 1,
quit_on_open = 0,
- follow = 1,
hide_dotfiles = 1,
git_hl = 1,
root_folder_modifier = ":t",
- tab_open = 0,
allow_resize = 1,
- lsp_diagnostics = 1,
auto_ignore_ft = { "startify", "dashboard" },
icons = {
default = "",
@@ -63,17 +73,17 @@ function M.setup()
-- Implicitly update nvim-tree when project module is active
if lvim.builtin.project.active then
- vim.g.nvim_tree_update_cwd = 1
- vim.g.nvim_tree_respect_buf_cwd = 1
- vim.g.nvim_tree_disable_netrw = 0
- vim.g.nvim_tree_hijack_netrw = 0
+ lvim.builtin.nvimtree.respect_buf_cwd = 1
+ lvim.builtin.nvimtree.setup.update_cwd = 1
+ lvim.builtin.nvimtree.setup.disable_netrw = 0
+ lvim.builtin.nvimtree.setup.hijack_netrw = 0
vim.g.netrw_banner = 0
end
local tree_cb = nvim_tree_config.nvim_tree_callback
- if not g.nvim_tree_bindings then
- g.nvim_tree_bindings = {
+ if not lvim.builtin.nvimtree.setup.view.mappings.list then
+ lvim.builtin.nvimtree.setup.view.mappings.list = {
{ key = { "l", "<CR>", "o" }, cb = tree_cb "edit" },
{ key = "h", cb = tree_cb "close_node" },
{ key = "v", cb = tree_cb "vsplit" },
@@ -96,11 +106,12 @@ function M.setup()
if lvim.builtin.nvimtree.on_config_done then
lvim.builtin.nvimtree.on_config_done(nvim_tree_config)
end
+ require("nvim-tree").setup(lvim.builtin.nvimtree.setup)
end
function M.on_open()
- if package.loaded["bufferline.state"] and lvim.builtin.nvimtree.side == "left" then
- require("bufferline.state").set_offset(lvim.builtin.nvimtree.width + 1, "")
+ if package.loaded["bufferline.state"] and lvim.builtin.nvimtree.setup.view.side == "left" then
+ require("bufferline.state").set_offset(lvim.builtin.nvimtree.setup.view.width + 1, "")
end
end
diff --git a/lua/core/project.lua b/lua/core/project.lua
index 7fb04933..e7527440 100644
--- a/lua/core/project.lua
+++ b/lua/core/project.lua
@@ -35,7 +35,7 @@ function M.config()
---@type string
---@usage path to store the project history for use in telescope
- datapath = CACHE_PATH,
+ datapath = get_cache_dir(),
}
end
diff --git a/lua/core/telescope.lua b/lua/core/telescope.lua
index 4ae56df0..ba0a9ee1 100644
--- a/lua/core/telescope.lua
+++ b/lua/core/telescope.lua
@@ -1,5 +1,7 @@
local M = {}
+local utils = require "utils"
+
function M.config()
-- Define this minimal config so that it's available if telescope is not yet available.
lvim.builtin.telescope = {
@@ -24,7 +26,6 @@ function M.config()
layout_strategy = "horizontal",
layout_config = {
width = 0.75,
- prompt_position = "bottom",
preview_cutoff = 120,
horizontal = { mirror = false },
vertical = { mirror = false },
@@ -87,16 +88,11 @@ function M.find_lunarvim_files(opts)
opts = opts or {}
local themes = require "telescope.themes"
local theme_opts = themes.get_ivy {
- previewer = false,
sorting_strategy = "ascending",
layout_strategy = "bottom_pane",
- layout_config = {
- height = 5,
- width = 0.5,
- },
- prompt = ">> ",
+ prompt_prefix = ">> ",
prompt_title = "~ LunarVim files ~",
- cwd = CONFIG_PATH,
+ cwd = utils.join_paths(get_runtime_dir(), "lvim"),
find_command = { "git", "ls-files" },
}
opts = vim.tbl_deep_extend("force", theme_opts, opts)
@@ -109,14 +105,79 @@ function M.grep_lunarvim_files(opts)
local theme_opts = themes.get_ivy {
sorting_strategy = "ascending",
layout_strategy = "bottom_pane",
- prompt = ">> ",
+ prompt_prefix = ">> ",
prompt_title = "~ search LunarVim ~",
- cwd = CONFIG_PATH,
+ cwd = utils.join_paths(get_runtime_dir(), "lvim"),
}
opts = vim.tbl_deep_extend("force", theme_opts, opts)
require("telescope.builtin").live_grep(opts)
end
+function M.view_lunarvim_changelog()
+ local finders = require "telescope.finders"
+ local make_entry = require "telescope.make_entry"
+ local pickers = require "telescope.pickers"
+ local previewers = require "telescope.previewers"
+ local actions = require "telescope.actions"
+ local opts = {}
+
+ local conf = require("telescope.config").values
+ opts.entry_maker = make_entry.gen_from_git_commits(opts)
+
+ pickers.new(opts, {
+ prompt_title = "LunarVim changelog",
+
+ finder = finders.new_oneshot_job(
+ vim.tbl_flatten {
+ "git",
+ "log",
+ "--pretty=oneline",
+ "--abbrev-commit",
+ "--",
+ ".",
+ },
+ opts
+ ),
+ previewer = {
+ previewers.git_commit_diff_to_parent.new(opts),
+ previewers.git_commit_diff_to_head.new(opts),
+ previewers.git_commit_diff_as_was.new(opts),
+ previewers.git_commit_message.new(opts),
+ },
+
+ --TODO: consider opening a diff view when pressing enter
+ attach_mappings = function(_, map)
+ map("i", "<enter>", actions._close)
+ map("n", "<enter>", actions._close)
+ map("i", "<esc>", actions._close)
+ map("n", "<esc>", actions._close)
+ map("n", "q", actions._close)
+ return true
+ end,
+ sorter = conf.file_sorter(opts),
+ }):find()
+end
+
+function M.code_actions()
+ local opts = {
+ winblend = 15,
+ layout_config = {
+ prompt_position = "top",
+ width = 80,
+ height = 12,
+ },
+ borderchars = {
+ prompt = { "─", "│", " ", "│", "╭", "╮", "│", "│" },
+ results = { "─", "│", "─", "│", "├", "┤", "╯", "╰" },
+ preview = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" },
+ },
+ border = {},
+ previewer = false,
+ shorten_path = false,
+ }
+ require("telescope.builtin").lsp_code_actions(require("telescope.themes").get_dropdown(opts))
+end
+
function M.setup()
local telescope = require "telescope"
diff --git a/lua/core/terminal.lua b/lua/core/terminal.lua
index f9be8734..3a0c6e46 100644
--- a/lua/core/terminal.lua
+++ b/lua/core/terminal.lua
@@ -1,5 +1,5 @@
local M = {}
-local utils = require "utils"
+local Log = require "core.log"
M.config = function()
lvim.builtin["terminal"] = {
@@ -81,7 +81,6 @@ end
M._exec_toggle = function(exec)
local binary = M._split(exec)[1]
if vim.fn.executable(binary) ~= 1 then
- local Log = require "core.log"
Log:error("Unable to run executable " .. binary .. ". Please make sure it is installed properly.")
return
end
@@ -90,29 +89,16 @@ M._exec_toggle = function(exec)
exec_term:toggle()
end
-local function get_log_path(name)
- --handle custom paths not managed by Plenary.log
- local logger = require "core.log"
- local file
- if name == "nvim" then
- file = CACHE_PATH .. "/log"
- else
- file = logger:new({ plugin = name }):get_path()
- end
- if utils.is_file(file) then
- return file
- end
-end
-
---Toggles a log viewer according to log.viewer.layout_config
----@param name can be the name of any of the managed logs, e,g. "lunarvim" or the default ones {"nvim", "lsp", "packer.nvim"}
-M.toggle_log_view = function(name)
- local logfile = get_log_path(name)
- if not logfile then
- return
+---@param logfile string the fullpath to the logfile
+M.toggle_log_view = function(logfile)
+ local log_viewer = lvim.log.viewer.cmd
+ if vim.fn.executable(log_viewer) ~= 1 then
+ log_viewer = "less +F"
end
+ log_viewer = log_viewer .. " " .. logfile
local term_opts = vim.tbl_deep_extend("force", lvim.builtin.terminal, {
- cmd = lvim.log.viewer.cmd .. " " .. logfile,
+ cmd = log_viewer,
open_mapping = lvim.log.viewer.layout_config.open_mapping,
direction = lvim.log.viewer.layout_config.direction,
-- TODO: this might not be working as expected
@@ -122,7 +108,6 @@ M.toggle_log_view = function(name)
local Terminal = require("toggleterm.terminal").Terminal
local log_view = Terminal:new(term_opts)
- -- require("core.log"):debug("term", vim.inspect(term_opts))
log_view:toggle()
end
diff --git a/lua/core/which-key.lua b/lua/core/which-key.lua
index 71c0b695..c9e9b2f4 100644
--- a/lua/core/which-key.lua
+++ b/lua/core/which-key.lua
@@ -72,25 +72,26 @@ M.config = function()
["h"] = { "<cmd>nohlsearch<CR>", "No Highlight" },
b = {
name = "Buffers",
- j = { "<cmd>BufferPick<cr>", "jump to buffer" },
- f = { "<cmd>Telescope buffers<cr>", "Find buffer" },
- w = { "<cmd>BufferWipeout<cr>", "wipeout buffer" },
+ j = { "<cmd>BufferPick<cr>", "Jump" },
+ f = { "<cmd>Telescope buffers<cr>", "Find" },
+ b = { "<cmd>b#<cr>", "Previous" },
+ w = { "<cmd>BufferWipeout<cr>", "Wipeout" },
e = {
"<cmd>BufferCloseAllButCurrent<cr>",
- "close all but current buffer",
+ "Close all but current",
},
- h = { "<cmd>BufferCloseBuffersLeft<cr>", "close all buffers to the left" },
+ h = { "<cmd>BufferCloseBuffersLeft<cr>", "Close all to the left" },
l = {
"<cmd>BufferCloseBuffersRight<cr>",
- "close all BufferLines to the right",
+ "Close all to the right",
},
D = {
"<cmd>BufferOrderByDirectory<cr>",
- "sort BufferLines automatically by directory",
+ "Sort by directory",
},
L = {
"<cmd>BufferOrderByLanguage<cr>",
- "sort BufferLines automatically by language",
+ "Sort by language",
},
},
p = {
@@ -130,11 +131,15 @@ M.config = function()
"<cmd>Telescope git_bcommits<cr>",
"Checkout commit(for current file)",
},
+ d = {
+ "<cmd>Gitsigns diffthis HEAD<cr>",
+ "Git Diff",
+ },
},
l = {
name = "LSP",
- a = { "<cmd>lua vim.lsp.buf.code_action()<cr>", "Code Action" },
+ a = { "<cmd>lua require('core.telescope').code_actions()<cr>", "Code Action" },
d = {
"<cmd>Telescope lsp_document_diagnostics<cr>",
"Document Diagnostics",
@@ -143,9 +148,9 @@ M.config = function()
"<cmd>Telescope lsp_workspace_diagnostics<cr>",
"Workspace Diagnostics",
},
- -- f = { "<cmd>silent FormatWrite<cr>", "Format" },
f = { "<cmd>lua vim.lsp.buf.formatting()<cr>", "Format" },
i = { "<cmd>LspInfo<cr>", "Info" },
+ I = { "<cmd>LspInstallInfo<cr>", "Installer Info" },
j = {
"<cmd>lua vim.lsp.diagnostic.goto_next({popup_opts = {border = lvim.lsp.popup_border}})<cr>",
"Next Diagnostic",
@@ -154,6 +159,7 @@ M.config = function()
"<cmd>lua vim.lsp.diagnostic.goto_prev({popup_opts = {border = lvim.lsp.popup_border}})<cr>",
"Prev Diagnostic",
},
+ l = { "<cmd>lua vim.lsp.codelens.run()<cr>", "CodeLens Action" },
p = {
name = "Peek",
d = { "<cmd>lua require('lsp.peek').Peek('definition')<cr>", "Definition" },
@@ -171,7 +177,7 @@ M.config = function()
L = {
name = "+LunarVim",
c = {
- "<cmd>edit ~/.config/lvim/config.lua<cr>",
+ "<cmd>edit" .. get_config_dir() .. "/config.lua<cr>",
"Edit config.lua",
},
f = {
@@ -187,23 +193,32 @@ M.config = function()
"<cmd>lua require('core.info').toggle_popup(vim.bo.filetype)<cr>",
"Toggle LunarVim Info",
},
+ I = {
+ "<cmd>lua require('core.telescope').view_lunarvim_changelog()<cr>",
+ "View LunarVim's changelog",
+ },
l = {
name = "+logs",
d = {
- "<cmd>lua require('core.terminal').toggle_log_view('lunarvim')<cr>",
+ "<cmd>lua require('core.terminal').toggle_log_view(require('core.log').get_path())<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" },
+ D = { "<cmd>lua vim.fn.execute('edit ' .. require('core.log').get_path())<cr>", "Open the default logfile" },
+ l = { "<cmd>lua require('core.terminal').toggle_log_view(vim.lsp.get_log_path())<cr>", "view lsp log" },
+ L = { "<cmd>lua vim.fn.execute('edit ' .. vim.lsp.get_log_path())<cr>", "Open the LSP logfile" },
+ n = {
+ "<cmd>lua require('core.terminal').toggle_log_view(os.getenv('NVIM_LOG_FILE'))<cr>",
+ "view neovim log",
+ },
+ N = { "<cmd>edit $NVIM_LOG_FILE<cr>", "Open the Neovim logfile" },
p = {
"<cmd>lua require('core.terminal').toggle_log_view('packer.nvim')<cr>",
"view packer log",
},
- P = { "<cmd>edit ~/.cache/nvim/packer.nvim.log<cr>", "Open the Packer logfile" },
+ P = { "<cmd>exe 'edit '.stdpath('cache').'/packer.nvim.log'<cr>", "Open the Packer logfile" },
},
+ r = { "<cmd>lua require('utils').reload_lv_config()<cr>", "Reload configurations" },
+ u = { "<cmd>LvimUpdate<cr>", "Update LunarVim" },
},
s = {
name = "Search",
diff --git a/lua/impatient.lua b/lua/impatient.lua
new file mode 100644
index 00000000..d438851c
--- /dev/null
+++ b/lua/impatient.lua
@@ -0,0 +1,360 @@
+-- modified version from https://github.com/lewis6991/impatient.nvim
+
+local vim = vim
+local uv = vim.loop
+local impatient_load_start = uv.hrtime()
+local api = vim.api
+local ffi = require "ffi"
+
+local get_option, set_option = api.nvim_get_option, api.nvim_set_option
+local get_runtime_file = api.nvim_get_runtime_file
+
+local impatient_dur
+
+local M = {
+ cache = {},
+ profile = nil,
+ dirty = false,
+ path = nil,
+ log = {},
+}
+
+_G.__luacache = M
+
+--{{{
+local cachepack = {}
+
+-- using double for packing/unpacking numbers has no conversion overhead
+-- 32-bit ARM causes a bus error when casting to double, so use int there
+local number_t = jit.arch ~= "arm" and "double" or "int"
+ffi.cdef("typedef " .. number_t .. " number_t;")
+
+local c_number_t = ffi.typeof "number_t[1]"
+local c_sizeof_number_t = ffi.sizeof "number_t"
+
+local out_buf = {}
+
+function out_buf.write_number(buf, num)
+ buf[#buf + 1] = ffi.string(c_number_t(num), c_sizeof_number_t)
+end
+
+function out_buf.write_string(buf, str)
+ out_buf.write_number(buf, #str)
+ buf[#buf + 1] = str
+end
+
+function out_buf.to_string(buf)
+ return table.concat(buf)
+end
+
+local in_buf = {}
+
+function in_buf.read_number(buf)
+ if buf.size < buf.pos then
+ error "buffer access violation"
+ end
+ local res = ffi.cast("number_t*", buf.ptr + buf.pos)[0]
+ buf.pos = buf.pos + c_sizeof_number_t
+ return res
+end
+
+function in_buf.read_string(buf)
+ local len = in_buf.read_number(buf)
+ local res = ffi.string(buf.ptr + buf.pos, len)
+ buf.pos = buf.pos + len
+
+ return res
+end
+
+function cachepack.pack(cache)
+ local total_keys = vim.tbl_count(cache)
+ local buf = {}
+
+ out_buf.write_number(buf, total_keys)
+ for k, v in pairs(cache) do
+ out_buf.write_string(buf, k)
+ out_buf.write_string(buf, v[1] or "")
+ out_buf.write_number(buf, v[2] or 0)
+ out_buf.write_string(buf, v[3] or "")
+ end
+
+ return out_buf.to_string(buf)
+end
+
+function cachepack.unpack(str, raw_buf_size)
+ if raw_buf_size == 0 or str == nil or (raw_buf_size == nil and #str == 0) then
+ return {}
+ end
+
+ local buf = {
+ ptr = raw_buf_size and str or ffi.new("const char[?]", #str, str),
+ pos = 0,
+ size = raw_buf_size or #str,
+ }
+ local cache = {}
+
+ local total_keys = in_buf.read_number(buf)
+ for _ = 1, total_keys do
+ local k = in_buf.read_string(buf)
+ local v = {
+ in_buf.read_string(buf),
+ in_buf.read_number(buf),
+ in_buf.read_string(buf),
+ }
+ cache[k] = v
+ end
+
+ return cache
+end
+--}}}
+
+local function log(...)
+ M.log[#M.log + 1] = table.concat({ string.format(...) }, " ")
+end
+
+function M.print_log()
+ for _, l in ipairs(M.log) do
+ print(l)
+ end
+end
+
+function M.enable_profile()
+ M.profile = {}
+ M.print_profile = function()
+ M.profile["impatient"] = {
+ resolve = 0,
+ load = impatient_dur,
+ loader = "standard",
+ }
+ require("impatient.profile").print_profile(M.profile)
+ end
+ vim.cmd [[command! LuaCacheProfile lua _G.__luacache.print_profile()]]
+end
+
+local function is_cacheable(path)
+ -- Don't cache files in /tmp since they are not likely to persist.
+ -- Note: Appimage versions of Neovim mount $VIMRUNTIME in /tmp in a unique
+ -- directory on each launch.
+ return not vim.startswith(path, "/tmp/")
+end
+
+local function hash(modpath)
+ local stat = uv.fs_stat(modpath)
+ if stat then
+ return stat.mtime.sec
+ end
+end
+
+local function hrtime()
+ if M.profile then
+ return uv.hrtime()
+ end
+end
+
+local function load_package_with_cache(name, loader)
+ local resolve_start = hrtime()
+
+ local basename = name:gsub("%.", "/")
+ local paths = { "lua/" .. basename .. ".lua", "lua/" .. basename .. "/init.lua" }
+
+ for _, path in ipairs(paths) do
+ local modpath = get_runtime_file(path, false)[1]
+ if modpath then
+ local load_start = hrtime()
+ local chunk, err = loadfile(modpath)
+
+ if M.profile then
+ M.profile[name] = {
+ resolve = load_start - resolve_start,
+ load = hrtime() - load_start,
+ loader = loader or "standard",
+ }
+ end
+
+ if chunk == nil then
+ return err
+ end
+
+ if is_cacheable(modpath) then
+ log("Creating cache for module %s", name)
+ M.cache[name] = { modpath, hash(modpath), string.dump(chunk) }
+ M.dirty = true
+ else
+ log("Unable to cache module %s", name)
+ end
+
+ return chunk
+ end
+ end
+ return nil
+end
+
+local reduced_rtp
+
+-- Speed up non-cached loads by reducing the rtp path during requires
+function M.update_reduced_rtp()
+ local luadirs = get_runtime_file("lua/", true)
+
+ for i = 1, #luadirs do
+ luadirs[i] = luadirs[i]:sub(1, -6)
+ end
+
+ reduced_rtp = table.concat(luadirs, ",")
+end
+
+local function load_package_with_cache_reduced_rtp(name)
+ local orig_rtp = get_option "runtimepath"
+ local orig_ei = get_option "eventignore"
+
+ if not reduced_rtp then
+ M.update_reduced_rtp()
+ end
+
+ set_option("eventignore", "all")
+ set_option("rtp", reduced_rtp)
+
+ local found = load_package_with_cache(name, "reduced")
+
+ set_option("rtp", orig_rtp)
+ set_option("eventignore", orig_ei)
+
+ return found
+end
+
+local function load_from_cache(name)
+ local resolve_start = hrtime()
+ if M.cache[name] == nil then
+ log("No cache for module %s", name)
+ return "No cache entry"
+ end
+
+ local modpath, mhash, codes = unpack(M.cache[name])
+
+ if mhash ~= hash(modpath) then
+ log("Stale cache for module %s", name)
+ M.cache[name] = nil
+ M.dirty = true
+ return "Stale cache"
+ end
+
+ local load_start = hrtime()
+ local chunk = loadstring(codes)
+
+ if M.profile then
+ M.profile[name] = {
+ resolve = load_start - resolve_start,
+ load = hrtime() - load_start,
+ loader = "cache",
+ }
+ end
+
+ if not chunk then
+ M.cache[name] = nil
+ M.dirty = true
+ log("Error loading cache for module. Invalidating", name)
+ return "Cache error"
+ end
+
+ return chunk
+end
+
+function M.save_cache()
+ if M.dirty then
+ log("Updating cache file: %s", M.path)
+ local f = io.open(M.path, "w+b")
+ f:write(cachepack.pack(M.cache))
+ f:flush()
+ M.dirty = false
+ end
+end
+
+function M.clear_cache()
+ M.cache = {}
+ os.remove(M.path)
+end
+
+impatient_dur = uv.hrtime() - impatient_load_start
+
+function M.setup(opts)
+ opts = opts or {}
+ M.path = opts.path or vim.fn.stdpath "cache" .. "/lvim_cache"
+
+ if opts.enable_profiling then
+ M.enable_profile()
+ end
+
+ local impatient_setup_start = uv.hrtime()
+ local stat = uv.fs_stat(M.path)
+ if stat then
+ log("Loading cache file %s", M.path)
+ local ok
+ -- Linux/macOS lets us easily mmap the cache file for faster reads without passing to Lua
+ if jit.os == "Linux" or jit.os == "OSX" then
+ local size = stat.size
+
+ local C = ffi.C
+ local O_RDONLY = 0x00
+ local PROT_READ = 0x01
+ local MAP_PRIVATE = 0x02
+
+ ffi.cdef [[
+ int open(const char *pathname, int flags);
+ int close(int fd);
+ void *mmap(void *addr, size_t length, int prot, int flags, int fd, long int offset);
+ int munmap(void *addr, size_t length);
+ ]]
+ local f = C.open(M.path, O_RDONLY)
+
+ local addr = C.mmap(nil, size, PROT_READ, MAP_PRIVATE, f, 0)
+ ok = ffi.cast("intptr_t", addr) ~= -1
+
+ if ok then
+ M.cache = cachepack.unpack(ffi.cast("char *", addr), size)
+ C.munmap(addr, size)
+ end
+
+ C.close(f)
+ else
+ local f = io.open(M.path, "rb")
+ ok, M.cache = pcall(function()
+ return cachepack.unpack(f:read "*a")
+ end)
+ end
+
+ if not ok then
+ log("Corrupted cache file, %s. Invalidating...", M.path)
+ os.remove(M.path)
+ M.cache = {}
+ end
+ M.dirty = not ok
+ end
+
+ local insert = table.insert
+ local package = package
+
+ -- Fix the position of the preloader. This also makes loading modules like 'ffi'
+ -- and 'bit' quicker
+ if package.loaders[1] == vim._load_package then
+ -- Move vim._load_package to the second position
+ local vim_load = table.remove(package.loaders, 1)
+ insert(package.loaders, 2, vim_load)
+ end
+
+ insert(package.loaders, 2, load_from_cache)
+ insert(package.loaders, 3, load_package_with_cache_reduced_rtp)
+ insert(package.loaders, 4, load_package_with_cache)
+
+ vim.cmd [[
+ augroup impatient
+ autocmd VimEnter,VimLeave * lua _G.__luacache.save_cache()
+ autocmd OptionSet runtimepath lua _G.__luacache.update_reduced_rtp(true)
+ augroup END
+
+ command! LuaCacheClear lua _G.__luacache.clear_cache()
+ command! LuaCacheLog lua _G.__luacache.print_log()
+ ]]
+
+ impatient_dur = impatient_dur + (uv.hrtime() - impatient_setup_start)
+end
+
+return M
diff --git a/lua/impatient/profile.lua b/lua/impatient/profile.lua
new file mode 100644
index 00000000..0f4f8236
--- /dev/null
+++ b/lua/impatient/profile.lua
@@ -0,0 +1,145 @@
+local M = {}
+
+local api = vim.api
+
+function M.print_profile(profile)
+ if not profile then
+ print "Error: profiling was not enabled"
+ return
+ end
+
+ local total_resolve = 0
+ local total_load = 0
+ local name_pad = 0
+ local modules = {}
+ local plugins = {}
+
+ for module, p in pairs(profile) do
+ p.resolve = p.resolve / 1000000
+ p.load = p.load / 1000000
+ p.total = p.resolve + p.load
+ p.module = module:gsub("/", ".")
+
+ local plugin = p.module:match "([^.]+)"
+ if plugin then
+ if not plugins[plugin] then
+ plugins[plugin] = {
+ module = plugin,
+ resolve = 0,
+ load = 0,
+ total = 0,
+ }
+ end
+ local r = plugins[plugin]
+
+ r.resolve = r.resolve + p.resolve
+ r.load = r.load + p.load
+ r.total = r.total + p.total
+
+ if not r.loader then
+ r.loader = p.loader
+ elseif r.loader ~= p.loader then
+ r.loader = "mixed"
+ end
+ end
+
+ total_resolve = total_resolve + p.resolve
+ total_load = total_load + p.load
+
+ if #module > name_pad then
+ name_pad = #module
+ end
+
+ modules[#modules + 1] = p
+ end
+
+ table.sort(modules, function(a, b)
+ return a.module > b.module
+ end)
+
+ do
+ local plugins_a = {}
+ for _, v in pairs(plugins) do
+ plugins_a[#plugins_a + 1] = v
+ end
+ plugins = plugins_a
+ end
+
+ table.sort(plugins, function(a, b)
+ return a.total > b.total
+ end)
+
+ local lines = {}
+ local function add(...)
+ lines[#lines + 1] = string.format(...)
+ end
+
+ local l = string.rep("─", name_pad + 1)
+
+ add(
+ "%s┬───────────┬────────────┬────────────┬────────────┐",
+ l
+ )
+ add("%-" .. name_pad .. "s │ Loader │ Resolve │ Load │ Total │", "")
+ add(
+ "%s┼───────────┼────────────┼────────────┼────────────┤",
+ l
+ )
+ add(
+ "%-" .. name_pad .. "s │ │ %8.4fms │ %8.4fms │ %8.4fms │",
+ "Total",
+ total_resolve,
+ total_load,
+ total_resolve + total_load
+ )
+ add(
+ "%s┴───────────┴────────────┴────────────┴────────────┤",
+ l
+ )
+ add("%-" .. name_pad .. "s │", "By Plugin")
+ add(
+ "%s┬───────────┬────────────┬────────────┬────────────┤",
+ l
+ )
+ for _, p in ipairs(plugins) do
+ add(
+ "%-" .. name_pad .. "s │ %9s │ %8.4fms │ %8.4fms │ %8.4fms │",
+ p.module,
+ p.loader,
+ p.resolve,
+ p.load,
+ p.total
+ )
+ end
+ add(
+ "%s┴───────────┴────────────┴────────────┴────────────┤",
+ l
+ )
+ add("%-" .. name_pad .. "s │", "By Module")
+ add(
+ "%s┬───────────┬────────────┬────────────┬────────────┤",
+ l
+ )
+ for _, p in pairs(modules) do
+ add(
+ "%-" .. name_pad .. "s │ %9s │ %8.4fms │ %8.4fms │ %8.4fms │",
+ p.module,
+ p.loader,
+ p.resolve,
+ p.load,
+ p.total
+ )
+ end
+ add(
+ "%s┴───────────┴────────────┴────────────┴────────────┘",
+ l
+ )
+
+ local bufnr = api.nvim_create_buf(false, false)
+ api.nvim_buf_set_lines(bufnr, 0, 0, false, lines)
+ api.nvim_buf_set_option(bufnr, "buftype", "nofile")
+ api.nvim_buf_set_name(bufnr, "Impatient Profile Report")
+ api.nvim_set_current_buf(bufnr)
+end
+
+return M
diff --git a/lua/interface/text.lua b/lua/interface/text.lua
index f68cc491..6bf280e8 100644
--- a/lua/interface/text.lua
+++ b/lua/interface/text.lua
@@ -13,20 +13,36 @@ local function max_len_line(lines)
return max_len
end
---- Center align lines relatively to the parent container
+--- Left align lines relatively to the parent container
-- @param container The container where lines will be displayed
-- @param lines The text to align
-- @param alignment The alignment value, range: [0-1]
-function M.align(container, lines, alignment)
+function M.align_left(container, lines, alignment)
local max_len = max_len_line(lines)
local indent_amount = math.ceil(math.max(container.width - max_len, 0) * alignment)
- return M.shift_left(lines, indent_amount)
+ return M.shift_right(lines, indent_amount)
+end
+
+--- Center align lines relatively to the parent container
+-- @param container The container where lines will be displayed
+-- @param lines The text to align
+-- @param alignment The alignment value, range: [0-1]
+function M.align_center(container, lines, alignment)
+ local output = {}
+ local max_len = max_len_line(lines)
+
+ for _, line in ipairs(lines) do
+ local padding = string.rep(" ", (math.max(container.width, max_len) - line:len()) * alignment)
+ table.insert(output, padding .. line)
+ end
+
+ return output
end
--- Shift lines by a given amount
-- @params lines The lines the shift
-- @param amount The amount of spaces to add
-function M.shift_left(lines, amount)
+function M.shift_right(lines, amount)
local output = {}
local padding = string.rep(" ", amount)
diff --git a/lua/keymappings.lua b/lua/keymappings.lua
index 557e0bde..027ca83f 100644
--- a/lua/keymappings.lua
+++ b/lua/keymappings.lua
@@ -83,8 +83,8 @@ function M.config()
["<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 } },
+ ["<C-j>"] = { 'pumvisible() ? "\\<down>" : "\\<C-j>"', { expr = true, noremap = true } },
+ ["<C-k>"] = { 'pumvisible() ? "\\<up>" : "\\<C-k>"', { expr = true, noremap = true } },
},
---@usage change or add keymappings for normal mode
diff --git a/lua/lsp/config.lua b/lua/lsp/config.lua
new file mode 100644
index 00000000..f13d9659
--- /dev/null
+++ b/lua/lsp/config.lua
@@ -0,0 +1,45 @@
+return {
+ templates_dir = join_paths(get_runtime_dir(), "site", "after", "ftplugin"),
+ diagnostics = {
+ signs = {
+ active = true,
+ values = {
+ { name = "LspDiagnosticsSignError", text = "" },
+ { name = "LspDiagnosticsSignWarning", text = "" },
+ { name = "LspDiagnosticsSignHint", text = "" },
+ { name = "LspDiagnosticsSignInformation", text = "" },
+ },
+ },
+ virtual_text = true,
+ update_in_insert = false,
+ underline = true,
+ severity_sort = true,
+ },
+ override = {},
+ document_highlight = true,
+ code_lens_refresh = true,
+ popup_border = "single",
+ on_attach_callback = nil,
+ on_init_callback = nil,
+ automatic_servers_installation = true,
+ buffer_mappings = {
+ normal_mode = {
+ ["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 require'lsp.handlers'.show_line_diagnostics()<CR>",
+ "Show line diagnostics",
+ },
+ },
+ insert_mode = {},
+ visual_mode = {},
+ },
+ null_ls = {
+ setup = {},
+ },
+}
diff --git a/lua/lsp/handlers.lua b/lua/lsp/handlers.lua
index 2322e76a..ffb7564a 100644
--- a/lua/lsp/handlers.lua
+++ b/lua/lsp/handlers.lua
@@ -3,52 +3,73 @@
local M = {}
function M.setup()
- vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, {
+ local config = { -- your config
virtual_text = lvim.lsp.diagnostics.virtual_text,
- 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)
+ 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,
+ }
+ if vim.fn.has "nvim-0.5.1" > 0 then
+ vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, result, ctx, _)
+ local uri = result.uri
+ local bufnr = vim.uri_to_bufnr(uri)
+ if not bufnr then
+ return
+ end
- if not bufnr then
- return
- end
+ local diagnostics = result.diagnostics
+ local ok, vim_diag = pcall(require, "vim.diagnostic")
+ if ok then
+ -- FIX: why can't we just use vim.diagnostic.get(buf_id)?
+ config.signs = true
+ for i, diagnostic in ipairs(diagnostics) do
+ local rng = diagnostic.range
+ diagnostics[i].lnum = rng["start"].line
+ diagnostics[i].end_lnum = rng["end"].line
+ diagnostics[i].col = rng["start"].character
+ diagnostics[i].end_col = rng["end"].character
+ end
+ local namespace = vim.lsp.diagnostic.get_namespace(ctx.client_id)
- local diagnostics = params.diagnostics
+ vim_diag.set(namespace, bufnr, diagnostics, config)
+ if not vim.api.nvim_buf_is_loaded(bufnr) then
+ return
+ end
- 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-_]+)$"))
+ local sign_names = {
+ "DiagnosticSignError",
+ "DiagnosticSignWarn",
+ "DiagnosticSignInfo",
+ "DiagnosticSignHint",
+ }
+ for i, sign in ipairs(lvim.lsp.diagnostics.signs.values) do
+ vim.fn.sign_define(sign_names[i], { texthl = sign_names[i], text = sign.text, numhl = "" })
end
- diagnostics[i].message = string.format("%s: %s", source, v.message)
+ vim_diag.show(namespace, bufnr, diagnostics, config)
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)
+ vim.lsp.diagnostic.save(diagnostics, bufnr, ctx.client_id)
+ if not vim.api.nvim_buf_is_loaded(bufnr) then
+ return
+ end
+ vim.lsp.diagnostic.display(diagnostics, bufnr, ctx.client_id, config)
end
end
+ else
+ vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, _, params, client_id, _)
+ local uri = params.uri
+ local bufnr = vim.uri_to_bufnr(uri)
+ if not bufnr then
+ return
+ end
- vim.lsp.diagnostic.save(diagnostics, bufnr, client_id)
-
- if not vim.api.nvim_buf_is_loaded(bufnr) then
- return
+ local diagnostics = params.diagnostics
+ 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.diagnostic.display(diagnostics, bufnr, client_id, config)
end
vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, {
@@ -60,4 +81,89 @@ function M.setup()
})
end
+local function split_by_chunk(text, chunkSize)
+ local s = {}
+ for i = 1, #text, chunkSize do
+ s[#s + 1] = text:sub(i, i + chunkSize - 1)
+ end
+ return s
+end
+
+function M.show_line_diagnostics()
+ -- TODO: replace all this with vim.diagnostic.show_position_diagnostics()
+ local diagnostics = vim.lsp.diagnostic.get_line_diagnostics()
+ local severity_highlight = {
+ "LspDiagnosticsFloatingError",
+ "LspDiagnosticsFloatingWarning",
+ "LspDiagnosticsFloatingInformation",
+ "LspDiagnosticsFloatingHint",
+ }
+ local ok, vim_diag = pcall(require, "vim.diagnostic")
+ if ok then
+ local buf_id = vim.api.nvim_win_get_buf(0)
+ local win_id = vim.api.nvim_get_current_win()
+ local cursor_position = vim.api.nvim_win_get_cursor(win_id)
+ severity_highlight = {
+ "DiagnosticFloatingError",
+ "DiagnosticFloatingWarn",
+ "DiagnosticFloatingInfo",
+ "DiagnosticFloatingHint",
+ }
+ diagnostics = vim_diag.get(buf_id, { lnum = cursor_position[1] - 1 })
+ end
+ local lines = {}
+ local max_width = vim.fn.winwidth(0) - 5
+ local height = #diagnostics
+ local width = 0
+ local opts = {}
+ local close_events = { "CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre" }
+ if height == 0 then
+ return
+ end
+ local bufnr = vim.api.nvim_create_buf(false, true)
+ local diag_message
+ table.sort(diagnostics, function(a, b)
+ return a.severity < b.severity
+ end)
+ for i, diagnostic in ipairs(diagnostics) do
+ local source = diagnostic.source
+ diag_message = diagnostic.message:gsub("[\n\r]", " ")
+ if source then
+ if string.find(source, "/") then
+ source = string.sub(diagnostic.source, string.find(diagnostic.source, "([%w-_]+)$"))
+ end
+ diag_message = string.format("%d. %s: %s", i, source, diag_message)
+ else
+ diag_message = string.format("%d. %s", i, diag_message)
+ end
+ if diagnostic.code then
+ diag_message = string.format("%s [%s]", diag_message, diagnostic.code)
+ end
+ local msgs = split_by_chunk(diag_message, max_width)
+ for _, diag in ipairs(msgs) do
+ table.insert(lines, { message = diag, severity = diagnostic.severity })
+ width = math.max(diag:len(), width)
+ end
+ end
+ height = #lines
+ opts = vim.lsp.util.make_floating_popup_options(width, height, opts)
+ opts["style"] = "minimal"
+ opts["border"] = "rounded"
+ opts["focusable"] = true
+
+ 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)
+ for i, diag in ipairs(lines) do
+ vim.api.nvim_buf_set_lines(bufnr, i - 1, i - 1, 0, { diag.message })
+ vim.api.nvim_buf_add_highlight(bufnr, -1, severity_highlight[diag.severity], i - 1, 0, diag.message:len())
+ end
+
+ 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)
+end
+
return M
diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua
index 9c948803..88111005 100644
--- a/lua/lsp/init.lua
+++ b/lua/lsp/init.lua
@@ -1,15 +1,6 @@
local M = {}
local Log = require "core.log"
-
-function M.config()
- 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()
-end
+local utils = require "utils"
local function lsp_highlight_document(client)
if lvim.lsp.document_highlight == false then
@@ -19,9 +10,6 @@ local function lsp_highlight_document(client)
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()
@@ -33,26 +21,49 @@ local function lsp_highlight_document(client)
end
end
-local function add_lsp_buffer_keybindings(bufnr)
- local status_ok, wk = pcall(require, "which-key")
- if not status_ok then
+local function lsp_code_lens_refresh(client)
+ if lvim.lsp.code_lens_refresh == false then
return
end
- 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",
- },
+ if client.resolved_capabilities.code_lens then
+ vim.api.nvim_exec(
+ [[
+ augroup lsp_code_lens_refresh
+ autocmd! * <buffer>
+ autocmd InsertLeave <buffer> lua vim.lsp.codelens.refresh()
+ autocmd InsertLeave <buffer> lua vim.lsp.codelens.display()
+ augroup END
+ ]],
+ false
+ )
+ end
+end
+
+local function add_lsp_buffer_keybindings(bufnr)
+ local mappings = {
+ normal_mode = "n",
+ insert_mode = "i",
+ visual_mode = "v",
}
- wk.register(keys, { mode = "n", buffer = bufnr })
+
+ if lvim.builtin.which_key.active then
+ -- Remap using which_key
+ local status_ok, wk = pcall(require, "which-key")
+ if not status_ok then
+ return
+ end
+ for mode_name, mode_char in pairs(mappings) do
+ wk.register(lvim.lsp.buffer_mappings[mode_name], { mode = mode_char, buffer = bufnr })
+ end
+ else
+ -- Remap using nvim api
+ for mode_name, mode_char in pairs(mappings) do
+ for key, remap in pairs(lvim.lsp.buffer_mappings[mode_name]) do
+ vim.api.nvim_buf_set_keymap(bufnr, mode_char, key, remap[1], { noremap = true, silent = true })
+ end
+ end
+ end
end
function M.common_capabilities()
@@ -65,35 +76,30 @@ function M.common_capabilities()
"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
- if not client_id then
- error "Unable to determine client_id"
+ local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
+ if status_ok then
+ capabilities = cmp_nvim_lsp.update_capabilities(capabilities)
end
- client = vim.lsp.get_client_by_id(tonumber(client_id))
-
- local enabled_caps = {}
+ return capabilities
+end
- for k, v in pairs(client.resolved_capabilities) do
- if v == true then
- table.insert(enabled_caps, k)
+local function select_default_formater(client)
+ local client_formatting = client.resolved_capabilities.document_formatting
+ or client.resolved_capabilities.document_range_formatting
+ if client.name == "null-ls" or not client_formatting then
+ return
+ end
+ Log:debug("Checking for formatter overriding for " .. client.name)
+ local client_filetypes = client.config.filetypes or {}
+ for _, filetype in ipairs(client_filetypes) do
+ if lvim.lang[filetype] and #vim.tbl_keys(lvim.lang[filetype].formatters) > 0 then
+ Log:debug("Formatter overriding detected. Disabling formatting capabilities for " .. client.name)
+ client.resolved_capabilities.document_formatting = false
+ client.resolved_capabilities.document_range_formatting = false
end
end
-
- return enabled_caps
end
function M.common_on_init(client, bufnr)
@@ -102,55 +108,58 @@ function M.common_on_init(client, bufnr)
Log:debug "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:debug(
- string.format("Overriding language server [%s] with format provider [%s]", client.name, formatters[1].exe)
- )
- end
+ select_default_formater(client)
end
function M.common_on_attach(client, bufnr)
if lvim.lsp.on_attach_callback then
lvim.lsp.on_attach_callback(client, bufnr)
- Log:debug "Called lsp.on_init_callback"
+ Log:debug "Called lsp.on_attach_callback"
end
lsp_highlight_document(client)
+ lsp_code_lens_refresh(client)
add_lsp_buffer_keybindings(bufnr)
- require("lsp.null-ls").setup(vim.bo.filetype)
end
-function M.setup(lang)
- local lsp_utils = require "lsp.utils"
- local lsp = lvim.lang[lang].lsp
- if lsp_utils.is_client_active(lsp.provider) then
- return
+local function bootstrap_nlsp(opts)
+ opts = opts or {}
+ local lsp_settings_status_ok, lsp_settings = pcall(require, "nlspsettings")
+ if lsp_settings_status_ok then
+ lsp_settings.setup(opts)
end
+end
- local overrides = lvim.lsp.override
- if type(overrides) == "table" then
- if vim.tbl_contains(overrides, lang) then
- return
- end
+function M.get_common_opts()
+ return {
+ on_attach = M.common_on_attach,
+ on_init = M.common_on_init,
+ capabilities = M.common_capabilities(),
+ }
+end
+
+function M.setup()
+ Log:debug "Setting up LSP support"
+
+ local lsp_status_ok, _ = pcall(require, "lspconfig")
+ if not lsp_status_ok then
+ return
end
- if lsp.provider ~= nil and lsp.provider ~= "" then
- local lspconfig = require "lspconfig"
+ 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
- if not lsp.setup.on_attach then
- lsp.setup.on_attach = M.common_on_attach
- end
- if not lsp.setup.on_init then
- lsp.setup.on_init = M.common_on_init
- end
- if not lsp.setup.capabilities then
- lsp.setup.capabilities = M.common_capabilities()
- end
+ require("lsp.handlers").setup()
- lspconfig[lsp.provider].setup(lsp.setup)
+ if not utils.is_directory(lvim.lsp.templates_dir) then
+ require("lsp.templates").generate_templates()
end
+
+ bootstrap_nlsp { config_home = utils.join_paths(get_config_dir(), "lsp-settings") }
+
+ require("lsp.null-ls").setup()
+
+ require("utils").toggle_autoformat()
end
return M
diff --git a/lua/lsp/manager.lua b/lua/lsp/manager.lua
new file mode 100644
index 00000000..9cb81910
--- /dev/null
+++ b/lua/lsp/manager.lua
@@ -0,0 +1,86 @@
+local M = {}
+
+local Log = require "core.log"
+local lsp_utils = require "lsp.utils"
+
+function M.init_defaults(languages)
+ for _, entry in ipairs(languages) do
+ if not lvim.lang[entry] then
+ lvim.lang[entry] = {
+ formatters = {},
+ linters = {},
+ lsp = {},
+ }
+ end
+ end
+end
+
+local function is_overridden(server)
+ local overrides = lvim.lsp.override
+ if type(overrides) == "table" then
+ if vim.tbl_contains(overrides, server) then
+ return true
+ end
+ end
+end
+
+---Resolve the configuration for a server based on both common and user configuration
+---@param name string
+---@param user_config table [optional]
+---@return table
+local function resolve_config(name, user_config)
+ local config = {
+ on_attach = require("lsp").common_on_attach,
+ on_init = require("lsp").common_on_init,
+ capabilities = require("lsp").common_capabilities(),
+ }
+
+ local status_ok, custom_config = pcall(require, "lsp/providers/" .. name)
+ if status_ok then
+ Log:debug("Using custom configuration for requested server: " .. name)
+ config = vim.tbl_deep_extend("force", config, custom_config)
+ end
+
+ if user_config then
+ config = vim.tbl_deep_extend("force", config, user_config)
+ end
+
+ return config
+end
+
+---Setup a language server by providing a name
+---@param server_name string name of the language server
+---@param user_config table [optional] when available it will take predence over any default configurations
+function M.setup(server_name, user_config)
+ vim.validate { name = { server_name, "string" } }
+
+ if lsp_utils.is_client_active(server_name) or is_overridden(server_name) then
+ return
+ end
+
+ local config = resolve_config(server_name, user_config)
+ local server_available, requested_server = require("nvim-lsp-installer.servers").get_server(server_name)
+
+ local function ensure_installed(server)
+ if server:is_installed() then
+ return true
+ end
+ if not lvim.lsp.automatic_servers_installation then
+ Log:debug(server.name .. " is not managed by the automatic installer")
+ return false
+ end
+ Log:debug(string.format("Installing [%s]", server.name))
+ server:install()
+ vim.schedule(function()
+ vim.cmd [[LspStart]]
+ end)
+ end
+
+ if server_available and ensure_installed(requested_server) then
+ requested_server:setup(config)
+ else
+ require("lspconfig")[server_name].setup(config)
+ end
+end
+
+return M
diff --git a/lua/lsp/null-ls/formatters.lua b/lua/lsp/null-ls/formatters.lua
index 26be00da..4728b908 100644
--- a/lua/lsp/null-ls/formatters.lua
+++ b/lua/lsp/null-ls/formatters.lua
@@ -1,36 +1,23 @@
local M = {}
-local formatters_by_ft = {}
local null_ls = require "null-ls"
local services = require "lsp.null-ls.services"
local Log = require "core.log"
-local function list_names(formatters, options)
- options = options or {}
- local filter = options.filter or "supported"
-
- return vim.tbl_keys(formatters[filter])
-end
-
function M.list_supported_names(filetype)
- if not formatters_by_ft[filetype] then
- return {}
- end
- return list_names(formatters_by_ft[filetype], { filter = "supported" })
-end
-
-function M.list_unsupported_names(filetype)
- if not formatters_by_ft[filetype] then
- return {}
- end
- return list_names(formatters_by_ft[filetype], { filter = "unsupported" })
+ local null_ls_methods = require "null-ls.methods"
+ local formatter_method = null_ls_methods.internal["FORMATTING"]
+ local registered_providers = services.list_registered_providers_names(filetype)
+ return registered_providers[formatter_method] or {}
end
function M.list_available(filetype)
local formatters = {}
+ local tbl = require "utils.table"
for _, provider in pairs(null_ls.builtins.formatting) do
- -- TODO: Add support for wildcard filetypes
- if vim.tbl_contains(provider.filetypes or {}, filetype) then
+ if tbl.contains(provider.filetypes or {}, function(ft)
+ return ft == "*" or ft == filetype
+ end) then
table.insert(formatters, provider.name)
end
end
@@ -42,19 +29,24 @@ function M.list_configured(formatter_configs)
local formatters, errors = {}, {}
for _, fmt_config in ipairs(formatter_configs) do
- local formatter = null_ls.builtins.formatting[fmt_config.exe]
+ local formatter_name = fmt_config.exe:gsub("-", "_")
+ local formatter = null_ls.builtins.formatting[formatter_name]
if not formatter then
- Log:error("Not a valid formatter:", fmt_config.exe)
+ Log:error("Not a valid formatter: " .. fmt_config.exe)
errors[fmt_config.exe] = {} -- Add data here when necessary
else
local formatter_cmd = services.find_command(formatter._opts.command)
if not formatter_cmd then
- Log:warn("Not found:", formatter._opts.command)
+ Log:warn("Not found: " .. formatter._opts.command)
errors[fmt_config.exe] = {} -- Add data here when necessary
else
- Log:debug("Using formatter:", formatter_cmd)
- formatters[fmt_config.exe] = formatter.with { command = formatter_cmd, extra_args = fmt_config.args }
+ Log:debug("Using formatter: " .. formatter_cmd)
+ formatters[fmt_config.exe] = formatter.with {
+ command = formatter_cmd,
+ extra_args = fmt_config.args,
+ filetypes = fmt_config.filetypes,
+ }
end
end
end
@@ -62,13 +54,13 @@ function M.list_configured(formatter_configs)
return { supported = formatters, unsupported = errors }
end
-function M.setup(filetype, options)
- if not lvim.lang[filetype] or (formatters_by_ft[filetype] and not options.force_reload) then
+function M.setup(formatter_configs)
+ if vim.tbl_isempty(formatter_configs) then
return
end
- formatters_by_ft[filetype] = M.list_configured(lvim.lang[filetype].formatters)
- null_ls.register { sources = formatters_by_ft[filetype].supported }
+ local formatters_by_ft = M.list_configured(formatter_configs)
+ null_ls.register { sources = formatters_by_ft.supported }
end
return M
diff --git a/lua/lsp/null-ls/init.lua b/lua/lsp/null-ls/init.lua
index ce4c07d9..0d030c22 100644
--- a/lua/lsp/null-ls/init.lua
+++ b/lua/lsp/null-ls/init.lua
@@ -1,44 +1,32 @@
local M = {}
-function M.list_supported_provider_names(filetype)
- local names = {}
-
- local formatters = require "lsp.null-ls.formatters"
- local linters = require "lsp.null-ls.linters"
-
- vim.list_extend(names, formatters.list_supported_names(filetype))
- vim.list_extend(names, linters.list_supported_names(filetype))
-
- return names
-end
-
-function M.list_unsupported_provider_names(filetype)
- local names = {}
-
- local formatters = require "lsp.null-ls.formatters"
- local linters = require "lsp.null-ls.linters"
-
- vim.list_extend(names, formatters.list_unsupported_names(filetype))
- vim.list_extend(names, linters.list_unsupported_names(filetype))
-
- return names
-end
-
--- TODO: for linters and formatters with spaces and '-' replace with '_'
-function M.setup(filetype, options)
- options = options or {}
-
- local ok, _ = pcall(require, "null-ls")
- if not ok then
- require("core.log"):error "Missing null-ls dependency"
+local Log = require "core.log"
+local formatters = require "lsp.null-ls.formatters"
+local linters = require "lsp.null-ls.linters"
+
+function M:setup()
+ local status_ok, null_ls = pcall(require, "null-ls")
+ if not status_ok then
+ Log:error "Missing null-ls dependency"
return
end
- local formatters = require "lsp.null-ls.formatters"
- local linters = require "lsp.null-ls.linters"
-
- formatters.setup(filetype, options)
- linters.setup(filetype, options)
+ null_ls.config()
+ require("lspconfig")["null-ls"].setup(lvim.lsp.null_ls.setup)
+ for filetype, config in pairs(lvim.lang) do
+ if not vim.tbl_isempty(config.formatters) then
+ vim.tbl_map(function(c)
+ c.filetypes = { filetype }
+ end, config.formatters)
+ formatters.setup(config.formatters)
+ end
+ if not vim.tbl_isempty(config.linters) then
+ vim.tbl_map(function(c)
+ c.filetypes = { filetype }
+ end, config.formatters)
+ linters.setup(config.linters)
+ end
+ end
end
return M
diff --git a/lua/lsp/null-ls/linters.lua b/lua/lsp/null-ls/linters.lua
index bc191d7e..549c6cdd 100644
--- a/lua/lsp/null-ls/linters.lua
+++ b/lua/lsp/null-ls/linters.lua
@@ -1,36 +1,23 @@
local M = {}
-local linters_by_ft = {}
local null_ls = require "null-ls"
local services = require "lsp.null-ls.services"
local Log = require "core.log"
-local function list_names(linters, options)
- options = options or {}
- local filter = options.filter or "supported"
-
- return vim.tbl_keys(linters[filter])
-end
-
function M.list_supported_names(filetype)
- if not linters_by_ft[filetype] then
- return {}
- end
- return list_names(linters_by_ft[filetype], { filter = "supported" })
-end
-
-function M.list_unsupported_names(filetype)
- if not linters_by_ft[filetype] then
- return {}
- end
- return list_names(linters_by_ft[filetype], { filter = "unsupported" })
+ local null_ls_methods = require "null-ls.methods"
+ local linter_method = null_ls_methods.internal["DIAGNOSTICS"]
+ local registered_providers = services.list_registered_providers_names(filetype)
+ return registered_providers[linter_method] or {}
end
function M.list_available(filetype)
local linters = {}
+ local tbl = require "utils.table"
for _, provider in pairs(null_ls.builtins.diagnostics) do
- -- TODO: Add support for wildcard filetypes
- if vim.tbl_contains(provider.filetypes or {}, filetype) then
+ if tbl.contains(provider.filetypes or {}, function(ft)
+ return ft == "*" or ft == filetype
+ end) then
table.insert(linters, provider.name)
end
end
@@ -42,19 +29,24 @@ function M.list_configured(linter_configs)
local linters, errors = {}, {}
for _, lnt_config in pairs(linter_configs) do
- local linter = null_ls.builtins.diagnostics[lnt_config.exe]
+ local linter_name = lnt_config.exe:gsub("-", "_")
+ local linter = null_ls.builtins.diagnostics[linter_name]
if not linter then
- Log:error("Not a valid linter:", lnt_config.exe)
+ Log:error("Not a valid linter: " .. lnt_config.exe)
errors[lnt_config.exe] = {} -- Add data here when necessary
else
local linter_cmd = services.find_command(linter._opts.command)
if not linter_cmd then
- Log:warn("Not found:", linter._opts.command)
+ Log:warn("Not found: " .. linter._opts.command)
errors[lnt_config.exe] = {} -- Add data here when necessary
else
- Log:debug("Using linter:", linter_cmd)
- linters[lnt_config.exe] = linter.with { command = linter_cmd, extra_args = lnt_config.args }
+ Log:debug("Using linter: " .. linter_cmd)
+ linters[lnt_config.exe] = linter.with {
+ command = linter_cmd,
+ extra_args = lnt_config.args,
+ filetypes = lnt_config.filetypes,
+ }
end
end
end
@@ -62,13 +54,13 @@ function M.list_configured(linter_configs)
return { supported = linters, unsupported = errors }
end
-function M.setup(filetype, options)
- if not lvim.lang[filetype] or (linters_by_ft[filetype] and not options.force_reload) then
+function M.setup(linter_configs)
+ if vim.tbl_isempty(linter_configs) then
return
end
- linters_by_ft[filetype] = M.list_configured(lvim.lang[filetype].linters)
- null_ls.register { sources = linters_by_ft[filetype].supported }
+ local linters = M.list_configured(linter_configs)
+ null_ls.register { sources = linters.supported }
end
return M
diff --git a/lua/lsp/null-ls/services.lua b/lua/lsp/null-ls/services.lua
index a1e3a06c..ef9e7d22 100644
--- a/lua/lsp/null-ls/services.lua
+++ b/lua/lsp/null-ls/services.lua
@@ -4,8 +4,8 @@ local function find_root_dir()
local util = require "lspconfig/util"
local lsp_utils = require "lsp.utils"
- local status_ok, ts_client = lsp_utils.is_client_active "typescript"
- if status_ok then
+ local ts_client = lsp_utils.is_client_active "typescript"
+ if ts_client then
return ts_client.config.root_dir
end
local dirname = vim.fn.expand "%:p:h"
@@ -28,6 +28,7 @@ local local_providers = {
prettier_d_slim = { find = from_node_modules },
eslint_d = { find = from_node_modules },
eslint = { find = from_node_modules },
+ stylelint = { find = from_node_modules },
}
function M.find_command(command)
@@ -44,4 +45,19 @@ function M.find_command(command)
return nil
end
+function M.list_registered_providers_names(filetype)
+ local u = require "null-ls.utils"
+ local c = require "null-ls.config"
+ local registered = {}
+ for method, source in pairs(c.get()._methods) do
+ for name, filetypes in pairs(source) do
+ if u.filetype_matches(filetypes, filetype) then
+ registered[method] = registered[method] or {}
+ table.insert(registered[method], name)
+ end
+ end
+ end
+ return registered
+end
+
return M
diff --git a/lua/lsp/peek.lua b/lua/lsp/peek.lua
index cc8e57a9..cb00488e 100644
--- a/lua/lsp/peek.lua
+++ b/lua/lsp/peek.lua
@@ -42,6 +42,7 @@ local function create_floating_file(location, opts)
local winnr = vim.api.nvim_open_win(bufnr, false, opts)
vim.api.nvim_win_set_option(winnr, "winblend", 0)
+ vim.api.nvim_win_set_cursor(winnr, { range.start.line + 1, range.start.character })
vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr)
-- Set some autocmds to close the window
@@ -53,9 +54,8 @@ local function create_floating_file(location, opts)
return bufnr, winnr
end
-local function preview_location_callback(_, method, result)
+local function preview_location_callback(result)
if result == nil or vim.tbl_isempty(result) then
- print("peek: No location found: " .. method)
return nil
end
@@ -73,6 +73,14 @@ local function preview_location_callback(_, method, result)
end
end
+local function preview_location_callback_old_signature(_, _, result)
+ return preview_location_callback(result)
+end
+
+local function preview_location_callback_new_signature(_, result)
+ return preview_location_callback(result)
+end
+
function M.open_file()
-- Get the file currently open in the floating window
local filepath = vim.fn.expand "%:."
@@ -128,7 +136,11 @@ function M.Peek(what)
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)
+ local preview_callback = preview_location_callback_old_signature
+ if vim.fn.has "nvim-0.5.1" > 0 then
+ preview_callback = preview_location_callback_new_signature
+ end
+ local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_callback)
if not success then
print(
'peek: Error calling LSP method "textDocument/' .. what .. '". The current language lsp might not support it.'
diff --git a/lua/lsp/providers/jsonls.lua b/lua/lsp/providers/jsonls.lua
new file mode 100644
index 00000000..1fffa686
--- /dev/null
+++ b/lua/lsp/providers/jsonls.lua
@@ -0,0 +1,197 @@
+local default_schemas = nil
+local status_ok, jsonls_settings = pcall(require, "nlspsettings.jsonls")
+if status_ok then
+ default_schemas = jsonls_settings.get_default_schemas()
+end
+
+local schemas = {
+ {
+ description = "TypeScript compiler configuration file",
+ fileMatch = {
+ "tsconfig.json",
+ "tsconfig.*.json",
+ },
+ url = "https://json.schemastore.org/tsconfig.json",
+ },
+ {
+ description = "Lerna config",
+ fileMatch = { "lerna.json" },
+ url = "https://json.schemastore.org/lerna.json",
+ },
+ {
+ description = "Babel configuration",
+ fileMatch = {
+ ".babelrc.json",
+ ".babelrc",
+ "babel.config.json",
+ },
+ url = "https://json.schemastore.org/babelrc.json",
+ },
+ {
+ description = "ESLint config",
+ fileMatch = {
+ ".eslintrc.json",
+ ".eslintrc",
+ },
+ url = "https://json.schemastore.org/eslintrc.json",
+ },
+ {
+ description = "Bucklescript config",
+ fileMatch = { "bsconfig.json" },
+ url = "https://raw.githubusercontent.com/rescript-lang/rescript-compiler/8.2.0/docs/docson/build-schema.json",
+ },
+ {
+ description = "Prettier config",
+ fileMatch = {
+ ".prettierrc",
+ ".prettierrc.json",
+ "prettier.config.json",
+ },
+ url = "https://json.schemastore.org/prettierrc",
+ },
+ {
+ description = "Vercel Now config",
+ fileMatch = { "now.json" },
+ url = "https://json.schemastore.org/now",
+ },
+ {
+ description = "Stylelint config",
+ fileMatch = {
+ ".stylelintrc",
+ ".stylelintrc.json",
+ "stylelint.config.json",
+ },
+ url = "https://json.schemastore.org/stylelintrc",
+ },
+ {
+ description = "A JSON schema for the ASP.NET LaunchSettings.json files",
+ fileMatch = { "launchsettings.json" },
+ url = "https://json.schemastore.org/launchsettings.json",
+ },
+ {
+ description = "Schema for CMake Presets",
+ fileMatch = {
+ "CMakePresets.json",
+ "CMakeUserPresets.json",
+ },
+ url = "https://raw.githubusercontent.com/Kitware/CMake/master/Help/manual/presets/schema.json",
+ },
+ {
+ description = "Configuration file as an alternative for configuring your repository in the settings page.",
+ fileMatch = {
+ ".codeclimate.json",
+ },
+ url = "https://json.schemastore.org/codeclimate.json",
+ },
+ {
+ description = "LLVM compilation database",
+ fileMatch = {
+ "compile_commands.json",
+ },
+ url = "https://json.schemastore.org/compile-commands.json",
+ },
+ {
+ description = "Config file for Command Task Runner",
+ fileMatch = {
+ "commands.json",
+ },
+ url = "https://json.schemastore.org/commands.json",
+ },
+ {
+ description = "AWS CloudFormation provides a common language for you to describe and provision all the infrastructure resources in your cloud environment.",
+ fileMatch = {
+ "*.cf.json",
+ "cloudformation.json",
+ },
+ url = "https://raw.githubusercontent.com/awslabs/goformation/v5.2.9/schema/cloudformation.schema.json",
+ },
+ {
+ description = "The AWS Serverless Application Model (AWS SAM, previously known as Project Flourish) extends AWS CloudFormation to provide a simplified way of defining the Amazon API Gateway APIs, AWS Lambda functions, and Amazon DynamoDB tables needed by your serverless application.",
+ fileMatch = {
+ "serverless.template",
+ "*.sam.json",
+ "sam.json",
+ },
+ url = "https://raw.githubusercontent.com/awslabs/goformation/v5.2.9/schema/sam.schema.json",
+ },
+ {
+ description = "Json schema for properties json file for a GitHub Workflow template",
+ fileMatch = {
+ ".github/workflow-templates/**.properties.json",
+ },
+ url = "https://json.schemastore.org/github-workflow-template-properties.json",
+ },
+ {
+ description = "golangci-lint configuration file",
+ fileMatch = {
+ ".golangci.toml",
+ ".golangci.json",
+ },
+ url = "https://json.schemastore.org/golangci-lint.json",
+ },
+ {
+ description = "JSON schema for the JSON Feed format",
+ fileMatch = {
+ "feed.json",
+ },
+ url = "https://json.schemastore.org/feed.json",
+ versions = {
+ ["1"] = "https://json.schemastore.org/feed-1.json",
+ ["1.1"] = "https://json.schemastore.org/feed.json",
+ },
+ },
+ {
+ description = "Packer template JSON configuration",
+ fileMatch = {
+ "packer.json",
+ },
+ url = "https://json.schemastore.org/packer.json",
+ },
+ {
+ description = "NPM configuration file",
+ fileMatch = {
+ "package.json",
+ },
+ url = "https://json.schemastore.org/package.json",
+ },
+ {
+ description = "JSON schema for Visual Studio component configuration files",
+ fileMatch = {
+ "*.vsconfig",
+ },
+ url = "https://json.schemastore.org/vsconfig.json",
+ },
+ {
+ description = "Resume json",
+ fileMatch = { "resume.json" },
+ url = "https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json",
+ },
+}
+
+local function extend(tab1, tab2)
+ for _, value in ipairs(tab2) do
+ table.insert(tab1, value)
+ end
+ return tab1
+end
+
+local extended_schemas = extend(schemas, default_schemas)
+
+local opts = {
+ settings = {
+ json = {
+ schemas = extended_schemas,
+ },
+ },
+ setup = {
+ commands = {
+ Format = {
+ function()
+ vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 })
+ end,
+ },
+ },
+ },
+}
+
+return opts
diff --git a/lua/lsp/providers/sumneko_lua.lua b/lua/lsp/providers/sumneko_lua.lua
new file mode 100644
index 00000000..4fee1fd1
--- /dev/null
+++ b/lua/lsp/providers/sumneko_lua.lua
@@ -0,0 +1,19 @@
+local opts = {
+ settings = {
+ Lua = {
+ diagnostics = {
+ globals = { "vim", "lvim" },
+ },
+ workspace = {
+ library = {
+ [require("utils").join_paths(get_runtime_dir(), "lvim", "lua")] = true,
+ [vim.fn.expand "$VIMRUNTIME/lua"] = true,
+ [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true,
+ },
+ maxPreload = 100000,
+ preloadFileSize = 10000,
+ },
+ },
+ },
+}
+return opts
diff --git a/lua/lsp/providers/vuels.lua b/lua/lsp/providers/vuels.lua
new file mode 100644
index 00000000..3f44275d
--- /dev/null
+++ b/lua/lsp/providers/vuels.lua
@@ -0,0 +1,26 @@
+local opts = {
+ setup = {
+ root_dir = function(fname)
+ local util = require "lspconfig/util"
+ return util.root_pattern "package.json"(fname) or util.root_pattern "vue.config.js"(fname) or vim.fn.getcwd()
+ end,
+ init_options = {
+ config = {
+ vetur = {
+ completion = {
+ autoImport = true,
+ tagCasing = "kebab",
+ useScaffoldSnippets = true,
+ },
+ useWorkspaceDependencies = true,
+ validation = {
+ script = true,
+ style = true,
+ template = true,
+ },
+ },
+ },
+ },
+ },
+}
+return opts
diff --git a/lua/lsp/providers/yamlls.lua b/lua/lsp/providers/yamlls.lua
new file mode 100644
index 00000000..156a35b0
--- /dev/null
+++ b/lua/lsp/providers/yamlls.lua
@@ -0,0 +1,30 @@
+local opts = {
+ settings = {
+ yaml = {
+ hover = true,
+ completion = true,
+ validate = true,
+ schemaStore = {
+ enable = true,
+ url = "https://www.schemastore.org/api/json/catalog.json",
+ },
+ schemas = {
+ kubernetes = {
+ "daemon.{yml,yaml}",
+ "manager.{yml,yaml}",
+ "restapi.{yml,yaml}",
+ "role.{yml,yaml}",
+ "role_binding.{yml,yaml}",
+ "*onfigma*.{yml,yaml}",
+ "*ngres*.{yml,yaml}",
+ "*ecre*.{yml,yaml}",
+ "*eployment*.{yml,yaml}",
+ "*ervic*.{yml,yaml}",
+ "kubectl-edit*.yaml",
+ },
+ },
+ },
+ },
+}
+
+return opts
diff --git a/lua/lsp/templates.lua b/lua/lsp/templates.lua
new file mode 100644
index 00000000..fbbc37f6
--- /dev/null
+++ b/lua/lsp/templates.lua
@@ -0,0 +1,98 @@
+local M = {}
+
+local Log = require "core.log"
+local utils = require "utils"
+local get_supported_filetypes = require("lsp.utils").get_supported_filetypes
+
+local ftplugin_dir = lvim.lsp.templates_dir
+
+local join_paths = _G.join_paths
+
+function M.remove_template_files()
+ -- remove any outdated files
+ for _, file in ipairs(vim.fn.glob(ftplugin_dir .. "/*.lua", 1, 1)) do
+ vim.fn.delete(file)
+ end
+end
+
+---Checks if a server is ignored by default because of a conflict
+---Only TSServer is enabled by default for the javascript-family
+---@param server_name string
+function M.is_ignored(server_name, filetypes)
+ --TODO: this is easy to be made configurable once stable
+ filetypes = filetypes or get_supported_filetypes(server_name)
+
+ if vim.tbl_contains(filetypes, "javascript") then
+ if server_name == "tsserver" then
+ return false
+ else
+ return true
+ end
+ end
+
+ local blacklist = {
+ "jedi_language_server",
+ "pylsp",
+ "sqlls",
+ "sqls",
+ "angularls",
+ "ansiblels",
+ }
+ return vim.tbl_contains(blacklist, server_name)
+end
+
+---Generates an ftplugin file based on the server_name in the selected directory
+---@param server_name string name of a valid language server, e.g. pyright, gopls, tsserver, etc.
+---@param dir string the full path to the desired directory
+function M.generate_ftplugin(server_name, dir)
+ -- we need to go through lspconfig to get the corresponding filetypes currently
+ local filetypes = get_supported_filetypes(server_name) or {}
+ if not filetypes then
+ return
+ end
+
+ if M.is_ignored(server_name, filetypes) then
+ return
+ end
+
+ -- print("got associated filetypes: " .. vim.inspect(filetypes))
+
+ for _, filetype in ipairs(filetypes) do
+ local filename = join_paths(dir, filetype .. ".lua")
+ local setup_cmd = string.format([[require("lsp.manager").setup(%q)]], server_name)
+ -- print("using setup_cmd: " .. setup_cmd)
+ -- overwrite the file completely
+ utils.write_file(filename, setup_cmd .. "\n", "a")
+ end
+end
+
+---Generates ftplugin files based on a list of server_names
+---The files are generated to a runtimepath: "$LUNARVIM_RUNTIME_DIR/site/after/ftplugin/template.lua"
+---@param servers_names table list of servers to be enabled. Will add all by default
+function M.generate_templates(servers_names)
+ servers_names = servers_names or {}
+
+ Log:debug "Templates installation in progress"
+
+ M.remove_template_files()
+
+ if vim.tbl_isempty(servers_names) then
+ local available_servers = require("nvim-lsp-installer.servers").get_available_servers()
+
+ for _, server in pairs(available_servers) do
+ table.insert(servers_names, server.name)
+ end
+ end
+
+ -- create the directory if it didn't exist
+ if not utils.is_directory(lvim.lsp.templates_dir) then
+ vim.fn.mkdir(ftplugin_dir, "p")
+ end
+
+ for _, server in ipairs(servers_names) do
+ M.generate_ftplugin(server, ftplugin_dir)
+ end
+ Log:debug "Templates installation is complete"
+end
+
+return M
diff --git a/lua/lsp/utils.lua b/lua/lsp/utils.lua
index 17b9c3bc..59003406 100644
--- a/lua/lsp/utils.lua
+++ b/lua/lsp/utils.lua
@@ -1,28 +1,62 @@
local M = {}
+local tbl = require "utils.table"
+
function M.is_client_active(name)
local clients = vim.lsp.get_active_clients()
+ return tbl.find_first(clients, function(client)
+ return client.name == name
+ end)
+end
+
+function M.get_active_clients_by_ft(filetype)
+ local matches = {}
+ local clients = vim.lsp.get_active_clients()
for _, client in pairs(clients) do
- if client.name == name then
- return true, client
+ local supported_filetypes = client.config.filetypes or {}
+ if client.name ~= "null-ls" and vim.tbl_contains(supported_filetypes, filetype) then
+ table.insert(matches, client)
end
end
- return false
+ return matches
end
--- FIXME: this should return a list instead
-function M.get_active_client_by_ft(filetype)
- if not lvim.lang[filetype] or not lvim.lang[filetype].lsp then
- return nil
+function M.get_client_capabilities(client_id)
+ 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
+ if not client_id then
+ error "Unable to determine client_id"
+ return
end
- local clients = vim.lsp.get_active_clients()
- for _, client in pairs(clients) do
- if client.name == lvim.lang[filetype].lsp.provider then
- return client
+ local client = vim.lsp.get_client_by_id(tonumber(client_id))
+
+ local enabled_caps = {}
+ for capability, status in pairs(client.resolved_capabilities) do
+ if status == true then
+ table.insert(enabled_caps, capability)
+ end
+ end
+
+ return enabled_caps
+end
+
+function M.get_supported_filetypes(server_name)
+ -- print("got filetypes query request for: " .. server_name)
+ local configs = require "lspconfig/configs"
+ pcall(require, ("lspconfig/" .. server_name))
+ for _, config in pairs(configs) do
+ if config.name == server_name then
+ return config.document_config.default_config.filetypes or {}
end
end
- return nil
end
return M
diff --git a/lua/lualine/themes/onedarker.lua b/lua/lualine/themes/onedarker.lua
new file mode 100644
index 00000000..396657bb
--- /dev/null
+++ b/lua/lualine/themes/onedarker.lua
@@ -0,0 +1,35 @@
+-- Copyright (c) 2020-2021 shadmansaleh
+-- MIT license, see LICENSE for more details.
+-- Credit: Zoltan Dalmadi(lightline)
+-- LuaFormatter off
+local colors = {
+ blue = "#61afef",
+ green = "#98c379",
+ purple = "#c678dd",
+ red1 = "#e06c75",
+ red2 = "#be5046",
+ yellow = "#e5c07b",
+ orange = "#D19A66",
+ fg = "#abb2bf",
+ bg = "#282c34",
+ gray1 = "#5c6370",
+ gray2 = "#2c323d",
+ gray3 = "#3e4452",
+}
+-- LuaFormatter on
+return {
+ normal = {
+ a = { fg = colors.fg, bg = colors.blue, gui = "bold" },
+ b = { fg = colors.fg, bg = colors.bg },
+ c = { fg = colors.fg, bg = colors.bg },
+ },
+ insert = { a = { fg = colors.fg, bg = colors.green, gui = "bold" } },
+ visual = { a = { fg = colors.fg, bg = colors.purple, gui = "bold" } },
+ command = { a = { fg = colors.fg, bg = colors.yellow, gui = "bold" } },
+ replace = { a = { fg = colors.fg, bg = colors.red1, gui = "bold" } },
+ inactive = {
+ a = { fg = colors.gray1, bg = colors.bg, gui = "bold" },
+ b = { fg = colors.gray1, bg = colors.bg },
+ c = { fg = colors.gray1, bg = colors.bg },
+ },
+}
diff --git a/lua/spacegray/Git.lua b/lua/onedarker/Git.lua
index b47ccf23..b47ccf23 100644
--- a/lua/spacegray/Git.lua
+++ b/lua/onedarker/Git.lua
diff --git a/lua/spacegray/LSP.lua b/lua/onedarker/LSP.lua
index dd3d77ac..82b9f799 100644
--- a/lua/spacegray/LSP.lua
+++ b/lua/onedarker/LSP.lua
@@ -11,10 +11,18 @@ local LSP = {
LspDiagnosticsFloatingWarning = { fg = C.warning_orange },
LspDiagnosticsFloatingInformation = { fg = C.info_yellow },
LspDiagnosticsFloatingHint = { fg = C.hint_blue },
+ DiagnosticFloatingError = { fg = C.error_red },
+ DiagnosticFloatingWarn = { fg = C.warning_orange },
+ DiagnosticFloatingInfo = { fg = C.info_yellow },
+ DiagnosticFloatingHint = { fg = C.hint_blue },
LspDiagnosticsSignError = { fg = C.error_red },
LspDiagnosticsSignWarning = { fg = C.warning_orange },
LspDiagnosticsSignInformation = { fg = C.info_yellow },
LspDiagnosticsSignHint = { fg = C.hint_blue },
+ DiagnosticSignError = { fg = C.error_red },
+ DiagnosticSignWarn = { fg = C.warning_orange },
+ DiagnosticSignInfo = { fg = C.info_yellow },
+ DiagnosticSignHint = { fg = C.hint_blue },
LspDiagnosticsError = { fg = C.error_red },
LspDiagnosticsWarning = { fg = C.warning_orange },
LspDiagnosticsInformation = { fg = C.info_yellow },
@@ -23,11 +31,19 @@ local LSP = {
LspDiagnosticsUnderlineWarning = { style = "underline" },
LspDiagnosticsUnderlineInformation = { style = "underline" },
LspDiagnosticsUnderlineHint = { style = "underline" },
+ DiagnosticUnderlineError = { style = "underline" },
+ DiagnosticUnderlineWarn = { style = "underline" },
+ DiagnosticUnderlineInfo = { style = "underline" },
+ DiagnosticUnderlineHint = { style = "underline" },
+ LspReferenceRead = { bg = C.fg_gutter, style = "bold" },
+ LspReferenceText = { bg = C.fg_gutter, style = "bold" },
+ LspReferenceWrite = { bg = C.fg_gutter, style = "bold" },
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 = Config.transparent_background and "NONE" or C.bg },
+ TelescopePromptPrefix = { fg = C.purple },
NvimTreeFolderIcon = { fg = C.blue },
NvimTreeIndentMarker = { fg = C.gray },
NvimTreeNormal = { fg = C.light_gray, bg = C.alt_bg },
@@ -37,6 +53,7 @@ local LSP = {
NvimTreeImageFile = { fg = C.purple },
NvimTreeSpecialFile = { fg = C.orange },
NvimTreeGitStaged = { fg = C.sign_add },
+ NvimTreeCursorLine = { bg = C.bg },
NvimTreeGitNew = { fg = C.sign_add },
NvimTreeGitDirty = { fg = C.sign_add },
NvimTreeGitDeleted = { fg = C.sign_delete },
@@ -70,13 +87,16 @@ local LSP = {
StatusLineTerm = { fg = C.alt_bg },
StatusLineTermNC = { fg = C.alt_bg },
CodiVirtualText = { fg = C.hint_blue },
- IndentBlanklineContextChar = { fg = C.accent },
+ IndentBlanklineContextChar = { fg = C.context },
+ IndentBlanklineChar = { fg = C.dark_gray },
+ IndentBlanklineSpaceChar = { fg = C.cyan_test },
+ IndentBlanklineSpaceCharBlankline = { fg = C.info_yellow },
DashboardHeader = { fg = C.blue },
DashboardCenter = { fg = C.purple },
DashboardFooter = { fg = C.cyan },
- xmlTag = { fg = C.cyan },
- xmlTagName = { fg = C.cyan },
- xmlEndTag = { fg = C.cyan },
+ xmlTag = { fg = C.blue },
+ xmlTagName = { fg = C.blue },
+ xmlEndTag = { fg = C.blue },
CompeDocumentation = { bg = C.alt_bg },
DiffViewNormal = { fg = C.gray, bg = C.alt_bg },
DiffviewStatusAdded = { fg = C.sign_add },
@@ -94,6 +114,8 @@ local LSP = {
diffOldFile = { fg = C.red },
debugPc = { bg = C.cyan },
debugBreakpoint = { fg = C.red, style = "reverse" },
+ FocusedSymbol = { fg = C.purple, style = "bold" },
+ SymbolsOutlineConnector = { fg = C.context },
}
return LSP
diff --git a/lua/onedarker/Treesitter.lua b/lua/onedarker/Treesitter.lua
new file mode 100644
index 00000000..0718b852
--- /dev/null
+++ b/lua/onedarker/Treesitter.lua
@@ -0,0 +1,66 @@
+local Treesitter = {
+ TSComment = { fg = C.gray },
+ TSAnnotation = { fg = C.blue },
+ TSAttribute = { fg = C.cyan },
+ TSConstructor = { fg = C.yellow },
+ TSType = { fg = C.yellow },
+ TSTypeBuiltin = { fg = C.yellow },
+ TSConditional = { fg = C.purple },
+ TSException = { fg = C.purple },
+ TSInclude = { fg = C.purple },
+ TSKeyword = { fg = C.purple },
+ TSKeywordReturn = { fg = C.purple },
+ TSKeywordFunction = { fg = C.purple },
+ TSLabel = { fg = C.blue },
+ TSNone = { fg = C.fg },
+ TSNamespace = { fg = C.purple },
+ TSRepeat = { fg = C.purple },
+ TSConstant = { fg = C.orange },
+ TSConstBuiltin = { fg = C.orange },
+ TSFloat = { fg = C.orange },
+ TSNumber = { fg = C.orange },
+ TSBoolean = { fg = C.orange },
+ TSCharacter = { fg = C.green },
+ TSError = { fg = C.error_red },
+ TSFunction = { fg = C.blue },
+ TSFuncBuiltin = { fg = C.blue },
+ TSMethod = { fg = C.blue },
+ TSConstMacro = { fg = C.cyan },
+ TSFuncMacro = { fg = C.blue },
+ TSProperty = { fg = C.cyan },
+ TSOperator = { fg = C.purple },
+ TSField = { fg = C.blue },
+ TSParameter = { fg = C.red },
+ TSParameterReference = { fg = C.red },
+ TSVariable = { fg = C.fg },
+ TSVariableBuiltin = { fg = C.red },
+ TSSymbol = { fg = C.cyan },
+ TSText = { fg = C.fg },
+ TSTextReference = { fg = C.red },
+ TSPunctDelimiter = { fg = C.fg },
+ TSTagDelimiter = { fg = C.gray },
+ TSTagAttribute = { fg = C.orange },
+ TSPunctBracket = { fg = C.fg },
+ TSPunctSpecial = { fg = C.fg },
+ TSString = { fg = C.green },
+ TSStringRegex = { fg = C.orange },
+ TSStringEscape = { fg = C.orange },
+ TSTag = { fg = C.blue },
+ TSEmphasis = { style = "italic" },
+ TSUnderline = { style = "underline" },
+ TSNote = { fg = C.info_yellow, style = "bold" },
+ TSWarning = { fg = C.warning_orange, style = "bold" },
+ TSDanger = { fg = C.error_red, style = "bold" },
+ TSTitle = { fg = C.blue, style = "bold" },
+ TSLiteral = { fg = C.green },
+ TSURI = { fg = C.blue, style = "underline" },
+ TSMath = { fg = C.fg },
+ TSKeywordOperator = { fg = C.purple },
+ TSStructure = { fg = C.fg },
+ TSStrong = { fg = C.yellow_orange },
+ TSQueryLinterError = { fg = C.warning_orange },
+ TSEnvironment = { fg = C.fg },
+ TSEnvironmentName = { fg = C.fg },
+}
+
+return Treesitter
diff --git a/lua/spacegray/Whichkey.lua b/lua/onedarker/Whichkey.lua
index 5d1ae7ce..86b42bd6 100644
--- a/lua/spacegray/Whichkey.lua
+++ b/lua/onedarker/Whichkey.lua
@@ -1,8 +1,8 @@
local Whichkey = {
WhichKey = { fg = C.purple },
WhichKeySeperator = { fg = C.green },
- WhichKeyGroup = { fg = C.blue },
- WhichKeyDesc = { fg = C.light_blue },
+ WhichKeyGroup = { fg = C.cyan },
+ WhichKeyDesc = { fg = C.blue },
WhichKeyFloat = { bg = C.dark },
}
diff --git a/lua/spacegray/config.lua b/lua/onedarker/config.lua
index ebac7109..ebac7109 100644
--- a/lua/spacegray/config.lua
+++ b/lua/onedarker/config.lua
diff --git a/lua/onedarker/diff.lua b/lua/onedarker/diff.lua
new file mode 100644
index 00000000..49463daa
--- /dev/null
+++ b/lua/onedarker/diff.lua
@@ -0,0 +1,12 @@
+local diff = {
+ DiffAdd = { fg = C.none, bg = C.diff_add },
+ DiffDelete = { fg = C.none, bg = C.diff_delete },
+ DiffChange = { fg = C.none, bg = C.diff_change, style = "bold" },
+ DiffText = { fg = C.none, bg = C.diff_text },
+ DiffAdded = { fg = C.green },
+ DiffRemoved = { fg = C.red },
+ DiffFile = { fg = C.cyan },
+ DiffIndexLine = { fg = C.gray },
+}
+
+return diff
diff --git a/lua/spacegray/highlights.lua b/lua/onedarker/highlights.lua
index 208c2c62..28e7c07f 100644
--- a/lua/spacegray/highlights.lua
+++ b/lua/onedarker/highlights.lua
@@ -16,8 +16,8 @@ local highlights = {
Comment = { fg = C.gray, style = "italic" },
Folded = { fg = C.accent, bg = C.alt_bg },
FoldColumn = { fg = C.accent, bg = C.alt_bg },
- LineNr = { fg = C.gray },
- FloatBoder = { fg = C.gray, bg = C.alt_bg },
+ LineNr = { fg = C.context },
+ FloatBorder = { fg = C.gray, bg = C.alt_bg },
Whitespace = { fg = C.bg },
VertSplit = { fg = C.bg, bg = C.fg },
CursorLine = { bg = C.dark },
@@ -30,7 +30,7 @@ local highlights = {
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 },
+ QuickFixLine = { bg = C.dark_gray },
PmenuSbar = { bg = C.alt_bg },
PmenuThumb = { bg = C.gray },
MatchWord = { style = "underline" },
@@ -53,37 +53,37 @@ local highlights = {
MoreMsg = { fg = C.orange },
Question = { fg = C.orange },
EndOfBuffer = { fg = C.bg },
- NonText = { fg = C.bg },
- Variable = { fg = C.light_blue },
+ NonText = { fg = C.context },
+ Variable = { fg = C.cyan },
String = { fg = C.green },
- Character = { fg = C.light_green },
- Constant = { fg = C.blue },
- Number = { fg = C.red },
- Boolean = { fg = C.red },
- Float = { fg = C.red },
- Identifier = { fg = C.light_blue },
- Function = { fg = C.yellow },
- Operator = { fg = C.gray },
- Type = { fg = C.purple },
- StorageClass = { fg = C.purple },
+ Character = { fg = C.green },
+ Constant = { fg = C.orange },
+ Number = { fg = C.orange },
+ Boolean = { fg = C.orange },
+ Float = { fg = C.orange },
+ Identifier = { fg = C.fg },
+ Function = { fg = C.blue },
+ Operator = { fg = C.purple },
+ Type = { fg = C.yellow },
+ StorageClass = { fg = C.cyan },
Structure = { fg = C.purple },
Typedef = { fg = C.purple },
- Keyword = { fg = C.blue },
- Statement = { fg = C.blue },
- Conditional = { fg = C.blue },
- Repeat = { fg = C.blue },
+ Keyword = { fg = C.purple },
+ Statement = { fg = C.purple },
+ Conditional = { fg = C.purple },
+ Repeat = { fg = C.purple },
Label = { fg = C.blue },
- Exception = { fg = C.blue },
- Include = { fg = C.blue },
+ Exception = { fg = C.purple },
+ Include = { fg = C.purple },
PreProc = { fg = C.purple },
Define = { fg = C.purple },
Macro = { fg = C.purple },
PreCondit = { fg = C.purple },
- Special = { fg = C.orange },
- SpecialChar = { fg = C.white },
+ Special = { fg = C.purple },
+ SpecialChar = { fg = C.fg },
Tag = { fg = C.blue },
Debug = { fg = C.red },
- Delimiter = { fg = C.gray },
+ Delimiter = { fg = C.fg },
SpecialComment = { fg = C.gray },
Underlined = { style = "underline" },
Bold = { style = "bold" },
@@ -92,8 +92,16 @@ local highlights = {
Todo = { fg = C.red, bg = C.bg, style = "bold" },
Error = { fg = C.error_red, bg = C.bg, style = "bold" },
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 },
+ TabLineSel = { fg = C.fg, bg = C.alt_bg },
+ TabLineFill = { fg = C.fg, bg = C.alt_bg },
+ CmpDocumentation = { fg = C.fg, bg = C.none },
+ CmpDocumentationBorder = { fg = C.fg_dark, bg = C.none },
+ CmpItemAbbr = { fg = C.fg, bg = C.none },
+ CmpItemAbbrDeprecated = { fg = C.gray, bg = C.none },
+ CmpItemAbbrMatch = { fg = C.cyan, bg = C.none },
+ CmpItemAbbrMatchFuzzy = { fg = C.cyan, bg = C.none },
+ CmpItemKind = { fg = C.blue, bg = C.none },
+ CmpItemMenu = { fg = C.light_gray, bg = C.none },
}
return highlights
diff --git a/lua/onedarker/init.lua b/lua/onedarker/init.lua
new file mode 100644
index 00000000..73043ac3
--- /dev/null
+++ b/lua/onedarker/init.lua
@@ -0,0 +1,32 @@
+vim.api.nvim_command "hi clear"
+if vim.fn.exists "syntax_on" then
+ vim.api.nvim_command "syntax reset"
+end
+vim.o.background = "dark"
+vim.o.termguicolors = true
+vim.g.colors_name = "onedarker"
+
+local util = require "onedarker.util"
+Config = require "onedarker.config"
+C = require "onedarker.palette"
+local highlights = require "onedarker.highlights"
+local Treesitter = require "onedarker.Treesitter"
+local markdown = require "onedarker.markdown"
+local Whichkey = require "onedarker.Whichkey"
+local Git = require "onedarker.Git"
+local LSP = require "onedarker.LSP"
+local diff = require "onedarker.diff"
+
+local skeletons = {
+ highlights,
+ Treesitter,
+ markdown,
+ Whichkey,
+ Git,
+ LSP,
+ diff,
+}
+
+for _, skeleton in ipairs(skeletons) do
+ util.initialise(skeleton)
+end
diff --git a/lua/spacegray/markdown.lua b/lua/onedarker/markdown.lua
index 2b83e056..d3a5d485 100644
--- a/lua/spacegray/markdown.lua
+++ b/lua/onedarker/markdown.lua
@@ -10,7 +10,7 @@ local markdown = {
markdownH4 = { fg = C.blue },
markdownH5 = { fg = C.blue },
markdownH6 = { fg = C.blue },
- markdownHeadingDelimiter = { fg = C.red },
+ markdownHeadingDelimiter = { fg = C.blue },
markdownHeadingRule = { fg = C.accent },
markdownId = { fg = C.purple },
markdownIdDeclaration = { fg = C.blue },
diff --git a/lua/onedarker/palette.lua b/lua/onedarker/palette.lua
new file mode 100644
index 00000000..81ea3af3
--- /dev/null
+++ b/lua/onedarker/palette.lua
@@ -0,0 +1,45 @@
+local colors = {
+ none = "NONE",
+ fg = "#abb2bf",
+ bg = "#1f2227",
+ alt_bg = "#282c34",
+ dark = "#282c34",
+ accent = "#BBBBBB",
+ dark_gray = "#2a2f3e",
+ fg_gutter = "#353d46",
+ context = "#4b5263",
+ popup_back = "#282c34",
+ search_orange = "#613214",
+ search_blue = "#5e81ac",
+ gray = "#5c6370",
+ light_gray = "#abb2bf",
+ blue = "#61AFEF",
+ dark_blue = "#223E55",
+ green = "#98C379",
+ cyan = "#56B6C2",
+ red = "#e06c75",
+ orange = "#D19A66",
+ light_red = "#be5046",
+ yellow = "#E5C07B",
+ yellow_orange = "#D7BA7D",
+ purple = "#C678DD",
+ magenta = "#D16D9E",
+ cursor_fg = "#515052",
+ cursor_bg = "#AEAFAD",
+ sign_add = "#587c0c",
+ sign_change = "#0c7d9d",
+ sign_delete = "#94151b",
+ error_red = "#F44747",
+ warning_orange = "#ff8800",
+ info_yellow = "#FFCC66",
+ hint_blue = "#4FC1FF",
+ purple_test = "#ff007c",
+ cyan_test = "#00dfff",
+ ui_blue = "#264F78",
+ diff_add = "#303d27",
+ diff_delete = "#6e3b40",
+ diff_change = "#18344c",
+ diff_text = "#265478",
+}
+
+return colors
diff --git a/lua/spacegray/util.lua b/lua/onedarker/util.lua
index dbac18a2..dbac18a2 100644
--- a/lua/spacegray/util.lua
+++ b/lua/onedarker/util.lua
diff --git a/lua/plugin-loader.lua b/lua/plugin-loader.lua
index aa1e888d..c20dd21a 100644
--- a/lua/plugin-loader.lua
+++ b/lua/plugin-loader.lua
@@ -1,9 +1,18 @@
local plugin_loader = {}
-function plugin_loader:init()
- local install_path = "~/.local/share/lunarvim/site/pack/packer/start/packer.nvim"
+local utils = require "utils"
+local Log = require "core.log"
+-- we need to reuse this outside of init()
+local compile_path = get_config_dir() .. "/plugin/packer_compiled.lua"
+
+function plugin_loader:init(opts)
+ opts = opts or {}
+
+ local install_path = opts.install_path or vim.fn.stdpath "data" .. "/site/pack/packer/start/packer.nvim"
+ local package_root = opts.package_root or vim.fn.stdpath "data" .. "/site/pack"
+
if vim.fn.empty(vim.fn.glob(install_path)) > 0 then
- vim.fn.system { "git", "clone", "https://github.com/wbthomason/packer.nvim", install_path }
+ vim.fn.system { "git", "clone", "--depth", "1", "https://github.com/wbthomason/packer.nvim", install_path }
vim.cmd "packadd packer.nvim"
end
@@ -12,15 +21,13 @@ function plugin_loader:init()
return
end
- local util = require "packer.util"
-
packer.init {
- package_root = util.join_paths "~/.local/share/lunarvim/site/pack/",
- compile_path = util.join_paths("~/.config/lvim", "plugin", "packer_compiled.lua"),
+ package_root = package_root,
+ compile_path = compile_path,
git = { clone_timeout = 300 },
display = {
open_fn = function()
- return util.float { border = "rounded" }
+ return require("packer.util").float { border = "rounded" }
end,
},
}
@@ -29,6 +36,20 @@ function plugin_loader:init()
return self
end
+function plugin_loader:cache_clear()
+ if vim.fn.delete(compile_path) == 0 then
+ Log:debug "deleted packer_compiled.lua"
+ end
+end
+
+function plugin_loader:cache_reset()
+ self.cache_clear()
+ require("packer").compile()
+ if utils.is_file(compile_path) then
+ Log:debug "generated packer_compiled.lua"
+ end
+end
+
function plugin_loader:load(configurations)
return self.packer.startup(function(use)
for _, plugins in ipairs(configurations) do
@@ -39,8 +60,4 @@ function plugin_loader:load(configurations)
end)
end
-return {
- init = function()
- return plugin_loader:init()
- end,
-}
+return plugin_loader
diff --git a/lua/plugins.lua b/lua/plugins.lua
index 0b71d48a..65eb16a8 100644
--- a/lua/plugins.lua
+++ b/lua/plugins.lua
@@ -6,12 +6,7 @@ return {
{ "jose-elias-alvarez/null-ls.nvim" },
{ "antoinemadec/FixCursorHold.nvim" }, -- Needed while issue https://github.com/neovim/neovim/issues/12587 is still open
{
- "kabouzeid/nvim-lspinstall",
- event = "VimEnter",
- config = function()
- local lspinstall = require "core.lspinstall"
- lspinstall.setup()
- end,
+ "williamboman/nvim-lsp-installer",
},
{ "nvim-lua/popup.nvim" },
@@ -24,49 +19,42 @@ return {
end,
disable = not lvim.builtin.telescope.active,
},
-
- -- Completion & Snippets
+ -- Install nvim-cmp, and buffer source as a dependency
{
- "hrsh7th/nvim-compe",
- event = "InsertEnter",
+ "hrsh7th/nvim-cmp",
config = function()
- require("core.compe").setup()
+ require("core.cmp").setup()
+ end,
+ requires = {
+ "L3MON4D3/LuaSnip",
+ "saadparwaiz1/cmp_luasnip",
+ "hrsh7th/cmp-buffer",
+ "hrsh7th/cmp-nvim-lsp",
+ "hrsh7th/cmp-path",
+ "hrsh7th/cmp-nvim-lua",
+ },
+ run = function()
+ -- cmp's config requires cmp to be installed to run the first time
+ if not lvim.builtin.cmp then
+ require("core.cmp").config()
+ end
end,
- disable = not lvim.builtin.compe.active,
- -- wants = "vim-vsnip",
- -- requires = {
- -- {
- -- "hrsh7th/vim-vsnip",
- -- wants = "friendly-snippets",
- -- event = "InsertCharPre",
- -- },
- -- {
- -- "rafamadriz/friendly-snippets",
- -- event = "InsertCharPre",
- -- },
- -- },
- },
- {
- "hrsh7th/vim-vsnip",
- -- wants = "friendly-snippets",
- event = "InsertEnter",
- disable = not lvim.builtin.compe.active,
},
{
"rafamadriz/friendly-snippets",
- event = "InsertCharPre",
- disable = not lvim.builtin.compe.active,
+ -- event = "InsertCharPre",
+ -- disable = not lvim.builtin.compe.active,
},
-- Autopairs
{
"windwp/nvim-autopairs",
-- event = "InsertEnter",
- after = "nvim-compe",
+ after = "nvim-cmp",
config = function()
require("core.autopairs").setup()
end,
- disable = not lvim.builtin.autopairs.active or not lvim.builtin.compe.active,
+ disable = not lvim.builtin.autopairs.active,
},
-- Treesitter
@@ -116,7 +104,7 @@ return {
"terrortylor/nvim-comment",
event = "BufRead",
config = function()
- require("nvim_comment").setup()
+ require("core.comment").setup()
end,
disable = not lvim.builtin.comment.active,
},
@@ -183,7 +171,7 @@ return {
-- Terminal
{
- "akinsho/nvim-toggleterm.lua",
+ "akinsho/toggleterm.nvim",
event = "BufWinEnter",
config = function()
require("core.terminal").setup()
diff --git a/lua/spacegray/Treesitter.lua b/lua/spacegray/Treesitter.lua
deleted file mode 100644
index 4e5ce16e..00000000
--- a/lua/spacegray/Treesitter.lua
+++ /dev/null
@@ -1,56 +0,0 @@
-local Treesitter = {
- TSComment = { fg = C.gray },
- TSAnnotation = { fg = C.purple },
- TSAttribute = { fg = C.cyan },
- TSConstructor = { fg = C.purple },
- TSType = { fg = C.purple },
- TSTypeBuiltin = { fg = C.purple },
- TSConditional = { fg = C.blue },
- TSException = { fg = C.blue },
- TSInclude = { fg = C.blue },
- TSKeyword = { fg = C.blue },
- TSKeywordFunction = { fg = C.blue },
- TSLabel = { fg = C.blue },
- TSNamespace = { fg = C.blue },
- TSRepeat = { fg = C.blue },
- TSConstant = { fg = C.orange },
- TSConstBuiltin = { fg = C.red },
- TSFloat = { fg = C.red },
- TSNumber = { fg = C.red },
- TSBoolean = { fg = C.red },
- TSCharacter = { fg = C.light_green },
- TSError = { fg = C.error_red },
- TSFunction = { fg = C.yellow },
- TSFuncBuiltin = { fg = C.yellow },
- TSMethod = { fg = C.yellow },
- TSConstMacro = { fg = C.cyan },
- 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.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.yellow_orange },
- TSURI = { fg = C.yellow_orange, style = "underline" },
- TSKeywordOperator = { fg = C.blue },
- TSStructure = { fg = C.light_blue },
- TSStrong = { fg = C.yellow_orange },
- TSQueryLinterError = { fg = C.warning_orange },
-}
-
-return Treesitter
diff --git a/lua/spacegray/init.lua b/lua/spacegray/init.lua
deleted file mode 100644
index 9ae24dbb..00000000
--- a/lua/spacegray/init.lua
+++ /dev/null
@@ -1,43 +0,0 @@
-vim.api.nvim_command "hi clear"
-if vim.fn.exists "syntax_on" then
- vim.api.nvim_command "syntax reset"
-end
-vim.o.background = "dark"
-vim.o.termguicolors = true
-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"
-local Whichkey = require "spacegray.Whichkey"
-local Git = require "spacegray.Git"
-local LSP = require "spacegray.LSP"
-
-local skeletons = {
- highlights,
- Treesitter,
- markdown,
- Whichkey,
- Git,
- LSP,
-}
-
-for _, skeleton in ipairs(skeletons) do
- util.initialise(skeleton)
-end
-
-async:send()
diff --git a/lua/spacegray/palette.lua b/lua/spacegray/palette.lua
deleted file mode 100644
index 924482fd..00000000
--- a/lua/spacegray/palette.lua
+++ /dev/null
@@ -1,40 +0,0 @@
-local colors = {
- 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 = "#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",
- sign_add = "#587c0c",
- sign_change = "#0c7d9d",
- sign_delete = "#94151b",
- error_red = "#F44747",
- warning_orange = "#ff8800",
- info_yellow = "#FFCC66",
- hint_blue = "#4FC1FF",
- purple_test = "#ff007c",
- cyan_test = "#00dfff",
- ui_blue = "#264F78",
-}
-
-return colors
diff --git a/lua/utils/hooks.lua b/lua/utils/hooks.lua
new file mode 100644
index 00000000..fa667cfd
--- /dev/null
+++ b/lua/utils/hooks.lua
@@ -0,0 +1,33 @@
+local M = {}
+
+local Log = require "core.log"
+local in_headless = #vim.api.nvim_list_uis() == 0
+
+function M.run_pre_update()
+ Log:debug "Starting pre-update hook"
+end
+
+---Reset any startup cache files used by Packer and Impatient
+---Tip: Useful for clearing any outdated settings
+function M.reset_cache()
+ _G.__luacache.clear_cache()
+ require("plugin-loader"):cache_reset()
+end
+
+function M.run_post_update()
+ M.reset_cache()
+ Log:debug "Starting post-update hook"
+ package.loaded["lsp.templates"] = nil
+ require("lsp.templates").generate_templates()
+
+ if not in_headless then
+ vim.schedule(function()
+ require("packer").install()
+ -- TODO: add a changelog
+ vim.notify("Update complete", vim.log.levels.INFO)
+ vim.cmd "LspStart"
+ end)
+ end
+end
+
+return M
diff --git a/lua/utils/init.lua b/lua/utils/init.lua
index 8ea842ca..eaac54f4 100644
--- a/lua/utils/init.lua
+++ b/lua/utils/init.lua
@@ -90,16 +90,16 @@ function utils.reload_lv_config()
config:load()
require("keymappings").setup() -- this should be done before loading the plugins
- vim.cmd "source ~/.local/share/lunarvim/lvim/lua/plugins.lua"
+ vim.cmd("source " .. utils.join_paths(get_runtime_dir(), "lvim", "lua", "plugins.lua"))
local plugins = require "plugins"
- local plugin_loader = require("plugin-loader").init()
utils.toggle_autoformat()
+ local plugin_loader = require "plugin-loader"
+ plugin_loader:cache_reset()
plugin_loader:load { plugins, lvim.plugins }
- vim.cmd ":PackerCompile"
vim.cmd ":PackerInstall"
+ vim.cmd ":PackerCompile"
-- vim.cmd ":PackerClean"
- local null_ls = require "lsp.null-ls"
- null_ls.setup(vim.bo.filetype, { force_reload = true })
+ require("lsp").setup()
Log:info "Reloaded configuration"
end
@@ -119,14 +119,119 @@ function utils.gsub_args(args)
return args
end
+--- Returns a table with the default values that are missing.
+--- either paramter can be empty.
+--@param config (table) table containing entries that take priority over defaults
+--@param default_config (table) table contatining default values if found
+function utils.apply_defaults(config, default_config)
+ config = config or {}
+ default_config = default_config or {}
+ local new_config = vim.tbl_deep_extend("keep", vim.empty_dict(), config)
+ new_config = vim.tbl_deep_extend("keep", new_config, default_config)
+ return new_config
+end
+
--- Checks whether a given path exists and is a file.
---@param filename (string) path to check
+--@param path (string) path to check
--@returns (bool)
-function utils.is_file(filename)
- local stat = uv.fs_stat(filename)
+function utils.is_file(path)
+ local stat = uv.fs_stat(path)
return stat and stat.type == "file" or false
end
+--- Checks whether a given path exists and is a directory
+--@param path (string) path to check
+--@returns (bool)
+function utils.is_directory(path)
+ local stat = uv.fs_stat(path)
+ return stat and stat.type == "directory" or false
+end
+
+function utils.write_file(path, txt, flag)
+ uv.fs_open(path, flag, 438, function(open_err, fd)
+ assert(not open_err, open_err)
+ uv.fs_write(fd, txt, -1, function(write_err)
+ assert(not write_err, write_err)
+ uv.fs_close(fd, function(close_err)
+ assert(not close_err, close_err)
+ end)
+ end)
+ end)
+end
+
+utils.join_paths = _G.join_paths
+
+function utils.write_file(path, txt, flag)
+ uv.fs_open(path, flag, 438, function(open_err, fd)
+ assert(not open_err, open_err)
+ uv.fs_write(fd, txt, -1, function(write_err)
+ assert(not write_err, write_err)
+ uv.fs_close(fd, function(close_err)
+ assert(not close_err, close_err)
+ end)
+ end)
+ end)
+end
+
+function utils.debounce(ms, fn)
+ local timer = vim.loop.new_timer()
+ return function(...)
+ local argv = { ... }
+ timer:start(ms, 0, function()
+ timer:stop()
+ vim.schedule_wrap(fn)(unpack(argv))
+ end)
+ end
+end
+
+function utils.search_file(file, args)
+ local Job = require "plenary.job"
+ local stderr = {}
+ local stdout, ret = Job
+ :new({
+ command = "grep",
+ args = { args, file },
+ cwd = get_cache_dir(),
+ on_stderr = function(_, data)
+ table.insert(stderr, data)
+ end,
+ })
+ :sync()
+ return stdout, ret, stderr
+end
+
+function utils.file_contains(file, query)
+ local stdout, ret, stderr = utils.search_file(file, query)
+ if ret == 0 then
+ return true
+ end
+ if not vim.tbl_isempty(stderr) then
+ error(vim.inspect(stderr))
+ end
+ if not vim.tbl_isempty(stdout) then
+ error(vim.inspect(stdout))
+ end
+ return false
+end
+
+function utils.log_contains(query)
+ local logfile = require("core.log"):get_path()
+ local stdout, ret, stderr = utils.search_file(logfile, query)
+ if ret == 0 then
+ return true
+ end
+ if not vim.tbl_isempty(stderr) then
+ error(vim.inspect(stderr))
+ end
+ if not vim.tbl_isempty(stdout) then
+ error(vim.inspect(stdout))
+ end
+ if not vim.tbl_isempty(stderr) then
+ error(vim.inspect(stderr))
+ end
+ return false
+end
+
return utils
-- TODO: find a new home for these autocommands
diff --git a/lua/utils/table.lua b/lua/utils/table.lua
new file mode 100644
index 00000000..1ac5949e
--- /dev/null
+++ b/lua/utils/table.lua
@@ -0,0 +1,24 @@
+local Table = {}
+
+--- Find the first entry for which the predicate returns true.
+-- @param t The table
+-- @param predicate The function called for each entry of t
+-- @return The entry for which the predicate returned True or nil
+function Table.find_first(t, predicate)
+ for _, entry in pairs(t) do
+ if predicate(entry) then
+ return entry
+ end
+ end
+ return nil
+end
+
+--- Check if the predicate returns True for at least one entry of the table.
+-- @param t The table
+-- @param predicate The function called for each entry of t
+-- @return True if predicate returned True at least once, false otherwise
+function Table.contains(t, predicate)
+ return Table.find_first(t, predicate) ~= nil
+end
+
+return Table