short abstract of my init.lua :
local use = require('packer').use
require('packer').startup(function()
use 'neovim/nvim-lspconfig' -- Collection of configurations for built-in LSP client
use 'hrsh7th/cmp-nvim-lsp'
use 'hrsh7th/cmp-buffer'
use 'hrsh7th/cmp-path'
use 'hrsh7th/cmp-cmdline'
use 'hrsh7th/nvim-cmp'
use 'hrsh7th/cmp-vsnip'
use 'hrsh7th/vim-vsnip'
use 'hrsh7th/cmp-nvim-lua'
use { 'nvim-treesitter/nvim-treesitter', run = { 'TSUpdate' } }
use 'nvim-treesitter/nvim-treesitter-textobjects'
end)
local nvim_lsp = require('lspconfig')
local on_attach = function(_client, bufnr)
vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
local opts = { noremap = true, silent = true }
-- vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', '<Cmd>lua vim.lsp.buf.declaration()<CR>', opts)
-- vim q
end
local cmp = require 'cmp'
cmp.setup({
snippet = {
-- REQUIRED - you must specify a snippet engine
expand = function(args)
vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
-- require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
-- require('snippy').expand_snippet(args.body) -- For `snippy` users.
-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
end,
},
window = {
completion = {
winhighlight = "Normal:Normal,FloatBorder:Pmenu,Search:None",
col_offset = -3,
side_padding = 0,
},
-- completion = cmp.config.window.bordered(),
-- documentation = cmp.config.window.bordered(),
},
formatting = {
fields = { "kind", "abbr", "menu" },
format = function(entry, vim_item)
if vim_item.kind == 'Color' and entry.completion_item.documentation then -- tailwind swatches
local _, _, r, g, b = string.find(entry.completion_item.documentation, '^rgb%((%d+), (%d+), (%d+)')
if r then
local color = string.format('%02x', r) .. string.format('%02x', g) .. string.format('%02x', b)
local group = 'Tw_' .. color
if vim.fn.hlID(group) < 1 then
vim.api.nvim_set_hl(0, group, { bg = '#' .. color })
-- vim.api.nvim_set_hl(0, CmpItemKindColor, {bg = '#' .. color})
end
local kind = require("lspkind").cmp_format({ mode = "symbol_text", maxwidth = 50 })(entry, vim_item)
local strings = vim.split(kind.kind, "%s", { trimempty = true })
kind.kind = " " .. (strings[1] or "") .. " "
kind.kind_hl_group = group
kind.menu = " (" .. (strings[2] or "") .. ")"
return kind
end
end
local kind = require("lspkind").cmp_format({ mode = "symbol_text", maxwidth = 50 })(entry, vim_item)
local strings = vim.split(kind.kind, "%s", { trimempty = true })
kind.kind = " " .. (strings[1] or "") .. " "
kind.menu = " (" .. (strings[2] or "") .. ")"
return kind
end,
},
mapping = cmp.mapping.preset.insert({
['<C-b>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.abort(),
['<CR>'] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
}),
sources = cmp.config.sources({
{ name = 'nvim_lsp' },
{ name = 'vsnip' }, -- For vsnip users.
{ name = 'nvim_lua' },
-- { name = 'luasnip' }, -- For luasnip users.
-- { name = 'ultisnips' }, -- For ultisnips users.
-- { name = 'snippy' }, -- For snippy users.
}, {
{ name = 'buffer' },
})
})
-- Set configuration for specific filetype.
--
cmp.setup.filetype('gitcommit', {
sources = cmp.config.sources({
{ name = 'cmp_git' }, -- You can specify the `cmp_git` source if you were installed it.
}, {
{ name = 'buffer' },
})
})
-- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline({ '/', '?' }, {
mapping = cmp.mapping.preset.cmdline(),
sources = {
{ name = 'buffer' }
}
})
-- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline(':', {
mapping = cmp.mapping.preset.cmdline(),
sources = cmp.config.sources({
{ name = 'path' }
}, {
{ name = 'cmdline' }
})
})
-- Set up lspconfig.
local capabilities = require('cmp_nvim_lsp').default_capabilities()
-- Enable the following language servers
local servers = { 'clangd', 'rust_analyzer', 'pyright', 'tsserver', 'hls', 'ocamllsp' }
for _, lsp in ipairs(servers) do
nvim_lsp[lsp].setup { on_attach = on_attach, capabilities = capabilities }
end
nvim_lsp['elixirls'].setup {
-- Unix
cmd = { os.getenv("HOME") .. "/elixir-ls/language_server.sh" },
on_attach = on_attach,
capabilities = capabilities
}
nvim_lsp['lua_ls'].setup {
on_attach = on_attach,
capabilities = capabilities,
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' },
},
-- Do not send telemetry data containing a randomized but unique identifier
telemetry = {
enable = false,
},
},
},
}
nvim_lsp.tailwindcss.setup({
capabilities = capabilities,
filetypes = { "html", "elixir", "eelixir", "heex" },
init_options = {
userLanguages = {
elixir = "html-eex",
eelixir = "html-eex",
heex = "html-eex",
},
},
settings = {
tailwindCSS = {
experimental = {
classRegex = {
'class[:]\\s*"([^"]*)"',
},
},
},
},
})
nvim_lsp.emmet_ls.setup({
-- on_attach = on_attach,
capabilities = capabilities,
filetypes = { 'html', 'typescriptreact', 'javascriptreact', 'css', 'sass', 'scss', 'less', 'elixir', 'eelixir', 'heex' },
init_options = {
userLanguages = {
elixir = "html-eex",
eelixir = "html-eex",
heex = "html-eex",
},
html = {
options = {
-- For possible options, see: https://github.com/emmetio/emmet/blob/master/src/config.ts#L79-L267
["bem.enabled"] = true,
},
},
}
})
require("lsp-colors").setup({
Error = "#db4b4b",
Warning = "#e0af68",
Information = "#0db9d7",
Hint = "#10B981"
})
require("trouble").setup()
require('nvim-lightbulb').update_lightbulb()
-- Map :Format to vim.lsp.buf.formatting()
vim.cmd([[ command! Format execute 'lua vim.lsp.buf.format({async = true})' ]])
-- Set completeopt to have a better completion experience
vim.o.completeopt = "menuone,noinsert"