From 0ea44d389f688c2020d9774a64ae26fe8474153c Mon Sep 17 00:00:00 2001 From: Tristan Jahnke Date: Mon, 15 Jun 2026 19:00:01 -0500 Subject: [PATCH] feat: Add better folding Signed-off-by: Tristan Jahnke --- lazy-lock.json | 383 +++++++++++++++++++++------ lua/config/options.lua | 6 + lua/plugins/conform.lua | 2 +- lua/plugins/go-nvim.lua | 5 +- lua/plugins/lspconfig.lua | 75 +++++- lua/plugins/mason-tool-installer.lua | 51 ++++ lua/plugins/neoscroll.lua | 17 -- lua/plugins/neotest.lua | 11 +- lua/plugins/nvim-coverage.lua | 3 +- lua/plugins/nvim-lint.lua | 2 +- lua/plugins/nvim-origami.lua | 98 +++++++ lua/plugins/nvim-treesitter.lua | 6 + lua/plugins/nvim-ufo.lua | 57 ++++ lua/plugins/snacks.lua | 46 +++- lua/plugins/vim-illuminate.lua | 40 --- snippets/go.json | 281 +++++++++++++++++++- snippets/package.json | 9 +- 17 files changed, 935 insertions(+), 157 deletions(-) create mode 100644 lua/plugins/mason-tool-installer.lua delete mode 100644 lua/plugins/neoscroll.lua create mode 100644 lua/plugins/nvim-origami.lua delete mode 100644 lua/plugins/vim-illuminate.lua diff --git a/lazy-lock.json b/lazy-lock.json index 2b9e68d..4d3ed40 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -1,77 +1,310 @@ { - "aerial.nvim": { "branch": "master", "commit": "28fe6e822ae344544c379d60fcb13c9519a1f08a" }, - "blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" }, - "blink.compat": { "branch": "main", "commit": "1454f14a8d855a578ceeba77c62538fa1459a67c" }, - "catppuccin": { "branch": "main", "commit": "0303a7208dba448c459767486a38a6ec05c4216b" }, - "cloak.nvim": { "branch": "main", "commit": "648aca6d33ec011dc3166e7af3b38820d01a71e4" }, - "conform.nvim": { "branch": "master", "commit": "619363c30309d29ffa631e67c8183f2a72caa373" }, - "diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" }, - "elixir-tools.nvim": { "branch": "main", "commit": "b51b48edc668924a6b2f6610f9a0aff34741d20e" }, - "emoji.nvim": { "branch": "main", "commit": "a79e45d35853bb6446638f4d74c6f778ddebd8e3" }, - "fidget.nvim": { "branch": "main", "commit": "82404b196e73a00b1727a91903beef5ddc319d22" }, - "friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" }, - "gitlab.nvim": { "branch": "main", "commit": "f01ccbdaef7e8460af72c75be65f5f359928a0b4" }, - "gitsigns.nvim": { "branch": "main", "commit": "25050e4ed39e628282831d4cbecb1850454ce915" }, - "go.nvim": { "branch": "master", "commit": "0768d79bbebdb1a112a845f9cd6293bfbd544dab" }, - "guihua.lua": { "branch": "master", "commit": "f8e06bd8a26dee3377d63c2adf1e57cdb58ac474" }, - "harpoon": { "branch": "harpoon2", "commit": "87b1a3506211538f460786c23f98ec63ad9af4e5" }, - "kulala.nvim": { "branch": "main", "commit": "69250f64e60f75c010feac413576acbd9ffa4ec8" }, - "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, - "lsp_signature.nvim": { "branch": "master", "commit": "b7ace9ddb1640ce266012a45a672dfdaedfa5ec6" }, - "lspkind.nvim": { "branch": "master", "commit": "c7274c48137396526b59d86232eabcdc7fed8a32" }, - "lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "0a695750d747db1e7e70bcf0267ef8951c95fc83" }, - "mason.nvim": { "branch": "main", "commit": "16ba83bfc8a25f52bb545134f5bee082b195c460" }, - "mini.nvim": { "branch": "main", "commit": "ff8b3580935818ef2f21bdd651f057a2ae071eab" }, - "neoscroll.nvim": { "branch": "master", "commit": "c8d29979cb0cb3a2437a8e0ae683fd82f340d3b8" }, - "neotest": { "branch": "master", "commit": "ad991822b7076b1d940b33a9d6d0d30416d5df81" }, - "neotest-elixir": { "branch": "master", "commit": "a242aebeaa6997c1c149138ff77f6cacbe33b6fc" }, - "neotest-go": { "branch": "main", "commit": "59b50505053f9c45a9febb79e11a56206c3e3901" }, - "neotest-jest": { "branch": "main", "commit": "0e7979d51301dfae5ef839d771bd28cf593fde3f" }, - "neotest-python": { "branch": "master", "commit": "e6df4f1892f6137f58135917db24d1655937d831" }, - "neotest-rust": { "branch": "main", "commit": "2c9941d4a358839918fac21d20fc8fef0e1ad05f" }, - "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" }, - "nvim-autopairs": { "branch": "master", "commit": "7b9923abad60b903ece7c52940e1321d39eccc79" }, - "nvim-colorizer.lua": { "branch": "master", "commit": "664c0b7cea1de71f8b65dfe951b7996fc3e6ccde" }, - "nvim-coverage": { "branch": "main", "commit": "a939e425e363319d952a6c35fb3f38b34041ded2" }, - "nvim-dap": { "branch": "master", "commit": "531771530d4f82ad2d21e436e3cc052d68d7aebb" }, - "nvim-dap-go": { "branch": "main", "commit": "b4421153ead5d726603b02743ea40cf26a51ed5f" }, - "nvim-dap-python": { "branch": "master", "commit": "1808458eba2b18f178f990e01376941a42c7f93b" }, - "nvim-dap-ui": { "branch": "master", "commit": "1a66cabaa4a4da0be107d5eda6d57242f0fe7e49" }, - "nvim-jqx": { "branch": "master", "commit": "07393e80fa8097e82f9038fec05e948fe8a60fd1" }, - "nvim-lint": { "branch": "master", "commit": "99cbc3ca8a76845fca50e496be7212bebf907dd3" }, - "nvim-lspconfig": { "branch": "master", "commit": "ed19590a3a9792901553c388d1aadafce012f80d" }, - "nvim-man": { "branch": "master", "commit": "7fe6b3b78c71c9ef834c49e3dcbd955f7ed5c6cb" }, - "nvim-navic": { "branch": "master", "commit": "f5eba192f39b453675d115351808bd51276d9de5" }, - "nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" }, - "nvim-scissors": { "branch": "main", "commit": "9cc1ba06afa8b23b0d30cadc02c40940df1d701e" }, - "nvim-silicon": { "branch": "main", "commit": "7f66bda8f60c97a5bf4b37e5b8acb0e829ae3c32" }, - "nvim-spectre": { "branch": "master", "commit": "72f56f7585903cd7bf92c665351aa585e150af0f" }, - "nvim-surround": { "branch": "main", "commit": "1098d7b3c34adcfa7feb3289ee434529abd4afd1" }, - "nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" }, - "nvim-treesitter-textobjects": { "branch": "main", "commit": "851e865342e5a4cb1ae23d31caf6e991e1c99f1e" }, - "nvim-ufo": { "branch": "main", "commit": "ab3eb124062422d276fae49e0dd63b3ad1062cfc" }, - "nvim-web-devicons": { "branch": "master", "commit": "dfbfaa967a6f7ec50789bead7ef87e336c1fa63c" }, - "octo.nvim": { "branch": "master", "commit": "7fed87415c401954f73401bbed0fd736b9611e7c" }, - "overseer.nvim": { "branch": "master", "commit": "a93d9f6d6defdac4bcd6d2c8ba988650e42e0a0e" }, - "package-info.nvim": { "branch": "master", "commit": "9725099fb118bab8360e560c1219bff60763b7e1" }, - "plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" }, - "pr-description.nvim": { "branch": "main", "commit": "76fbca834059448a88cb682e4bc064f49cb9f7a3" }, - "profile.nvim": { "branch": "master", "commit": "30433d7513f0d14665c1cfcea501c90f8a63e003" }, - "promise-async": { "branch": "main", "commit": "119e8961014c9bfaf1487bf3c2a393d254f337e2" }, - "refactoring.nvim": { "branch": "master", "commit": "624c01e8175901484eac74512baf35e9dfe269b8" }, - "render-markdown.nvim": { "branch": "main", "commit": "5adf0895310c1904e5abfaad40a2baad7fe44a07" }, - "smart-splits.nvim": { "branch": "master", "commit": "6806149fd36d1c5e797debe3e18b2c07219b685a" }, - "smartcolumn.nvim": { "branch": "main", "commit": "b9cdbdf42f7ac5a659204cd5926017c7ff724a19" }, - "snacks.nvim": { "branch": "main", "commit": "882c996cf28183f4d63640de0b4c02ec886d01f2" }, - "telescope.nvim": { "branch": "master", "commit": "7d324792b7943e4aa16ad007212e6acc6f9fe335" }, - "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, - "trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" }, - "undotree": { "branch": "master", "commit": "6fa6b57cda8459e1e4b2ca34df702f55242f4e4d" }, - "vim-dadbod": { "branch": "master", "commit": "6d1d41da4873a445c5605f2005ad2c68c99d8770" }, - "vim-dadbod-completion": { "branch": "master", "commit": "a8dac0b3cf6132c80dc9b18bef36d4cf7a9e1fe6" }, - "vim-dadbod-ui": { "branch": "master", "commit": "07e92e22114cc5b1ba4938d99897d85b58e20475" }, - "vim-illuminate": { "branch": "master", "commit": "0d1e93684da00ab7c057410fecfc24f434698898" }, - "vim-table-mode": { "branch": "master", "commit": "bb025308a45c67c7c8f0763ba37bc2ee3f534df0" }, - "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } + "aerial.nvim": { + "branch": "master", + "commit": "28fe6e822ae344544c379d60fcb13c9519a1f08a" + }, + "blink.cmp": { + "branch": "main", + "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" + }, + "blink.compat": { + "branch": "main", + "commit": "1454f14a8d855a578ceeba77c62538fa1459a67c" + }, + "catppuccin": { + "branch": "main", + "commit": "49a926655a2f5579e9c276470fc300baaa49e524" + }, + "cloak.nvim": { + "branch": "main", + "commit": "648aca6d33ec011dc3166e7af3b38820d01a71e4" + }, + "codecompanion.nvim": { + "branch": "main", + "commit": "7cc35b7f7f08d093469fa9ae67d3af716bd729c3" + }, + "conform.nvim": { + "branch": "master", + "commit": "619363c30309d29ffa631e67c8183f2a72caa373" + }, + "diffview.nvim": { + "branch": "main", + "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" + }, + "elixir-tools.nvim": { + "branch": "main", + "commit": "b51b48edc668924a6b2f6610f9a0aff34741d20e" + }, + "emoji.nvim": { + "branch": "main", + "commit": "a79e45d35853bb6446638f4d74c6f778ddebd8e3" + }, + "fidget.nvim": { + "branch": "main", + "commit": "82404b196e73a00b1727a91903beef5ddc319d22" + }, + "friendly-snippets": { + "branch": "main", + "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" + }, + "gitlab.nvim": { + "branch": "main", + "commit": "f01ccbdaef7e8460af72c75be65f5f359928a0b4" + }, + "gitsigns.nvim": { + "branch": "main", + "commit": "25050e4ed39e628282831d4cbecb1850454ce915" + }, + "go.nvim": { + "branch": "master", + "commit": "0768d79bbebdb1a112a845f9cd6293bfbd544dab" + }, + "guihua.lua": { + "branch": "master", + "commit": "f8e06bd8a26dee3377d63c2adf1e57cdb58ac474" + }, + "harpoon": { + "branch": "harpoon2", + "commit": "87b1a3506211538f460786c23f98ec63ad9af4e5" + }, + "kulala.nvim": { + "branch": "main", + "commit": "bf50254965aff8228fa51067d79bb16d2124461e" + }, + "lazy.nvim": { + "branch": "main", + "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" + }, + "lsp_signature.nvim": { + "branch": "master", + "commit": "b7ace9ddb1640ce266012a45a672dfdaedfa5ec6" + }, + "lspkind.nvim": { + "branch": "master", + "commit": "c7274c48137396526b59d86232eabcdc7fed8a32" + }, + "lualine.nvim": { + "branch": "master", + "commit": "221ce6b2d999187044529f49da6554a92f740a96" + }, + "mason-lspconfig.nvim": { + "branch": "main", + "commit": "21c5b3ebeaa0412e28096bb0701434c51c1fbf76" + }, + "mason-tool-installer.nvim": { + "branch": "main", + "commit": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc" + }, + "mason.nvim": { + "branch": "main", + "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" + }, + "mini.nvim": { + "branch": "main", + "commit": "7ed410c73ebb910754c2938a6dae50c51c3a096a" + }, + "minuet-ai.nvim": { + "branch": "main", + "commit": "d29dec4c36be2b41aa10e70938b7b09a03f0bdba" + }, + "neotest": { + "branch": "master", + "commit": "ad991822b7076b1d940b33a9d6d0d30416d5df81" + }, + "neotest-elixir": { + "branch": "master", + "commit": "a242aebeaa6997c1c149138ff77f6cacbe33b6fc" + }, + "neotest-golang": { + "branch": "main", + "commit": "f0ba097d4af098c036aac24cd647480d0d301ad2" + }, + "neotest-jest": { + "branch": "main", + "commit": "0e7979d51301dfae5ef839d771bd28cf593fde3f" + }, + "neotest-python": { + "branch": "master", + "commit": "e6df4f1892f6137f58135917db24d1655937d831" + }, + "neotest-rust": { + "branch": "main", + "commit": "2c9941d4a358839918fac21d20fc8fef0e1ad05f" + }, + "nui.nvim": { + "branch": "main", + "commit": "de740991c12411b663994b2860f1a4fd0937c130" + }, + "nvim-autopairs": { + "branch": "master", + "commit": "7b9923abad60b903ece7c52940e1321d39eccc79" + }, + "nvim-colorizer.lua": { + "branch": "master", + "commit": "664c0b7cea1de71f8b65dfe951b7996fc3e6ccde" + }, + "nvim-coverage": { + "branch": "main", + "commit": "a939e425e363319d952a6c35fb3f38b34041ded2" + }, + "nvim-dap": { + "branch": "master", + "commit": "531771530d4f82ad2d21e436e3cc052d68d7aebb" + }, + "nvim-dap-go": { + "branch": "main", + "commit": "b4421153ead5d726603b02743ea40cf26a51ed5f" + }, + "nvim-dap-python": { + "branch": "master", + "commit": "1808458eba2b18f178f990e01376941a42c7f93b" + }, + "nvim-dap-ui": { + "branch": "master", + "commit": "1a66cabaa4a4da0be107d5eda6d57242f0fe7e49" + }, + "nvim-jqx": { + "branch": "master", + "commit": "07393e80fa8097e82f9038fec05e948fe8a60fd1" + }, + "nvim-lint": { + "branch": "master", + "commit": "99cbc3ca8a76845fca50e496be7212bebf907dd3" + }, + "nvim-lspconfig": { + "branch": "master", + "commit": "a683e0ddf0cf64c6cd689e18ffb480ade3c162b7" + }, + "nvim-man": { + "branch": "master", + "commit": "7fe6b3b78c71c9ef834c49e3dcbd955f7ed5c6cb" + }, + "nvim-navic": { + "branch": "master", + "commit": "f5eba192f39b453675d115351808bd51276d9de5" + }, + "nvim-nio": { + "branch": "master", + "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" + }, + "nvim-origami": { + "branch": "main", + "commit": "47be2209d09755c0202da1e22a8d67af8f5ae178" + }, + "nvim-scissors": { + "branch": "main", + "commit": "9cc1ba06afa8b23b0d30cadc02c40940df1d701e" + }, + "nvim-silicon": { + "branch": "main", + "commit": "7f66bda8f60c97a5bf4b37e5b8acb0e829ae3c32" + }, + "nvim-spectre": { + "branch": "master", + "commit": "72f56f7585903cd7bf92c665351aa585e150af0f" + }, + "nvim-surround": { + "branch": "main", + "commit": "1098d7b3c34adcfa7feb3289ee434529abd4afd1" + }, + "nvim-treesitter": { + "branch": "main", + "commit": "4916d6592ede8c07973490d9322f187e07dfefac" + }, + "nvim-treesitter-textobjects": { + "branch": "main", + "commit": "851e865342e5a4cb1ae23d31caf6e991e1c99f1e" + }, + "nvim-ufo": { + "branch": "main", + "commit": "ab3eb124062422d276fae49e0dd63b3ad1062cfc" + }, + "nvim-web-devicons": { + "branch": "master", + "commit": "dfbfaa967a6f7ec50789bead7ef87e336c1fa63c" + }, + "octo.nvim": { + "branch": "master", + "commit": "7fed87415c401954f73401bbed0fd736b9611e7c" + }, + "overseer.nvim": { + "branch": "master", + "commit": "a93d9f6d6defdac4bcd6d2c8ba988650e42e0a0e" + }, + "package-info.nvim": { + "branch": "master", + "commit": "9725099fb118bab8360e560c1219bff60763b7e1" + }, + "plenary.nvim": { + "branch": "master", + "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" + }, + "pr-description.nvim": { + "branch": "main", + "commit": "d0af0074d6eec7af2b3724bc92c66163d82b29f3" + }, + "profile.nvim": { + "branch": "master", + "commit": "30433d7513f0d14665c1cfcea501c90f8a63e003" + }, + "refactoring.nvim": { + "branch": "master", + "commit": "7eaa150061ea18fdbe18fbb924d236e3ddccc57d" + }, + "render-markdown.nvim": { + "branch": "main", + "commit": "5adf0895310c1904e5abfaad40a2baad7fe44a07" + }, + "schemastore.nvim": { + "branch": "main", + "commit": "304d2286752923e3b0eb1ddcb3d4002a69b855ad" + }, + "smart-splits.nvim": { + "branch": "master", + "commit": "2aad9808f289f5d65cfa77840a04b8590e5e34e9" + }, + "smartcolumn.nvim": { + "branch": "main", + "commit": "b9cdbdf42f7ac5a659204cd5926017c7ff724a19" + }, + "snacks.nvim": { + "branch": "main", + "commit": "882c996cf28183f4d63640de0b4c02ec886d01f2" + }, + "telescope.nvim": { + "branch": "master", + "commit": "7d324792b7943e4aa16ad007212e6acc6f9fe335" + }, + "todo-comments.nvim": { + "branch": "main", + "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" + }, + "trouble.nvim": { + "branch": "main", + "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" + }, + "undotree": { + "branch": "master", + "commit": "6fa6b57cda8459e1e4b2ca34df702f55242f4e4d" + }, + "vim-dadbod": { + "branch": "master", + "commit": "6d1d41da4873a445c5605f2005ad2c68c99d8770" + }, + "vim-dadbod-completion": { + "branch": "master", + "commit": "a8dac0b3cf6132c80dc9b18bef36d4cf7a9e1fe6" + }, + "vim-dadbod-ui": { + "branch": "master", + "commit": "07e92e22114cc5b1ba4938d99897d85b58e20475" + }, + "vim-table-mode": { + "branch": "master", + "commit": "bb025308a45c67c7c8f0763ba37bc2ee3f534df0" + }, + "which-key.nvim": { + "branch": "main", + "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" + } } diff --git a/lua/config/options.lua b/lua/config/options.lua index 7a167bb..d972ee5 100644 --- a/lua/config/options.lua +++ b/lua/config/options.lua @@ -1,5 +1,11 @@ local opt = vim.opt -- for conciseness +-- Disable unused language providers (avoids checkhealth noise + startup cost) +vim.g.loaded_python3_provider = 0 +vim.g.loaded_perl_provider = 0 +vim.g.loaded_ruby_provider = 0 +vim.g.loaded_node_provider = 0 + -- line numbers opt.relativenumber = true -- show relative line numbers opt.number = true -- shows absolute line number on cursor line (when relative number is on) diff --git a/lua/plugins/conform.lua b/lua/plugins/conform.lua index 9c25432..614c853 100644 --- a/lua/plugins/conform.lua +++ b/lua/plugins/conform.lua @@ -9,7 +9,7 @@ return { formatters_by_ft = { lua = { "stylua" }, python = { "ruff_format", "ruff_organize_imports" }, - go = { "gofmt", "goimports" }, + go = { "goimports", "gofumpt" }, terraform = { "terraform_fmt" }, sh = { "shfmt" }, bash = { "shfmt" }, diff --git a/lua/plugins/go-nvim.lua b/lua/plugins/go-nvim.lua index 45bce8e..d21c1ea 100644 --- a/lua/plugins/go-nvim.lua +++ b/lua/plugins/go-nvim.lua @@ -16,9 +16,10 @@ return { test_template = "", test_template_dir = "", comment_placeholder = " ", - lsp_cfg = true, + -- Let nvim-lspconfig own gopls so settings live in one place. + lsp_cfg = false, lsp_gofumpt = true, - lsp_on_attach = true, + lsp_on_attach = false, lsp_keymaps = false, lsp_codelens = true, diagnostic = { diff --git a/lua/plugins/lspconfig.lua b/lua/plugins/lspconfig.lua index 678ac67..db8c69c 100644 --- a/lua/plugins/lspconfig.lua +++ b/lua/plugins/lspconfig.lua @@ -2,6 +2,7 @@ return { "neovim/nvim-lspconfig", dependencies = { "saghen/blink.cmp", + "b0o/schemastore.nvim", }, config = function() vim.lsp.log.set_level("WARN") @@ -50,12 +51,29 @@ return { }, }) - -- Terraform language server + -- Terraform / HCL language server vim.lsp.config("terraformls", { - filetypes = { "terraform", "terraform-vars", "tf" }, + filetypes = { "terraform", "terraform-vars", "tf", "hcl" }, root_markers = { ".terraform", ".git" }, }) + -- Markdown language server (links, headings, references, completion) + vim.lsp.config("marksman", { + filetypes = { "markdown", "markdown.mdx" }, + root_markers = { ".marksman.toml", ".git" }, + }) + + -- JSON language server with SchemaStore (package.json, tsconfig, gh actions...) + vim.lsp.config("jsonls", { + filetypes = { "json", "jsonc" }, + settings = { + json = { + schemas = require("schemastore").json.schemas(), + validate = { enable = true }, + }, + }, + }) + -- Pyright owns Python type checking vim.lsp.config("pyright", { settings = { @@ -70,7 +88,47 @@ return { }, }) - vim.lsp.enable({ "lua_ls", "pyright", "gopls", "terraformls" }) + -- Go language server + vim.lsp.config("gopls", { + root_markers = { "go.work", "go.mod", ".git" }, + settings = { + gopls = { + gofumpt = true, + staticcheck = true, + usePlaceholders = true, + completeUnimported = true, + experimentalPostfixCompletions = true, + analyses = { + unusedparams = true, + unusedwrite = true, + useany = true, + nilness = true, + shadow = true, + }, + codelenses = { + gc_details = true, + generate = true, + regenerate_cgo = true, + test = true, + tidy = true, + upgrade_dependency = true, + vendor = true, + }, + hints = { + assignVariableTypes = true, + compositeLiteralFields = true, + compositeLiteralTypes = true, + constantValues = true, + functionTypeParameters = true, + parameterNames = true, + rangeVariableTypes = true, + }, + semanticTokens = true, + }, + }, + }) + + vim.lsp.enable({ "lua_ls", "pyright", "gopls", "terraformls", "marksman", "jsonls" }) -- Diagnostic configuration vim.diagnostic.config({ @@ -123,6 +181,17 @@ return { bufmap("n", "", "lua vim.lsp.buf.rename()", "Rename symbol") bufmap("n", "", "lua vim.lsp.buf.code_action()", "Code action") + -- Hover: LSP hover, falls back to diagnostic float if no hover info + bufmap("n", "K", function() + local has_diag = #vim.diagnostic.get(bufnr, { lnum = vim.fn.line(".") - 1 }) > 0 + local clients = vim.lsp.get_clients({ bufnr = bufnr, method = "textDocument/hover" }) + if #clients > 0 then + vim.lsp.buf.hover({ border = "rounded" }) + elseif has_diag then + vim.diagnostic.open_float({ border = "rounded" }) + end + end, "Hover / diagnostic") + -- Diagnostics bufmap("n", "gl", "lua vim.diagnostic.open_float()", "Show diagnostics") bufmap("n", "[d", function() diff --git a/lua/plugins/mason-tool-installer.lua b/lua/plugins/mason-tool-installer.lua new file mode 100644 index 0000000..17f4cb8 --- /dev/null +++ b/lua/plugins/mason-tool-installer.lua @@ -0,0 +1,51 @@ +return { + "WhoIsSethDaniel/mason-tool-installer.nvim", + dependencies = { "mason-org/mason.nvim" }, + event = { "VeryLazy" }, + config = function() + require("mason-tool-installer").setup({ + ensure_installed = { + -- Go + "gofumpt", + "goimports", + "golangci-lint", + "delve", + "gomodifytags", + "impl", + "iferr", + "gotests", + + -- Python + "ruff", + "black", + + -- Lua + "stylua", + "luacheck", + + -- Shell + "shfmt", + "shellcheck", + + -- Web / config + "prettier", + "yamlfmt", + "yamllint", + "jsonlint", + "markdownlint", + + -- Terraform + "tflint", + "tfsec", + + -- Misc + "hadolint", + "codespell", + }, + auto_update = false, + run_on_start = true, + start_delay = 3000, + debounce_hours = 24, + }) + end, +} diff --git a/lua/plugins/neoscroll.lua b/lua/plugins/neoscroll.lua deleted file mode 100644 index eb238ba..0000000 --- a/lua/plugins/neoscroll.lua +++ /dev/null @@ -1,17 +0,0 @@ -return { - "karb94/neoscroll.nvim", - event = "VeryLazy", - config = function() - require("neoscroll").setup({ - mappings = { "", "", "", "", "", "", "zt", "zz", "zb" }, - hide_cursor = true, - stop_eof = true, - respect_scrolloff = false, - cursor_scrolls_alone = true, - easing_function = nil, - pre_hook = nil, - post_hook = nil, - performance_mode = false, - }) - end, -} diff --git a/lua/plugins/neotest.lua b/lua/plugins/neotest.lua index f18f1fa..dcf9a34 100644 --- a/lua/plugins/neotest.lua +++ b/lua/plugins/neotest.lua @@ -5,7 +5,7 @@ return { "nvim-lua/plenary.nvim", "nvim-treesitter/nvim-treesitter", "nvim-neotest/neotest-python", - "nvim-neotest/neotest-go", + "fredrikaverpil/neotest-golang", "jfpedroza/neotest-elixir", "nvim-neotest/neotest-jest", "rouge8/neotest-rust", @@ -19,11 +19,10 @@ return { runner = "pytest", python = "python3", }), - require("neotest-go")({ - experimental = { - test_table = true, - }, - args = { "-count=1", "-timeout=60s" }, + require("neotest-golang")({ + go_test_args = { "-v", "-race", "-count=1", "-timeout=60s" }, + dap_go_enabled = true, + runner = "go", }), require("neotest-elixir")({ mix_task = "test", diff --git a/lua/plugins/nvim-coverage.lua b/lua/plugins/nvim-coverage.lua index 3ddef2e..a5d60dd 100644 --- a/lua/plugins/nvim-coverage.lua +++ b/lua/plugins/nvim-coverage.lua @@ -24,7 +24,8 @@ return { coverage_file = "coverage.json", }, go = { - coverage_command = "go test -coverprofile=coverage.out ./... && go tool cover -func=coverage.out", + coverage_file = "coverage.out", + coverage_command = "go test -coverprofile=coverage.out -coverpkg=./... ./...", }, javascript = { coverage_command = "cat coverage/lcov-report/index.html | grep -o '\\\"decimal\\\">[^<]*' | head -n 4", diff --git a/lua/plugins/nvim-lint.lua b/lua/plugins/nvim-lint.lua index 420fc80..b4da0d5 100644 --- a/lua/plugins/nvim-lint.lua +++ b/lua/plugins/nvim-lint.lua @@ -8,7 +8,7 @@ return { python = { "ruff" }, javascript = { "eslint" }, typescript = { "eslint" }, - go = { "golangcilint", "staticcheck" }, + go = { "golangcilint" }, terraform = { "tflint", "tfsec" }, yaml = { "yamllint" }, json = { "jsonlint" }, diff --git a/lua/plugins/nvim-origami.lua b/lua/plugins/nvim-origami.lua new file mode 100644 index 0000000..aa01ed2 --- /dev/null +++ b/lua/plugins/nvim-origami.lua @@ -0,0 +1,98 @@ +return { + "chrisgrieser/nvim-origami", + event = "VeryLazy", + keys = { + { "z1", desc = "Fold level 1" }, + { "z2", desc = "Fold level 2" }, + { "z3", desc = "Fold level 3" }, + { "z4", desc = "Fold level 4" }, + { "z5", desc = "Fold level 5" }, + { "zP", desc = "Pick fold" }, + }, + init = function() + -- disable vim's auto-folding (recommended by origami) + vim.o.foldcolumn = "1" + vim.o.foldlevel = 99 + vim.o.foldlevelstart = 99 + vim.o.foldenable = true + end, + opts = { + useLspFoldsWithTreesitterFallback = { + enabled = true, + foldmethodIfNeitherIsAvailable = "indent", + }, + pauseFoldsOnSearch = true, + foldtext = { + enabled = true, + padding = { character = " ", width = 3 }, + lineCount = { + template = " %d lines", + hlgroup = "Comment", + }, + diagnosticsCount = true, + gitsignsCount = true, + }, + autoFold = { + enabled = true, + kinds = { "comment", "imports" }, + }, + foldKeymaps = { + setup = true, -- h/l/^/$ become fold-aware at line edges + closeOnlyOnFirstColumn = false, + scrollLeftOnCaret = false, + }, + }, + config = function(_, opts) + require("origami").setup(opts) + + -- Quick fold-level shortcuts: z1..z5 set foldlevel + for i = 1, 5 do + vim.keymap.set("n", "z" .. i, function() + vim.o.foldlevel = i + end, { desc = "Fold level " .. i }) + end + + -- Snacks picker: list every fold in the current buffer, jump on confirm + vim.keymap.set("n", "zP", function() + local ok, Snacks = pcall(require, "snacks") + if not ok then + vim.notify("snacks.nvim not available", vim.log.levels.WARN) + return + end + + local bufnr = vim.api.nvim_get_current_buf() + local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) + local items = {} + for lnum = 1, #lines do + local fs = vim.fn.foldlevel(lnum) + local prev = lnum > 1 and vim.fn.foldlevel(lnum - 1) or 0 + if fs > 0 and fs > prev then + local text = lines[lnum] + table.insert(items, { + text = string.format("%4d %s%s", lnum, string.rep(" ", fs - 1), text), + file = vim.api.nvim_buf_get_name(bufnr), + pos = { lnum, 0 }, + }) + end + end + + if #items == 0 then + vim.notify("No folds in buffer", vim.log.levels.INFO) + return + end + + Snacks.picker.pick({ + title = "Folds", + items = items, + format = "text", + confirm = function(picker, item) + picker:close() + if item then + vim.api.nvim_win_set_cursor(0, item.pos) + vim.cmd("normal! zv") + end + end, + }) + end, { desc = "Pick fold" }) + end, +} diff --git a/lua/plugins/nvim-treesitter.lua b/lua/plugins/nvim-treesitter.lua index b146ab1..33d5197 100644 --- a/lua/plugins/nvim-treesitter.lua +++ b/lua/plugins/nvim-treesitter.lua @@ -12,6 +12,11 @@ return { "bash", "c", "diff", + "go", + "gomod", + "gosum", + "gowork", + "hcl", "html", "javascript", "jsdoc", @@ -25,6 +30,7 @@ return { "python", "query", "regex", + "terraform", "toml", "tsx", "typescript", diff --git a/lua/plugins/nvim-ufo.lua b/lua/plugins/nvim-ufo.lua index 3cc2b1f..abb4ab9 100644 --- a/lua/plugins/nvim-ufo.lua +++ b/lua/plugins/nvim-ufo.lua @@ -1,5 +1,6 @@ return { "kevinhwang91/nvim-ufo", + enabled = false, -- trying nvim-origami instead; flip to true to switch back dependencies = "kevinhwang91/promise-async", event = { "BufReadPost", "BufNewFile" }, keys = { @@ -7,6 +8,12 @@ return { { "zM", desc = "Close all folds" }, { "zr", desc = "Open folds except kinds" }, { "zm", desc = "Close folds with" }, + { "z1", desc = "Fold level 1" }, + { "z2", desc = "Fold level 2" }, + { "z3", desc = "Fold level 3" }, + { "z4", desc = "Fold level 4" }, + { "z5", desc = "Fold level 5" }, + { "zP", desc = "Pick fold" }, }, init = function() -- Fold options must be set before ufo loads so folds work on first buffer @@ -51,5 +58,55 @@ return { vim.lsp.buf.hover({ border = "rounded" }) end end, { desc = "Peek fold or hover" }) + + -- Quick fold-level shortcuts: z1..z5 set foldlevel and close deeper folds + for i = 1, 5 do + vim.keymap.set("n", "z" .. i, function() + require("ufo").closeFoldsWith(i) + end, { desc = "Fold level " .. i }) + end + + -- Snacks picker: list every fold in the current buffer, jump on confirm + vim.keymap.set("n", "zP", function() + local ok, Snacks = pcall(require, "snacks") + if not ok then + vim.notify("snacks.nvim not available", vim.log.levels.WARN) + return + end + + local bufnr = vim.api.nvim_get_current_buf() + local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) + local items = {} + for lnum = 1, #lines do + local fs = vim.fn.foldlevel(lnum) + local prev = lnum > 1 and vim.fn.foldlevel(lnum - 1) or 0 + if fs > 0 and fs > prev then + local text = lines[lnum] + table.insert(items, { + text = string.format("%4d %s%s", lnum, string.rep(" ", fs - 1), text), + file = vim.api.nvim_buf_get_name(bufnr), + pos = { lnum, 0 }, + }) + end + end + + if #items == 0 then + vim.notify("No folds in buffer", vim.log.levels.INFO) + return + end + + Snacks.picker.pick({ + title = "Folds", + items = items, + format = "text", + confirm = function(picker, item) + picker:close() + if item then + vim.api.nvim_win_set_cursor(0, item.pos) + vim.cmd("normal! zv") + end + end, + }) + end, { desc = "Pick fold" }) end, } diff --git a/lua/plugins/snacks.lua b/lua/plugins/snacks.lua index cc0f4d9..f0deb44 100644 --- a/lua/plugins/snacks.lua +++ b/lua/plugins/snacks.lua @@ -47,12 +47,53 @@ return { }, ----- image = { - enabled = false, + enabled = true, + }, + ----- + -- Auto-disable LSP/treesitter/etc. on huge files (>1.5MB by default). + bigfile = { + enabled = true, + }, + ----- + -- Render the file before plugins load for a snappier startup feel. + quickfile = { + enabled = true, + }, + ----- + -- Pretty floating prompt for vim.ui.input (rename, etc.). + input = { + enabled = true, + }, + ----- + -- Combined number + sign + fold column with git sign integration. + statuscolumn = { + enabled = true, + }, + ----- + -- Smooth scrolling (replaces neoscroll). + scroll = { + enabled = true, + }, + ----- + -- Highlight + jump between LSP references to the word under cursor + -- (replaces vim-illuminate). Keymaps `]w` / `[w` are already defined below. + words = { + enabled = true, }, ----- picker = { enabled = true, hidden = true, + sources = { + files = { + exclude = { + ".git", + ".devenv", + ".direnv", + "node_modules", + }, + }, + }, actions = { trouble_open = function(...) return require("trouble.sources.snacks").actions.trouble_open.action(...) @@ -70,6 +111,7 @@ return { explorer = { enabled = true, hidden = true, + ignored = true, }, ----- indent = { @@ -117,7 +159,7 @@ return { { "ff", function() - Snacks.picker.files({ hidden = true }) + Snacks.picker.files({ hidden = true, ignored = true }) end, desc = "Find Files", }, diff --git a/lua/plugins/vim-illuminate.lua b/lua/plugins/vim-illuminate.lua deleted file mode 100644 index ba2383d..0000000 --- a/lua/plugins/vim-illuminate.lua +++ /dev/null @@ -1,40 +0,0 @@ -return { - { - "RRethy/vim-illuminate", - event = { "BufReadPost", "BufNewFile" }, - config = function() - require("illuminate").configure({ - providers = { - "lsp", - "treesitter", - "regex", - }, - delay = 100, - filetype_overrides = {}, - filetypes_denylist = { - "dirvish", - "fugitive", - "Trouble", - "snacks_dashboard", - }, - filetypes_allowlist = {}, - modes_denylist = {}, - modes_allowlist = {}, - providers_regex_syntax_denylist = {}, - providers_regex_syntax_allowlist = {}, - under_cursor = true, - large_file_cutoff = nil, - large_file_overrides = nil, - min_count_to_highlight = 1, - }) - - -- Keymaps for reference navigation - vim.keymap.set("n", "", function() - require("illuminate").goto_next_reference() - end, { desc = "Next reference" }) - vim.keymap.set("n", "", function() - require("illuminate").goto_prev_reference() - end, { desc = "Previous reference" }) - end, - }, -} diff --git a/snippets/go.json b/snippets/go.json index d74abfb..8804355 100644 --- a/snippets/go.json +++ b/snippets/go.json @@ -2,11 +2,40 @@ "function": { "prefix": "func", "body": [ - "func ${1:functionName}(${2}) ${3:returnType} {", + "func ${1:functionName}(${2})${3: returnType} {", "\t${0}", "}" ], - "description": "Function declaration" + "description": "Function declaration (delete placeholder for void return)" + }, + "function returning error": { + "prefix": "funce", + "body": [ + "func ${1:functionName}(${2}) error {", + "\t${0}", + "\treturn nil", + "}" + ], + "description": "Function returning error" + }, + "function returning (T, error)": { + "prefix": "functe", + "body": [ + "func ${1:functionName}(${2}) (${3:T}, error) {", + "\t${0}", + "\treturn ${4:zero}, nil", + "}" + ], + "description": "Function returning (T, error)" + }, + "method": { + "prefix": "method", + "body": [ + "func (${1:r} ${2:Receiver}) ${3:Name}(${4})${5: returnType} {", + "\t${0}", + "}" + ], + "description": "Method with receiver (delete placeholder for void return)" }, "struct": { "prefix": "struct", @@ -17,6 +46,25 @@ ], "description": "Struct declaration" }, + "json-tagged struct": { + "prefix": "jstruct", + "body": [ + "type ${1:StructName} struct {", + "\t${2:FieldName} ${3:string} `json:\"${4:field_name}${5:,omitempty}\"`", + "\t$0", + "}" + ], + "description": "Struct seeded with one json-tagged field (wire type)" + }, + "interface": { + "prefix": "interface", + "body": [ + "type ${1:Name} interface {", + "\t${0}", + "}" + ], + "description": "Interface declaration" + }, "if err != nil": { "prefix": "iferr", "body": [ @@ -25,5 +73,234 @@ "}" ], "description": "Standard error check" + }, + "if err != nil (wrap)": { + "prefix": "iferrf", + "body": [ + "if err != nil {", + "\treturn ${1:nil, }fmt.Errorf(\"${2:context}: %w\", err)", + "}" + ], + "description": "Error check wrapping with fmt.Errorf and %w" + }, + "if err != nil (test fatal)": { + "prefix": "iferrt", + "body": [ + "if err != nil {", + "\tt.Fatalf(\"${1:context}: %v\", err)", + "}" + ], + "description": "Error check that fails the test" + }, + "got want equal": { + "prefix": "gotwant", + "body": [ + "if got, want := ${1:expr}, ${2:expected}; !reflect.DeepEqual(got, want) {", + "\tt.Errorf(\"${3:name} = %v, want %v\", got, want)", + "}" + ], + "description": "Standard got/want equality assertion" + }, + "test function": { + "prefix": "tparallel", + "body": [ + "func Test${1:Name}(t *testing.T) {", + "\tt.Parallel()", + "", + "\t${0}", + "}" + ], + "description": "Test function with t.Parallel()" + }, + "table-driven test": { + "prefix": "ttable", + "body": [ + "func Test${1:Name}(t *testing.T) {", + "\tt.Parallel()", + "", + "\ttests := []struct {", + "\t\tname string", + "\t\t${2:in} ${3:string}", + "\t\twant ${4:string}", + "\t}{", + "\t\t{name: \"${5:case}\", $2: ${6}, want: ${7}},", + "\t}", + "", + "\tfor _, tt := range tests {", + "\t\tt.Run(tt.name, func(t *testing.T) {", + "\t\t\tt.Parallel()", + "", + "\t\t\t${0}", + "\t\t})", + "\t}", + "}" + ], + "description": "Table-driven test scaffold" + }, + "test helper": { + "prefix": "thelp", + "body": [ + "func ${1:helperName}(t *testing.T${2}) ${3:string} {", + "\tt.Helper()", + "", + "\t${0}", + "}" + ], + "description": "Test helper with t.Helper()" + }, + "benchmark": { + "prefix": "bench", + "body": [ + "func Benchmark${1:Name}(b *testing.B) {", + "\tfor i := 0; i < b.N; i++ {", + "\t\t${0}", + "\t}", + "}" + ], + "description": "Benchmark function" + }, + "MPL-2.0 header": { + "prefix": "mpl", + "body": [ + "// This Source Code Form is subject to the terms of the Mozilla Public", + "// License, v. 2.0. If a copy of the MPL was not distributed with this", + "// file, You can obtain one at https://mozilla.org/MPL/2.0/.", + "", + "package ${1:name}", + "", + "$0" + ], + "description": "MPL-2.0 file header + package line" + }, + "package doc": { + "prefix": "pkgdoc", + "body": [ + "// Package ${1:name} ${2:summary sentence.}", + "package $1", + "", + "$0" + ], + "description": "Package doc comment" + }, + "golden -update flag": { + "prefix": "goldenflag", + "body": [ + "// update regenerates the golden snapshot files when set. Run:", + "//", + "//\tgo test ./${1:pkg} -run ${2:TestName} -update", + "var update = flag.Bool(\"update\", false, \"regenerate golden snapshots\")", + "$0" + ], + "description": "Golden snapshot -update flag" + }, + "model.Diagnostic": { + "prefix": "diag", + "body": [ + "model.Diagnostic{", + "\tSeverity: model.Severity${1|Error,Warning|},", + "\tSummary: \"${2:summary}\",", + "\tDetail: \"${3:detail}\",", + "}$0" + ], + "description": "model.Diagnostic literal" + }, + "json-tagged field": { + "prefix": "jf", + "body": [ + "${1:FieldName} ${2:string} `json:\"${3:field_name}${4:,omitempty}\"`$0" + ], + "description": "Struct field with json tag (use inside a struct body)" + }, + "hcl BodySchema": { + "prefix": "hclschema", + "body": [ + "var ${1:name}Schema = &hcl.BodySchema{", + "\tAttributes: []hcl.AttributeSchema{", + "\t\t{Name: \"${2:attr}\"${3:, Required: true}},$0", + "\t},", + "\tBlocks: []hcl.BlockHeaderSchema{", + "\t\t{Type: \"${4:block}\"${5:, LabelNames: []string{\"name\"}}},", + "\t},", + "}" + ], + "description": "hcl.BodySchema with attributes and blocks" + }, + "hcl AttributeSchema entry": { + "prefix": "hclattr", + "body": [ + "{Name: \"${1:attr}\"${2:, Required: true}},$0" + ], + "description": "hcl.AttributeSchema row" + }, + "hcl BlockHeaderSchema entry": { + "prefix": "hclblock", + "body": [ + "{Type: \"${1:block}\"${2:, LabelNames: []string{\"name\"}}},$0" + ], + "description": "hcl.BlockHeaderSchema row" + }, + "hcl PartialContent decode": { + "prefix": "hcldecode", + "body": [ + "content, _, hdiag := ${1:block}.Body.PartialContent(${2:name}Schema)", + "diags := model.DiagnosticsFromHCL(hdiag)", + "$0" + ], + "description": "PartialContent + diagnostics translation" + }, + "hcl attribute lookup": { + "prefix": "hclattrlookup", + "body": [ + "if attribute, ok := content.Attributes[\"${1:name}\"]; ok {", + "\t${0}", + "}" + ], + "description": "Optional attribute lookup pattern" + }, + "hcl blocks OfType loop": { + "prefix": "hclblockloop", + "body": [ + "for _, ${1:inner} := range content.Blocks.OfType(\"${2:type}\") {", + "\t${0}", + "}" + ], + "description": "Iterate over inner blocks of a given type" + }, + "cobra subcommand": { + "prefix": "cobracmd", + "body": [ + "var ${1:name}Cmd = &cobra.Command{", + "\tUse: \"${2:$1}\",", + "\tShort: \"${3:short description}\",", + "\tLong: `${4:long description}`,", + "\tArgs: cobra.${5|NoArgs,ExactArgs(1),MaximumNArgs(1),MinimumNArgs(1),RangeArgs(1\\,2)|},", + "\tRunE: func(cmd *cobra.Command, args []string) error {", + "\t\t${0}", + "\t\treturn nil", + "\t},", + "}" + ], + "description": "Cobra subcommand definition" + }, + "cobra root command + main": { + "prefix": "cobraroot", + "body": [ + "var rootCmd = &cobra.Command{", + "\tUse: \"${1:open-inspector}\",", + "\tShort: \"${2:short description}\",", + "}", + "", + "func Execute() {", + "\tif err := rootCmd.Execute(); err != nil {", + "\t\tfmt.Fprintln(os.Stderr, err)", + "\t\tos.Exit(1)", + "\t}", + "}", + "", + "func init() {", + "\trootCmd.AddCommand(${3:childCmd})$0", + "}" + ], + "description": "Cobra root command with Execute() and init" } } diff --git a/snippets/package.json b/snippets/package.json index d7de5bc..ddf277f 100644 --- a/snippets/package.json +++ b/snippets/package.json @@ -14,15 +14,10 @@ "terraform", "terraform-vars", "opentofu", - "opentofu-vars" - ], - "path": "./terraform.json" - }, - { - "language": [ + "opentofu-vars", "tf" ], - "path": "./tf.json" + "path": "./terraform.json" } ] },