diff --git a/module-list.nix b/module-list.nix index a5e11c7..90a60ef 100644 --- a/module-list.nix +++ b/module-list.nix @@ -13,6 +13,7 @@ ./modules/plugins/theme/catppuccin.nix ./modules/plugins/style/neoformat.nix + ./modules/plugins/style/nvim-treesitter.nix ./modules/plugins/navigation/telescope.nix ./modules/plugins/navigation/nvim-tree.nix ./modules/plugins/gitsigns.nix diff --git a/modules/plugin.nix b/modules/plugin.nix index a299dd5..3d03103 100644 --- a/modules/plugin.nix +++ b/modules/plugin.nix @@ -59,7 +59,7 @@ let config = { name = lib.mkDefault name; - varName = lib.mkDefault (builtins.replaceStrings [ "-" "/" ] [ "_" "_" ] config.name); + varName = lib.mkDefault (builtins.replaceStrings [ "-" "/" "." ] [ "_" "_" "_" ] config.name); genConfig = with lib.nix2lua; lib.mkIf (!config.isDependency) (lib.flatten [ (local (set config.varName (require config.name))) diff --git a/modules/plugins/style/nvim-treesitter.nix b/modules/plugins/style/nvim-treesitter.nix new file mode 100644 index 0000000..928920a --- /dev/null +++ b/modules/plugins/style/nvim-treesitter.nix @@ -0,0 +1,121 @@ +{ config, lib, pkgs, ... }: + +let + inherit (builtins) elem attrNames; + + cfg = config.plugins.style.nvim-treesitter; + + treesitterWithGrammars = (cfg.treesitter.package.override { inherit (cfg) extraGrammars; }).withPlugins (lib.filterAtttrs (k: elem k (attrNames cfg.extraGrammars))); + + nvimTreeSitterWithBuiltinGrammars = + if cfg.grammars == null then cfg.package.withAllGrammars + else cfg.package.withPlugins cfg.grammars; + + finalNvimTreeSitter = + if cfg.extraGrammars == { } then nvimTreeSitterWithBuiltinGrammars + else + nvimTreeSitterWithBuiltinGrammars.overrideAttrs (oldAttrs: { + passthru.dependencies = oldAttrs.passthru.dependencies + ++ (lib.flip lib.mapAttrsToList cfg.extraGrammars (k: { language, ... }: + pkgs.runCommand "nvim-treesitter-${language}-grammar" { } '' + mkdir -p $out/parser + ln -s ${treesitterWithGrammars}/${language}.so $out/parser/${language}.so + '' + )); + + postPatch = oldAttrs.postPatch + (lib.concatLines + (lib.flip lib.mapAttrsToList cfg.extraGrammars (k: { src, language, ... }: + '' + if [ -d ${src}/queries ]; then + ln -s ${src}/queries queries/${language} + fi + '' + )) + ); + + }); +in +{ + options.plugins.style.nvim-treesitter = with lib; { + enable = mkEnableOption "nvim-treesitter"; + + package = mkPackageOption pkgs.vimPlugins "nvim-treesitter" { }; + + finalPackage = mkOption { + type = types.package; + visible = false; + readOnly = true; + description = "Resulting customized nvim-treesitter package."; + }; + + treesitter.package = mkPackageOption pkgs "tree-sitter" { }; + + grammars = mkOption { + type = with types; nullOr (functionTo (listOf package)); + default = null; + }; + + extraGrammars = mkOption { + type = with types; attrsOf attrs; + default = { }; + }; + + settings = mkOption { + type = types.attrs; + default = { }; + description = '' + Settings to configure nvim-treesitter. + + See: https://github.com/nvim-treesitter/nvim-treesitter?tab=readme-ov-file#modules + + - `highlight` and `indent` are enabled by default. + - `ensure_installed`, `sync_install`, `auto_install` will be ignored. + ''; + }; + + fold.enable = mkEnableOption "use nvim treesitter to fold expression" // { default = true; }; + }; + + config = lib.mkIf cfg.enable { + plugins.style.nvim-treesitter.finalPackage = finalNvimTreeSitter; + + plugin.nvim-treesitter = { + name = "nvim-treesitter.configs"; + package = finalNvimTreeSitter; + + beforeSetup = with lib.nix2lua; lib.optionals (cfg.extraGrammars != { }) (lib.flatten [ + (local (set "parser_config") + (pipe1 (require "nvim-treesitter.parsers") (call0 "get_parser_configs")) + ) + + (lib.mapAttrsToList (k: v: set "parser_config.${v.language}" { }) cfg.extraGrammars) + ]); + + setupSettings = lib.mkMerge [ + # enable hihlight and indent by default + { + highlight.enable = true; + indent.enable = true; + } + + # apply user settings + cfg.settings + + # force disable manual installation + # TODO: warn about that behavior + { + ensure_installed = { }; + sync_install = false; + auto_install = false; + } + ]; + }; + + vim.opt = lib.mkIf cfg.fold.enable { + foldmethod = "expr"; + foldexpr = "nvim_treesitter#foldexpr()"; + foldenable = lib.mkDefault false; # disable folding at startup + }; + }; + +}