Autcmd to organize imports for Go files. Remove unused imports on save

This commit is contained in:
Rakshit Sinha 2025-01-08 11:29:11 -08:00
parent cee16e3352
commit 073e01a8b2
1 changed files with 74 additions and 50 deletions

View File

@ -1,14 +1,14 @@
return { return {
-- Main LSP Configuration -- Main LSP Configuration
'neovim/nvim-lspconfig', "neovim/nvim-lspconfig",
event = { 'BufReadPre', 'BufNewFile' }, event = { "BufReadPre", "BufNewFile" },
dependencies = { dependencies = {
-- Allows extra capabilities provided by nvim-cmp -- Allows extra capabilities provided by nvim-cmp
'hrsh7th/cmp-nvim-lsp', "hrsh7th/cmp-nvim-lsp",
-- Modify imports when a file has been renamed -- Modify imports when a file has been renamed
{ 'antosha417/nvim-lsp-file-operations', config = true }, { "antosha417/nvim-lsp-file-operations", config = true },
-- Improved LSP functionality when working with lua files -- Improved LSP functionality when working with lua files
{ 'folke/neodev.nvim', opts = {} }, { "folke/neodev.nvim", opts = {} },
-- Automatically install LSPs and related tools to stdpath for Neovim -- Automatically install LSPs and related tools to stdpath for Neovim
-- { 'williamboman/mason.nvim', config = true }, -- NOTE: Must be loaded before dependants -- { 'williamboman/mason.nvim', config = true }, -- NOTE: Must be loaded before dependants
@ -16,7 +16,7 @@ return {
-- Useful status updates for LSP. -- Useful status updates for LSP.
-- NOTE: `opts = {}` is the same as calling `require('fidget').setup({})` -- NOTE: `opts = {}` is the same as calling `require('fidget').setup({})`
{ 'j-hui/fidget.nvim', opts = {} }, { "j-hui/fidget.nvim", opts = {} },
}, },
config = function() config = function()
-- Brief aside: **What is LSP?** -- Brief aside: **What is LSP?**
@ -49,12 +49,12 @@ return {
-- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this -- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this
-- function will be executed to configure the current buffer -- function will be executed to configure the current buffer
-- import lspconfig plugin -- import lspconfig plugin
local lspconfig = require('lspconfig') local lspconfig = require("lspconfig")
local util = require('lspconfig/util') local util = require("lspconfig/util")
lspconfig.gopls.setup({ lspconfig.gopls.setup({
cmd = { 'gopls' }, cmd = { "gopls" },
filetypes = { 'go', 'gomod', 'gowork', 'gotmpl' }, filetypes = { "go", "gomod", "gowork", "gotmpl" },
root_dir = util.root_pattern('go.work', 'go.mod', '.git'), root_dir = util.root_pattern("go.work", "go.mod", ".git"),
settings = { settings = {
gopls = { gopls = {
completeUnimported = true, completeUnimported = true,
@ -67,64 +67,64 @@ return {
}) })
-- import mason_lspconfig plugin -- import mason_lspconfig plugin
local mason_lspconfig = require('mason-lspconfig') local mason_lspconfig = require("mason-lspconfig")
-- import cmp-nvim-lsp plugin -- import cmp-nvim-lsp plugin
local cmp_nvim_lsp = require('cmp_nvim_lsp') local cmp_nvim_lsp = require("cmp_nvim_lsp")
local keymap = vim.keymap local keymap = vim.keymap
vim.api.nvim_create_autocmd('LspAttach', { vim.api.nvim_create_autocmd("LspAttach", {
group = vim.api.nvim_create_augroup('UserLspConfig', {}), group = vim.api.nvim_create_augroup("UserLspConfig", {}),
callback = function(event) callback = function(event)
-- Buffer local mappings -- Buffer local mappings
-- See `:help vim.lsp.*` for documentation on ay of the below function -- See `:help vim.lsp.*` for documentation on ay of the below function
local opts = { buffer = event.buf, silent = true } local opts = { buffer = event.buf, silent = true }
-- set keybinds -- set keybinds
opts.desc = 'Show LSP references' opts.desc = "Show LSP references"
keymap.set('n', 'gR', '<cmd>Telescope lsp_references<CR>', opts) -- show definition, references keymap.set("n", "gR", "<cmd>Telescope lsp_references<CR>", opts) -- show definition, references
opts.desc = 'Go to declaration' opts.desc = "Go to declaration"
keymap.set('n', 'gD', vim.lsp.buf.declaration, opts) -- go to declaration keymap.set("n", "gD", vim.lsp.buf.declaration, opts) -- go to declaration
opts.desc = 'Show LSP definitions' opts.desc = "Show LSP definitions"
keymap.set('n', 'gd', '<cmd>Telescope lsp_definitions<CR>', opts) -- show lsp definitions keymap.set("n", "gd", "<cmd>Telescope lsp_definitions<CR>", opts) -- show lsp definitions
opts.desc = 'Show LSP implementations' opts.desc = "Show LSP implementations"
keymap.set('n', 'gi', '<cmd>Telescope lsp_implementations<CR>', opts) -- show lsp implementations keymap.set("n", "gi", "<cmd>Telescope lsp_implementations<CR>", opts) -- show lsp implementations
opts.desc = 'Show LSP type definitions' opts.desc = "Show LSP type definitions"
keymap.set('n', 'gt', '<cmd>Telescope lsp_type_definitions<CR>', opts) -- show lsp type definitions keymap.set("n", "gt", "<cmd>Telescope lsp_type_definitions<CR>", opts) -- show lsp type definitions
opts.desc = 'See available code actions' opts.desc = "See available code actions"
keymap.set({ 'n', 'v' }, '<leader>ca', vim.lsp.buf.code_action, opts) -- see available code actions, in visual mode will apply to selection keymap.set({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action, opts) -- see available code actions, in visual mode will apply to selection
opts.desc = 'Smart rename' opts.desc = "Smart rename"
keymap.set('n', '<leader>rn', vim.lsp.buf.rename, opts) -- smart rename keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts) -- smart rename
opts.desc = 'Show buffer diagnostics' opts.desc = "Show buffer diagnostics"
keymap.set('n', '<leader>D', '<cmd>Telescope diagnostics bufnr=0<CR>', opts) -- show diagnostics for file keymap.set("n", "<leader>D", "<cmd>Telescope diagnostics bufnr=0<CR>", opts) -- show diagnostics for file
opts.desc = 'Show line diagnostics' opts.desc = "Show line diagnostics"
keymap.set('n', '<leader>d', vim.diagnostic.open_float, opts) -- show diagnostics for line keymap.set("n", "<leader>d", vim.diagnostic.open_float, opts) -- show diagnostics for line
opts.desc = 'Go to previous diagnostic' opts.desc = "Go to previous diagnostic"
keymap.set('n', '[d', vim.diagnostic.goto_prev, opts) -- jump to previous diagnostic in buffer keymap.set("n", "[d", vim.diagnostic.goto_prev, opts) -- jump to previous diagnostic in buffer
opts.desc = 'Go to next diagnostic' opts.desc = "Go to next diagnostic"
keymap.set('n', ']d', vim.diagnostic.goto_next, opts) -- jump to next diagnostic in buffer keymap.set("n", "]d", vim.diagnostic.goto_next, opts) -- jump to next diagnostic in buffer
opts.desc = 'Show documentation for what is under cursor' opts.desc = "Show documentation for what is under cursor"
keymap.set('n', 'K', vim.lsp.buf.hover, opts) -- show documentation for what is under cursor keymap.set("n", "K", vim.lsp.buf.hover, opts) -- show documentation for what is under cursor
opts.desc = 'Restart LSP' opts.desc = "Restart LSP"
keymap.set('n', '<leader>rs', ':LspRestart<CR>', opts) -- mapping to restart lsp if necessary keymap.set("n", "<leader>rs", ":LspRestart<CR>", opts) -- mapping to restart lsp if necessary
end, end,
}) })
-- Configure Neovim tab settings for Go files [Go indendation] -- Configure Neovim tab settings for Go files [Go indendation]
vim.api.nvim_create_autocmd('FileType', { vim.api.nvim_create_autocmd("FileType", {
pattern = 'go', pattern = "go",
callback = function() callback = function()
vim.bo.expandtab = true -- Use spaces instead of tabs vim.bo.expandtab = true -- Use spaces instead of tabs
vim.bo.tabstop = 4 -- Display each tab as 4 spaces vim.bo.tabstop = 4 -- Display each tab as 4 spaces
@ -133,13 +133,37 @@ return {
end, end,
}) })
-- Organize imports on save. Also helps remove unused imports on save.
vim.api.nvim_create_autocmd("BufWritePre", {
pattern = "*.go",
callback = function()
local params = vim.lsp.util.make_range_params()
params.context = { only = { "source.organizeImports" } }
-- buf_request_sync defaults to a 1000ms timeout. Depending on your
-- machine and codebase, you may want longer. Add an additional
-- argument after params if you find that you have to write the file
-- twice for changes to be saved.
-- E.g., vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, 3000)
local result = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params)
for cid, res in pairs(result or {}) do
for _, r in pairs(res.result or {}) do
if r.edit then
local enc = (vim.lsp.get_client_by_id(cid) or {}).offset_encoding or "utf-16"
vim.lsp.util.apply_workspace_edit(r.edit, enc)
end
end
end
vim.lsp.buf.format({ async = false })
end,
})
local capabilities = cmp_nvim_lsp.default_capabilities() local capabilities = cmp_nvim_lsp.default_capabilities()
-- Change the Diagnostic symbols in the sign column (gutter) -- Change the Diagnostic symbols in the sign column (gutter)
-- (not in youtube nvim video) -- (not in youtube nvim video)
local signs = { Error = '', Warn = '', Hint = '󰠠 ', Info = '' } local signs = { Error = "", Warn = "", Hint = "󰠠 ", Info = "" }
for type, icon in pairs(signs) do for type, icon in pairs(signs) do
local hl = 'DiagnosticSign' .. type local hl = "DiagnosticSign" .. type
vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = '' }) vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = "" })
end end
mason_lspconfig.setup_handlers({ mason_lspconfig.setup_handlers({
@ -151,18 +175,18 @@ return {
end, end,
-- Language specific configuration for any individual language server. Lua in this case -- Language specific configuration for any individual language server. Lua in this case
['lua_ls'] = function() ["lua_ls"] = function()
-- configure lua server (with special settings) -- configure lua server (with special settings)
lspconfig['lua_ls'].setup({ lspconfig["lua_ls"].setup({
capabilities = capabilities, capabilities = capabilities,
settings = { settings = {
Lua = { Lua = {
-- make the language server recognize "vim" global -- make the language server recognize "vim" global
diagnostics = { diagnostics = {
globals = { 'vim' }, globals = { "vim" },
}, },
completion = { completion = {
callSnippet = 'Replace', callSnippet = "Replace",
}, },
}, },
}, },