From 23fbc255a24cc306d07464945ac44f79a1694a83 Mon Sep 17 00:00:00 2001 From: Ricard Illa Date: Sat, 22 Jul 2023 00:33:57 +0200 Subject: [PATCH] feat: embrace neovim lsp --- home/neovim/default.nix | 20 ++- home/neovim/init.lua | 324 +++++++++++++++++++++++++++------------- 2 files changed, 236 insertions(+), 108 deletions(-) diff --git a/home/neovim/default.nix b/home/neovim/default.nix index ec5faf3..ba16a16 100644 --- a/home/neovim/default.nix +++ b/home/neovim/default.nix @@ -8,17 +8,27 @@ vimdiffAlias = true; withPython3 = true; extraPackages = with pkgs; [ + ansible-language-server + beancount-language-server black + docker-compose-language-service efm-langserver + gcc hlint - jq + ltex-ls + lua-language-server lua54Packages.luacheck - nixfmt + nixd + nixpkgs-fmt + nodePackages.dockerfile-language-server-nodejs nodePackages.pyright - pylint - ruff + ruff-lsp + shellcheck shfmt - stylua + sqlfluff + terraform-ls + tflint + vscode-langservers-extracted ]; extraPython3Packages = pyPkgs: with pyPkgs; [ pylint ]; plugins = [ pkgs.vimPlugins.packer-nvim ]; diff --git a/home/neovim/init.lua b/home/neovim/init.lua index bdc9c75..f8f2079 100644 --- a/home/neovim/init.lua +++ b/home/neovim/init.lua @@ -1,85 +1,90 @@ -- luacheck: globals vim require("packer").startup(function(use) - use("tpope/vim-sensible") + use("tpope/vim-sensible") - use("vimwiki/vimwiki") - use("freitass/todo.txt-vim") - use("ledger/vim-ledger") + use("vimwiki/vimwiki") + use("freitass/todo.txt-vim") + use("ledger/vim-ledger") - use("Shougo/deoplete.nvim") - use("dense-analysis/ale") + use("psliwka/vim-smoothie") - use("psliwka/vim-smoothie") + -- navigation + use("easymotion/vim-easymotion") + use("tpope/vim-unimpaired") + use("tpope/vim-surround") + use("christoomey/vim-tmux-navigator") - -- navigation - use("easymotion/vim-easymotion") - use("tpope/vim-unimpaired") - use("tpope/vim-surround") - use("christoomey/vim-tmux-navigator") + -- fern + use("lambdalisue/fern.vim") + use("lambdalisue/nerdfont.vim") + use("lambdalisue/fern-renderer-nerdfont.vim") + use("lambdalisue/glyph-palette.vim") + use("lambdalisue/fern-git-status.vim") + use("lambdalisue/fern-mapping-git.vim") -- to check + use("lambdalisue/fern-hijack.vim") - -- fern - use("lambdalisue/fern.vim") - use("lambdalisue/nerdfont.vim") - use("lambdalisue/fern-renderer-nerdfont.vim") - use("lambdalisue/glyph-palette.vim") - use("lambdalisue/fern-git-status.vim") - use("lambdalisue/fern-mapping-git.vim") -- to check - use("lambdalisue/fern-hijack.vim") + -- airline + use("vim-airline/vim-airline") + use("vim-airline/vim-airline-themes") - -- airline - use("vim-airline/vim-airline") - use("vim-airline/vim-airline-themes") + use("tpope/vim-fugitive") + use("airblade/vim-gitgutter") - use("tpope/vim-fugitive") - use("airblade/vim-gitgutter") + use("honza/vim-snippets") + use("SirVer/ultisnips") - use("honza/vim-snippets") - use("SirVer/ultisnips") + use("junegunn/fzf.vim") - use("junegunn/fzf.vim") + use("junegunn/goyo.vim") + use("junegunn/limelight.vim") - use("junegunn/goyo.vim") - use("junegunn/limelight.vim") + use("preservim/nerdcommenter") - use("preservim/nerdcommenter") + use("luochen1990/rainbow") + use("ap/vim-css-color") - use("luochen1990/rainbow") - use("ap/vim-css-color") + use("Yggdroot/indentLine") - use("Yggdroot/indentLine") + use("gruvbox-community/gruvbox") - use("gruvbox-community/gruvbox") + -- language support + use("darrikonn/vim-gofmt") + use("Glench/Vim-Jinja2-Syntax") + use("preservim/vim-markdown") + use("LnL7/vim-nix") + use("hashivim/vim-terraform") + use("LaTeX-Box-Team/LaTeX-Box") + use("vito-c/jq.vim") + use("tpope/vim-haml") + use({ "psf/black", branch = "stable" }) + use("elzr/vim-json") - -- language support - use("darrikonn/vim-gofmt") - use("Glench/Vim-Jinja2-Syntax") - use("preservim/vim-markdown") - use("LnL7/vim-nix") - use("hashivim/vim-terraform") - use("LaTeX-Box-Team/LaTeX-Box") - use("vito-c/jq.vim") - use("tpope/vim-haml") - use({ "psf/black", branch = "stable" }) - use("elzr/vim-json") - use("z0mbix/vim-shfmt") - use("ckipp01/stylua-nvim") + use("jpalardy/vim-slime") - use("jpalardy/vim-slime") - use("neovim/nvim-lspconfig") - use("lukas-reineke/lsp-format.nvim") + use("neovim/nvim-lspconfig") + use("hrsh7th/nvim-cmp") -- Autocompletion plugin + use("hrsh7th/cmp-nvim-lsp") -- LSP source for nvim-cmp + use("hrsh7th/cmp-buffer") + use("hrsh7th/cmp-path") + use("saadparwaiz1/cmp_luasnip") -- Snippets source for nvim-cmp + use("L3MON4D3/LuaSnip") -- Snippets plugin + use("lukas-reineke/lsp-format.nvim") - use("sheerun/vim-polyglot") + use("sheerun/vim-polyglot") + + use("nvim-treesitter/nvim-treesitter") + use("nvim-orgmode/orgmode") end) local o = vim.opt local function map(mode, shortcut, command) - vim.api.nvim_set_keymap(mode, shortcut, command, { noremap = true, silent = true }) + vim.api.nvim_set_keymap(mode, shortcut, command, { noremap = true, silent = true }) end local function nmap(shortcut, command) - map("n", shortcut, command) + map("n", shortcut, command) end --local function imap(shortcut, command) @@ -89,19 +94,19 @@ end o.wrap = false o.number = true o.compatible = false -o.mouse = "a" -- mouse support -o.showcmd = true -- show incomplete cmds down the bottom -o.showmode = true -- show current mode -o.showmatch = true -- set show matching parenthesis -o.visualbell = true -- no sounds -o.autoread = true -- reload files changed outside of vim +o.mouse = "a" -- mouse support +o.showcmd = true -- show incomplete cmds down the bottom +o.showmode = true -- show current mode +o.showmatch = true -- set show matching parenthesis +o.visualbell = true -- no sounds +o.autoread = true -- reload files changed outside of vim o.backspace = [[indent,eol,start]] -- allow backspacing over everything in insert mode -o.ignorecase = true -- ignore case when searching -o.shiftround = true -- use multiple of shiftwidth when indenting with '<' and '>' -o.smartcase = true -- ignore case if searching pattern is all lowecase, case-sensitive otherwise -o.smarttab = true -- insert tabs on the start of a line according to shiftwidth, not tabstop -o.hlsearch = true -- highlight search terms -o.incsearch = true -- show search matches as you type +o.ignorecase = true -- ignore case when searching +o.shiftround = true -- use multiple of shiftwidth when indenting with '<' and '>' +o.smartcase = true -- ignore case if searching pattern is all lowecase, case-sensitive otherwise +o.smarttab = true -- insert tabs on the start of a line according to shiftwidth, not tabstop +o.hlsearch = true -- highlight search terms +o.incsearch = true -- show search matches as you type o.hidden = true o.ruler = true o.clipboard = "unnamed" -- system clipboard @@ -111,9 +116,9 @@ vim.cmd("syntax on") vim.cmd("filetype plugin on") if vim.fn.has("multi_byte") == 1 and vim.o.encoding == "utf-8" then - o.listchars = [[tab:▸ ,extends:❯,precedes:❮,nbsp:±,trail:…]] + o.listchars = [[tab:▸ ,extends:❯,precedes:❮,nbsp:±,trail:…]] else - o.listchars = [[tab:> ,extends:>,precedes:<,nbsp:.,trail:_]] + o.listchars = [[tab:> ,extends:>,precedes:<,nbsp:.,trail:_]] end vim.g.mapleader = "," @@ -192,7 +197,7 @@ augroup my-glyph-palette augroup END ]]) nmap("t", ":Fern . -drawer -toggle") -nmap("f", ":Files") +-- nmap("f", ":Files") nmap("rg", ":Rg") nmap("", ": cd ..") nmap("b", ": Buffers") @@ -213,50 +218,163 @@ vim.g["airline_theme"] = "base16_gruvbox_dark_hard" vim.g["airline#extensions#tabline#enabled"] = 1 vim.g["airline#extensions#ale#enabled"] = 1 -vim.g["ale_lint_on_text_changed"] = "never" -vim.g["ale_lint_on_insert_leave"] = 0 -vim.g["ale_lint_on_enter"] = 0 - vim.g["deoplete#enable_at_startup"] = 1 --- vim.g["black_virtualenv"] = "/Users/rilla/virtualenvs/black" - -vim.g["shfmt_extra_args"] = "-i 4" vim.g["NERDDefaultAlign"] = "left" vim.g["UltiSnipsExpandTrigger"] = "" vim.g["UltiSnipsJumpForwardTrigger"] = "" vim.g["UltiSnipsJumpBackwardTrigger"] = "" -local formatters = { - go = ":GoFmt", - json = ":%!jq --indent 4 .", - nix = ":%!nixfmt < %", - -- python = ":Black", - python = [[lua vim.lsp.buf.format()]], - sh = ":Shfmt", - sql = ":%!sqlfluff fix -", - terraform = ":TerraformFmt", - lua = [[lua require("stylua-nvim").format_file()]], +local lspconfig = require("lspconfig") +local capabilities = require("cmp_nvim_lsp").default_capabilities() + +lspconfig.pyright.setup { capabilities = capabilities } +lspconfig.ruff_lsp.setup { capabilities = capabilities } + +lspconfig.nixd.setup { capabilities = capabilities } +lspconfig.jsonls.setup { capabilities = capabilities } +lspconfig.ansiblels.setup { capabilities = capabilities } +lspconfig.beancount.setup { capabilities = capabilities } +lspconfig.ltex.setup { capabilities = capabilities } + +lspconfig.terraformls.setup { capabilities = capabilities } +lspconfig.tflint.setup { capabilities = capabilities } + +lspconfig.docker_compose_language_service.setup { + root_dir = lspconfig.util.root_pattern("docker-compose.yaml", "docker-compose.yml"), + filetypes = { "yaml", "yaml.docker-compose" }, + capabilities = capabilities, +} +lspconfig.dockerls.setup { capabilities = capabilities } + +-- lspconfig.sqlls.setup {capabilities = capabilities} + +lspconfig.lua_ls.setup { + settings = { + Lua = { + runtime = { + -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) + version = "LuaJIT", + }, + diagnostics = { + -- Get the language server to recognize the `vim` global + globals = { "vim" }, + }, + workspace = { + -- Make the server aware of Neovim runtime files + library = vim.api.nvim_get_runtime_file("", true), + }, + -- Do not send telemetry data containing a randomized but unique identifier + telemetry = { + enable = false, + }, + }, + }, + capabilities = capabilities } -for pattern, command in pairs(formatters) do - vim.api.nvim_create_autocmd("FileType", { - pattern = pattern, - callback = function() - nmap("", command) - end, - }) -end +lspconfig.efm.setup { + init_options = { documentFormatting = true }, + filetypes = { "python", "sh" }, + settings = { + rootMarkers = { ".git/", "pyproject.toml" }, + languages = { + python = { { formatCommand = "black -", formatStdin = true } }, + sql = { { + formatCommand = "sqlfluff fix --dialect bigquery -", + formatStdin = true + } }, + sh = { { + formatCommand = "shfmt -i 4 -bn -sr -p -ci", + formatStdin = true, + lintCommand = "shellcheck -f gcc -x", + lintSource = "shellcheck", + lintFormats = { + "%f:%l:%c: %trror: %m", + "%f:%l:%c: %tarning: %m", + "%f:%l:%c: %tote: %m", + } + } }, + }, + }, + capabilities = capabilities +} -require("lspconfig").pyright.setup({}) +local luasnip = require 'luasnip' +local cmp = require 'cmp' +cmp.setup { + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + mapping = cmp.mapping.preset.insert({ + [''] = cmp.mapping.scroll_docs(-4), -- Up + [''] = cmp.mapping.scroll_docs(4), -- Down + -- C-b (back) C-f (forward) for snippet placeholder navigation. + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.confirm { + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }, + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + else + fallback() + end + end, { 'i', 's' }), + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { 'i', 's' }), + }), + sources = { + { name = 'nvim_lsp' }, + { name = 'luasnip' }, + { name = 'buffer' }, + { name = 'path' }, + { name = 'orgmode' }, + }, +} -require("lspconfig").efm.setup({ - init_options = { documentFormatting = true }, - settings = { - rootMarkers = { ".git/", "pyproject.toml" }, - languages = { - python = { { formatCommand = "black -", formatStdin = true } }, - }, - }, +local orgmode = require("orgmode") + +orgmode.setup_ts_grammar() +require("nvim-treesitter.configs").setup { + -- If TS highlights are not enabled at all, or disabled via `disable` prop, + -- highlighting will fallback to default Vim syntax highlighting + highlight = { + enable = true, + -- Required for spellcheck, some LaTex highlights and + -- code block highlights that do not have ts grammar + additional_vim_regex_highlighting = { "org" }, + }, + ensure_installed = { "org" }, -- Or run :TSUpdate org +} + +orgmode.setup { + org_agenda_files = { "~/Nextcloud/org/*" }, + org_default_notes_file = "~/Nextcloud/org/refile.org", +} + +vim.api.nvim_create_autocmd("LspAttach", { + group = vim.api.nvim_create_augroup("UserLspConfig", {}), + callback = function(ev) + -- Enable completion triggered by + vim.bo[ev.buf].omnifunc = "v:lua.vim.lsp.omnifunc" + + local opts = { buffer = ev.buf } + vim.keymap.set("n", "", function() + vim.lsp.buf.format({ async = true }) + end, opts) + end, })