From 90581a444bb8a996441006e4fabcf26ac019c346 Mon Sep 17 00:00:00 2001 From: ViViDboarder Date: Wed, 12 Jan 2022 09:21:57 -0800 Subject: [PATCH] Refactor null-ls and remove conflicted formatting --- neovim/lua/plugins/lsp.lua | 239 ++++++++++--------------- neovim/lua/plugins/null-ls/init.lua | 58 ++++++ neovim/lua/plugins/null-ls/linters.lua | 71 ++++++++ neovim/plugin/lsp.lua | 1 - 4 files changed, 220 insertions(+), 149 deletions(-) create mode 100644 neovim/lua/plugins/null-ls/init.lua create mode 100644 neovim/lua/plugins/null-ls/linters.lua diff --git a/neovim/lua/plugins/lsp.lua b/neovim/lua/plugins/lsp.lua index d1e64ee..fb70337 100644 --- a/neovim/lua/plugins/lsp.lua +++ b/neovim/lua/plugins/lsp.lua @@ -45,71 +45,81 @@ function M.config_lsp_ui() end) end -local function default_attach(client, bufnr) - local function buf_set_keymap(...) - vim.api.nvim_buf_set_keymap(bufnr, ...) - end - local function buf_set_option(...) - vim.api.nvim_buf_set_option(bufnr, ...) - end +local function get_default_attach(override_capabilities) + return function(client, bufnr) + -- Allow overriding capabilities to avoid duplicate lsps with capabilities + if override_capabilities ~= nil then + client.resolved_capabilities = vim.tbl_extend( + "force", + client.resolved_capabilities, + override_capabilities or {} + ) + end - -- Set built in features to use lsp functions - buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc") - if client.resolved_capabilities.goto_definition then - buf_set_option("tagfunc", "v:lua.vim.lsp.tagfunc") - end - if client.resolved_capabilities.document_formatting then - buf_set_option("formatexpr", "v:lua.vim.lsp.formatexpr()") - end + local function buf_set_keymap(...) + vim.api.nvim_buf_set_keymap(bufnr, ...) + end + local function buf_set_option(...) + vim.api.nvim_buf_set_option(bufnr, ...) + end - -- Mappings - -- TODO: Maybe prefix all of these for easier discovery - local opts = { noremap = true, silent = true } + -- Set built in features to use lsp functions + buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc") + if client.resolved_capabilities.goto_definition then + buf_set_option("tagfunc", "v:lua.vim.lsp.tagfunc") + end + if client.resolved_capabilities.document_formatting then + buf_set_option("formatexpr", "v:lua.vim.lsp.formatexpr()") + end - local lsp_keymap = utils.keymap_group("n", "l", opts, bufnr) - lsp_keymap("h", "lua vim.lsp.buf.hover()") - lsp_keymap("r", "lua vim.lsp.buf.rename()") - lsp_keymap("e", "lua vim.lsp.diagnostics.show_line_diagnostics()") + -- Mappings + -- TODO: Maybe prefix all of these for easier discovery + local opts = { noremap = true, silent = true } - buf_set_keymap("n", "gD", "lua vim.lsp.buf.declaration()", opts) - buf_set_keymap("n", "gd", "lua vim.lsp.buf.definition()", opts) - buf_set_keymap("n", "K", "lua vim.lsp.buf.hover()", opts) - buf_set_keymap("n", "gi", "lua vim.lsp.buf.implementation()", opts) - buf_set_keymap("n", "", "lua vim.lsp.buf.signature_help()", opts) - buf_set_keymap("n", "wa", "lua vim.lsp.buf.add_workspace_folder()", opts) - buf_set_keymap("n", "wr", "lua vim.lsp.buf.remove_workspace_folder()", opts) - buf_set_keymap("n", "wl", "lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))", opts) - buf_set_keymap("n", "D", "lua vim.lsp.buf.type_definition()", opts) - buf_set_keymap("n", "rn", "lua vim.lsp.buf.rename()", opts) - buf_set_keymap("n", "gr", "lua vim.lsp.buf.references()", opts) - buf_set_keymap("n", "e", "lua vim.lsp.diagnostic.show_line_diagnostics()", opts) - buf_set_keymap("n", "[d", "lua vim.lsp.diagnostic.goto_prev()", opts) - buf_set_keymap("n", "]d", "lua vim.lsp.diagnostic.goto_next()", opts) - buf_set_keymap("n", "q", "lua vim.lsp.diagnostic.set_loclist()", opts) + local lsp_keymap = utils.keymap_group("n", "l", opts, bufnr) + lsp_keymap("h", "lua vim.lsp.buf.hover()") + lsp_keymap("r", "lua vim.lsp.buf.rename()") + lsp_keymap("e", "lua vim.lsp.diagnostics.show_line_diagnostics()") - -- Open diagnostic on hold - if vim["diagnostic"] ~= nil then - vim.cmd([[autocmd CursorHold,CursorHoldI * lua vim.diagnostic.open_float(nil, {focus=false})]]) - end + buf_set_keymap("n", "gD", "lua vim.lsp.buf.declaration()", opts) + buf_set_keymap("n", "gd", "lua vim.lsp.buf.definition()", opts) + buf_set_keymap("n", "K", "lua vim.lsp.buf.hover()", opts) + buf_set_keymap("n", "gi", "lua vim.lsp.buf.implementation()", opts) + buf_set_keymap("n", "", "lua vim.lsp.buf.signature_help()", opts) + buf_set_keymap("n", "wa", "lua vim.lsp.buf.add_workspace_folder()", opts) + buf_set_keymap("n", "wr", "lua vim.lsp.buf.remove_workspace_folder()", opts) + buf_set_keymap("n", "wl", "lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))", opts) + buf_set_keymap("n", "D", "lua vim.lsp.buf.type_definition()", opts) + buf_set_keymap("n", "rn", "lua vim.lsp.buf.rename()", opts) + buf_set_keymap("n", "gr", "lua vim.lsp.buf.references()", opts) + buf_set_keymap("n", "e", "lua vim.lsp.diagnostic.show_line_diagnostics()", opts) + buf_set_keymap("n", "[d", "lua vim.lsp.diagnostic.goto_prev()", opts) + buf_set_keymap("n", "]d", "lua vim.lsp.diagnostic.goto_next()", opts) + buf_set_keymap("n", "q", "lua vim.lsp.diagnostic.set_loclist()", opts) - -- Set some keybinds conditional on server capabilities - if client.resolved_capabilities.document_formatting then - buf_set_keymap("n", "lf", "lua vim.lsp.buf.formatting()", opts) - vim.cmd([[ + -- Open diagnostic on hold + if vim["diagnostic"] ~= nil then + vim.cmd([[autocmd CursorHold,CursorHoldI * lua vim.diagnostic.open_float(nil, {focus=false})]]) + end + + -- Set some keybinds conditional on server capabilities + if client.resolved_capabilities.document_formatting then + buf_set_keymap("n", "lf", "lua vim.lsp.buf.formatting()", opts) + vim.cmd([[ augroup lsp_format autocmd! autocmd BufWritePre *.rs,*.go,*.sh lua vim.lsp.buf.formatting_sync(nil, 1000) " autocmd BufWritePre lua vim.lsp.buf.formatting_sync(nil, 1000) augroup END ]]) - end - if client.resolved_capabilities.document_range_formatting then - buf_set_keymap("n", "lfr", "lua vim.lsp.buf.range_formatting()", opts) - end + end + if client.resolved_capabilities.document_range_formatting then + buf_set_keymap("n", "lfr", "lua vim.lsp.buf.range_formatting()", opts) + end - -- Set autocommands conditional on server_capabilities - if client.resolved_capabilities.document_highlight then - vim.cmd([[ + -- Set autocommands conditional on server_capabilities + if client.resolved_capabilities.document_highlight then + vim.cmd([[ :hi LspReferenceRead cterm=bold ctermbg=red guibg=LightYellow :hi LspReferenceText cterm=bold ctermbg=red guibg=LightYellow :hi LspReferenceWrite cterm=bold ctermbg=red guibg=LightYellow @@ -119,24 +129,25 @@ local function default_attach(client, bufnr) autocmd CursorMoved lua vim.lsp.buf.clear_references() augroup END ]]) - end + end - -- Some override some fuzzy finder bindings to use lsp sources - if utils.try_require("telescope.nvim") ~= nil then - buf_set_keymap("n", "t", "Telescope lsp_document_symbols", opts) - buf_set_keymap("n", "ft", "Telescope lsp_dynamic_workspace_symbols", opts) - end + -- Some override some fuzzy finder bindings to use lsp sources + if utils.try_require("telescope.nvim") ~= nil then + buf_set_keymap("n", "t", "Telescope lsp_document_symbols", opts) + buf_set_keymap("n", "ft", "Telescope lsp_dynamic_workspace_symbols", opts) + end - -- Use LspSaga features, if possible - if utils.is_plugin_loaded("lspsaga.nvim") then - buf_set_keymap("n", "K", "lua require('lspsaga.hover').render_hover_doc()", opts) - buf_set_keymap("n", "rn", "lua require('lspsaga.rename').rename()", opts) - buf_set_keymap("n", "e", "lua require('lspsaga.diagnostic').show_line_diagnostics()", opts) - buf_set_keymap("n", "[d", "lua require('lspsaga.diagnostic').lsp_jump_diagnostic_prev()", opts) - buf_set_keymap("n", "]d", "lua require('lspsaga.diagnostic').lsp_jump_diagnostic_next()", opts) - buf_set_keymap("n", "", "lua require('lspsaga.signaturehelp').signature_help()", opts) - -- Code actions - buf_set_keymap("n", "ca", "lua require('lspsaga.codeaction').code_action()", opts) + -- Use LspSaga features, if possible + if utils.is_plugin_loaded("lspsaga.nvim") then + buf_set_keymap("n", "K", "lua require('lspsaga.hover').render_hover_doc()", opts) + buf_set_keymap("n", "rn", "lua require('lspsaga.rename').rename()", opts) + buf_set_keymap("n", "e", "lua require('lspsaga.diagnostic').show_line_diagnostics()", opts) + buf_set_keymap("n", "[d", "lua require('lspsaga.diagnostic').lsp_jump_diagnostic_prev()", opts) + buf_set_keymap("n", "]d", "lua require('lspsaga.diagnostic').lsp_jump_diagnostic_next()", opts) + buf_set_keymap("n", "", "lua require('lspsaga.signaturehelp').signature_help()", opts) + -- Code actions + buf_set_keymap("n", "ca", "lua require('lspsaga.codeaction').code_action()", opts) + end end end @@ -153,13 +164,19 @@ function M.config_lsp() utils.try_require("lspconfig", function(lsp_config) local capabilities = merged_capabilities() + -- Config null-ls + require("plugins.null-ls").configure({ capabilities = capabilities, on_attach = get_default_attach() }) + + -- Attach options to disable formatting + local no_format = { document_formatting = false, document_range_formatting = false } + -- Configure each server - lsp_config.bashls.setup({ capabilities = capabilities, on_attach = default_attach }) - lsp_config.gopls.setup({ capabilities = capabilities, on_attach = default_attach }) - lsp_config.pyright.setup({ capabilities = capabilities, on_attach = default_attach }) + lsp_config.bashls.setup({ capabilities = capabilities, on_attach = get_default_attach() }) + lsp_config.gopls.setup({ capabilities = capabilities, on_attach = get_default_attach(no_format) }) + lsp_config.pyright.setup({ capabilities = capabilities, on_attach = get_default_attach(no_format) }) lsp_config.rls.setup({ capabilities = capabilities, - on_attach = default_attach, + on_attach = get_default_attach(no_format), settings = { rust = { build_on_save = false, @@ -187,87 +204,13 @@ function M.config_lsp_saga() end) end -function M.config_null_ls() - utils.try_require("null-ls", function(null_ls) - local helpers = require("null-ls.helpers") - local alex_lint = { - name = "alex", - method = null_ls.methods.DIAGNOSTICS, - filetypes = { "markdown" }, - generator = null_ls.generator({ - command = "alex", - args = { "--stdin", "--quiet" }, - to_stdin = true, - from_stderr = true, - format = "line", - check_exit_code = function(code) - return code <= 1 - end, - on_output = helpers.diagnostics.from_patterns({ - { - pattern = [[ *(%d+):(%d+)-(%d+):(%d+) *(%w+) *(.+) +[%w]+ +([-%l]+)]], - groups = { "row", "col", "end_row", "end_col", "severity", "message", "code" }, - }, - }), - }), - } - - local sources = { - -- Generic - null_ls.builtins.formatting.prettier, - null_ls.builtins.formatting.trim_whitespace, - null_ls.builtins.formatting.trim_newlines, - -- Fish - null_ls.builtins.formatting.fish_indent, - -- Python - null_ls.builtins.formatting.reorder_python_imports, - null_ls.builtins.formatting.black, - null_ls.builtins.diagnostics.mypy, - -- Go - null_ls.builtins.diagnostics.golangci_lint, - -- Text - null_ls.builtins.diagnostics.proselint, - -- null_ls.builtins.diagnostics.write_good, - null_ls.builtins.code_actions.proselint, - alex_lint, - -- Ansible - null_ls.builtins.diagnostics.ansiblelint, - -- Shell - null_ls.builtins.diagnostics.shellcheck, - -- Rust - -- null_ls.builtins.formatting.rustfmt, - -- Lua - null_ls.builtins.diagnostics.luacheck, - null_ls.builtins.formatting.stylua, - -- Docker - null_ls.builtins.diagnostics.hadolint, - } - - -- HACK: Handle old versions of null_ls for vim < 0.6 that don't support `setup` - if null_ls["setup"] ~= nil then - null_ls.setup({ - on_attach = default_attach, - capabilities = merged_capabilities(), - sources = sources, - }) - else - null_ls.config({ - sources = sources, - }) - require("lspconfig")["null-ls"].setup({ - on_attach = default_attach, - }) - end - end) -end - local function get_luadev_config() local luadev = utils.try_require("lua-dev") if luadev ~= nil then return luadev.setup({ -- add any options here, or leave empty to use the default settings lspconfig = { - on_attach = default_attach, + on_attach = get_default_attach(), settings = { Lua = { completion = { @@ -287,7 +230,7 @@ function M.config_lsp_intaller() utils.try_require("nvim-lsp-installer", function(lsp_installer) -- Default options local opts = { - on_attach = default_attach, + on_attach = get_default_attach(), } lsp_installer.on_server_ready(function(server) diff --git a/neovim/lua/plugins/null-ls/init.lua b/neovim/lua/plugins/null-ls/init.lua new file mode 100644 index 0000000..7628d23 --- /dev/null +++ b/neovim/lua/plugins/null-ls/init.lua @@ -0,0 +1,58 @@ +local M = {} +local utils = require("utils") + +function M.configure(options) + utils.try_require("null-ls", function(null_ls) + -- Load newer versions of plugins + local alex = require("plugins.null-ls.linters").alex + local ansiblelint = require("plugins.null-ls.linters").ansiblelint + + -- Use ansiblelint for only ansible files + -- null_ls.builtins.diagnostics.ansiblelint.filetypes = { "yaml.ansible" } + + local sources = { + -- Generic + null_ls.builtins.formatting.prettier, + null_ls.builtins.formatting.trim_whitespace, + null_ls.builtins.formatting.trim_newlines, + -- Fish + null_ls.builtins.formatting.fish_indent, + -- Python + null_ls.builtins.formatting.reorder_python_imports, + null_ls.builtins.formatting.black, + null_ls.builtins.diagnostics.mypy, + -- Go + null_ls.builtins.diagnostics.golangci_lint, + null_ls.builtins.formatting.gofmt, + -- Text + null_ls.builtins.code_actions.proselint, + null_ls.builtins.diagnostics.proselint, + null_ls.builtins.diagnostics.write_good, + -- null_ls.builtins.diagnostics.alex + alex, + -- Ansible + -- null_ls.builtins.diagnostics.ansiblelint, + ansiblelint, + -- Shell + null_ls.builtins.diagnostics.shellcheck, + -- Rust + null_ls.builtins.formatting.rustfmt, + -- Lua + null_ls.builtins.diagnostics.luacheck, + null_ls.builtins.formatting.stylua, + -- Docker + null_ls.builtins.diagnostics.hadolint, + } + + if null_ls["setup"] ~= nil then + options.sources = sources + null_ls.setup(options) + else + -- HACK: Handle old versions of null_ls for vim < 0.6 that don't support `setup` + null_ls.config({ sources = sources }) + require("lspconfig")["null-ls"].setup(options) + end + end) +end + +return M diff --git a/neovim/lua/plugins/null-ls/linters.lua b/neovim/lua/plugins/null-ls/linters.lua new file mode 100644 index 0000000..bf1da46 --- /dev/null +++ b/neovim/lua/plugins/null-ls/linters.lua @@ -0,0 +1,71 @@ +local M = {} + +local null_ls = require("null-ls") +local helpers = require("null-ls.helpers") + +M.alex = { + name = "alex", + method = null_ls.methods.DIAGNOSTICS, + filetypes = { "markdown" }, + generator = null_ls.generator({ + command = "alex", + args = { "--stdin", "--quiet" }, + to_stdin = true, + from_stderr = true, + format = "line", + check_exit_code = function(code) + return code <= 1 + end, + on_output = helpers.diagnostics.from_patterns({ + { + pattern = [[ *(%d+):(%d+)-(%d+):(%d+) *(%w+) *(.+) +[%w]+ +([-%l]+)]], + groups = { "row", "col", "end_row", "end_col", "severity", "message", "code" }, + }, + }), + }), +} + +M.ansiblelint = { + name = "ansiblelint", + method = null_ls.methods.DIAGNOSTICS, + filetypes = { "yaml.ansible" }, + generator = null_ls.generator({ + command = "ansible-lint", + to_stdin = true, + ignore_stderr = true, + args = { "-f", "codeclimate", "-q", "--nocolor", "$FILENAME" }, + format = "json", + check_exit_code = function(code) + return code <= 2 + end, + multiple_files = true, + on_output = function(params) + local severities = { + blocker = helpers.diagnostics.severities.error, + critical = helpers.diagnostics.severities.error, + major = helpers.diagnostics.severities.error, + minor = helpers.diagnostics.severities.warning, + info = helpers.diagnostics.severities.information, + } + params.messages = {} + for _, message in ipairs(params.output) do + local col = nil + local row = message.location.lines.begin + if type(row) == "table" then + row = row.line + col = row.column + end + table.insert(params.messages, { + row = row, + col = col, + message = message.check_name, + severity = severities[message.severity], + filename = message.location.path, + }) + end + return params.messages + end, + }), +} + +return M diff --git a/neovim/plugin/lsp.lua b/neovim/plugin/lsp.lua index 48c0ffc..4fced0c 100644 --- a/neovim/plugin/lsp.lua +++ b/neovim/plugin/lsp.lua @@ -2,7 +2,6 @@ local utils = require("utils") local lsp_config = require("plugins.lsp") -- Configure my various lsp stuffs -lsp_config.config_null_ls() lsp_config.config_lsp_intaller() lsp_config.config_lsp() lsp_config.config_lsp_ui()