1-- Dev
2-- Things you actively use for coding.
3
4-- Sections:
5-- ## SNIPPETS
6-- -> luasnip [snippet engine]
7-- -> friendly-snippets [snippet templates]
8
9-- ## GIT
10-- -> gitsigns.nvim [git hunks]
11-- -> fugitive.vim [git commands]
12
13-- ## ANALYZER
14-- -> aerial.nvim [symbols tree]
15-- -> litee-calltree.nvim [calltree]
16
17-- ## CODE DOCUMENTATION
18-- -> dooku.nvim [html doc generator]
19-- -> markdown-preview.nvim [markdown previewer]
20-- -> markmap.nvim [markdown mindmap]
21
22-- ## ARTIFICIAL INTELLIGENCE
23-- -> neural [chatgpt code generator]
24-- -> copilot [github code suggestions]
25-- -> guess-indent [guess-indent]
26
27-- ## COMPILER
28-- -> compiler.nvim [compiler]
29-- -> overseer.nvim [task runner]
30
31-- ## DEBUGGER
32-- -> nvim-dap [debugger]
33
34-- ## TESTING
35-- -> neotest.nvim [unit testing]
36-- -> nvim-coverage [code coverage]
37
38-- ## LANGUAGE IMPROVEMENTS
39-- -> guttentags_plus [auto generate C/C++ tags]
40
41local is_windows = vim.fn.has('win32') == 1 -- true if on windows
42
43return {
44 -- SNIPPETS ----------------------------------------------------------------
45 -- Vim Snippets engine [snippet engine] + [snippet templates]
46 -- https://github.com/L3MON4D3/LuaSnip
47 -- https://github.com/rafamadriz/friendly-snippets
48 {
49 "L3MON4D3/LuaSnip",
50 build = not is_windows and "make install_jsregexp" or nil,
51 dependencies = {
52 "rafamadriz/friendly-snippets",
53 "zeioth/NormalSnippets",
54 "benfowler/telescope-luasnip.nvim",
55 },
56 event = "User BaseFile",
57 opts = {
58 history = true,
59 delete_check_events = "TextChanged",
60 region_check_events = "CursorMoved",
61 },
62 config = function(_, opts)
63 if opts then require("luasnip").config.setup(opts) end
64 vim.tbl_map(
65 function(type) require("luasnip.loaders.from_" .. type).lazy_load() end,
66 { "vscode", "snipmate", "lua" }
67 )
68 -- friendly-snippets - enable standardized comments snippets
69 require("luasnip").filetype_extend("typescript", { "tsdoc" })
70 require("luasnip").filetype_extend("javascript", { "jsdoc" })
71 require("luasnip").filetype_extend("lua", { "luadoc" })
72 require("luasnip").filetype_extend("python", { "pydoc" })
73 require("luasnip").filetype_extend("rust", { "rustdoc" })
74 require("luasnip").filetype_extend("cs", { "csharpdoc" })
75 require("luasnip").filetype_extend("java", { "javadoc" })
76 require("luasnip").filetype_extend("c", { "cdoc" })
77 require("luasnip").filetype_extend("cpp", { "cppdoc" })
78 require("luasnip").filetype_extend("php", { "phpdoc" })
79 require("luasnip").filetype_extend("kotlin", { "kdoc" })
80 require("luasnip").filetype_extend("ruby", { "rdoc" })
81 require("luasnip").filetype_extend("sh", { "shelldoc" })
82 end,
83 },
84
85 -- GIT ---------------------------------------------------------------------
86 -- Git signs [git hunks]
87 -- https://github.com/lewis6991/gitsigns.nvim
88 {
89 "lewis6991/gitsigns.nvim",
90 enabled = vim.fn.executable "git" == 1,
91 event = "User BaseGitFile",
92 opts = function()
93 local get_icon = require("base.utils").get_icon
94 return {
95 max_file_length = vim.g.big_file.lines,
96 signs = {
97 add = { text = get_icon("GitSign") },
98 change = { text = get_icon("GitSign") },
99 delete = { text = get_icon("GitSign") },
100 topdelete = { text = get_icon("GitSign") },
101 changedelete = { text = get_icon("GitSign") },
102 untracked = { text = get_icon("GitSign") },
103 },
104 }
105 end
106 },
107
108 -- Git fugitive mergetool + [git commands]
109 -- https://github.com/lewis6991/gitsigns.nvim
110 -- PR needed: Setup keymappings to move quickly when using this feature.
111 --
112 -- We only want this plugin to use it as mergetool like "git mergetool".
113 -- To enable this feature, add this to your global .gitconfig:
114 --
115 -- [mergetool "fugitive"]
116 -- cmd = nvim -c \"Gvdiffsplit!\" \"$MERGED\"
117 -- [merge]
118 -- tool = fugitive
119 -- [mergetool]
120 -- keepBackup = false
121 {
122 "tpope/vim-fugitive",
123 enabled = vim.fn.executable "git" == 1,
124 dependencies = { "tpope/vim-rhubarb" },
125 cmd = {
126 "Gvdiffsplit",
127 "Gdiffsplit",
128 "Gedit",
129 "Gsplit",
130 "Gread",
131 "Gwrite",
132 "Ggrep",
133 "GMove",
134 "GRename",
135 "GDelete",
136 "GRemove",
137 "GBrowse",
138 "Git",
139 "Gstatus",
140 },
141 config = function()
142 -- NOTE: On vimplugins we use config instead of opts.
143 vim.g.fugitive_no_maps = 1
144 end,
145 },
146
147 -- ANALYZER ----------------------------------------------------------------
148 -- [symbols tree]
149 -- https://github.com/stevearc/aerial.nvim
150 {
151 "stevearc/aerial.nvim",
152 event = "User BaseFile",
153 opts = {
154 filter_kind = { -- Symbols that will appear on the tree
155 -- "Class",
156 "Constructor",
157 "Enum",
158 "Function",
159 "Interface",
160 -- "Module",
161 "Method",
162 -- "Struct",
163 },
164 open_automatic = false, -- Open if the buffer is compatible
165 autojump = true,
166 link_folds_to_tree = false,
167 link_tree_to_folds = false,
168 attach_mode = "global",
169 backends = { "lsp", "treesitter", "markdown", "man" },
170 disable_max_lines = vim.g.big_file.lines,
171 disable_max_size = vim.g.big_file.size,
172 layout = {
173 min_width = 28,
174 default_direction = "right",
175 placement = "edge",
176 },
177 show_guides = true,
178 guides = {
179 mid_item = "├ ",
180 last_item = "└ ",
181 nested_top = "│ ",
182 whitespace = " ",
183 },
184 keymaps = {
185 ["[y"] = "actions.prev",
186 ["]y"] = "actions.next",
187 ["[Y"] = "actions.prev_up",
188 ["]Y"] = "actions.next_up",
189 ["{"] = false,
190 ["}"] = false,
191 ["[["] = false,
192 ["]]"] = false,
193 },
194 },
195 config = function(_, opts)
196 require("aerial").setup(opts)
197 -- HACK: The first time you open aerial on a session, close all folds.
198 vim.api.nvim_create_autocmd({"FileType", "BufEnter"}, {
199 desc = "Aerial: When aerial is opened, close all its folds.",
200 callback = function()
201 local is_aerial = vim.bo.filetype == "aerial"
202 local is_ufo_available = require("base.utils").is_available("nvim-ufo")
203 if is_ufo_available and is_aerial and vim.b.new_aerial_session == nil then
204 vim.b.new_aerial_session = false
205 require("aerial").tree_set_collapse_level(0, 0)
206 end
207 end,
208 })
209 end
210 },
211
212 -- Litee calltree [calltree]
213 -- https://github.com/ldelossa/litee.nvim
214 -- https://github.com/ldelossa/litee-calltree.nvim
215 -- press ? inside the panel to show help.
216 {
217 'ldelossa/litee.nvim',
218 event = "User BaseFile",
219 opts = {
220 notify = { enabled = false },
221 panel = {
222 orientation = "bottom",
223 panel_size = 10,
224 },
225 },
226 config = function(_, opts)
227 require('litee.lib').setup(opts)
228 end
229 },
230 {
231 'ldelossa/litee-calltree.nvim',
232 dependencies = 'ldelossa/litee.nvim',
233 event = "User BaseFile",
234 opts = {
235 on_open = "panel", -- or popout
236 map_resize_keys = false,
237 keymaps = {
238 expand = "<CR>",
239 collapse = "c",
240 collapse_all = "C",
241 jump = "<C-CR>"
242 },
243 },
244 config = function(_, opts)
245 require('litee.calltree').setup(opts)
246
247 -- Highlight only while on calltree
248 vim.api.nvim_create_autocmd({ "WinEnter" }, {
249 desc = "Clear highlights when leaving calltree + UX improvements.",
250 callback = function()
251 vim.defer_fn(function()
252 if vim.bo.filetype == "calltree" then
253 vim.wo.colorcolumn = "0"
254 vim.wo.foldcolumn = "0"
255 vim.cmd("silent! PinBuffer") -- stickybuf.nvim
256 vim.cmd("silent! hi LTSymbolJump ctermfg=015 ctermbg=110 cterm=italic,bold,underline guifg=#464646 guibg=#87afd7 gui=italic,bold")
257 vim.cmd("silent! hi LTSymbolJumpRefs ctermfg=015 ctermbg=110 cterm=italic,bold,underline guifg=#464646 guibg=#87afd7 gui=italic,bold")
258 else
259 vim.cmd("silent! highlight clear LTSymbolJump")
260 vim.cmd("silent! highlight clear LTSymbolJumpRefs")
261 end
262 end, 100)
263 end
264 })
265 end
266 },
267
268 -- CODE DOCUMENTATION ------------------------------------------------------
269 -- dooku.nvim [html doc generator]
270 -- https://github.com/zeioth/dooku.nvim
271 {
272 "zeioth/dooku.nvim",
273 cmd = {
274 "DookuGenerate",
275 "DookuOpen",
276 "DookuAutoSetup"
277 },
278 opts = {},
279 },
280
281 -- [markdown previewer]
282 -- https://github.com/iamcco/markdown-preview.nvim
283 -- Note: If you change the build command, wipe ~/.local/data/nvim/lazy
284 {
285 "iamcco/markdown-preview.nvim",
286 build = function() vim.fn["mkdp#util#install"]() end,
287 ft = { "markdown" },
288 cmd = {
289 "MarkdownPreview",
290 "MarkdownPreviewStop",
291 "MarkdownPreviewToggle",
292 },
293 },
294
295 -- [markdown markmap]
296 -- https://github.com/zeioth/markmap.nvim
297 -- Important: Make sure you have yarn in your PATH before running markmap.
298 {
299 "zeioth/markmap.nvim",
300 build = "yarn global add markmap-cli",
301 cmd = { "MarkmapOpen", "MarkmapSave", "MarkmapWatch", "MarkmapWatchStop" },
302 config = function(_, opts) require("markmap").setup(opts) end,
303 },
304
305 -- ARTIFICIAL INTELLIGENCE -------------------------------------------------
306 -- neural [chatgpt code generator]
307 -- https://github.com/dense-analysis/neural
308 --
309 -- NOTE: In order for this plugin to work, you will have to set
310 -- the next env var in your OS:
311 -- OPENAI_API_KEY="my_key_here"
312 {
313 "dense-analysis/neural",
314 cmd = { "Neural" },
315 config = function()
316 require("neural").setup {
317 source = {
318 openai = {
319 api_key = vim.env.OPENAI_API_KEY,
320 },
321 },
322 ui = {
323 prompt_icon = ">",
324 },
325 }
326 end,
327 },
328
329 -- copilot [github code suggestions]
330 -- https://github.com/github/copilot.vim
331 -- As alternative to chatgpt, you can use copilot uncommenting this.
332 -- Then you must run :Copilot setup
333 -- {
334 -- "github/copilot.vim",
335 -- event = "User BaseFile"
336 -- },
337 -- copilot-cmp
338 -- https://github.com/zbirenbaum/copilot-cmp
339 -- {
340 -- "zbirenbaum/copilot-cmp",
341 -- opts = { suggesion = { enabled = false }, panel = { enabled = false } },
342 -- config = function (_, opts) require("copilot_cmp").setup(opts) end
343 -- },
344
345 -- [guess-indent]
346 -- https://github.com/NMAC427/guess-indent.nvim
347 -- Note that this plugin won't autoformat the code.
348 -- It just set the buffer options to tabluate in a certain way.
349 {
350 "NMAC427/guess-indent.nvim",
351 event = "User BaseFile",
352 opts = {}
353 },
354
355 -- COMPILER ----------------------------------------------------------------
356 -- compiler.nvim [compiler]
357 -- https://github.com/zeioth/compiler.nvim
358 {
359 "zeioth/compiler.nvim",
360 cmd = {
361 "CompilerOpen",
362 "CompilerToggleResults",
363 "CompilerRedo",
364 "CompilerStop"
365 },
366 dependencies = { "stevearc/overseer.nvim" },
367 opts = {},
368 },
369
370 -- overseer [task runner]
371 -- https://github.com/stevearc/overseer.nvim
372 -- If you need to close a task immediately:
373 -- press ENTER in the output menu on the task you wanna close.
374 {
375 "stevearc/overseer.nvim",
376 cmd = {
377 "OverseerOpen",
378 "OverseerClose",
379 "OverseerToggle",
380 "OverseerSaveBundle",
381 "OverseerLoadBundle",
382 "OverseerDeleteBundle",
383 "OverseerRunCmd",
384 "OverseerRun",
385 "OverseerInfo",
386 "OverseerBuild",
387 "OverseerQuickAction",
388 "OverseerTaskAction",
389 "OverseerClearCache"
390 },
391 opts = {
392 task_list = { -- the window that shows the results.
393 direction = "bottom",
394 min_height = 25,
395 max_height = 25,
396 default_detail = 1,
397 },
398 -- component_aliases = {
399 -- default = {
400 -- -- Behaviors that will apply to all tasks.
401 -- "on_exit_set_status", -- don't delete this one.
402 -- "on_output_summarize", -- show last line on the list.
403 -- "display_duration", -- display duration.
404 -- "on_complete_notify", -- notify on task start.
405 -- "open_output", -- focus last executed task.
406 -- { "on_complete_dispose", timeout=300 }, -- dispose old tasks.
407 -- },
408 -- },
409 },
410 },
411
412 -- DEBUGGER ----------------------------------------------------------------
413 -- Debugger alternative to vim-inspector [debugger]
414 -- https://github.com/mfussenegger/nvim-dap
415 -- Here we configure the adapter+config of every debugger.
416 -- Debuggers don't have system dependencies, you just install them with mason.
417 -- We currently ship most of them with nvim.
418 {
419 "mfussenegger/nvim-dap",
420 enabled = vim.fn.has "win32" == 0,
421 event = "User BaseFile",
422 config = function()
423 local dap = require("dap")
424
425 -- C#
426 dap.adapters.coreclr = {
427 type = 'executable',
428 command = vim.fn.stdpath('data') .. '/mason/bin/netcoredbg',
429 args = { '--interpreter=vscode' }
430 }
431 dap.configurations.cs = {
432 {
433 type = "coreclr",
434 name = "launch - netcoredbg",
435 request = "launch",
436 program = function() -- Ask the user what executable wants to debug
437 return vim.fn.input('Path to dll: ', vim.fn.getcwd() .. '/bin/Program.exe', 'file')
438 end,
439 },
440 }
441
442 -- F#
443 dap.configurations.fsharp = dap.configurations.cs
444
445 -- Visual basic dotnet
446 dap.configurations.vb = dap.configurations.cs
447
448 -- Java
449 -- Note: The java debugger jdtls is automatically spawned and configured
450 -- by the plugin 'nvim-java' in './3-dev-core.lua'.
451
452 -- Python
453 dap.adapters.python = {
454 type = 'executable',
455 command = vim.fn.stdpath('data') .. '/mason/packages/debugpy/venv/bin/python',
456 args = { '-m', 'debugpy.adapter' },
457 }
458 dap.configurations.python = {
459 {
460 type = "python",
461 request = "launch",
462 name = "Launch file",
463 program = "${file}", -- This configuration will launch the current file if used.
464 },
465 }
466
467 -- Lua
468 dap.adapters.nlua = function(callback, config)
469 callback({ type = 'server', host = config.host or "127.0.0.1", port = config.port or 8086 })
470 end
471 dap.configurations.lua = {
472 {
473 type = 'nlua',
474 request = 'attach',
475 name = "Attach to running Neovim instance",
476 program = function() pcall(require "osv".launch({ port = 8086 })) end,
477 }
478 }
479
480 -- C
481 dap.adapters.codelldb = {
482 type = 'server',
483 port = "${port}",
484 executable = {
485 command = vim.fn.stdpath('data') .. '/mason/bin/codelldb',
486 args = { "--port", "${port}" },
487 detached = function() if is_windows then return false else return true end end,
488 }
489 }
490 dap.configurations.c = {
491 {
492 name = 'Launch',
493 type = 'codelldb',
494 request = 'launch',
495 program = function() -- Ask the user what executable wants to debug
496 return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/bin/program', 'file')
497 end,
498 cwd = '${workspaceFolder}',
499 stopOnEntry = false,
500 args = {},
501 },
502 }
503
504 -- C++
505 dap.configurations.cpp = dap.configurations.c
506
507 -- Rust
508 dap.configurations.rust = {
509 {
510 name = 'Launch',
511 type = 'codelldb',
512 request = 'launch',
513 program = function() -- Ask the user what executable wants to debug
514 return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/bin/program', 'file')
515 end,
516 cwd = '${workspaceFolder}',
517 stopOnEntry = false,
518 args = {},
519 initCommands = function() -- add rust types support (optional)
520 -- Find out where to look for the pretty printer Python module
521 local rustc_sysroot = vim.fn.trim(vim.fn.system('rustc --print sysroot'))
522
523 local script_import = 'command script import "' .. rustc_sysroot .. '/lib/rustlib/etc/lldb_lookup.py"'
524 local commands_file = rustc_sysroot .. '/lib/rustlib/etc/lldb_commands'
525
526 local commands = {}
527 local file = io.open(commands_file, 'r')
528 if file then
529 for line in file:lines() do
530 table.insert(commands, line)
531 end
532 file:close()
533 end
534 table.insert(commands, 1, script_import)
535
536 return commands
537 end,
538 }
539 }
540
541 -- Go
542 -- Requires:
543 -- * You have initialized your module with 'go mod init module_name'.
544 -- * You :cd your project before running DAP.
545 dap.adapters.delve = {
546 type = 'server',
547 port = '${port}',
548 executable = {
549 command = vim.fn.stdpath('data') .. '/mason/packages/delve/dlv',
550 args = { 'dap', '-l', '127.0.0.1:${port}' },
551 }
552 }
553 dap.configurations.go = {
554 {
555 type = "delve",
556 name = "Compile module and debug this file",
557 request = "launch",
558 program = "./${relativeFileDirname}",
559 },
560 {
561 type = "delve",
562 name = "Compile module and debug this file (test)",
563 request = "launch",
564 mode = "test",
565 program = "./${relativeFileDirname}"
566 },
567 }
568
569 -- Dart / Flutter
570 dap.adapters.dart = {
571 type = 'executable',
572 command = vim.fn.stdpath('data') .. '/mason/bin/dart-debug-adapter',
573 args = { 'dart' }
574 }
575 dap.adapters.flutter = {
576 type = 'executable',
577 command = vim.fn.stdpath('data') .. '/mason/bin/dart-debug-adapter',
578 args = { 'flutter' }
579 }
580 dap.configurations.dart = {
581 {
582 type = "dart",
583 request = "launch",
584 name = "Launch dart",
585 dartSdkPath = "/opt/flutter/bin/cache/dart-sdk/", -- ensure this is correct
586 flutterSdkPath = "/opt/flutter", -- ensure this is correct
587 program = "${workspaceFolder}/lib/main.dart", -- ensure this is correct
588 cwd = "${workspaceFolder}",
589 },
590 {
591 type = "flutter",
592 request = "launch",
593 name = "Launch flutter",
594 dartSdkPath = "/opt/flutter/bin/cache/dart-sdk/", -- ensure this is correct
595 flutterSdkPath = "/opt/flutter", -- ensure this is correct
596 program = "${workspaceFolder}/lib/main.dart", -- ensure this is correct
597 cwd = "${workspaceFolder}",
598 }
599 }
600
601 -- Kotlin
602 -- Kotlin projects have very weak project structure conventions.
603 -- You must manually specify what the project root and main class are.
604 dap.adapters.kotlin = {
605 type = 'executable',
606 command = vim.fn.stdpath('data') .. '/mason/bin/kotlin-debug-adapter',
607 }
608 dap.configurations.kotlin = {
609 {
610 type = 'kotlin',
611 request = 'launch',
612 name = 'Launch kotlin program',
613 projectRoot = "${workspaceFolder}/app", -- ensure this is correct
614 mainClass = "AppKt", -- ensure this is correct
615 },
616 }
617
618 -- Javascript / Typescript (firefox)
619 dap.adapters.firefox = {
620 type = 'executable',
621 command = vim.fn.stdpath('data') .. '/mason/bin/firefox-debug-adapter',
622 }
623 dap.configurations.typescript = {
624 {
625 name = 'Debug with Firefox',
626 type = 'firefox',
627 request = 'launch',
628 reAttach = true,
629 url = 'http://localhost:4200', -- Write the actual URL of your project.
630 webRoot = '${workspaceFolder}',
631 firefoxExecutable = '/usr/bin/firefox'
632 }
633 }
634 dap.configurations.javascript = dap.configurations.typescript
635 dap.configurations.javascriptreact = dap.configurations.typescript
636 dap.configurations.typescriptreact = dap.configurations.typescript
637
638 -- Javascript / Typescript (chromium)
639 -- If you prefer to use this adapter, comment the firefox one.
640 -- But to use this adapter, you must manually run one of these two, first:
641 -- * chromium --remote-debugging-port=9222 --user-data-dir=remote-profile
642 -- * google-chrome-stable --remote-debugging-port=9222 --user-data-dir=remote-profile
643 -- After starting the debugger, you must manually reload page to get all features.
644 -- dap.adapters.chrome = {
645 -- type = 'executable',
646 -- command = vim.fn.stdpath('data')..'/mason/bin/chrome-debug-adapter',
647 -- }
648 -- dap.configurations.typescript = {
649 -- {
650 -- name = 'Debug with Chromium',
651 -- type = "chrome",
652 -- request = "attach",
653 -- program = "${file}",
654 -- cwd = vim.fn.getcwd(),
655 -- sourceMaps = true,
656 -- protocol = "inspector",
657 -- port = 9222,
658 -- webRoot = "${workspaceFolder}"
659 -- }
660 -- }
661 -- dap.configurations.javascript = dap.configurations.typescript
662 -- dap.configurations.javascriptreact = dap.configurations.typescript
663 -- dap.configurations.typescriptreact = dap.configurations.typescript
664
665 -- PHP
666 dap.adapters.php = {
667 type = 'executable',
668 command = vim.fn.stdpath("data") .. '/mason/bin/php-debug-adapter',
669 }
670 dap.configurations.php = {
671 {
672 type = 'php',
673 request = 'launch',
674 name = 'Listen for Xdebug',
675 port = 9000
676 }
677 }
678
679 -- Shell
680 dap.adapters.bashdb = {
681 type = 'executable',
682 command = vim.fn.stdpath("data") .. '/mason/packages/bash-debug-adapter/bash-debug-adapter',
683 name = 'bashdb',
684 }
685 dap.configurations.sh = {
686 {
687 type = 'bashdb',
688 request = 'launch',
689 name = "Launch file",
690 showDebugOutput = true,
691 pathBashdb = vim.fn.stdpath("data") .. '/mason/packages/bash-debug-adapter/extension/bashdb_dir/bashdb',
692 pathBashdbLib = vim.fn.stdpath("data") .. '/mason/packages/bash-debug-adapter/extension/bashdb_dir',
693 trace = true,
694 file = "${file}",
695 program = "${file}",
696 cwd = '${workspaceFolder}',
697 pathCat = "cat",
698 pathBash = "/bin/bash",
699 pathMkfifo = "mkfifo",
700 pathPkill = "pkill",
701 args = {},
702 env = {},
703 terminalKind = "integrated",
704 }
705 }
706
707 -- Elixir
708 dap.adapters.mix_task = {
709 type = 'executable',
710 command = vim.fn.stdpath("data") .. '/mason/bin/elixir-ls-debugger',
711 args = {}
712 }
713 dap.configurations.elixir = {
714 {
715 type = "mix_task",
716 name = "mix test",
717 task = 'test',
718 taskArgs = { "--trace" },
719 request = "launch",
720 startApps = true, -- for Phoenix projects
721 projectDir = "${workspaceFolder}",
722 requireFiles = {
723 "test/**/test_helper.exs",
724 "test/**/*_test.exs"
725 }
726 },
727 }
728 end, -- of dap config
729 dependencies = {
730 "rcarriga/nvim-dap-ui",
731 "rcarriga/cmp-dap",
732 "jay-babu/mason-nvim-dap.nvim",
733 "jbyuki/one-small-step-for-vimkind",
734 "nvim-java/nvim-java",
735 },
736 },
737
738 -- nvim-dap-ui [dap ui]
739 -- https://github.com/mfussenegger/nvim-dap-ui
740 -- user interface for the debugger dap
741 {
742 "rcarriga/nvim-dap-ui",
743 dependencies = { "nvim-neotest/nvim-nio" },
744 opts = { floating = { border = "rounded" } },
745 config = function(_, opts)
746 local dap, dapui = require("dap"), require("dapui")
747 dap.listeners.after.event_initialized["dapui_config"] = function(
748 )
749 dapui.open()
750 end
751 dap.listeners.before.event_terminated["dapui_config"] = function(
752 )
753 dapui.close()
754 end
755 dap.listeners.before.event_exited["dapui_config"] = function()
756 dapui.close()
757 end
758 dapui.setup(opts)
759 end,
760 },
761
762 -- cmp-dap [dap autocomplete]
763 -- https://github.com/mfussenegger/cmp-dap
764 -- Enables autocomplete for the debugger dap.
765 {
766 "rcarriga/cmp-dap",
767 dependencies = { "nvim-cmp" },
768 config = function()
769 require("cmp").setup.filetype(
770 { "dap-repl", "dapui_watches", "dapui_hover" },
771 {
772 sources = {
773 { name = "dap" },
774 },
775 }
776 )
777 end,
778 },
779
780 -- TESTING -----------------------------------------------------------------
781 -- Run tests inside of nvim [unit testing]
782 -- https://github.com/nvim-neotest/neotest
783 --
784 --
785 -- MANUAL:
786 -- -- Unit testing:
787 -- To tun an unit test you can run any of these commands:
788 --
789 -- :Neotest run -- Runs the nearest test to the cursor.
790 -- :Neotest stop -- Stop the nearest test to the cursor.
791 -- :Neotest run file -- Run all tests in the file.
792 --
793 -- -- E2e and Test Suite
794 -- Normally you will prefer to open your e2e framework GUI outside of nvim.
795 -- But you have the next commands in ../base/3-autocmds.lua:
796 --
797 -- :TestNodejs -- Run all tests for this nodejs project.
798 -- :TestNodejsE2e -- Run the e2e tests/suite for this nodejs project.
799 {
800 "nvim-neotest/neotest",
801 cmd = { "Neotest" },
802 dependencies = {
803 "sidlatau/neotest-dart",
804 "Issafalcon/neotest-dotnet",
805 "jfpedroza/neotest-elixir",
806 "nvim-neotest/neotest-go",
807 "rcasia/neotest-java",
808 "nvim-neotest/neotest-jest",
809 "olimorris/neotest-phpunit",
810 "nvim-neotest/neotest-python",
811 "rouge8/neotest-rust",
812 "lawrence-laz/neotest-zig",
813 },
814 opts = function()
815 return {
816 -- your neotest config here
817 adapters = {
818 require("neotest-dart"),
819 require("neotest-dotnet"),
820 require("neotest-elixir"),
821 require("neotest-go"),
822 require("neotest-java"),
823 require("neotest-jest"),
824 require("neotest-phpunit"),
825 require("neotest-python"),
826 require("neotest-rust"),
827 require("neotest-zig"),
828 },
829 }
830 end,
831 config = function(_, opts)
832 -- get neotest namespace (api call creates or returns namespace)
833 local neotest_ns = vim.api.nvim_create_namespace "neotest"
834 vim.diagnostic.config({
835 virtual_text = {
836 format = function(diagnostic)
837 local message = diagnostic.message:gsub("\n", " "):gsub("\t", " "):gsub("%s+", " "):gsub("^%s+", "")
838 return message
839 end,
840 },
841 }, neotest_ns)
842 require("neotest").setup(opts)
843 end,
844 },
845
846 -- Shows a float panel with the [code coverage]
847 -- https://github.com/andythigpen/nvim-coverage
848 --
849 -- Your project must generate coverage/lcov.info for this to work.
850 --
851 -- On jest, make sure your packages.json file has this:
852 -- "tests": "jest --coverage"
853 --
854 -- If you use other framework or language, refer to nvim-coverage docs:
855 -- https://github.com/andythigpen/nvim-coverage/blob/main/doc/nvim-coverage.txt
856 {
857 "zeioth/nvim-coverage", -- Our fork until all our PRs are merged.
858 cmd = {
859 "Coverage",
860 "CoverageLoad",
861 "CoverageLoadLcov",
862 "CoverageShow",
863 "CoverageHide",
864 "CoverageToggle",
865 "CoverageClear",
866 "CoverageSummary",
867 },
868 dependencies = { "nvim-lua/plenary.nvim" },
869 opts = {
870 summary = {
871 min_coverage = 80.0, -- passes if higher than
872 },
873 },
874 config = function(_, opts) require("coverage").setup(opts) end,
875 },
876
877 -- LANGUAGE IMPROVEMENTS ----------------------------------------------------
878 -- guttentags_plus [auto generate C/C++ tags]
879 -- https://github.com/skywind3000/gutentags_plus
880 -- This plugin is necessary for using <C-]> (go to ctag).
881 {
882 "skywind3000/gutentags_plus",
883 ft = { "c", "cpp" },
884 dependencies = { "ludovicchabant/vim-gutentags" },
885 config = function()
886 -- NOTE: On vimplugins we use config instead of opts.
887 vim.g.gutentags_plus_nomap = 1
888 vim.g.gutentags_resolve_symlinks = 1
889 vim.g.gutentags_cache_dir = vim.fn.stdpath "cache" .. "/tags"
890 vim.api.nvim_create_autocmd("FileType", {
891 desc = "Auto generate C/C++ tags",
892 callback = function()
893 local is_c = vim.bo.filetype == "c" or vim.bo.filetype == "cpp"
894 if is_c then vim.g.gutentags_enabled = 1
895 else vim.g.gutentags_enabled = 0 end
896 end,
897 })
898 end,
899 },
900
901} -- end of return