From d2f1bf38edb6c97b58a1d14e0ae3e7017a7345e6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 20:59:55 +0000 Subject: [PATCH 1/2] Initial plan From 1c85a549af429a56dacf20372f4f26037f007e6b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 21:03:44 +0000 Subject: [PATCH 2/2] Migrate from ALE to Neovim LSP with completion and formatting Co-authored-by: yangr0 <51311097+yangr0@users.noreply.github.com> --- nvim/init.lua | 15 +-- nvim/lua/main/configs/ale.lua | 33 ------ nvim/lua/main/configs/lsp.lua | 183 ++++++++++++++++++++++++++++++++++ nvim/lua/main/init.lua | 2 +- nvim/lua/main/packer.lua | 18 +++- 5 files changed, 209 insertions(+), 42 deletions(-) delete mode 100644 nvim/lua/main/configs/ale.lua create mode 100644 nvim/lua/main/configs/lsp.lua diff --git a/nvim/init.lua b/nvim/init.lua index 4a9a066..48858c1 100644 --- a/nvim/init.lua +++ b/nvim/init.lua @@ -1,21 +1,22 @@ require("main") -- DEPENDENCIES --- neovim --- vimplug +-- neovim >= 0.8.0 -- python3 -- cargo --- flake8 --- black +-- Node.js (for some LSP servers) +-- pip -- INSTALL --- sudo pacman -S neovim python flake8 python-pip (arch) --- sudo apt install neovim python3 flake8 python3-pip (debian) +-- sudo pacman -S neovim python nodejs npm (arch) +-- sudo apt install neovim python3 nodejs npm python3-pip (debian) -- pip3 install --user black neovim -- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -- export PATH=$PATH:$HOME/.local/bin:$HOME/.cargo/bin --- rustup component add rust-analyzer +-- rustup component add rust-analyzer rustfmt clippy -- cargo install tree-sitter-cli -- git clone --depth=1 https://github.com/iinc0gnit0/dotfiles -- mkdir ~/.config -- cp -r dotfiles/nvim ~/.config +-- Open neovim and run :PackerSync to install plugins +-- LSP servers and formatters will be installed automatically via Mason diff --git a/nvim/lua/main/configs/ale.lua b/nvim/lua/main/configs/ale.lua deleted file mode 100644 index 2126187..0000000 --- a/nvim/lua/main/configs/ale.lua +++ /dev/null @@ -1,33 +0,0 @@ -vim.g.ale_use_neovim_diagnostics_api = 1 -vim.g.ale_completion_enabled = 1 -vim.g.ale_completion_autoimport = 1 -vim.g.ale_rust_cargo_use_clippy = 1 -vim.g.ale_set_loclist = 0 -vim.g.ale_set_highlights = 1 -vim.g.ale_python_flake8_options = "--ignore=W503,E501" -vim.g.rustfmt_autosave = 1 -vim.g.ale_c_parse_compile_commands = 1 -vim.g.ale_fix_on_save = 1 -vim.g.ale_set_balloons = 1 -vim.g.ale_linters_explicit = 1 -vim.g.ale_linters = { - ["rust"] = {"cargo", "analyzer"}, - ["python"] = {"flake8"}, - ["javascript"] = {"eslint"}, - ["javascriptreact"] = {"eslint"}, - ["typescript"] = {"eslint"}, - ["typescriptreact"] = {"eslint"}, - ["cpp"] = {"clangd"}, - ["terraform"] = {"checkov"} -} -vim.g.ale_fixers = { - ["*"] = {"remove_trailing_lines", "trim_whitespace"}, - ["rust"] = {"rustfmt"}, - ["python"] = {"black"}, - ["javascript"] = {"eslint"}, - ["javascriptreact"] = {"eslint"}, - ["typescript"] = {"eslint"}, - ["typescriptreact"] = {"eslint"}, - ["cpp"] = {"clangtidy", "clang-format"}, - ["terraform"] = {"terraform"} -} diff --git a/nvim/lua/main/configs/lsp.lua b/nvim/lua/main/configs/lsp.lua new file mode 100644 index 0000000..c0c4270 --- /dev/null +++ b/nvim/lua/main/configs/lsp.lua @@ -0,0 +1,183 @@ +-- Mason setup for managing LSP servers +require("mason").setup() +require("mason-lspconfig").setup({ + ensure_installed = { + "rust_analyzer", + "pyright", + "clangd", + "ts_ls", + "eslint", + "terraformls", + }, + automatic_installation = true, +}) + +-- Completion setup +local cmp = require("cmp") +local luasnip = require("luasnip") + +cmp.setup({ + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + mapping = cmp.mapping.preset.insert({ + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.abort(), + [''] = cmp.mapping.confirm({ 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 = cmp.config.sources({ + { name = 'nvim_lsp' }, + { name = 'luasnip' }, + }, { + { name = 'buffer' }, + { name = 'path' }, + }) +}) + +-- LSP capabilities for autocompletion +local capabilities = require('cmp_nvim_lsp').default_capabilities() + +-- LSP keybindings +local on_attach = function(client, bufnr) + local opts = { buffer = bufnr, noremap = true, silent = true } + + -- Keybindings + vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts) + vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts) + vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts) + vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts) + vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts) + vim.keymap.set('n', '', vim.lsp.buf.signature_help, opts) + vim.keymap.set('n', 'rn', vim.lsp.buf.rename, opts) + vim.keymap.set('n', 'ca', vim.lsp.buf.code_action, opts) + vim.keymap.set('n', 'f', function() vim.lsp.buf.format({ async = true }) end, opts) + vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts) + vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts) + vim.keymap.set('n', 'e', vim.diagnostic.open_float, opts) + vim.keymap.set('n', 'q', vim.diagnostic.setloclist, opts) +end + +-- Configure diagnostics +vim.diagnostic.config({ + virtual_text = true, + signs = true, + update_in_insert = false, + underline = true, + severity_sort = true, + float = { + border = 'rounded', + source = 'always', + }, +}) + +-- Diagnostic signs +local signs = { Error = "✘", Warn = "▲", Hint = "⚑", Info = "»" } +for type, icon in pairs(signs) do + local hl = "DiagnosticSign" .. type + vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl }) +end + +-- LSP server configurations +local lspconfig = require("lspconfig") + +-- Rust +lspconfig.rust_analyzer.setup({ + on_attach = on_attach, + capabilities = capabilities, + settings = { + ['rust-analyzer'] = { + cargo = { + allFeatures = true, + }, + checkOnSave = { + command = "clippy", + }, + }, + }, +}) + +-- Python +lspconfig.pyright.setup({ + on_attach = on_attach, + capabilities = capabilities, +}) + +-- C/C++ +lspconfig.clangd.setup({ + on_attach = on_attach, + capabilities = capabilities, +}) + +-- TypeScript/JavaScript +lspconfig.ts_ls.setup({ + on_attach = on_attach, + capabilities = capabilities, +}) + +-- ESLint +lspconfig.eslint.setup({ + on_attach = function(client, bufnr) + on_attach(client, bufnr) + -- Auto-fix on save + vim.api.nvim_create_autocmd("BufWritePre", { + buffer = bufnr, + command = "EslintFixAll", + }) + end, + capabilities = capabilities, +}) + +-- Terraform +lspconfig.terraformls.setup({ + on_attach = on_attach, + capabilities = capabilities, +}) + +-- Formatting setup with conform.nvim +require("conform").setup({ + formatters_by_ft = { + rust = { "rustfmt" }, + python = { "black" }, + javascript = { "eslint_d" }, + javascriptreact = { "eslint_d" }, + typescript = { "eslint_d" }, + typescriptreact = { "eslint_d" }, + cpp = { "clang_format" }, + c = { "clang_format" }, + terraform = { "terraform_fmt" }, + }, + format_on_save = { + timeout_ms = 500, + lsp_fallback = true, + }, +}) + +-- Also format on save for all files (trim whitespace, etc) +vim.api.nvim_create_autocmd("BufWritePre", { + pattern = "*", + callback = function(args) + require("conform").format({ bufnr = args.buf }) + end, +}) diff --git a/nvim/lua/main/init.lua b/nvim/lua/main/init.lua index 3903799..3472aa7 100644 --- a/nvim/lua/main/init.lua +++ b/nvim/lua/main/init.lua @@ -2,7 +2,7 @@ require("main.packer") require("main.set") require("main.autocmd") require("main.configs.ts") -require("main.configs.ale") +require("main.configs.lsp") require("main.configs.gruvbox") require("main.configs.lualine") require("main.configs.indent-blankline") diff --git a/nvim/lua/main/packer.lua b/nvim/lua/main/packer.lua index b081325..89a8d5d 100644 --- a/nvim/lua/main/packer.lua +++ b/nvim/lua/main/packer.lua @@ -16,7 +16,23 @@ require("packer").startup(function(use) "nvim-treesitter/nvim-treesitter", run = ":TSUpdate" }) - use("dense-analysis/ale") + + -- LSP Support + use("neovim/nvim-lspconfig") + use("williamboman/mason.nvim") + use("williamboman/mason-lspconfig.nvim") + + -- Autocompletion + use("hrsh7th/nvim-cmp") + use("hrsh7th/cmp-nvim-lsp") + use("hrsh7th/cmp-buffer") + use("hrsh7th/cmp-path") + use("L3MON4D3/LuaSnip") + use("saadparwaiz1/cmp_luasnip") + + -- Formatting + use("stevearc/conform.nvim") + use({ "ellisonleao/gruvbox.nvim", as = "gruvbox"