3-dev-core.lua

  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}