1-- Dev core
2-- Things that are just there.
3
4-- Sections:
5-- ## TREE SITTER
6-- -> nvim-treesitter [syntax highlight]
7-- -> nvim-ts-autotag [treesitter understand html tags]
8-- -> ts-comments.nvim [treesitter comments]
9-- -> nvim-colorizer [hex colors]
10
11-- ## LSP
12-- -> nvim-java [java support]
13-- -> mason-lspconfig [auto start lsp]
14-- -> nvim-lspconfig [lsp configs]
15-- -> mason.nvim [lsp package manager]
16-- -> SchemaStore.nvim [mason extra schemas]
17-- -> none-ls-autoload.nvim [mason package loader]
18-- -> none-ls [lsp code formatting]
19-- -> neodev [lsp for nvim lua api]
20-- -> garbage-day [lsp garbage collector]
21
22-- ## AUTO COMPLETION
23-- -> nvim-cmp [auto completion engine]
24-- -> cmp-nvim-buffer [auto completion buffer]
25-- -> cmp-nvim-path [auto completion path]
26-- -> cmp-nvim-lsp [auto completion lsp]
27-- -> cmp-luasnip [auto completion snippets]
28
29local utils = require("base.utils")
30local utils_lsp = require("base.utils.lsp")
31
32return {
33 -- TREE SITTER ---------------------------------------------------------
34 -- [syntax highlight] + [treesitter understand html tags] + [comments]
35 -- https://github.com/nvim-treesitter/nvim-treesitter
36 -- https://github.com/windwp/nvim-ts-autotag
37 -- https://github.com/windwp/nvim-treesitter-textobjects
38 {
39 "nvim-treesitter/nvim-treesitter",
40 dependencies = {
41 "windwp/nvim-ts-autotag",
42 "nvim-treesitter/nvim-treesitter-textobjects",
43 },
44 event = "User BaseDefered",
45 cmd = {
46 "TSBufDisable",
47 "TSBufEnable",
48 "TSBufToggle",
49 "TSDisable",
50 "TSEnable",
51 "TSToggle",
52 "TSInstall",
53 "TSInstallInfo",
54 "TSInstallSync",
55 "TSModuleInfo",
56 "TSUninstall",
57 "TSUpdate",
58 "TSUpdateSync",
59 },
60 build = ":TSUpdate",
61 init = function(plugin)
62 -- perf: make treesitter queries available at startup.
63 require("lazy.core.loader").add_to_rtp(plugin)
64 require("nvim-treesitter.query_predicates")
65 end,
66 opts = {
67 auto_install = false, -- Currently bugged. Use [:TSInstall all] and [:TSUpdate all]
68 autotag = { enable = true },
69 highlight = {
70 enable = true,
71 disable = function(_, bufnr)
72 local excluded_filetypes = {} -- disabled for
73 local is_disabled = vim.tbl_contains(
74 excluded_filetypes, vim.bo.filetype) or utils.is_big_file(bufnr)
75 return is_disabled
76 end,
77 },
78 matchup = {
79 enable = true,
80 enable_quotes = true,
81 disable = function(_, bufnr)
82 local excluded_filetypes = {} -- disabled for
83 local is_disabled = vim.tbl_contains(
84 excluded_filetypes, vim.bo.filetype) or utils.is_big_file(bufnr)
85 return is_disabled
86 end,
87 },
88 incremental_selection = { enable = true },
89 indent = { enable = true },
90 textobjects = {
91 select = {
92 enable = true,
93 lookahead = true,
94 keymaps = {
95 ["ak"] = { query = "@block.outer", desc = "around block" },
96 ["ik"] = { query = "@block.inner", desc = "inside block" },
97 ["ac"] = { query = "@class.outer", desc = "around class" },
98 ["ic"] = { query = "@class.inner", desc = "inside class" },
99 ["a?"] = { query = "@conditional.outer", desc = "around conditional" },
100 ["i?"] = { query = "@conditional.inner", desc = "inside conditional" },
101 ["af"] = { query = "@function.outer", desc = "around function " },
102 ["if"] = { query = "@function.inner", desc = "inside function " },
103 ["al"] = { query = "@loop.outer", desc = "around loop" },
104 ["il"] = { query = "@loop.inner", desc = "inside loop" },
105 ["aa"] = { query = "@parameter.outer", desc = "around argument" },
106 ["ia"] = { query = "@parameter.inner", desc = "inside argument" },
107 },
108 },
109 move = {
110 enable = true,
111 set_jumps = true,
112 goto_next_start = {
113 ["]k"] = { query = "@block.outer", desc = "Next block start" },
114 ["]f"] = { query = "@function.outer", desc = "Next function start" },
115 ["]a"] = { query = "@parameter.inner", desc = "Next parameter start" },
116 },
117 goto_next_end = {
118 ["]K"] = { query = "@block.outer", desc = "Next block end" },
119 ["]F"] = { query = "@function.outer", desc = "Next function end" },
120 ["]A"] = { query = "@parameter.inner", desc = "Next parameter end" },
121 },
122 goto_previous_start = {
123 ["[k"] = { query = "@block.outer", desc = "Previous block start" },
124 ["[f"] = { query = "@function.outer", desc = "Previous function start" },
125 ["[a"] = { query = "@parameter.inner", desc = "Previous parameter start" },
126 },
127 goto_previous_end = {
128 ["[K"] = { query = "@block.outer", desc = "Previous block end" },
129 ["[F"] = { query = "@function.outer", desc = "Previous function end" },
130 ["[A"] = { query = "@parameter.inner", desc = "Previous parameter end" },
131 },
132 },
133 swap = {
134 enable = true,
135 swap_next = {
136 [">K"] = { query = "@block.outer", desc = "Swap next block" },
137 [">F"] = { query = "@function.outer", desc = "Swap next function" },
138 [">A"] = { query = "@parameter.inner", desc = "Swap next parameter" },
139 },
140 swap_previous = {
141 ["<K"] = { query = "@block.outer", desc = "Swap previous block" },
142 ["<F"] = { query = "@function.outer", desc = "Swap previous function" },
143 ["<A"] = { query = "@parameter.inner", desc = "Swap previous parameter" },
144 },
145 },
146 },
147 },
148 },
149
150 -- ts-comments.nvim [treesitter comments]
151 -- https://github.com/folke/ts-comments.nvim
152 -- This plugin can be safely removed after nvim 0.11 is released.
153 {
154 "folke/ts-comments.nvim",
155 event = "User BaseFile",
156 enabled = vim.fn.has("nvim-0.10.0") == 1,
157 opts = {},
158 },
159
160 -- [hex colors]
161 -- https://github.com/NvChad/nvim-colorizer.lua
162 {
163 "NvChad/nvim-colorizer.lua",
164 event = "User BaseFile",
165 cmd = {
166 "ColorizerToggle",
167 "ColorizerAttachToBuffer",
168 "ColorizerDetachFromBuffer",
169 "ColorizerReloadAllBuffers",
170 },
171 opts = { user_default_options = { names = false } },
172 },
173
174 -- LSP -------------------------------------------------------------------
175
176 -- nvim-java [java support]
177 -- https://github.com/nvim-java/nvim-java
178 -- Reliable jdtls support. Must go before mason-lspconfig and lsp-config.
179 {
180 "nvim-java/nvim-java",
181 ft = { "java" },
182 dependencies = {
183 "nvim-java/lua-async-await",
184 'nvim-java/nvim-java-refactor',
185 "nvim-java/nvim-java-core",
186 "nvim-java/nvim-java-test",
187 "nvim-java/nvim-java-dap",
188 "MunifTanjim/nui.nvim",
189 "neovim/nvim-lspconfig",
190 "mfussenegger/nvim-dap",
191 "williamboman/mason.nvim",
192 },
193 opts = {
194 notifications = {
195 dap = false,
196 },
197 -- NOTE: One of these files must be in your project root directory.
198 -- Otherwise the debugger will end in the wrong directory and fail.
199 root_markers = {
200 'settings.gradle',
201 'settings.gradle.kts',
202 'pom.xml',
203 'build.gradle',
204 'mvnw',
205 'gradlew',
206 'build.gradle',
207 'build.gradle.kts',
208 '.git',
209 },
210 },
211 },
212
213 -- nvim-lspconfig [lsp configs]
214 -- https://github.com/neovim/nvim-lspconfig
215 -- This plugin provide default configs for the lsp servers available on mason.
216 {
217 "neovim/nvim-lspconfig",
218 event = "User BaseFile",
219 dependencies = "nvim-java/nvim-java",
220 },
221
222 -- mason-lspconfig [auto start lsp]
223 -- https://github.com/williamboman/mason-lspconfig.nvim
224 -- This plugin auto starts the lsp servers installed by Mason
225 -- every time Neovim trigger the event FileType.
226 {
227 "williamboman/mason-lspconfig.nvim",
228 dependencies = { "neovim/nvim-lspconfig" },
229 event = "User BaseFile",
230 opts = function(_, opts)
231 if not opts.handlers then opts.handlers = {} end
232 opts.handlers[1] = function(server) utils_lsp.setup(server) end
233 end,
234 config = function(_, opts)
235 require("mason-lspconfig").setup(opts)
236 utils_lsp.apply_default_lsp_settings() -- Apply our default lsp settings.
237 utils.trigger_event("FileType") -- This line starts this plugin.
238 end,
239 },
240
241 -- mason [lsp package manager]
242 -- https://github.com/williamboman/mason.nvim
243 -- https://github.com/zeioth/mason-extra-cmds
244 {
245 "williamboman/mason.nvim",
246 dependencies = { "zeioth/mason-extra-cmds", opts = {} },
247 cmd = {
248 "Mason",
249 "MasonInstall",
250 "MasonUninstall",
251 "MasonUninstallAll",
252 "MasonLog",
253 "MasonUpdate",
254 "MasonUpdateAll", -- this cmd is provided by mason-extra-cmds
255 },
256 opts = {
257 registries = {
258 "github:nvim-java/mason-registry",
259 "github:mason-org/mason-registry",
260 },
261 ui = {
262 icons = {
263 package_installed = "✓",
264 package_uninstalled = "✗",
265 package_pending = "⟳",
266 },
267 },
268 }
269 },
270
271 -- Schema Store [mason extra schemas]
272 -- https://github.com/b0o/SchemaStore.nvim
273 "b0o/SchemaStore.nvim",
274
275 -- none-ls-autoload.nvim [mason package loader]
276 -- https://github.com/zeioth/mason-none-ls.nvim
277 -- This plugin auto starts the packages installed by Mason
278 -- every time Neovim trigger the event FileType ().
279 -- By default it will use none-ls builtin sources.
280 -- But you can add external sources if a mason package has no builtin support.
281 {
282 "zeioth/none-ls-autoload.nvim",
283 event = "User BaseFile",
284 dependencies = {
285 "williamboman/mason.nvim",
286 "zeioth/none-ls-external-sources.nvim"
287 },
288 opts = {
289 -- Here you can add support for sources not oficially suppored by none-ls.
290 external_sources = {
291 -- diagnostics
292 'none-ls-external-sources.diagnostics.cpplint',
293 'none-ls-external-sources.diagnostics.eslint',
294 'none-ls-external-sources.diagnostics.eslint_d',
295 'none-ls-external-sources.diagnostics.flake8',
296 'none-ls-external-sources.diagnostics.luacheck',
297 'none-ls-external-sources.diagnostics.psalm',
298 'none-ls-external-sources.diagnostics.shellcheck',
299 'none-ls-external-sources.diagnostics.yamllint',
300
301 -- formatting
302 'none-ls-external-sources.formatting.autopep8',
303 'none-ls-external-sources.formatting.beautysh',
304 'none-ls-external-sources.formatting.easy-coding-standard',
305 'none-ls-external-sources.formatting.eslint',
306 'none-ls-external-sources.formatting.eslint_d',
307 'none-ls-external-sources.formatting.jq',
308 'none-ls-external-sources.formatting.latexindent',
309 'none-ls-external-sources.formatting.reformat_gherkin',
310 'none-ls-external-sources.formatting.rustfmt',
311 'none-ls-external-sources.formatting.standardrb',
312 'none-ls-external-sources.formatting.yq',
313 },
314 },
315 },
316
317 -- none-ls [lsp code formatting]
318 -- https://github.com/nvimtools/none-ls.nvim
319 {
320 "nvimtools/none-ls.nvim",
321 event = "User BaseFile",
322 opts = function()
323 local builtin_sources = require("null-ls").builtins
324
325 -- You can customize your 'builtin sources' and 'external sources' here.
326 builtin_sources.formatting.shfmt.with({
327 command = "shfmt",
328 args = { "-i", "2", "-filename", "$FILENAME" },
329 })
330
331 -- Attach the user lsp mappings to every none-ls client.
332 return { on_attach = utils_lsp.apply_user_lsp_mappings }
333 end
334 },
335
336 -- neodev.nvim [lsp for nvim lua api]
337 -- https://github.com/folke/neodev.nvim
338 {
339 "folke/neodev.nvim",
340 ft = { "lua" },
341 opts = {}
342 },
343
344 -- garbage-day.nvim [lsp garbage collector]
345 -- https://github.com/zeioth/garbage-day.nvim
346 {
347 "zeioth/garbage-day.nvim",
348 event = "User BaseFile",
349 opts = {
350 aggressive_mode = false,
351 excluded_lsp_clients = {
352 "null-ls", "jdtls", "marksman"
353 },
354 grace_period = (60 * 15),
355 wakeup_delay = 3000,
356 notifications = false,
357 retries = 3,
358 timeout = 1000,
359 }
360 },
361
362 -- AUTO COMPLETION --------------------------------------------------------
363 -- Auto completion engine [autocompletion engine]
364 -- https://github.com/hrsh7th/nvim-cmp
365 {
366 "hrsh7th/nvim-cmp",
367 dependencies = {
368 "saadparwaiz1/cmp_luasnip",
369 "hrsh7th/cmp-buffer",
370 "hrsh7th/cmp-path",
371 "hrsh7th/cmp-nvim-lsp"
372 },
373 event = "InsertEnter",
374 opts = function()
375 -- ensure dependencies exist
376 local cmp = require("cmp")
377 local luasnip = require("luasnip")
378 local lspkind = require("lspkind")
379
380 -- border opts
381 local border_opts = {
382 border = "rounded",
383 winhighlight = "Normal:NormalFloat,FloatBorder:FloatBorder,CursorLine:PmenuSel,Search:None",
384 }
385
386 -- helper
387 local function has_words_before()
388 local line, col = unpack(vim.api.nvim_win_get_cursor(0))
389 return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match "%s" == nil
390 end
391
392 return {
393 enabled = function() -- disable in certain cases on dap.
394 local is_prompt = vim.bo.buftype == "prompt"
395 local is_dap_prompt = utils.is_available("cmp-dap")
396 and vim.tbl_contains(
397 { "dap-repl", "dapui_watches", "dapui_hover" }, vim.bo.filetype)
398 if is_prompt and not is_dap_prompt then
399 return false
400 else
401 return vim.g.cmp_enabled
402 end
403 end,
404 preselect = cmp.PreselectMode.None,
405 formatting = {
406 fields = { "kind", "abbr", "menu" },
407 format = lspkind.cmp_format(utils.get_plugin_opts("lspkind.nvim")),
408 },
409 snippet = {
410 expand = function(args) luasnip.lsp_expand(args.body) end,
411 },
412 duplicates = {
413 nvim_lsp = 1,
414 luasnip = 1,
415 cmp_tabnine = 1,
416 buffer = 1,
417 path = 1,
418 },
419 confirm_opts = {
420 behavior = cmp.ConfirmBehavior.Replace,
421 select = false,
422 },
423 window = {
424 completion = cmp.config.window.bordered(border_opts),
425 documentation = cmp.config.window.bordered(border_opts),
426 },
427 mapping = {
428 ["<PageUp>"] = cmp.mapping.select_prev_item {
429 behavior = cmp.SelectBehavior.Select,
430 count = 8,
431 },
432 ["<PageDown>"] = cmp.mapping.select_next_item {
433 behavior = cmp.SelectBehavior.Select,
434 count = 8,
435 },
436 ["<C-PageUp>"] = cmp.mapping.select_prev_item {
437 behavior = cmp.SelectBehavior.Select,
438 count = 16,
439 },
440 ["<C-PageDown>"] = cmp.mapping.select_next_item {
441 behavior = cmp.SelectBehavior.Select,
442 count = 16,
443 },
444 ["<S-PageUp>"] = cmp.mapping.select_prev_item {
445 behavior = cmp.SelectBehavior.Select,
446 count = 16,
447 },
448 ["<S-PageDown>"] = cmp.mapping.select_next_item {
449 behavior = cmp.SelectBehavior.Select,
450 count = 16,
451 },
452 ["<Up>"] = cmp.mapping.select_prev_item {
453 behavior = cmp.SelectBehavior.Select,
454 },
455 ["<Down>"] = cmp.mapping.select_next_item {
456 behavior = cmp.SelectBehavior.Select,
457 },
458 ["<C-p>"] = cmp.mapping.select_prev_item {
459 behavior = cmp.SelectBehavior.Insert,
460 },
461 ["<C-n>"] = cmp.mapping.select_next_item {
462 behavior = cmp.SelectBehavior.Insert,
463 },
464 ["<C-k>"] = cmp.mapping.select_prev_item {
465 behavior = cmp.SelectBehavior.Insert,
466 },
467 ["<C-j>"] = cmp.mapping.select_next_item {
468 behavior = cmp.SelectBehavior.Insert,
469 },
470 ["<C-u>"] = cmp.mapping(cmp.mapping.scroll_docs(-4), { "i", "c" }),
471 ["<C-d>"] = cmp.mapping(cmp.mapping.scroll_docs(4), { "i", "c" }),
472 ["<C-Space>"] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }),
473 ["<C-y>"] = cmp.config.disable,
474 ["<C-e>"] = cmp.mapping {
475 i = cmp.mapping.abort(),
476 c = cmp.mapping.close(),
477 },
478 ["<CR>"] = cmp.mapping.confirm { select = false },
479 ["<Tab>"] = cmp.mapping(function(fallback)
480 if cmp.visible() then
481 cmp.select_next_item()
482 elseif luasnip.expand_or_jumpable() then
483 luasnip.expand_or_jump()
484 elseif has_words_before() then
485 cmp.complete()
486 else
487 fallback()
488 end
489 end, { "i", "s" }),
490 ["<S-Tab>"] = cmp.mapping(function(fallback)
491 if cmp.visible() then
492 cmp.select_prev_item()
493 elseif luasnip.jumpable(-1) then
494 luasnip.jump(-1)
495 else
496 fallback()
497 end
498 end, { "i", "s" }),
499 },
500 sources = cmp.config.sources {
501 { name = "nvim_lsp", priority = 1000 },
502 { name = "luasnip", priority = 750 },
503 { name = "buffer", priority = 500 },
504 { name = "path", priority = 250 },
505 },
506 }
507 end,
508 },
509
510}