diff options
42 files changed, 900 insertions, 858 deletions
diff --git a/.config/nvim/.gitignore b/.config/nvim/.gitignore index 009ad45..36647be 100644 --- a/.config/nvim/.gitignore +++ b/.config/nvim/.gitignore @@ -12,3 +12,4 @@ lua-language-server/ site/ package.json package-lock.json +node_modules/ diff --git a/.config/nvim/config.lua b/.config/nvim/config.lua index 6ff78f0..ca28fa4 100644 --- a/.config/nvim/config.lua +++ b/.config/nvim/config.lua @@ -20,7 +20,6 @@ options.builtin.telescope.active = true options.builtin.bufferline.active = true options.builtin.lualine.active = true options.builtin.lualine.style = "dark" -options.builtin.dap.active = false -- Whichkey options.builtin.which_key.mappings.l.d = { "<cmd>TroubleToggle<cr>", "Diagnostics" } @@ -59,33 +58,6 @@ options.builtin.treesitter.autotag.enable = false options.builtin.treesitter.playground.enable = false options.builtin.treesitter.indent.disable = { "python" } --- LSP Linters and formatters -options.lang.json.formatters = { - { - exe = "prettier", - }, -} - -options.lang.lua.formatters = { - { - exe = "stylua", - }, -} - -options.lang.python.formatters = { - { - exe = "black", - }, -} - -options.lang.python.linters = { - { - exe = "flake8", - }, -} - -options.lang.sh.linters = { { exe = "shellcheck", args = { "--sverity", "error" } } } - -- Extra plugings options.plugins = { diff --git a/.config/nvim/ftplugin/json.lua b/.config/nvim/ftplugin/json.lua index 53a6790..a2047cd 100644 --- a/.config/nvim/ftplugin/json.lua +++ b/.config/nvim/ftplugin/json.lua @@ -1,5 +1,2 @@ -options.lang.json.formatters = { - { - exe = "prettier", - }, -} +local formatters = require "lsp.null-ls.formatters" +formatters.setup { { exe = "prettier", filetypes = { "json" } } } diff --git a/.config/nvim/ftplugin/lua.lua b/.config/nvim/ftplugin/lua.lua index d0408a1..6e10a53 100644 --- a/.config/nvim/ftplugin/lua.lua +++ b/.config/nvim/ftplugin/lua.lua @@ -1,5 +1,2 @@ -options.lang.lua.formatters = { - { - exe = "stylua", - }, -} +local formatters = require "lsp.null-ls.formatters" +formatters.setup { { exe = "stylua", filetypes = { "lua" } } } diff --git a/.config/nvim/ftplugin/python.lua b/.config/nvim/ftplugin/python.lua index 2ec643d..f1e9a50 100644 --- a/.config/nvim/ftplugin/python.lua +++ b/.config/nvim/ftplugin/python.lua @@ -1,11 +1,4 @@ -options.lang.python.formatters = { - { - exe = "black", - }, -} - -options.lang.python.linters = { - { - exe = "flake8", - }, -} +local formatters = require "lsp.null-ls.formatters" +local linters = require "lsp.null-ls.linters" +formatters.setup { { exe = "black", filetypes = { "python" } } } +formatters.setup { { exe = "flake8", filetypes = { "python" } } } diff --git a/.config/nvim/ftplugin/sh.lua b/.config/nvim/ftplugin/sh.lua index 442273a..6fcc649 100644 --- a/.config/nvim/ftplugin/sh.lua +++ b/.config/nvim/ftplugin/sh.lua @@ -1 +1,4 @@ -options.lang.sh.linters = { { exe = "shellcheck", args = { "--sverity", "error" } } } +local formatters = require "lsp.null-ls.formatters" +formatters.setup { + { exe = "shellcheck", args = { "--sverity", "error" }, filetypes = { "sh" } }, +} diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua index 42af218..1810297 100644 --- a/.config/nvim/init.lua +++ b/.config/nvim/init.lua @@ -1,11 +1,12 @@ require("bootstrap"):init() + require("config"):load() local plugins = require "plugins" -require("plugin-loader"):load { plugins, options.plugins } +require("plugin-loader").load { plugins, options.plugins } local Log = require "core.log" -Log:debug "Starting nvim" +Log:debug "Starting NeoVim" vim.g.colors_name = options.colorscheme -- Colorscheme must get called after plugins are loaded or it will break new installs. vim.cmd("colorscheme " .. options.colorscheme) @@ -13,6 +14,4 @@ vim.cmd("colorscheme " .. options.colorscheme) local commands = require "core.commands" commands.load(commands.defaults) -require("keymappings").setup() - require("lsp").setup() diff --git a/.config/nvim/lsp-settings/jsonls.json b/.config/nvim/lsp-settings/jsonls.json new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/.config/nvim/lsp-settings/jsonls.json diff --git a/.config/nvim/lsp-settings/rust_analyzer.json b/.config/nvim/lsp-settings/rust_analyzer.json new file mode 100644 index 0000000..8130c24 --- /dev/null +++ b/.config/nvim/lsp-settings/rust_analyzer.json @@ -0,0 +1,4 @@ +{ + "rust-analyzer.lens.enable": true, + "rust-analyzer.lens.references": true +} diff --git a/.config/nvim/lsp-settings/terraformls.json b/.config/nvim/lsp-settings/terraformls.json new file mode 100644 index 0000000..050973c --- /dev/null +++ b/.config/nvim/lsp-settings/terraformls.json @@ -0,0 +1,5 @@ +{ + "terraform-ls.experimentalFeatures": { + "validateOnSave": true + } +} diff --git a/.config/nvim/lua/bootstrap.lua b/.config/nvim/lua/bootstrap.lua index 03256d7..a461964 100644 --- a/.config/nvim/lua/bootstrap.lua +++ b/.config/nvim/lua/bootstrap.lua @@ -1,7 +1,6 @@ local M = {} -package.loaded["utils.hooks"] = nil -local _, hooks = pcall(require, "utils.hooks") +local uv = vim.loop ---Join path segments that were passed as input ---@return string @@ -71,70 +70,11 @@ end ---Update LunarVim ---pulls the latest changes from github and, resets the startup cache function M:update() + package.loaded["utils.hooks"] = nil + local _, hooks = pcall(require, "utils.hooks") 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 repo_dir = join_paths(get_runtime_dir(), "nvim") - local args = { "-C", repo_dir } - vim.list_extend(args, subcmd) - - local stderr = {} - local stdout, ret = Job - :new({ - command = "git", - args = args, - cwd = repo_dir, - 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 "nvim 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/.config/nvim/lua/config/defaults.lua b/.config/nvim/lua/config/defaults.lua index bb2bcc6..a4b1140 100644 --- a/.config/nvim/lua/config/defaults.lua +++ b/.config/nvim/lua/config/defaults.lua @@ -1,21 +1,19 @@ -local home_dir = vim.loop.os_homedir() -local utils = require "utils" - -options = { +return { leader = "space", colorscheme = "dark", line_wrap_cursor_movement = true, transparent_window = false, format_on_save = true, - vsnip_dir = utils.join_paths(home_dir, ".config", "snippets"), - database = { - save_location = utils.join_paths(home_dir, ".config", "nvim_db"), - auto_execute = 1, - }, keys = {}, builtin = {}, + plugins = { + -- use config.lua for this not put here + }, + + autocommands = {}, + lang = {}, log = { ---@usage can be { "trace", "debug", "info", "warn", "error", "fatal" }, level = "warn", @@ -30,11 +28,7 @@ options = { float_opts = {}, }, }, + -- currently disabled due to instabilities + override_notify = false, }, - plugins = { - -- use config.lua for this not put here - }, - - autocommands = {}, - lang = {}, } diff --git a/.config/nvim/lua/config/init.lua b/.config/nvim/lua/config/init.lua index f4179ee..f40e30e 100644 --- a/.config/nvim/lua/config/init.lua +++ b/.config/nvim/lua/config/init.lua @@ -1,148 +1,126 @@ -local M = {} +local utils = require "utils" +local Log = require "core.log" ---- Initialize nvim default configuration --- Define nvim global variable -function M:init(opts) - opts = opts or {} - self.path = opts.path - local utils = require "utils" +local M = {} +local user_config_dir = get_config_dir() +local user_config_file = utils.join_paths(user_config_dir, "config.lua") - require "config.defaults" +local function apply_defaults(configs, defaults) + configs = configs or {} + return vim.tbl_deep_extend("keep", configs, defaults) +end - -- Fallback config.lua to config.lua - if not utils.is_file(self.path) then - local config = self.path:gsub("config.lua$", "config.lua") - print(self.path, "not found, falling back to", config) +---Get the full path to the user configuration file +---@return string +function M:get_user_config_path() + return user_config_file +end - self.path = config +--- Initialize nvim default configuration +-- Define options global variable +function M:init() + if vim.tbl_isempty(nvim or {}) then + options = require "config.defaults" + local home_dir = vim.loop.os_homedir() + options.vsnip_dir = utils.join_paths(home_dir, ".config", "snippets") + options.database = { + save_location = utils.join_paths(home_dir, ".config", "lunarvim_db"), + auto_execute = 1, + } end local builtins = require "core.builtins" - builtins.config(self) + builtins.config { user_config_file = user_config_file } local settings = require "config.settings" settings.load_options() + local default_keymaps = require("keymappings").get_defaults() + options.keys = apply_defaults(options.keys, default_keymaps) + + local autocmds = require "core.autocmds" + options.autocommands = apply_defaults(options.autocommands, autocmds.load_augroups()) + local lsp_config = require "lsp.config" - options.lsp = vim.deepcopy(lsp_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", - } + options.lsp = apply_defaults(options.lsp, vim.deepcopy(lsp_config)) + local supported_languages = require "config.supported_languages" require("lsp.manager").init_defaults(supported_languages) end +local function handle_deprecated_settings() + local function deprecation_notice(setting) + local in_headless = #vim.api.nvim_list_uis() == 0 + if in_headless then + return + end + + local msg = string.format( + "Deprecation notice: [%s] setting is no longer supported. See https://github.com/LunarVim/LunarVim#breaking-changes", + setting + ) + vim.schedule(function() + Log:warn(msg) + end) + end + + for lang, entry in pairs(options.lang) do + local deprecated_config = entry.formatters or entry.linters or {} + if not vim.tbl_isempty(deprecated_config) then + deprecation_notice(string.format("lang.%s", lang)) + end + end +end + --- Override the configuration with a user provided one -- @param config_path The path to the configuration overrides function M:load(config_path) local autocmds = require "core.autocmds" - - config_path = config_path or self.path - local ok, err = pcall(vim.cmd, "luafile " .. config_path) + config_path = config_path or self.get_user_config_path() + local ok, err = pcall(dofile, config_path) if not ok then - print("Invalid configuration", config_path) - print(err) - return + if utils.is_file(user_config_file) then + Log:warn("Invalid configuration: " .. err) + else + Log:warn(string.format("Unable to find configuration file [%s]", config_path)) + end end - self.path = config_path + handle_deprecated_settings() autocmds.define_augroups(options.autocommands) + vim.g.mapleader = (options.leader == "space" and " ") or options.leader + require("keymappings").load(options.keys) + local settings = require "config.settings" settings.load_commands() end +--- Override the configuration with a user provided one +-- @param config_path The path to the configuration overrides +function M:reload() + local core_modules = {} + for module, _ in pairs(package.loaded) do + if module:match "core" then + package.loaded[module] = nil + table.insert(core_modules, module) + end + end + + M:init() + M:load() + + local plugins = require "plugins" + utils.toggle_autoformat() + local plugin_loader = require "plugin-loader" + plugin_loader.cache_clear() + plugin_loader.load { plugins, options.plugins } + vim.cmd ":PackerInstall" + vim.cmd ":PackerCompile" + -- vim.cmd ":PackerClean" + require("lsp").setup() + Log:info "Reloaded configuration" +end + return M diff --git a/.config/nvim/lua/config/settings.lua b/.config/nvim/lua/config/settings.lua index 09f4a8b..4b5c340 100644 --- a/.config/nvim/lua/config/settings.lua +++ b/.config/nvim/lua/config/settings.lua @@ -70,6 +70,7 @@ M.load_commands = function() cmd "au ColorScheme * hi MsgArea ctermbg=none guibg=none" cmd "au ColorScheme * hi TelescopeBorder ctermbg=none guibg=none" cmd "au ColorScheme * hi NvimTreeNormal ctermbg=none guibg=none" + cmd "au ColorScheme * hi EndOfBuffer ctermbg=none guibg=none" cmd "let &fcs='eob: '" end end diff --git a/.config/nvim/lua/config/supported_languages.lua b/.config/nvim/lua/config/supported_languages.lua new file mode 100644 index 0000000..db28df1 --- /dev/null +++ b/.config/nvim/lua/config/supported_languages.lua @@ -0,0 +1,94 @@ +return { + "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", +} diff --git a/.config/nvim/lua/core/autocmds.lua b/.config/nvim/lua/core/autocmds.lua index 9ee9e90..1f50308 100644 --- a/.config/nvim/lua/core/autocmds.lua +++ b/.config/nvim/lua/core/autocmds.lua @@ -1,110 +1,68 @@ -local autocommands = {} -local config = require "config" +local M = {} -options.autocommands = { - _general_settings = { - { - "Filetype", - "*", - "lua require('utils.ft').do_filetype(vim.fn.expand(\"<amatch>\"))", - }, - { - "FileType", - "qf", - "nnoremap <silent> <buffer> q :q<CR>", +--- Load the default set of autogroups and autocommands. +function M.load_augroups() + local user_config_file = vim.fn.resolve(require("config"):get_user_config_path()) + + return { + _general_settings = { + { "FileType", "qf,help,man", "nnoremap <silent> <buffer> q :close<CR>" }, + { + "TextYankPost", + "*", + "lua require('vim.highlight').on_yank({higroup = 'Search', timeout = 200})", + }, + { + "BufWinEnter", + "dashboard", + "setlocal cursorline signcolumn=yes cursorcolumn number", + }, + { "BufWritePost", user_config_file, "lua require('config'):reload()" }, + { "FileType", "qf", "set nobuflisted" }, + -- { "VimLeavePre", "*", "set title set titleold=" }, }, - { - "FileType", - "lsp-installer", - "nnoremap <silent> <buffer> q :q<CR>", + _formatoptions = { + { + "BufWinEnter,BufRead,BufNewFile", + "*", + "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", + }, }, - { - "TextYankPost", - "*", - "lua require('vim.highlight').on_yank({higroup = 'Search', timeout = 200})", + _filetypechanges = { + { "BufWinEnter", ".tf", "setlocal filetype=terraform" }, + { "BufRead", "*.tf", "setlocal filetype=terraform" }, + { "BufNewFile", "*.tf", "setlocal filetype=terraform" }, + { "BufWinEnter", ".zsh", "setlocal filetype=sh" }, + { "BufRead", "*.zsh", "setlocal filetype=sh" }, + { "BufNewFile", "*.zsh", "setlocal filetype=sh" }, }, - { - "BufWinEnter", - "*", - "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", + _git = { + { "FileType", "gitcommit", "setlocal wrap" }, + { "FileType", "gitcommit", "setlocal spell" }, }, - { - "BufWinEnter", - "dashboard", - "setlocal cursorline signcolumn=yes cursorcolumn number", + _markdown = { + { "FileType", "markdown", "setlocal wrap" }, + { "FileType", "markdown", "setlocal spell" }, }, - { - "BufRead", - "*", - "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", + _buffer_bindings = { + { "FileType", "floaterm", "nnoremap <silent> <buffer> q :q<CR>" }, }, - { - "BufNewFile", - "*", - "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", + _auto_resize = { + -- will cause split windows to be resized evenly if main window is resized + { "VimResized", "*", "tabdo wincmd =" }, }, - { "BufWritePost", config.path, "lua require('utils').reload_config()" }, - { - "FileType", - "qf", - "set nobuflisted", + _general_lsp = { + { + "FileType", + "lspinfo,lsp-installer,null-ls-info", + "nnoremap <silent> <buffer> q :close<CR>", + }, }, - -- { "VimLeavePre", "*", "set title set titleold=" }, - }, - _filetypechanges = { - { "BufWinEnter", ".tf", "setlocal filetype=terraform" }, - { "BufRead", "*.tf", "setlocal filetype=terraform" }, - { "BufNewFile", "*.tf", "setlocal filetype=terraform" }, - { "BufWinEnter", ".zsh", "setlocal filetype=sh" }, - { "BufRead", "*.zsh", "setlocal filetype=sh" }, - { "BufNewFile", "*.zsh", "setlocal filetype=sh" }, - }, - -- _solidity = { - -- {'BufWinEnter', '.sol', 'setlocal filetype=solidity'}, {'BufRead', '*.sol', 'setlocal filetype=solidity'}, - -- {'BufNewFile', '*.sol', 'setlocal filetype=solidity'} - -- }, - -- _gemini = { - -- {'BufWinEnter', '.gmi', 'setlocal filetype=markdown'}, {'BufRead', '*.gmi', 'setlocal filetype=markdown'}, - -- {'BufNewFile', '*.gmi', 'setlocal filetype=markdown'} - -- }, - _git = { - { "FileType", "gitcommit", "setlocal wrap" }, - { "FileType", "gitcommit", "setlocal spell" }, - }, - _markdown = { - { "FileType", "markdown", "setlocal wrap" }, - { "FileType", "markdown", "setlocal spell" }, - }, - _buffer_bindings = { - { "FileType", "floaterm", "nnoremap <silent> <buffer> q :q<CR>" }, - }, - _auto_resize = { - -- will cause split windows to be resized evenly if main window is resized - { "VimResized", "*", "wincmd =" }, - }, - _packer_compile = { - -- will run PackerCompile after writing plugins.lua - { "BufWritePost", "plugins.lua", "PackerCompile" }, - }, - _general_lsp = { - { "FileType", "lspinfo", "nnoremap <silent> <buffer> q :q<CR>" }, - }, - - -- _fterm_lazygit = { - -- -- will cause esc key to exit lazy git - -- {"TermEnter", "*", "call LazyGitNativation()"} - -- }, - -- _mode_switching = { - -- -- will switch between absolute and relative line numbers depending on mode - -- {'InsertEnter', '*', 'if &relativenumber | let g:ms_relativenumberoff = 1 | setlocal number norelativenumber | endif'}, - -- {'InsertLeave', '*', 'if exists("g:ms_relativenumberoff") | setlocal relativenumber | endif'}, - -- {'InsertEnter', '*', 'if &cursorline | let g:ms_cursorlineoff = 1 | setlocal nocursorline | endif'}, - -- {'InsertLeave', '*', 'if exists("g:ms_cursorlineoff") | setlocal cursorline | endif'}, - -- }, - custom_groups = {}, -} + custom_groups = {}, + } +end -function autocommands.define_augroups(definitions) -- {{{1 +function M.define_augroups(definitions) -- {{{1 -- Create autocommand groups based on the passed definitions -- -- The key will be the name of the group, and each definition @@ -126,4 +84,4 @@ function autocommands.define_augroups(definitions) -- {{{1 end end -return autocommands +return M diff --git a/.config/nvim/lua/core/autopairs.lua b/.config/nvim/lua/core/autopairs.lua index 630f3de..ec7f651 100644 --- a/.config/nvim/lua/core/autopairs.lua +++ b/.config/nvim/lua/core/autopairs.lua @@ -4,8 +4,6 @@ function M.config() options.builtin.autopairs = { active = true, on_config_done = nil, - ---@usage auto insert after select function or method item - map_complete = true, ---@usage -- modifies the function or method delimiter by filetypes map_char = { all = "(", @@ -52,19 +50,12 @@ M.setup = function() end), } - if package.loaded["cmp"] then - require("nvim-autopairs.completion.cmp").setup { - map_cr = false, - map_complete = options.builtin.autopairs.map_complete, - map_char = options.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 } - ) + local cmp_status_ok, cmp = pcall(require, "cmp") + if cmp_status_ok then + -- If you want insert `(` after select function or method item + local cmp_autopairs = require "nvim-autopairs.completion.cmp" + local map_char = options.builtin.autopairs.map_char + cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done { map_char = map_char }) end require("nvim-treesitter.configs").setup { autopairs = { enable = true } } diff --git a/.config/nvim/lua/core/builtins/init.lua b/.config/nvim/lua/core/builtins/init.lua index c3b3618..10ce680 100644 --- a/.config/nvim/lua/core/builtins/init.lua +++ b/.config/nvim/lua/core/builtins/init.lua @@ -1,12 +1,10 @@ local M = {} local builtins = { - "keymappings", "core.which-key", "core.gitsigns", "core.cmp", "core.dashboard", - "core.dap", "core.terminal", "core.telescope", "core.treesitter", diff --git a/.config/nvim/lua/core/cmp.lua b/.config/nvim/lua/core/cmp.lua index fd9e96c..36d85fb 100644 --- a/.config/nvim/lua/core/cmp.lua +++ b/.config/nvim/lua/core/cmp.lua @@ -1,14 +1,29 @@ local M = {} +M.methods = {} +---checks if the character preceding the cursor is a space character +---@return boolean true if it is a space character, false otherwise local check_backspace = function() local col = vim.fn.col "." - 1 return col == 0 or vim.fn.getline("."):sub(col, col):match "%s" end +M.methods.check_backspace = check_backspace local function T(str) return vim.api.nvim_replace_termcodes(str, true, true, true) end +---wraps vim.fn.feedkeys while replacing key codes with escape codes +---Ex: feedkeys("<CR>", "n") becomes feedkeys("^M", "n") +---@param key string +---@param mode string +local function feedkeys(key, mode) + vim.fn.feedkeys(T(key), mode) +end +M.methods.feedkeys = feedkeys + +---checks if emmet_ls is available and active in the buffer +---@return boolean true if available, false otherwise local is_emmet_active = function() local clients = vim.lsp.buf_get_clients() @@ -19,16 +34,17 @@ local is_emmet_active = function() end return false end +M.methods.is_emmet_active = is_emmet_active -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 +---when inside a snippet, seeks to the nearest luasnip field if possible, and checks if it is jumpable +---@param dir number 1 for forward, -1 for backward; defaults to 1 +---@return boolean true if a jumpable luasnip field is found while inside a snippet +local function jumpable(dir) + local luasnip_ok, luasnip = pcall(require, "luasnip") + if not 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 @@ -124,16 +140,39 @@ M.config = function() return false end + if dir == -1 then + return inside_snippet() and luasnip.jumpable(-1) + else + return inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable() + end +end +M.methods.jumpable = jumpable + +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 + options.builtin.cmp = { confirm_opts = { behavior = cmp.ConfirmBehavior.Replace, select = false, }, + completion = { + ---@usage The minimum length of a word to complete on. + keyword_length = 1, + }, experimental = { ghost_text = true, native_menu = false, }, formatting = { + fields = { "kind", "abbr", "menu" }, kind_icons = { Class = " ", Color = " ", @@ -163,7 +202,6 @@ M.config = function() }, source_names = { nvim_lsp = "(LSP)", - emoji = "(Emoji)", path = "(Path)", calc = "(Calc)", cmp_tabnine = "(Tabnine)", @@ -200,33 +238,30 @@ M.config = function() { name = "luasnip" }, { name = "cmp_tabnine" }, { name = "nvim_lua" }, - { name = "buffer" }, + { name = "buffer", keyword_length = 5 }, { name = "calc" }, - { name = "emoji" }, { name = "treesitter" }, { name = "crates" }, }, mapping = { + ["<C-k>"] = cmp.mapping.select_prev_item(), + ["<C-j>"] = cmp.mapping.select_next_item(), ["<C-d>"] = cmp.mapping.scroll_docs(-4), ["<C-f>"] = cmp.mapping.scroll_docs(4), -- TODO: potentially fix emmet nonsense - ["<Tab>"] = cmp.mapping(function() + ["<Tab>"] = cmp.mapping(function(fallback) 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 + elseif jumpable() then luasnip.jump(1) elseif check_backspace() then - vim.fn.feedkeys(T "<Tab>", "n") + fallback() elseif is_emmet_active() then return vim.fn["cmp#complete"]() else - vim.fn.feedkeys(T "<Tab>", "n") + fallback() end end, { "i", @@ -235,7 +270,7 @@ M.config = function() ["<S-Tab>"] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item() - elseif inside_snippet() and luasnip.jumpable(-1) then + elseif jumpable(-1) then luasnip.jump(-1) else fallback() @@ -246,13 +281,13 @@ M.config = function() }), ["<C-Space>"] = cmp.mapping.complete(), - ["<C-e>"] = cmp.mapping.close(), + ["<C-e>"] = cmp.mapping.abort(), ["<CR>"] = cmp.mapping(function(fallback) if cmp.visible() and cmp.confirm(options.builtin.cmp.confirm_opts) then return end - if inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable() then + if jumpable() then if not luasnip.jump(1) then fallback() end @@ -265,7 +300,6 @@ M.config = function() end M.setup = function() - require("luasnip/loaders/from_vscode").lazy_load() require("cmp").setup(options.builtin.cmp) end diff --git a/.config/nvim/lua/core/commands.lua b/.config/nvim/lua/core/commands.lua index 8a56c40..ce635ad 100644 --- a/.config/nvim/lua/core/commands.lua +++ b/.config/nvim/lua/core/commands.lua @@ -10,8 +10,12 @@ M.defaults = { endif endfunction ]], + -- :NvimInfo [[ command! NvimInfo lua require('core.info').toggle_popup(vim.bo.filetype) ]], [[ command! NvimCacheReset lua require('utils.hooks').reset_cache() ]], + [[ command! NvimUpdate lua require('bootstrap').update() ]], + [[ command! NvimSyncCorePlugins lua require('plugin-loader'):sync_core_plugins() ]], + [[ command! NvimReload lua require('config'):reload() ]], } M.load = function(commands) diff --git a/.config/nvim/lua/core/dap.lua b/.config/nvim/lua/core/dap.lua deleted file mode 100644 index fb56f82..0000000 --- a/.config/nvim/lua/core/dap.lua +++ /dev/null @@ -1,75 +0,0 @@ -local M = {} - -M.config = function() - options.builtin.dap = { - active = false, - on_config_done = nil, - breakpoint = { - text = "", - texthl = "LspDiagnosticsSignError", - linehl = "", - numhl = "", - }, - breakpoint_rejected = { - text = "", - texthl = "LspDiagnosticsSignHint", - linehl = "", - numhl = "", - }, - stopped = { - text = "", - texthl = "LspDiagnosticsSignInformation", - linehl = "DiagnosticUnderlineInfo", - numhl = "LspDiagnosticsSignInformation", - }, - } -end - -M.setup = function() - local dap = require "dap" - - vim.fn.sign_define("DapBreakpoint", options.builtin.dap.breakpoint) - vim.fn.sign_define("DapBreakpointRejected", options.builtin.dap.breakpoint_rejected) - vim.fn.sign_define("DapStopped", options.builtin.dap.stopped) - dap.defaults.fallback.terminal_win_cmd = "50vsplit new" - - options.builtin.which_key.mappings["d"] = { - name = "Debug", - t = { "<cmd>lua require'dap'.toggle_breakpoint()<cr>", "Toggle Breakpoint" }, - b = { "<cmd>lua require'dap'.step_back()<cr>", "Step Back" }, - c = { "<cmd>lua require'dap'.continue()<cr>", "Continue" }, - C = { "<cmd>lua require'dap'.run_to_cursor()<cr>", "Run To Cursor" }, - d = { "<cmd>lua require'dap'.disconnect()<cr>", "Disconnect" }, - g = { "<cmd>lua require'dap'.session()<cr>", "Get Session" }, - i = { "<cmd>lua require'dap'.step_into()<cr>", "Step Into" }, - o = { "<cmd>lua require'dap'.step_over()<cr>", "Step Over" }, - u = { "<cmd>lua require'dap'.step_out()<cr>", "Step Out" }, - p = { "<cmd>lua require'dap'.pause.toggle()<cr>", "Pause" }, - r = { "<cmd>lua require'dap'.repl.toggle()<cr>", "Toggle Repl" }, - s = { "<cmd>lua require'dap'.continue()<cr>", "Start" }, - q = { "<cmd>lua require'dap'.close()<cr>", "Quit" }, - } - - if options.builtin.dap.on_config_done then - options.builtin.dap.on_config_done(dap) - end -end - --- TODO put this up there ^^^ call in ftplugin - --- M.dap = function() --- if options.plugin.dap.active then --- local dap_install = require "dap-install" --- dap_install.config("python_dbg", {}) --- end --- end --- --- M.dap = function() --- -- gem install readapt ruby-debug-ide --- if options.plugin.dap.active then --- local dap_install = require "dap-install" --- dap_install.config("ruby_vsc_dbg", {}) --- end --- end - -return M diff --git a/.config/nvim/lua/core/dashboard.lua b/.config/nvim/lua/core/dashboard.lua index 0f27ccf..20edd22 100644 --- a/.config/nvim/lua/core/dashboard.lua +++ b/.config/nvim/lua/core/dashboard.lua @@ -31,24 +31,28 @@ M.config = function(config) custom_section = { a = { - description = { " Find File " }, + description = { " Find File " }, command = "Telescope find_files", }, b = { + description = { " New File " }, + command = ":ene!", + }, + c = { description = { " Recent Projects " }, command = "Telescope projects", }, - c = { + d = { description = { " Recently Used Files" }, command = "Telescope oldfiles", }, - d = { + e = { description = { " Find Word " }, command = "Telescope live_grep", }, - e = { + f = { description = { " Configuration " }, - command = ":e " .. config.path, + command = ":e " .. config.user_config_file, }, }, } diff --git a/.config/nvim/lua/core/info.lua b/.config/nvim/lua/core/info.lua index cf4387e..d448492 100644 --- a/.config/nvim/lua/core/info.lua +++ b/.config/nvim/lua/core/info.lua @@ -17,55 +17,37 @@ local function str_list(list) return fmt("[ %s ]", table.concat(list, ", ")) end -local function get_formatter_suggestion_msg(ft) - local config = require "config" +local function make_formatters_info(ft) local null_formatters = require "lsp.null-ls.formatters" + local registered_formatters = null_formatters.list_registered_providers(ft) local supported_formatters = null_formatters.list_available(ft) local section = { - " HINT ", - "", - fmt("* List of supported formatters: %s", str_list(supported_formatters)), + "Formatters info", + fmt( + "* Active: %s%s", + table.concat(registered_formatters, " , "), + vim.tbl_count(registered_formatters) > 0 and " " or "" + ), + fmt("* Supported: %s", str_list(supported_formatters)), } - if not vim.tbl_isempty(supported_formatters) then - vim.list_extend(section, { - "* Configured formatter needs to be installed and executable.", - fmt("* Enable installed formatter(s) with following config in %s", config.path), - "", - fmt( - " options.lang.%s.formatters = { { exe = '%s' } }", - ft, - table.concat(supported_formatters, "│") - ), - }) - end - return section end -local function get_linter_suggestion_msg(ft) - local config = require "config" +local function make_linters_info(ft) local null_linters = require "lsp.null-ls.linters" local supported_linters = null_linters.list_available(ft) + local registered_linters = null_linters.list_registered_providers(ft) local section = { - " HINT ", - "", - fmt("* List of supported linters: %s", str_list(supported_linters)), + "Linters info", + fmt( + "* Active: %s%s", + table.concat(registered_linters, " , "), + vim.tbl_count(registered_linters) > 0 and " " or "" + ), + fmt("* Supported: %s", str_list(supported_linters)), } - if not vim.tbl_isempty(supported_linters) then - vim.list_extend(section, { - "* Configured linter needs to be installed and executable.", - fmt("* Enable installed linter(s) with following config in %s", config.path), - "", - fmt( - " options.lang.%s.linters = { { exe = '%s' } }", - ft, - table.concat(supported_linters, "│") - ), - }) - end - return section end @@ -79,14 +61,21 @@ 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 filetypes = lsp_utils.get_supported_filetypes(name) local document_formatting = client.resolved_capabilities.document_formatting + local attached_buffers_list = table.concat( + vim.lsp.get_buffers_by_client_id(client.id), + ", " + ) local client_info = { - fmt("* Name: %s", name), - fmt("* Id: %s", tostring(id)), - fmt("* Supports formatting: %s", tostring(document_formatting)), + fmt("* Name: %s", name), + fmt("* Id: [%s]", tostring(id)), + fmt("* filetype(s): [%s]", table.concat(filetypes, ", ")), + fmt("* Attached buffers: [%s]", tostring(attached_buffers_list)), + fmt("* Supports formatting: %s", tostring(document_formatting)), } if not vim.tbl_isempty(client_enabled_caps) then - local caps_text = "* Capabilities list: " + local caps_text = "* Capabilities list: " local caps_text_len = caps_text:len() local enabled_caps = text.format_table(client_enabled_caps, 3, " | ") enabled_caps = text.shift_right(enabled_caps, caps_text_len) @@ -100,18 +89,29 @@ end function M.toggle_popup(ft) local clients = lsp_utils.get_active_clients_by_ft(ft) local client_names = {} - + local bufnr = vim.api.nvim_get_current_buf() + local ts_active_buffers = vim.tbl_keys(vim.treesitter.highlighter.active) + local is_treesitter_active = function() + local status = "inactive" + if vim.tbl_contains(ts_active_buffers, bufnr) then + status = "active" + end + return status + end local header = { - fmt("Detected filetype: %s", ft), - fmt( - "Treesitter active: %s", - tostring(next(vim.treesitter.highlighter.active) ~= nil) - ), + fmt("Detected filetype: %s", ft), + fmt("Current buffer number: [%s]", bufnr), + } + + local ts_info = { + "Treesitter info", + fmt("* current buffer: %s", is_treesitter_active()), + fmt("* list: [%s]", table.concat(ts_active_buffers, ", ")), } local lsp_info = { "Language Server Protocol (LSP) info", - fmt "* Associated server(s):", + fmt "* Active server(s):", } for _, client in pairs(clients) do @@ -119,22 +119,9 @@ function M.toggle_popup(ft) table.insert(client_names, client.name) end - local null_formatters = require "lsp.null-ls.formatters" - local null_linters = require "lsp.null-ls.linters" - local registered_formatters = null_formatters.list_supported_names(ft) - local registered_linters = null_linters.list_supported_names(ft) - local registered_providers = {} - vim.list_extend(registered_providers, registered_formatters) - vim.list_extend(registered_providers, registered_linters) - local registered_count = vim.tbl_count(registered_providers) - local null_ls_info = { - "Formatters and linters", - fmt( - "* Configured providers: %s%s", - table.concat(registered_providers, " , "), - registered_count > 0 and " " or "" - ), - } + local formatters_info = make_formatters_info(ft) + + local linters_info = make_linters_info(ft) local content_provider = function(popup) local content = {} @@ -145,15 +132,13 @@ function M.toggle_popup(ft) { "" }, header, { "" }, - lsp_info, - { "" }, - null_ls_info, - { "" }, + ts_info, { "" }, - get_formatter_suggestion_msg(ft), + lsp_info, { "" }, + formatters_info, { "" }, - get_linter_suggestion_msg(ft), + linters_info, } do vim.list_extend(content, section) end @@ -162,14 +147,27 @@ function M.toggle_popup(ft) end local function set_syntax_hl() - vim.cmd [[highlight nvimInfoIdentifier gui=bold]] - vim.cmd [[highlight link nvimInfoHeader Type]] - vim.cmd [[let m=matchadd("nvimInfoHeader", "Language Server Protocol (LSP) info")]] - vim.cmd [[let m=matchadd("nvimInfoHeader", "Formatters and linters")]] - vim.cmd('let m=matchadd("nvimInfoIdentifier", " ' .. ft .. '$")') + vim.cmd [[highlight NvimInfoIdentifier gui=bold]] + vim.cmd [[highlight link NvimInfoHeader Type]] + vim.cmd [[let m=matchadd("NvimInfoHeader", "Treesitter info")]] + vim.cmd [[let m=matchadd("NvimInfoHeader", "Language Server Protocol (LSP) info")]] + vim.cmd [[let m=matchadd("NvimInfoHeader", "Formatters info")]] + vim.cmd [[let m=matchadd("NvimInfoHeader", "Linters info")]] + vim.cmd('let m=matchadd("NvimInfoIdentifier", " ' .. ft .. '$")') vim.cmd 'let m=matchadd("string", "true")' + vim.cmd 'let m=matchadd("string", "active")' + vim.cmd 'let m=matchadd("boolean", "inactive")' + vim.cmd 'let m=matchadd("string", "")' vim.cmd 'let m=matchadd("error", "false")' - tbl_set_highlight(registered_providers, "nvimInfoIdentifier") + -- tbl_set_highlight(registered_providers, "NvimInfoIdentifier") + tbl_set_highlight( + require("lsp.null-ls.formatters").list_available(ft), + "NvimInfoIdentifier" + ) + tbl_set_highlight( + require("lsp.null-ls.linters").list_available(ft), + "NvimInfoIdentifier" + ) end local Popup = require("interface.popup"):new { diff --git a/.config/nvim/lua/core/log.lua b/.config/nvim/lua/core/log.lua index de03521..c44808f 100644 --- a/.config/nvim/lua/core/log.lua +++ b/.config/nvim/lua/core/log.lua @@ -1,60 +1,127 @@ local Log = {} +local logfile = string.format("%s/%s.log", vim.fn.stdpath "cache", "nvim") + +Log.levels = { + TRACE = 1, + DEBUG = 2, + INFO = 3, + WARN = 4, + ERROR = 5, +} + +vim.tbl_add_reverse_lookup(Log.levels) + +function Log:init() + local status_ok, structlog = pcall(require, "structlog") + if not status_ok then + return nil + end + + local log_level = Log.levels[(options.log.level):upper() or "WARN"] + local nvim_log = { + nvim = { + sinks = { + structlog.sinks.Console(log_level, { + async = false, + processors = { + structlog.processors.Namer(), + structlog.processors.StackWriter( + { "line", "file" }, + { max_parents = 0, stack_level = 2 } + ), + structlog.processors.Timestamper "%H:%M:%S", + }, + formatter = structlog.formatters.FormatColorizer( -- + "%s [%-5s] %s: %-30s", + { "timestamp", "level", "logger_name", "msg" }, + { level = structlog.formatters.FormatColorizer.color_level() } + ), + }), + structlog.sinks.File(Log.levels.TRACE, logfile, { + processors = { + structlog.processors.Namer(), + structlog.processors.StackWriter( + { "line", "file" }, + { max_parents = 3, stack_level = 2 } + ), + structlog.processors.Timestamper "%H:%M:%S", + }, + formatter = structlog.formatters.Format( -- + "%s [%-5s] %s: %-30s", + { "timestamp", "level", "logger_name", "msg" } + ), + }), + }, + }, + } + + structlog.configure(nvim_log) + + local logger = structlog.get_logger "nvim" + + return logger +end + --- Adds a log entry using Plenary.log ----@param msg any +---@fparam msg any ---@param level string [same as vim.log.log_levels] -function Log:add_entry(msg, level) - assert(type(level) == "string") +function Log:add_entry(level, msg, event) if self.__handle then - -- plenary uses lower-case log levels - self.__handle[level:lower()](msg) + self.__handle:log(level, vim.inspect(msg), event) return end - local status_ok, plenary = pcall(require, "plenary") - if status_ok then - local default_opts = { plugin = "nvim", level = options.log.level } - local handle = plenary.log.new(default_opts) - handle[level:lower()](msg) - self.__handle = handle + + local logger = self:init() + if not logger then + return end - -- don't do anything if plenary is not available + + self.__handle = logger + self.__handle:log(level, vim.inspect(msg), event) end ---Retrieves the path of the logfile ---@return string path of the logfile function Log:get_path() - return string.format("%s/%s.log", vim.fn.stdpath "cache", "nvim") + return logfile end ---Add a log entry at TRACE level ---@param msg any -function Log:trace(msg) - self:add_entry(msg, "TRACE") +---@param event any +function Log:trace(msg, event) + self:add_entry(self.levels.TRACE, msg, event) end ---Add a log entry at DEBUG level ---@param msg any -function Log:debug(msg) - self:add_entry(msg, "DEBUG") +---@param event any +function Log:debug(msg, event) + self:add_entry(self.levels.DEBUG, msg, event) end ---Add a log entry at INFO level ---@param msg any -function Log:info(msg) - self:add_entry(msg, "INFO") +---@param event any +function Log:info(msg, event) + self:add_entry(self.levels.INFO, msg, event) end ---Add a log entry at WARN level ---@param msg any -function Log:warn(msg) - self:add_entry(msg, "WARN") +---@param event any +function Log:warn(msg, event) + self:add_entry(self.levels.WARN, msg, event) end ---Add a log entry at ERROR level ---@param msg any -function Log:error(msg) - self:add_entry(msg, "ERROR") +---@param event any +function Log:error(msg, event) + self:add_entry(self.levels.ERROR, msg, event) end setmetatable({}, Log) + return Log diff --git a/.config/nvim/lua/core/lualine/components.lua b/.config/nvim/lua/core/lualine/components.lua index 9333a17..6ef1cff 100644 --- a/.config/nvim/lua/core/lualine/components.lua +++ b/.config/nvim/lua/core/lualine/components.lua @@ -117,12 +117,12 @@ return { -- add formatter local formatters = require "lsp.null-ls.formatters" - local supported_formatters = formatters.list_supported_names(buf_ft) + local supported_formatters = formatters.list_registered_providers(buf_ft) vim.list_extend(buf_client_names, supported_formatters) -- add linter local linters = require "lsp.null-ls.linters" - local supported_linters = linters.list_supported_names(buf_ft) + local supported_linters = linters.list_registered_providers(buf_ft) vim.list_extend(buf_client_names, supported_linters) return table.concat(buf_client_names, ", ") @@ -135,11 +135,14 @@ return { progress = { "progress", cond = conditions.hide_in_width, color = {} }, spaces = { function() - local label = "Spaces: " if not vim.api.nvim_buf_get_option(0, "expandtab") then - label = "Tab size: " + return "Tab size: " .. vim.api.nvim_buf_get_option(0, "tabstop") .. " " end - return label .. vim.api.nvim_buf_get_option(0, "shiftwidth") .. " " + local size = vim.api.nvim_buf_get_option(0, "shiftwidth") + if size == 0 then + size = vim.api.nvim_buf_get_option(0, "tabstop") + end + return "Spaces: " .. size .. " " end, color = {}, cond = conditions.hide_in_width, diff --git a/.config/nvim/lua/core/telescope.lua b/.config/nvim/lua/core/telescope.lua index 108b6f3..7ef2e58 100644 --- a/.config/nvim/lua/core/telescope.lua +++ b/.config/nvim/lua/core/telescope.lua @@ -15,14 +15,6 @@ function M.config() options.builtin.telescope = vim.tbl_extend("force", options.builtin.telescope, { defaults = { - find_command = { - "rg", - "--no-heading", - "--with-filename", - "--line-number", - "--column", - "--smart-case", - }, prompt_prefix = " ", selection_caret = " ", entry_prefix = " ", @@ -37,55 +29,55 @@ function M.config() horizontal = { mirror = false }, vertical = { mirror = false }, }, - file_sorter = require("telescope.sorters").get_fzy_sorter, - file_ignore_patterns = {}, - generic_sorter = require("telescope.sorters").get_generic_fuzzy_sorter, - path_display = { "shorten" }, - winblend = 0, - border = {}, - borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" }, - color_devicons = true, - use_less = true, - set_env = { ["CoptionsLoptionsRTERM"] = "truecolor" }, -- default = nil, - file_previewer = require("telescope.previewers").vim_buffer_cat.new, - grep_previewer = require("telescope.previewers").vim_buffer_vimgrep.new, - qflist_previewer = require("telescope.previewers").vim_buffer_qflist.new, - - -- Developer configurations: Not meant for general override - -- buffer_previewer_maker = require("telescope.previewers").buffer_previewer_maker, + vimgrep_arguments = { + "rg", + "--color=never", + "--no-heading", + "--with-filename", + "--line-number", + "--column", + "--smart-case", + "--hidden", + }, mappings = { i = { - -- ["<C-n>"] = actions.cycle_history_next, - -- ["<C-p>"] = actions.cycle_history_prev, + ["<C-n>"] = actions.move_selection_next, + ["<C-p>"] = actions.move_selection_previous, ["<C-c>"] = actions.close, - ["<C-j>"] = actions.move_selection_next, - ["<C-k>"] = actions.move_selection_previous, + ["<C-j>"] = actions.cycle_history_next, + ["<C-k>"] = actions.cycle_history_prev, ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist, ["<CR>"] = actions.select_default + actions.center, - -- To disable a keymap, put [map] = false - -- So, to not map "<C-n>", just put - -- ["<c-t>"] = trouble.open_with_trouble, - -- ["<c-x>"] = false, - -- ["<esc>"] = actions.close, - -- optionstherwise, just set the mapping to the function that you want it to be. - -- ["<C-i>"] = actions.select_horizontal, - -- Add up multiple actions - -- You can perform as many actions in a row as you like - -- ["<CR>"] = actions.select_default + actions.center + my_cool_custom_action, }, n = { - ["<C-j>"] = actions.move_selection_next, - ["<C-k>"] = actions.move_selection_previous, + ["<C-n>"] = actions.move_selection_next, + ["<C-p>"] = actions.move_selection_previous, ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist, - -- ["<c-t>"] = trouble.open_with_trouble, - -- ["<C-i>"] = my_cool_custom_action, + }, + }, + file_ignore_patterns = {}, + path_display = { shorten = 5 }, + winblend = 0, + border = {}, + borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" }, + color_devicons = true, + set_env = { ["COLORTERM"] = "truecolor" }, -- default = nil, + pickers = { + find_files = { + find_command = { "fd", "--type=file", "--hidden", "--smart-case" }, + }, + live_grep = { + --@usage don't include the filename in the search results + only_sort_text = true, }, }, }, extensions = { - fzy_native = { - override_generic_sorter = false, - override_file_sorter = true, + fzf = { + fuzzy = true, -- false will only do exact matching + override_generic_sorter = true, -- override the generic sorter + override_file_sorter = true, -- override the file sorter + case_mode = "smart_case", -- or "ignore_case" or "respect_case" }, }, }) @@ -108,20 +100,60 @@ function M.code_actions() previewer = false, shorten_path = false, } - require("telescope.builtin").lsp_code_actions(require("telescope.themes").get_dropdown(opts)) + require("telescope.builtin").lsp_code_actions( + require("telescope.themes").get_dropdown(opts) + ) end function M.setup() + local previewers = require "telescope.previewers" + local sorters = require "telescope.sorters" + local actions = require "telescope.actions" + + options.builtin.telescope = vim.tbl_extend("keep", { + file_previewer = previewers.vim_buffer_cat.new, + grep_previewer = previewers.vim_buffer_vimgrep.new, + qflist_previewer = previewers.vim_buffer_qflist.new, + file_sorter = sorters.get_fuzzy_file, + generic_sorter = sorters.get_generic_fuzzy_sorter, + ---@usage Mappings are fully customizable. Many familiar mapping patterns are setup as defaults. + mappings = { + i = { + ["<C-n>"] = actions.move_selection_next, + ["<C-p>"] = actions.move_selection_previous, + ["<C-c>"] = actions.close, + ["<C-j>"] = actions.cycle_history_next, + ["<C-k>"] = actions.cycle_history_prev, + ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist, + ["<CR>"] = actions.select_default + actions.center, + }, + n = { + ["<C-n>"] = actions.move_selection_next, + ["<C-p>"] = actions.move_selection_previous, + ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist, + }, + }, + }, options.builtin.telescope) + local telescope = require "telescope" telescope.setup(options.builtin.telescope) + if options.builtin.project.active then - telescope.load_extension "projects" + pcall(function() + require("telescope").load_extension "projects" + end) end if options.builtin.telescope.on_config_done then options.builtin.telescope.on_config_done(telescope) end + + if + options.builtin.telescope.extensions and options.builtin.telescope.extensions.fzf + then + require("telescope").load_extension "fzf" + end end return M diff --git a/.config/nvim/lua/core/treesitter.lua b/.config/nvim/lua/core/treesitter.lua index 59adda4..b56c245 100644 --- a/.config/nvim/lua/core/treesitter.lua +++ b/.config/nvim/lua/core/treesitter.lua @@ -1,4 +1,3 @@ - local M = {} local Log = require "core.log" @@ -17,8 +16,17 @@ M.config = function() disable = { "latex" }, }, context_commentstring = { - enable = false, - config = { css = "// %s" }, + enable = true, + config = { + -- Languages that have a single comment style + typescript = "// %s", + css = "/* %s */", + scss = "/* %s */", + html = "<!-- %s -->", + svelte = "<!-- %s -->", + vue = "<!-- %s -->", + json = "", + }, }, -- indent = {enable = true, disable = {"python", "html", "javascript"}}, -- TODO seems to be broken @@ -72,7 +80,11 @@ M.setup = function() return end - treesitter_configs.setup(options.builtin.treesitter) + local opts = vim.deepcopy(options.builtin.treesitter) + + -- avoid running any installers in headless mode since it's harder to detect failures + opts.ensure_installed = #vim.api.nvim_list_uis() == 0 and {} or opts.ensure_installed + treesitter_configs.setup(opts) if options.builtin.treesitter.on_config_done then options.builtin.treesitter.on_config_done(treesitter_configs) diff --git a/.config/nvim/lua/core/which-key.lua b/.config/nvim/lua/core/which-key.lua index fe38358..ccf0c2d 100644 --- a/.config/nvim/lua/core/which-key.lua +++ b/.config/nvim/lua/core/which-key.lua @@ -61,7 +61,7 @@ M.config = function() -- NOTE: Prefer using : over <cmd> as the latter avoids going back in normal-mode. -- see https://neovim.io/doc/user/map.html#:map-cmd vmappings = { - ["k"] = { "<ESC><CMD>lua ___comment_gc(vim.fn.visualmode())<CR>", "Comment" }, + ["/"] = { "<ESC><CMD>lua ___comment_gc(vim.fn.visualmode())<CR>", "Comment" }, }, mappings = { ["w"] = { "<cmd>w!<CR>", "Save" }, @@ -69,7 +69,7 @@ M.config = function() ["k"] = { "<cmd>lua require('Comment').toggle()<CR>", "Comment" }, ["c"] = { "<cmd>BufferClose!<CR>", "Close Buffer" }, ["f"] = { "<cmd>Telescope find_files<CR>", "Find File" }, - ["n"] = { "<cmd>nohlsearch<CR>", "No Highlight" }, + ["h"] = { "<cmd>nohlsearch<CR>", "No Highlight" }, b = { name = "Buffers", j = { "<cmd>BufferPick<cr>", "Jump" }, @@ -98,7 +98,7 @@ M.config = function() name = "Packer", c = { "<cmd>PackerCompile<cr>", "Compile" }, i = { "<cmd>PackerInstall<cr>", "Install" }, - r = { "<cmd>lua require('utils').reload_config()<cr>", "Reload" }, + r = { "<cmd>lua require('plugin-loader').recompile()<cr>", "Re-compile" }, s = { "<cmd>PackerSync<cr>", "Sync" }, S = { "<cmd>PackerStatus<cr>", "Status" }, u = { "<cmd>PackerUpdate<cr>", "Update" }, @@ -139,7 +139,10 @@ M.config = function() l = { name = "LSP", - a = { "<cmd>lua require('core.telescope').code_actions()<cr>", "Code Action" }, + a = { + "<cmd>lua require('core.telescope').code_actions()<cr>", + "Code Action", + }, d = { "<cmd>Telescope lsp_document_diagnostics<cr>", "Document Diagnostics", @@ -148,15 +151,15 @@ 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 = options.lsp.popup_border}})<cr>", + "<cmd>lua vim.lsp.diagnostic.goto_next({popup_opts = {border = lsp.popup_border}})<cr>", "Next Diagnostic", }, k = { - "<cmd>lua vim.lsp.diagnostic.goto_prev({popup_opts = {border = options.lsp.popup_border}})<cr>", + "<cmd>lua vim.lsp.diagnostic.goto_prev({popup_opts = {border = lsp.popup_border}})<cr>", "Prev Diagnostic", }, l = { "<cmd>lua vim.lsp.codelens.run()<cr>", "CodeLens Action" }, @@ -180,19 +183,23 @@ M.config = function() "Workspace Symbols", }, }, - i = { - name = "+nvim", + L = { + name = "+NeoVim", c = { - "<cmd>edit ~/.config/nvim/config.lua<cr>", + "<cmd>edit " .. get_config_dir() .. "/config.lua<cr>", "Edit config.lua", }, k = { "<cmd>lua require('keymappings').print()<cr>", - "View LunarVim's default keymappings", + "View NeoVim's default keymappings", }, i = { "<cmd>lua require('core.info').toggle_popup(vim.bo.filetype)<cr>", - "Toggle nvim Info", + "Toggle NeoVim Info", + }, + I = { + "<cmd>lua require('core.telescope.custom-finders').view_lunarvim_changelog()<cr>", + "View NeoVim's changelog", }, l = { name = "+logs", @@ -226,7 +233,8 @@ M.config = function() "Open the Packer logfile", }, }, - r = { "<cmd>lua require('utils').reload_config()<cr>", "Reload configurations" }, + r = { "<cmd>NvimReload<cr>", "Reload Neovim's configuration" }, + u = { "<cmd>NvimUpdate<cr>", "Update NeoVim" }, }, s = { name = "Search", diff --git a/.config/nvim/lua/dark/palette.lua b/.config/nvim/lua/dark/palette.lua index a85effb..92ff012 100644 --- a/.config/nvim/lua/dark/palette.lua +++ b/.config/nvim/lua/dark/palette.lua @@ -4,7 +4,7 @@ local colors = { alt_bg = "#171717", accent = "#202020", white = "#F2F6F3", - gray = "#404040", + gray = "#606060", light_gray = "#D0D0D0", blue = "#A5D6FF", gray_blue = "#5F819D", diff --git a/.config/nvim/lua/keymappings.lua b/.config/nvim/lua/keymappings.lua index cc6865a..5d71b97 100644 --- a/.config/nvim/lua/keymappings.lua +++ b/.config/nvim/lua/keymappings.lua @@ -57,13 +57,14 @@ end -- Load key mappings for all provided modes -- @param keymaps A list of key mappings for each mode function M.load(keymaps) + keymaps = keymaps or {} for mode, mapping in pairs(keymaps) do M.load_mode(mode, mapping) end end -function M.config() - options.keys = { +function M.get_defaults() + local keys = { ---@usage change or add keymappings for insert mode insert_mode = { -- 'jk' for quitting insert mode @@ -81,16 +82,6 @@ function M.config() ["<A-Down>"] = "<C-\\><C-N><C-w>j", ["<A-Left>"] = "<C-\\><C-N><C-w>h", ["<A-Right>"] = "<C-\\><C-N><C-w>l", - -- navigate tab completion with <c-j> and <c-k> - -- runs conditionally - ["<C-j>"] = { - 'pumvisible() ? "\\<C-n>" : "\\<C-j>"', - { expr = true, noremap = true }, - }, - ["<C-k>"] = { - 'pumvisible() ? "\\<C-p>" : "\\<C-k>"', - { expr = true, noremap = true }, - }, }, ---@usage change or add keymappings for normal mode @@ -167,12 +158,14 @@ function M.config() } if vim.fn.has "mac" == 1 then - options.keys.normal_mode["<A-Up>"] = options.keys.normal_mode["<C-Up>"] - options.keys.normal_mode["<A-Down>"] = options.keys.normal_mode["<C-Down>"] - options.keys.normal_mode["<A-Left>"] = options.keys.normal_mode["<C-Left>"] - options.keys.normal_mode["<A-Right>"] = options.keys.normal_mode["<C-Right>"] + keys.normal_mode["<A-Up>"] = keys.normal_mode["<C-Up>"] + keys.normal_mode["<A-Down>"] = keys.normal_mode["<C-Down>"] + keys.normal_mode["<A-Left>"] = keys.normal_mode["<C-Left>"] + keys.normal_mode["<A-Right>"] = keys.normal_mode["<C-Right>"] Log:debug "Activated mac keymappings" end + + return keys end function M.print(mode) @@ -184,9 +177,4 @@ function M.print(mode) end end -function M.setup() - vim.g.mapleader = (options.leader == "space" and " ") or options.leader - M.load(options.keys) -end - return M diff --git a/.config/nvim/lua/lsp/config.lua b/.config/nvim/lua/lsp/config.lua index 9c25249..673f924 100644 --- a/.config/nvim/lua/lsp/config.lua +++ b/.config/nvim/lua/lsp/config.lua @@ -1,5 +1,5 @@ return { - templates_dir = join_paths(get_config_dir(), "ftplugin"), + templates_dir = join_paths(get_runtime_dir(), "site", "after", "ftplugin"), diagnostics = { signs = { active = true, @@ -15,7 +15,6 @@ return { underline = true, severity_sort = true, }, - override = {}, document_highlight = true, code_lens_refresh = true, popup_border = "single", @@ -42,4 +41,25 @@ return { null_ls = { setup = {}, }, + override = { + "angularls", + "ansiblels", + "denols", + "ember", + "emmet_ls", + "eslint", + "eslintls", + "graphql", + "jedi_language_server", + "ltex", + "phpactor", + "pylsp", + "rome", + "sqlls", + "sqls", + "stylelint_lsp", + "tailwindcss", + "tflint", + "volar", + }, } diff --git a/.config/nvim/lua/lsp/handlers.lua b/.config/nvim/lua/lsp/handlers.lua index 6801045..01666be 100644 --- a/.config/nvim/lua/lsp/handlers.lua +++ b/.config/nvim/lua/lsp/handlers.lua @@ -132,7 +132,18 @@ function M.show_line_diagnostics() table.sort(diagnostics, function(a, b) return a.severity < b.severity end) - for i, diagnostic in ipairs(diagnostics) do + + local hash = {} + local diagnostics_no_dupes = {} + for _, v in ipairs(diagnostics) do + if not hash[v["message"]] then + diagnostics_no_dupes[#diagnostics_no_dupes + 1] = v -- you could print here instead of saving to result table if you wanted + hash[v["message"]] = true + end + end + -- print(vim.inspect(diagnostics_no_dupes)) + + for i, diagnostic in ipairs(diagnostics_no_dupes) do local source = diagnostic.source diag_message = diagnostic.message:gsub("[\n\r]", " ") if source then diff --git a/.config/nvim/lua/lsp/init.lua b/.config/nvim/lua/lsp/init.lua index 42c2536..f92ecd3 100644 --- a/.config/nvim/lua/lsp/init.lua +++ b/.config/nvim/lua/lsp/init.lua @@ -95,17 +95,16 @@ function M.common_capabilities() end local function select_default_formater(client) - local client_formatting = client.resolved_capabilities.document_formatting - or client.resolved_capabilities.document_range_formatting - if client.name == "null-ls" or not client_formatting then + if + client.name == "null-ls" or not client.resolved_capabilities.document_formatting + then return end Log:debug("Checking for formatter overriding for " .. client.name) + local formatters = require "lvim.lsp.null-ls.formatters" local client_filetypes = client.config.filetypes or {} for _, filetype in ipairs(client_filetypes) do - if - options.lang[filetype] and #vim.tbl_keys(options.lang[filetype].formatters) > 0 - then + if #vim.tbl_keys(formatters.list_registered_providers(filetype)) > 0 then Log:debug( "Formatter overriding detected. Disabling formatting capabilities for " .. client.name diff --git a/.config/nvim/lua/lsp/manager.lua b/.config/nvim/lua/lsp/manager.lua index a7d6892..24fb6e3 100644 --- a/.config/nvim/lua/lsp/manager.lua +++ b/.config/nvim/lua/lsp/manager.lua @@ -15,15 +15,6 @@ function M.init_defaults(languages) end end -local function is_overridden(server) - local overrides = options.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] @@ -35,11 +26,8 @@ local function resolve_config(name, user_config) capabilities = require("lsp").common_capabilities(), } - local status_ok, custom_config = pcall( - require, - "lsp/providers/" .. name - ) - if status_ok then + local has_custom_provider, custom_config = pcall(require, "lsp/providers/" .. name) + if has_custom_provider then Log:debug("Using custom configuration for requested server: " .. name) config = vim.tbl_deep_extend("force", config, custom_config) end @@ -51,38 +39,56 @@ local function resolve_config(name, user_config) return config end +-- manually start the server and don't wait for the usual filetype trigger from lspconfig +local function buf_try_add(server_name, bufnr) + bufnr = bufnr or vim.api.nvim_get_current_buf() + require("lspconfig")[server_name].manager.try_add_wrapper(bufnr) +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 + if lsp_utils.is_client_active(server_name) then return end + local servers = require "nvim-lsp-installer.servers" local config = resolve_config(server_name, user_config) - local server_available, requested_server = require("nvim-lsp-installer.servers").get_server(server_name) + local server_available, requested_server = 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 + if server_available then + local install_notification = false + + if not requested_server:is_installed() then + if options.lsp.automatic_servers_installation then + Log:debug "Automatic server installation detected" + requested_server:install() + install_notification = true + else + Log:debug(requested_server.name .. " is not managed by the automatic installer") + end 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) + requested_server:on_ready(function() + if install_notification then + vim.notify( + string.format("Installation complete for [%s] server", requested_server.name), + vim.log.levels.INFO + ) + end + install_notification = false + requested_server:setup(config) + end) else - require("lspconfig")[server_name].setup(config) + -- since it may not be installed, don't attempt to configure the LSP unless there is a custom provider + local has_custom_provider, _ = pcall(require, "lsp/providers/" .. server_name) + if has_custom_provider then + require("lspconfig")[server_name].setup(config) + buf_try_add(server_name) + end end end diff --git a/.config/nvim/lua/lsp/null-ls/formatters.lua b/.config/nvim/lua/lsp/null-ls/formatters.lua index 577a0d9..991f613 100644 --- a/.config/nvim/lua/lsp/null-ls/formatters.lua +++ b/.config/nvim/lua/lsp/null-ls/formatters.lua @@ -4,7 +4,7 @@ local null_ls = require "null-ls" local services = require "lsp.null-ls.services" local Log = require "core.log" -function M.list_supported_names(filetype) +function M.list_registered_providers(filetype) local null_ls_methods = require "null-ls.methods" local formatter_method = null_ls_methods.internal["FORMATTING"] local registered_providers = services.list_registered_providers_names(filetype) @@ -24,6 +24,7 @@ function M.list_available(filetype) end end + table.sort(formatters) return formatters end diff --git a/.config/nvim/lua/lsp/null-ls/init.lua b/.config/nvim/lua/lsp/null-ls/init.lua index a18209b..9560240 100644 --- a/.config/nvim/lua/lsp/null-ls/init.lua +++ b/.config/nvim/lua/lsp/null-ls/init.lua @@ -1,8 +1,6 @@ local M = {} 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") @@ -17,21 +15,8 @@ function M:setup() if vim.tbl_isempty(options.lsp.null_ls.setup or {}) then options.lsp.null_ls.setup = default_opts end + require("lspconfig")["null-ls"].setup(options.lsp.null_ls.setup) - for filetype, config in pairs(options.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/.config/nvim/lua/lsp/null-ls/linters.lua b/.config/nvim/lua/lsp/null-ls/linters.lua index 3f834ba..85555ba 100644 --- a/.config/nvim/lua/lsp/null-ls/linters.lua +++ b/.config/nvim/lua/lsp/null-ls/linters.lua @@ -4,7 +4,7 @@ local null_ls = require "null-ls" local services = require "lsp.null-ls.services" local Log = require "core.log" -function M.list_supported_names(filetype) +function M.list_registered_providers(filetype) local null_ls_methods = require "null-ls.methods" local linter_method = null_ls_methods.internal["DIAGNOSTICS"] local registered_providers = services.list_registered_providers_names(filetype) @@ -24,6 +24,7 @@ function M.list_available(filetype) end end + table.sort(linters) return linters end diff --git a/.config/nvim/lua/lsp/templates.lua b/.config/nvim/lua/lsp/templates.lua index 2cce567..084c1f9 100644 --- a/.config/nvim/lua/lsp/templates.lua +++ b/.config/nvim/lua/lsp/templates.lua @@ -2,7 +2,7 @@ local M = {} local Log = require "core.log" local utils = require "utils" -local get_supported_filetypes = require("lsp.utils").get_supported_filetypes +local lsp_utils = require "lsp.utils" local ftplugin_dir = options.lsp.templates_dir @@ -15,48 +15,23 @@ function M.remove_template_files() 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 + local has_custom_provider, _ = pcall(require, "lsp/providers/" .. server_name) + if + vim.tbl_contains(options.lsp.override, server_name) and not has_custom_provider + then return end - if M.is_ignored(server_name, filetypes) then + -- we need to go through lspconfig to get the corresponding filetypes currently + local filetypes = lsp_utils.get_supported_filetypes(server_name) or {} + if not 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) diff --git a/.config/nvim/lua/lsp/utils.lua b/.config/nvim/lua/lsp/utils.lua index 5900340..afc3eba 100644 --- a/.config/nvim/lua/lsp/utils.lua +++ b/.config/nvim/lua/lsp/utils.lua @@ -49,14 +49,19 @@ function M.get_client_capabilities(client_id) 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 + -- temporary workaround: https://github.com/neovim/nvim-lspconfig/pull/1358 + if server_name == "dockerls" then + return { "dockerfile" } + end + local lsp_installer_servers = require "nvim-lsp-installer.servers" + local server_available, requested_server = lsp_installer_servers.get_server( + server_name + ) + if not server_available then + return {} end + + return requested_server:get_supported_filetypes() end return M diff --git a/.config/nvim/lua/plugin-loader.lua b/.config/nvim/lua/plugin-loader.lua index f2c1dad..d2b7972 100644 --- a/.config/nvim/lua/plugin-loader.lua +++ b/.config/nvim/lua/plugin-loader.lua @@ -5,7 +5,9 @@ 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) +local _, packer = pcall(require, "packer") + +function plugin_loader.init(opts) opts = opts or {} local install_path = opts.install_path @@ -24,14 +26,10 @@ function plugin_loader:init(opts) vim.cmd "packadd packer.nvim" end - local packer_ok, packer = pcall(require, "packer") - if not packer_ok then - return - end - packer.init { package_root = package_root, compile_path = compile_path, + log = { level = "warn" }, git = { clone_timeout = 300 }, display = { open_fn = function() @@ -39,33 +37,65 @@ function plugin_loader:init(opts) end, }, } +end - self.packer = packer - return self +-- packer expects a space separated list +local function pcall_packer_command(cmd, kwargs) + local status_ok, msg = pcall(function() + require("packer")[cmd](unpack(kwargs or {})) + end) + if not status_ok then + Log:warn(cmd .. " failed with: " .. vim.inspect(msg)) + Log:trace(vim.inspect(vim.fn.eval "v:errmsg")) + end end -function plugin_loader:cache_clear() +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() +function plugin_loader.recompile() + plugin_loader.cache_clear() + pcall_packer_command "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 - for _, plugin in ipairs(plugins) do - use(plugin) +function plugin_loader.load(configurations) + Log:debug "loading plugins configuration" + local status_ok, _ = xpcall(function() + packer.startup(function(use) + for _, plugins in ipairs(configurations) do + for _, plugin in ipairs(plugins) do + use(plugin) + end end - end - end) + end) + end, debug.traceback) + if not status_ok then + Log:warn "problems detected while loading plugins' configurations" + Log:trace(debug.traceback()) + end +end + +function plugin_loader.get_core_plugins() + local list = {} + local plugins = require "plugins" + for _, item in pairs(plugins) do + table.insert(list, item[1]:match "/(%S*)") + end + return list +end + +function plugin_loader.sync_core_plugins() + local core_plugins = plugin_loader.get_core_plugins() + Log:trace( + string.format("Syncing core plugins: [%q]", table.concat(core_plugins, ", ")) + ) + pcall_packer_command("sync", core_plugins) end return plugin_loader diff --git a/.config/nvim/lua/plugins.lua b/.config/nvim/lua/plugins.lua index 28e5780..0511fa8 100644 --- a/.config/nvim/lua/plugins.lua +++ b/.config/nvim/lua/plugins.lua @@ -1,38 +1,74 @@ +local commit = { + packer = "7f62848f3a92eac61ae61def5f59ddb5e2cc6823", + lsp_config = "6224c54a9945a52bf43a8bc1a42a112084590c0b", + nlsp_settings = "29f49afe27b43126d45a05baf3161a28b929f2f1", + null_ls = "64b269b51c7490660dcb2008f59ae260f2cdbbe4", + fix_cursor_hold = "0e4e22d21975da60b0fd2d302285b3b603f9f71e", + lsp_installer = "c9dbc8afc2d56227ed0cba5a3348b8dd170e3a1d", + structlog = "6f1403a192791ff1fa7ac845a73de9e860f781f1", + popup = "f91d80973f80025d4ed00380f2e06c669dfda49d", + plenary = "96e821e8001c21bc904d3c15aa96a70c11462c5f", + telescope = "078a48db9e0720b07bfcb8b59342c5305a1d1fdc", + telescope_fzf_native = "59e38e1661ffdd586cb7fc22ca0b5a05c7caf988", + nvim_cmp = "1774ff0f842146521c63707245d3de5db2bb3732", + friendly_snippets = "94f1d917435c71bc6494d257afa90d4c9449aed2", + autopairs = "f858ab38b532715dbaf7b2773727f8622ba04322", + treesitter = "47cfda2c6711077625c90902d7722238a8294982", + context_commentstring = "159c5b9a2cdb8a8fe342078b7ac8139de76bad62", + nvim_tree = "f92b7e7627c5a36f4af6814c408211539882c4f3", + gitsigns = "61a81b0c003de3e12555a5626d66fb6a060d8aca", + which_key = "d3032b6d3e0adb667975170f626cb693bfc66baa", + comment = "620445b87a0d1640fac6991f9c3338af8dec1884", + project = "3a1f75b18f214064515ffba48d1eb7403364cc6a", + nvim_web_devicons = "ee101462d127ed6a5561ce9ce92bfded87d7d478", + lualine = "3f5cdc51a08c437c7705e283eebd4cf9fbb18f80", + barbar = "6e638309efcad2f308eb9c5eaccf6f62b794bbab", + toggleterm = "5f9ba91157a25be5ee7395fbc11b1a8f25938365", + luasnip = "bab7cc2c32fba00776d2f2fc4704bed4eee2d082", + cmp_luasnip = "16832bb50e760223a403ffa3042859845dd9ef9d", + cmp_buffer = "d1ca295ce584ec80763a6dc043080874b57ccffc", + cmp_nvim_lsp = "accbe6d97548d8d3471c04d512d36fa61d0e4be8", + cmp_path = "97661b00232a2fe145fe48e295875bc3299ed1f7", + cmp_nvim_lua = "d276254e7198ab7d00f117e88e223b4bd8c02d21", +} + return { -- Packer can manage itself as an optional plugin - { "wbthomason/packer.nvim" }, - { "neovim/nvim-lspconfig" }, - { "tamago324/nlsp-settings.nvim" }, - { "jose-elias-alvarez/null-ls.nvim" }, - { "antoinemadec/FixCursorHold.nvim" }, -- Needed while issue https://github.com/neovim/neovim/issues/12587 is still open + { "wbthomason/packer.nvim", commit = commit.packer }, + { "neovim/nvim-lspconfig", commit = commit.lsp_config }, + { "tamago324/nlsp-settings.nvim", commit = commit.nlsp_settings }, + { "jose-elias-alvarez/null-ls.nvim", commit = commit.null_ls }, + { "antoinemadec/FixCursorHold.nvim", commit = commit.fix_cursor_hold }, -- Needed while issue https://github.com/neovim/neovim/issues/12587 is still open { "williamboman/nvim-lsp-installer", + commit = commit.lsp_installer, }, + { "Tastyep/structlog.nvim", commit = commit.structlog }, - { "nvim-lua/popup.nvim" }, - { "nvim-lua/plenary.nvim" }, + { "nvim-lua/popup.nvim", commit = commit.popup }, + { "nvim-lua/plenary.nvim", commit = commit.plenary }, -- Telescope { "nvim-telescope/telescope.nvim", + commit = commit.telescope, config = function() require("core.telescope").setup() end, disable = not options.builtin.telescope.active, }, + { + "nvim-telescope/telescope-fzf-native.nvim", + commit = commit.telescope_fzf_native, + run = "make", + disable = not options.builtin.telescope.active, + }, -- Install nvim-cmp, and buffer source as a dependency { "hrsh7th/nvim-cmp", + commit = commit.nvim_cmp, config = function() 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 options.builtin.cmp then @@ -42,13 +78,39 @@ return { }, { "rafamadriz/friendly-snippets", + commit = commit.friendly_snippets, -- event = "InsertCharPre", -- disable = not options.builtin.compe.active, }, + { + "L3MON4D3/LuaSnip", + commit = commit.luasnip, + }, + { + "saadparwaiz1/cmp_luasnip", + commit = commit.cmp_luasnip, + }, + { + "hrsh7th/cmp-buffer", + commit = commit.cmp_buffer, + }, + { + "hrsh7th/cmp-nvim-lsp", + commit = commit.cmp_nvim_lsp, + }, + { + "hrsh7th/cmp-path", + commit = commit.cmp_path, + }, + { + "hrsh7th/cmp-nvim-lua", + commit = commit.cmp_nvim_lua, + }, -- Autopairs { "windwp/nvim-autopairs", + commit = commit.autopairs, -- event = "InsertEnter", config = function() require("core.autopairs").setup() @@ -59,19 +121,25 @@ return { -- Treesitter { "nvim-treesitter/nvim-treesitter", + commit = commit.treesitter, branch = "0.5-compat", -- run = ":TSUpdate", config = function() require("core.treesitter").setup() end, }, + { + "JoosepAlviste/nvim-ts-context-commentstring", + commit = commit.context_commentstring, + event = "BufReadPost", + }, -- NvimTree { "kyazdani42/nvim-tree.lua", -- event = "BufWinOpen", -- cmd = "NvimTreeToggle", - -- commit = "fd7f60e242205ea9efc9649101c81a07d5f458bb", + commit = commit.nvim_tree, config = function() require("core.nvimtree").setup() end, @@ -80,6 +148,7 @@ return { { "lewis6991/gitsigns.nvim", + commit = commit.gitsigns, config = function() require("core.gitsigns").setup() @@ -90,8 +159,8 @@ return { -- Whichkey { - "abzcoding/which-key.nvim", - branch = "fix/neovim-6-position", + "folke/which-key.nvim", + commit = commit.which_key, config = function() require("core.which-key").setup() end, @@ -102,6 +171,7 @@ return { -- Comments { "numToStr/Comment.nvim", + commit = commit.comment, event = "BufRead", config = function() require("core.comment").setup() @@ -112,6 +182,7 @@ return { -- project.nvim { "ahmedkhalf/project.nvim", + commit = commit.project, config = function() require("core.project").setup() end, @@ -119,12 +190,13 @@ return { }, -- Icons - { "kyazdani42/nvim-web-devicons" }, + { "kyazdani42/nvim-web-devicons", commit = commit.nvim_web_devicons }, -- Status Line and Bufferline { -- "hoob3rt/lualine.nvim", - "shadmansaleh/lualine.nvim", + "nvim-lualine/lualine.nvim", + commit = commit.lualine, -- "Lunarvim/lualine.nvim", config = function() require("core.lualine").setup() @@ -134,6 +206,7 @@ return { { "romgrk/barbar.nvim", + commit = commit.barbar, config = function() require("core.bufferline").setup() end, @@ -141,24 +214,6 @@ return { disable = not options.builtin.bufferline.active, }, - -- Debugging - { - "mfussenegger/nvim-dap", - -- event = "BufWinEnter", - config = function() - require("core.dap").setup() - end, - disable = not options.builtin.dap.active, - }, - - -- Debugger management - { - "Pocco81/DAPInstall.nvim", - -- event = "BufWinEnter", - -- event = "BufRead", - disable = not options.builtin.dap.active, - }, - -- Dashboard { "ChristianChiarulli/dashboard-nvim", @@ -172,6 +227,7 @@ return { -- Terminal { "akinsho/toggleterm.nvim", + commit = commit.toggleterm, event = "BufWinEnter", config = function() require("core.terminal").setup() diff --git a/.config/nvim/lua/utils/ft.lua b/.config/nvim/lua/utils/ft.lua deleted file mode 100644 index e9852e6..0000000 --- a/.config/nvim/lua/utils/ft.lua +++ /dev/null @@ -1,47 +0,0 @@ --- Here be dragons --- Opening files with telescope will not start LSP without this -local ft = {} - -ft.find_lua_ftplugins = function(filetype) - local patterns = { - string.format("ftplugin/%s.lua", filetype), - - -- Looks like we don't need this, because the first one works - -- string.format("after/ftplugin/%s.lua", filetype), - } - - local result = {} - for _, pat in ipairs(patterns) do - vim.list_extend(result, vim.api.nvim_get_runtime_file(pat, true)) - end - - return result -end - -ft.do_filetype = function(filetype) - local ftplugins = ft.find_lua_ftplugins(filetype) - - local f_env = setmetatable({ - -- Override print, so the prints still go through, otherwise it's confusing for people - print = vim.schedule_wrap(print), - }, { - -- Buf default back read/write to whatever is going on in the global landscape - __index = _G, - __newindex = _G, - }) - - for _, file in ipairs(ftplugins) do - local f = loadfile(file) - if not f then - vim.api.nvim_err_writeln("Unable to load file: " .. file) - else - local ok, msg = pcall(setfenv(f, f_env)) - - if not ok then - vim.api.nvim_err_writeln("Error while processing file: " .. file .. "\n" .. msg) - end - end - end -end - -return ft |