From 08d1df4643915a7715a58c0d24d292f89a3b5f04 Mon Sep 17 00:00:00 2001 From: Bryan Ramos Date: Thu, 30 Apr 2026 10:27:00 -0400 Subject: [PATCH 1/6] fix(treesitter): migrate to neovim 0.12 APIs --- lua/plugins/lsp.lua | 82 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua index c31339b..5b1e8d5 100644 --- a/lua/plugins/lsp.lua +++ b/lua/plugins/lsp.lua @@ -18,13 +18,40 @@ local mason_ensure_installed = { "yamlls", -- YAML } +local treesitter_parsers = { + "lua", + "c", + "cpp", + "python", + "nix", + "rust", + "bash", + "markdown", + "html", + "html_tags", + "javascript", + "ecma", + "jsx", + "css", + "vim", + "git_config", + "git_rebase", + "gitattributes", + "gitcommit", + "gitignore", +} + return { { - "nvim-treesitter/nvim-treesitter", + "neovim-treesitter/nvim-treesitter", + name = "nvim-treesitter", + dependencies = { "neovim-treesitter/treesitter-parser-registry" }, + lazy = false, build = ":TSUpdate", - config = function() - require('nvim-treesitter.configs').setup({ - ensure_installed = { + init = function() + vim.api.nvim_create_autocmd("FileType", { + group = vim.api.nvim_create_augroup("config_treesitter", { clear = true }), + pattern = { "lua", "c", "cpp", @@ -35,22 +62,47 @@ return { "markdown", "html", "javascript", + "javascriptreact", "css", - "vim", - - "git_config", - "git_rebase", + "gitconfig", + "gitrebase", "gitattributes", "gitcommit", - "gitignore" + "gitignore", }, - auto_install = true, - sync_install = true, - highlight = { - enable = true, - } + callback = function(event) + if pcall(vim.treesitter.start, event.buf) then + vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()" + vim.wo.foldmethod = "expr" + vim.bo[event.buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" + end + end, }) + end, + config = function() + require("nvim-treesitter").setup() + + local installed = require("nvim-treesitter.config").get_installed() + local missing = vim.iter(treesitter_parsers) + :filter(function(parser) + return not vim.tbl_contains(installed, parser) + end) + :totable() + + if #missing == 0 then + return + end + + if vim.fn.executable("tree-sitter") == 0 then + vim.notify_once( + "tree-sitter CLI is required to install or update parsers; enter a Nix shell that provides tree-sitter before running :TSUpdate", + vim.log.levels.WARN + ) + return + end + + require("nvim-treesitter").install(missing) end }, @@ -302,7 +354,7 @@ return { { "taproot-wizards/bitcoin-script-hints.nvim", - dependencies = { "nvim-treesitter/nvim-treesitter" }, + dependencies = { "nvim-treesitter" }, config = function() require("bitcoin-script-hints").setup() end From 0beb2bef07fc6ed9cfb21997218148a8307eef87 Mon Sep 17 00:00:00 2001 From: Bryan Ramos Date: Thu, 30 Apr 2026 10:27:03 -0400 Subject: [PATCH 2/6] chore(dev): add reproducible neovim tools --- flake.lock | 27 +++++++++++++++++++++++++++ flake.nix | 32 ++++++++++++++++++++++++++++++++ justfile | 10 ++++++++++ 3 files changed, 69 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 justfile diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..ff7718e --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1777268161, + "narHash": "sha256-bxrdOn8SCOv8tN4JbTF/TXq7kjo9ag4M+C8yzzIRYbE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1c3fe55ad329cbcb28471bb30f05c9827f724c76", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..1242ede --- /dev/null +++ b/flake.nix @@ -0,0 +1,32 @@ +{ + description = "Neovim configuration development tools"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = { nixpkgs, ... }: + let + supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; + forAllSystems = nixpkgs.lib.genAttrs supportedSystems; + in + { + devShells = forAllSystems (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + { + default = pkgs.mkShell { + packages = with pkgs; [ + curl + gcc + git + just + neovim + stylua + tree-sitter + ]; + }; + }); + }; +} diff --git a/justfile b/justfile new file mode 100644 index 0000000..f876a5e --- /dev/null +++ b/justfile @@ -0,0 +1,10 @@ +treesitter_parsers := "lua c cpp python nix rust bash markdown html html_tags javascript ecma jsx css vim git_config git_rebase gitattributes gitcommit gitignore" + +default: + just --list + +check: + nvim --headless README.md '+checkhealth vim.treesitter' '+qa' + +update-treesitter: + nvim --headless "+lua require('nvim-treesitter').install(vim.split('{{treesitter_parsers}}', ' ')):wait(300000)" '+qa' From 165488546a7745528322837bd84a3f27baa5b384 Mon Sep 17 00:00:00 2001 From: Bryan Ramos Date: Thu, 30 Apr 2026 10:31:55 -0400 Subject: [PATCH 3/6] Revert "chore(dev): add reproducible neovim tools" This reverts commit fdb943672ef0d1ca09bddf1a4f9e3675c857d945. --- flake.lock | 27 --------------------------- flake.nix | 32 -------------------------------- justfile | 10 ---------- 3 files changed, 69 deletions(-) delete mode 100644 flake.lock delete mode 100644 flake.nix delete mode 100644 justfile diff --git a/flake.lock b/flake.lock deleted file mode 100644 index ff7718e..0000000 --- a/flake.lock +++ /dev/null @@ -1,27 +0,0 @@ -{ - "nodes": { - "nixpkgs": { - "locked": { - "lastModified": 1777268161, - "narHash": "sha256-bxrdOn8SCOv8tN4JbTF/TXq7kjo9ag4M+C8yzzIRYbE=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "1c3fe55ad329cbcb28471bb30f05c9827f724c76", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "nixpkgs": "nixpkgs" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index 1242ede..0000000 --- a/flake.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - description = "Neovim configuration development tools"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - }; - - outputs = { nixpkgs, ... }: - let - supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; - forAllSystems = nixpkgs.lib.genAttrs supportedSystems; - in - { - devShells = forAllSystems (system: - let - pkgs = nixpkgs.legacyPackages.${system}; - in - { - default = pkgs.mkShell { - packages = with pkgs; [ - curl - gcc - git - just - neovim - stylua - tree-sitter - ]; - }; - }); - }; -} diff --git a/justfile b/justfile deleted file mode 100644 index f876a5e..0000000 --- a/justfile +++ /dev/null @@ -1,10 +0,0 @@ -treesitter_parsers := "lua c cpp python nix rust bash markdown html html_tags javascript ecma jsx css vim git_config git_rebase gitattributes gitcommit gitignore" - -default: - just --list - -check: - nvim --headless README.md '+checkhealth vim.treesitter' '+qa' - -update-treesitter: - nvim --headless "+lua require('nvim-treesitter').install(vim.split('{{treesitter_parsers}}', ' ')):wait(300000)" '+qa' From 6e5c670a31784e900c86dd3dc46500944aff4926 Mon Sep 17 00:00:00 2001 From: Bryan Ramos Date: Thu, 30 Apr 2026 10:36:45 -0400 Subject: [PATCH 4/6] fix(treesitter): bootstrap cli with mason --- lua/plugins/lsp.lua | 105 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 94 insertions(+), 11 deletions(-) diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua index 5b1e8d5..fb62760 100644 --- a/lua/plugins/lsp.lua +++ b/lua/plugins/lsp.lua @@ -45,7 +45,13 @@ return { { "neovim-treesitter/nvim-treesitter", name = "nvim-treesitter", - dependencies = { "neovim-treesitter/treesitter-parser-registry" }, + dependencies = { + "neovim-treesitter/treesitter-parser-registry", + { + "williamboman/mason.nvim", + enabled = not is_nixos, + }, + }, lazy = false, build = ":TSUpdate", init = function() @@ -83,6 +89,87 @@ return { config = function() require("nvim-treesitter").setup() + local function has_c_compiler() + return vim.fn.executable("cc") == 1 + or vim.fn.executable("gcc") == 1 + or vim.fn.executable("clang") == 1 + end + + local function install_missing_parsers(missing) + if not has_c_compiler() then + vim.notify_once( + "A C compiler is required to install or update Treesitter parsers", + vim.log.levels.WARN + ) + return + end + + require("nvim-treesitter").install(missing) + end + + local function ensure_treesitter_cli(callback) + if vim.fn.executable("tree-sitter") == 1 then + callback() + return + end + + if #vim.api.nvim_list_uis() == 0 then + return + end + + if is_nixos then + vim.notify_once( + "tree-sitter CLI is required to install or update parsers; provide it through your Nix system or dev environment before running :TSUpdate", + vim.log.levels.WARN + ) + return + end + + local mason_ok, mason = pcall(require, "mason") + local registry_ok, registry = pcall(require, "mason-registry") + if not mason_ok or not registry_ok then + vim.notify_once( + "tree-sitter CLI is required to install or update parsers; install tree-sitter-cli or enable mason.nvim", + vim.log.levels.WARN + ) + return + end + + mason.setup() + registry.refresh(function() + local package_ok, package = pcall(registry.get_package, "tree-sitter-cli") + if not package_ok then + vim.notify_once( + "Mason registry does not include tree-sitter-cli; install tree-sitter-cli before running :TSUpdate", + vim.log.levels.WARN + ) + return + end + + if package:is_installed() then + callback() + return + end + + if package:is_installing() then + vim.notify_once("tree-sitter-cli is already being installed by Mason", vim.log.levels.INFO) + return + end + + vim.notify_once("Installing tree-sitter-cli with Mason for Treesitter parser updates", vim.log.levels.INFO) + package:install({}, function(success, error) + if success then + callback() + else + vim.notify( + "Failed to install tree-sitter-cli with Mason: " .. tostring(error), + vim.log.levels.WARN + ) + end + end) + end) + end + local installed = require("nvim-treesitter.config").get_installed() local missing = vim.iter(treesitter_parsers) :filter(function(parser) @@ -90,19 +177,15 @@ return { end) :totable() - if #missing == 0 then + if #missing == 0 and (is_nixos or #vim.api.nvim_list_uis() == 0) then return end - if vim.fn.executable("tree-sitter") == 0 then - vim.notify_once( - "tree-sitter CLI is required to install or update parsers; enter a Nix shell that provides tree-sitter before running :TSUpdate", - vim.log.levels.WARN - ) - return - end - - require("nvim-treesitter").install(missing) + ensure_treesitter_cli(function() + if #missing > 0 then + install_missing_parsers(missing) + end + end) end }, From 798a266ed7bf68e0259f266af70c88472da8aa4a Mon Sep 17 00:00:00 2001 From: Bryan Ramos Date: Thu, 30 Apr 2026 10:41:11 -0400 Subject: [PATCH 5/6] fix(mason): enable portable tool installs --- lua/plugins/disabled.lua | 2 -- lua/plugins/lsp.lua | 51 +++++++++++++++++++++------------------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/lua/plugins/disabled.lua b/lua/plugins/disabled.lua index 64e75ec..0b7a483 100644 --- a/lua/plugins/disabled.lua +++ b/lua/plugins/disabled.lua @@ -1,5 +1,3 @@ return { - { "williamboman/mason.nvim", enabled = false }, - { "williamboman/mason-lspconfig.nvim", enabled = false }, { "jay-babu/mason-nvim-dap.nvim", enabled = false }, } diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua index fb62760..1260b2a 100644 --- a/lua/plugins/lsp.lua +++ b/lua/plugins/lsp.lua @@ -1,11 +1,7 @@ -- Neovim 0.11+ LSP configuration -- Uses nvim-lspconfig for server definitions + vim.lsp.enable() API --- Detect NixOS (Mason doesn't work on NixOS due to FHS issues) -local is_nixos = vim.fn.filereadable("/etc/NIXOS") == 1 - --- Servers to ensure are installed via Mason (non-NixOS only) --- On NixOS, install these via extraPackages or per-project devShells +-- Servers to ensure are installed via Mason. local mason_ensure_installed = { "lua_ls", -- Neovim config "nil_ls", -- Nix (nixd not available in Mason) @@ -47,10 +43,7 @@ return { name = "nvim-treesitter", dependencies = { "neovim-treesitter/treesitter-parser-registry", - { - "williamboman/mason.nvim", - enabled = not is_nixos, - }, + "williamboman/mason.nvim", }, lazy = false, build = ":TSUpdate", @@ -107,8 +100,25 @@ return { require("nvim-treesitter").install(missing) end + local function tree_sitter_cli_works() + if vim.fn.executable("tree-sitter") == 0 then + return false + end + + local result = vim.system({ "tree-sitter", "--version" }, { text = true }):wait() + if result.code == 0 then + return true + end + + vim.notify_once( + "tree-sitter CLI is installed but cannot run. On NixOS, enable nix-ld so Mason-installed binaries can execute.", + vim.log.levels.WARN + ) + return false + end + local function ensure_treesitter_cli(callback) - if vim.fn.executable("tree-sitter") == 1 then + if tree_sitter_cli_works() then callback() return end @@ -117,14 +127,6 @@ return { return end - if is_nixos then - vim.notify_once( - "tree-sitter CLI is required to install or update parsers; provide it through your Nix system or dev environment before running :TSUpdate", - vim.log.levels.WARN - ) - return - end - local mason_ok, mason = pcall(require, "mason") local registry_ok, registry = pcall(require, "mason-registry") if not mason_ok or not registry_ok then @@ -147,7 +149,9 @@ return { end if package:is_installed() then - callback() + if tree_sitter_cli_works() then + callback() + end return end @@ -158,7 +162,7 @@ return { vim.notify_once("Installing tree-sitter-cli with Mason for Treesitter parser updates", vim.log.levels.INFO) package:install({}, function(success, error) - if success then + if success and tree_sitter_cli_works() then callback() else vim.notify( @@ -177,7 +181,7 @@ return { end) :totable() - if #missing == 0 and (is_nixos or #vim.api.nvim_list_uis() == 0) then + if #missing == 0 and #vim.api.nvim_list_uis() == 0 then return end @@ -248,17 +252,16 @@ return { end }, - -- Mason: portable LSP installer (disabled on NixOS where it doesn't work) + -- Mason: portable LSP installer. On NixOS this requires nix-ld for + -- downloaded Linux binaries to run. { "williamboman/mason.nvim", - enabled = not is_nixos, config = function() require("mason").setup() end }, { "williamboman/mason-lspconfig.nvim", - enabled = not is_nixos, dependencies = { "williamboman/mason.nvim" }, config = function() require("mason-lspconfig").setup({ From f11e6a02db5cd8e4c8c1bdec0d34557ff995c32c Mon Sep 17 00:00:00 2001 From: Bryan Ramos Date: Thu, 30 Apr 2026 10:43:31 -0400 Subject: [PATCH 6/6] fix(treesitter): avoid auto-closing folds --- lazy-lock.json | 28 ++++++++++++++++++++++++++++ lua/plugins/lsp.lua | 2 -- 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 lazy-lock.json diff --git a/lazy-lock.json b/lazy-lock.json new file mode 100644 index 0000000..f403e7c --- /dev/null +++ b/lazy-lock.json @@ -0,0 +1,28 @@ +{ + "LuaSnip": { "branch": "master", "commit": "642b0c595e11608b4c18219e93b88d7637af27bc" }, + "autoclose.nvim": { "branch": "main", "commit": "bafd0368716216fa6a7bb2a43ecd889b44efdb46" }, + "base16-vim": { "branch": "master", "commit": "3be3cd82cd31acfcab9a41bad853d9c68d30478d" }, + "bitcoin-script-hints.nvim": { "branch": "main", "commit": "628badbb09a230e3838d863b21dcc07cdd2429bc" }, + "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, + "cmp-nvim-lsp": { "branch": "main", "commit": "cbc7b02bb99fae35cb42f514762b89b5126651ef" }, + "cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" }, + "gitsigns.nvim": { "branch": "main", "commit": "6d808f99bd63303646794406e270bd553ad7792e" }, + "indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" }, + "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, + "log-highlight.nvim": { "branch": "main", "commit": "ca88628f6dd3b9bb46f9a7401669e24cf7de47a4" }, + "lualine.nvim": { "branch": "master", "commit": "131a558e13f9f28b15cd235557150ccb23f89286" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "0c2823e0418f3d9230ff8b201c976e84de1cb401" }, + "mason.nvim": { "branch": "main", "commit": "cb8445f8ce85d957416c106b780efd51c6298f89" }, + "neo-tree.nvim": { "branch": "main", "commit": "19d20a99bf0061a5ecc4343d2f09fa713306c965" }, + "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" }, + "nvim-cmp": { "branch": "main", "commit": "a1d504892f2bc56c2e79b65c6faded2fd21f3eca" }, + "nvim-lspconfig": { "branch": "master", "commit": "f7e89f3d19fb436e1fbeff3bf4291eef35da94e3" }, + "nvim-navic": { "branch": "master", "commit": "f5eba192f39b453675d115351808bd51276d9de5" }, + "nvim-treesitter": { "branch": "main", "commit": "df7489eeea351bece7fd0f9c825be5cb6a1438f0" }, + "nvim-web-devicons": { "branch": "master", "commit": "4fc505ac7bd7692824a142e96e5f529c133862f8" }, + "plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" }, + "telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" }, + "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, + "treesitter-parser-registry": { "branch": "main", "commit": "6eb15358bb9fc88f0d3401d8538d56652e9bdf3c" }, + "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } +} diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua index 1260b2a..3372cff 100644 --- a/lua/plugins/lsp.lua +++ b/lua/plugins/lsp.lua @@ -72,8 +72,6 @@ return { }, callback = function(event) if pcall(vim.treesitter.start, event.buf) then - vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()" - vim.wo.foldmethod = "expr" vim.bo[event.buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" end end,