@ -0,0 +1,116 @@ | |||||
local M = {} | |||||
function M.setup() | |||||
local has_words_before = function() | |||||
local line, col = unpack(vim.api.nvim_win_get_cursor(0)) | |||||
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match "%s" == nil | |||||
end | |||||
local luasnip = require("luasnip") | |||||
local cmp = require("cmp") | |||||
cmp.setup { | |||||
completion = { completeopt = "menu,menuone,noinsert", keyword_length = 1 }, | |||||
experimental = { native_menu = false, ghost_text = false }, | |||||
snippet = { | |||||
expand = function(args) | |||||
require("luasnip").lsp_expand(args.body) | |||||
end, | |||||
}, | |||||
formatting = { | |||||
format = function(entry, vim_item) | |||||
vim_item.menu = ({ | |||||
nvim_lsp = "[LSP]", | |||||
buffer = "[Buffer]", | |||||
luasnip = "[Snip]", | |||||
nvim_lua = "[Lua]", | |||||
treesitter = "[Treesitter]", | |||||
path = "[Path]", | |||||
})[entry.source.name] | |||||
return vim_item | |||||
end, | |||||
}, | |||||
mapping = { | |||||
["<C-k>"] = cmp.mapping(cmp.mapping.select_prev_item(), { "i", "c" }), | |||||
["<C-j>"] = cmp.mapping(cmp.mapping.select_next_item(), { "i", "c" }), | |||||
["<C-b>"] = cmp.mapping(cmp.mapping.scroll_docs(-4), { "i", "c" }), | |||||
["<C-f>"] = cmp.mapping(cmp.mapping.scroll_docs(4), { "i", "c" }), | |||||
["<C-Space>"] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }), | |||||
["<C-e>"] = cmp.mapping { i = cmp.mapping.close(), c = cmp.mapping.close() }, | |||||
["<CR>"] = cmp.mapping { | |||||
i = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Replace, select = false }, | |||||
c = function(fallback) | |||||
if cmp.visible() then | |||||
cmp.confirm { behavior = cmp.ConfirmBehavior.Replace, select = false } | |||||
else | |||||
fallback() | |||||
end | |||||
end, | |||||
}, | |||||
["<Tab>"] = cmp.mapping(function(fallback) | |||||
if cmp.visible() then | |||||
cmp.select_next_item() | |||||
elseif luasnip.expand_or_jumpable() then | |||||
luasnip.expand_or_jump() | |||||
elseif has_words_before() then | |||||
cmp.complete() | |||||
else | |||||
fallback() | |||||
end | |||||
end, { | |||||
"i", | |||||
"s", | |||||
"c", | |||||
}), | |||||
["<S-Tab>"] = 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", | |||||
"c", | |||||
}), | |||||
}, | |||||
sources = { | |||||
{ name = "nvim_lsp" }, | |||||
{ name = "treesitter" }, | |||||
{ name = "buffer" }, | |||||
{ name = "luasnip" }, | |||||
{ name = "nvim_lua" }, | |||||
{ name = "path" }, | |||||
-- { name = "spell" }, | |||||
-- { name = "emoji" }, | |||||
-- { name = "calc" }, | |||||
}, | |||||
window = { | |||||
documentation = { | |||||
border = { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, | |||||
winhighlight = "NormalFloat:NormalFloat,FloatBorder:TelescopeBorder", | |||||
}, | |||||
}, | |||||
} | |||||
-- Use buffer source for `/` | |||||
cmp.setup.cmdline("/", { | |||||
sources = { | |||||
{ name = "buffer" }, | |||||
}, | |||||
}) | |||||
-- Use cmdline & path source for ':' | |||||
cmp.setup.cmdline(":", { | |||||
sources = cmp.config.sources({ | |||||
{ name = "path" }, | |||||
}, { | |||||
{ name = "cmdline" }, | |||||
}), | |||||
}) | |||||
end | |||||
return M |
@ -0,0 +1,14 @@ | |||||
local M = {} | |||||
function M.setup() | |||||
local luasnip = require "luasnip" | |||||
luasnip.config.set_config { | |||||
history = false, | |||||
updateevents = "TextChanged,TextChangedI", | |||||
} | |||||
require("luasnip/loaders/from_vscode").load() | |||||
end | |||||
return M |
@ -0,0 +1,52 @@ | |||||
local M = {} | |||||
local servers = { | |||||
gopls = {}, | |||||
html = {}, | |||||
jsonls = {}, | |||||
pyright = {}, | |||||
tsserver = {}, | |||||
vimls = {}, | |||||
dartls = {}, | |||||
dockerls = {}, | |||||
intelephense = {}, | |||||
sqlls = {}, | |||||
volar = {}, | |||||
} | |||||
local function on_attach(client, bufnr) | |||||
-- Enable completion triggered by <C-X><C-O> | |||||
-- See `:help omnifunc` and `:help ins-completion` for more information. | |||||
vim.api.nvim_buf_set_option(bufnr, "omnifunc", "v:lua.vim.lsp.omnifunc") | |||||
-- Use LSP as the handler for formatexpr. | |||||
-- See `:help formatexpr` for more information. | |||||
vim.api.nvim_buf_set_option(0, "formatexpr", "v:lua.vim.lsp.formatexpr()") | |||||
-- Configure key mappings | |||||
require("lsp.keymaps").setup(client, bufnr) | |||||
end | |||||
local lsp_signature = require "lsp_signature" | |||||
lsp_signature.setup { | |||||
bind = true, | |||||
handler_opts = { | |||||
border = "rounded", | |||||
}, | |||||
} | |||||
local capabilities = require("cmp_nvim_lsp").update_capabilities(vim.lsp.protocol.make_client_capabilities()) | |||||
local opts = { | |||||
on_attach = on_attach, | |||||
capabilities = cababilities, | |||||
flags = { | |||||
debounce_text_changes = 150, | |||||
}, | |||||
} | |||||
function M.setup() | |||||
require("lsp.installer").setup(servers, opts) | |||||
end | |||||
return M |
@ -0,0 +1,26 @@ | |||||
local lsp_installer_servers = require "nvim-lsp-installer.servers" | |||||
local utils = require "utils" | |||||
local M = {} | |||||
function M.setup(servers, options) | |||||
for server_name, _ in pairs(servers) do | |||||
local server_available, server = lsp_installer_servers.get_server(server_name) | |||||
if server_available then | |||||
server:on_ready(function() | |||||
local opts = vim.tbl_deep_extend("force", options, servers[server.name] or {}) | |||||
server:setup(opts) | |||||
end) | |||||
if not server:is_installed() then | |||||
utils.info("Installing " .. server.name) | |||||
server:install() | |||||
end | |||||
else | |||||
utils.error(server) | |||||
end | |||||
end | |||||
end | |||||
return M |
@ -0,0 +1,36 @@ | |||||
local M = {} | |||||
local keymap = vim.api.nvim_set_keymap | |||||
local buf_keymap = vim.api.nvim_buf_set_keymap | |||||
local function keymappings(client, bufnr) | |||||
local opts = { noremap = true, silent = true } | |||||
-- Key mappings | |||||
vim.keymap.set("n", "K", vim.lsp.buf.hover, 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", function () vim.diagnostic.goto_prev({severity = vim.diagnostic.severity.ERROR}) end, opts) | |||||
vim.keymap.set("n", "]e", function () vim.diagnostic.goto_next({severity = vim.diagnostic.severity.ERROR}) end, opts) | |||||
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts) | |||||
vim.keymap.set("n", "K", vim.lsp.buf.code_action, opts) | |||||
vim.keymap.set("n", "<leader>of", vim.diagnostic.open_float, opts) | |||||
if client.resolved_capabilities.document_formatting then | |||||
vim.keymap.set("n", "<leader>ff", vim.lsp.buf.formatting, opts) | |||||
end | |||||
vim.keymap.set("n", "<leader>d", vim.lsp.buf.definition, opts) | |||||
vim.keymap.set("n", "<leader>D", vim.lsp.buf.declaration, opts) | |||||
vim.keymap.set("n", "<leader>h", vim.lsp.buf.signature_help, opts) | |||||
vim.keymap.set("n", "<leader>i", vim.lsp.buf.implementation, opts) | |||||
vim.keymap.set("n", "<leader>T", vim.lsp.buf.type_definition, opts) | |||||
end | |||||
function M.setup(client, bufnr) | |||||
keymappings(client, bufnr) | |||||
end | |||||
return M |
@ -0,0 +1,37 @@ | |||||
_G.dump = function(...) | |||||
print(vim.inspect(...)) | |||||
end | |||||
_G.prequire = function(...) | |||||
local status, lib = pcall(require, ...) | |||||
if status then | |||||
return lib | |||||
end | |||||
return nil | |||||
end | |||||
local M = {} | |||||
function M.t(str) | |||||
return vim.api.nvim_replace_termcodes(str, true, true, true) | |||||
end | |||||
function M.log(msg, hl, name) | |||||
name = name or "Neovim" | |||||
hl = hl or "Todo" | |||||
vim.api.nvim_echo({ { name .. ": ", hl }, { msg } }, true, {}) | |||||
end | |||||
function M.warn(msg, name) | |||||
vim.notify(msg, vim.log.levels.WARN, { title = name }) | |||||
end | |||||
function M.error(msg, name) | |||||
vim.notify(msg, vim.log.levels.ERROR, { title = name }) | |||||
end | |||||
function M.info(msg, name) | |||||
vim.notify(msg, vim.log.levels.INFO, { title = name }) | |||||
end | |||||
return M |