From cee920622d343d4d457099e065b60826aa2a83cd Mon Sep 17 00:00:00 2001 From: Snoweuph Date: Sun, 8 Feb 2026 17:17:25 +0100 Subject: [PATCH] language/twig: add treesitter, LSP, diagnostics, and formatting support. Due to better tools like twig-cs-fixer and curlylint not beeing packaged in nix, this uses worse alterantives. --- configuration.nix | 1 + docs/manual/release-notes/rl-0.9.md | 5 ++ modules/plugins/languages/default.nix | 1 + modules/plugins/languages/twig.nix | 120 ++++++++++++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 modules/plugins/languages/twig.nix diff --git a/configuration.nix b/configuration.nix index 9cce777a..f82feb0a 100644 --- a/configuration.nix +++ b/configuration.nix @@ -101,6 +101,7 @@ isMaximal: { tailwind.enable = false; svelte.enable = false; tera.enable = false; + twig.enable = false; # Nim LSP is broken on Darwin and therefore # should be disabled by default. Users may still enable diff --git a/docs/manual/release-notes/rl-0.9.md b/docs/manual/release-notes/rl-0.9.md index 4a322868..720b7c99 100644 --- a/docs/manual/release-notes/rl-0.9.md +++ b/docs/manual/release-notes/rl-0.9.md @@ -222,6 +222,11 @@ - Added Formatting support to `languages.php` via [PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer). +- Added minimal `languages.twig`. Currently using [djlint](https://djlint.com/) + for most options, as better alternatives like + [twig-cs-fixer](https://github.com/VincentLanglet/Twig-CS-Fixer) aren't + packaged for nix. + - Didn't Add [`syntax-gaslighting`](https://github.com/NotAShelf/syntax-gaslighting.nvim), you're crazy. diff --git a/modules/plugins/languages/default.nix b/modules/plugins/languages/default.nix index 1cdead76..acaec5b3 100644 --- a/modules/plugins/languages/default.nix +++ b/modules/plugins/languages/default.nix @@ -23,6 +23,7 @@ in { ./kotlin.nix ./html.nix ./tera.nix + ./twig.nix ./haskell.nix ./java.nix ./jinja.nix diff --git a/modules/plugins/languages/twig.nix b/modules/plugins/languages/twig.nix new file mode 100644 index 00000000..8edcd024 --- /dev/null +++ b/modules/plugins/languages/twig.nix @@ -0,0 +1,120 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (builtins) attrNames; + inherit (lib.options) mkEnableOption mkOption; + inherit (lib.modules) mkIf mkMerge; + inherit (lib.meta) getExe; + inherit (lib.types) listOf enum; + inherit (lib.nvim.types) mkGrammarOption diagnostics; + inherit (lib.nvim.attrsets) mapListToAttrs; + + cfg = config.vim.languages.twig; + + defaultServers = ["twig-language-server"]; + servers = { + twig-language-server = { + enable = true; + cmd = [(getExe pkgs.twig-language-server) "--stdio"]; + filetypes = ["twig"]; + root_markers = [".git"]; + }; + }; + + defaultFormat = ["djlint"]; + formats = { + djlint = { + command = getExe pkgs.djlint; + }; + # TODO: if twig-cs-fixer gets packaged for nix, add it and default to it. + }; + defaultDiagnosticsProvider = ["djlint"]; + diagnosticsProviders = { + djlint = { + config = { + cmd = getExe pkgs.djlint; + }; + }; + # TODO: if curlylint gets packaged for nix, add it. + }; +in { + options.vim.languages.twig = { + enable = mkEnableOption "Twig templating language support"; + + treesitter = { + enable = mkEnableOption "Twig treesitter" // {default = config.vim.languages.enableTreesitter;}; + package = mkGrammarOption pkgs "twig"; + }; + + lsp = { + enable = mkEnableOption "Twig LSP support" // {default = config.vim.lsp.enable;}; + servers = mkOption { + type = listOf (enum (attrNames servers)); + default = defaultServers; + description = "Twig LSP server to use"; + }; + }; + + format = { + enable = mkEnableOption "PHP formatting" // {default = config.vim.languages.enableFormat;}; + type = mkOption { + description = "Twig formatter to use"; + type = listOf (enum (attrNames formats)); + default = defaultFormat; + }; + }; + + extraDiagnostics = { + enable = mkEnableOption "extra Twig diagnostics" // {default = config.vim.languages.enableExtraDiagnostics;}; + types = diagnostics { + langDesc = "Twig"; + inherit diagnosticsProviders; + inherit defaultDiagnosticsProvider; + }; + }; + }; + + config = mkIf cfg.enable (mkMerge [ + (mkIf cfg.treesitter.enable { + vim.treesitter.enable = true; + vim.treesitter.grammars = [cfg.treesitter.package]; + }) + + (mkIf cfg.lsp.enable { + vim.lsp.servers = + mapListToAttrs (n: { + name = n; + value = servers.${n}; + }) + cfg.lsp.servers; + }) + + (mkIf cfg.format.enable { + vim.formatter.conform-nvim = { + enable = true; + setupOpts = { + formatters_by_ft.twig = cfg.format.type; + formatters = + mapListToAttrs (name: { + inherit name; + value = formats.${name}; + }) + cfg.format.type; + }; + }; + }) + + (mkIf cfg.extraDiagnostics.enable { + vim.diagnostics.nvim-lint = { + enable = true; + linters_by_ft.twig = cfg.extraDiagnostics.types; + linters = + mkMerge (map (name: {${name} = diagnosticsProviders.${name}.config;}) + cfg.extraDiagnostics.types); + }; + }) + ]); +}