diff --git a/docs/release-notes/rl-0.8.md b/docs/release-notes/rl-0.8.md index a1a967ff..c01bc043 100644 --- a/docs/release-notes/rl-0.8.md +++ b/docs/release-notes/rl-0.8.md @@ -352,6 +352,7 @@ [rrvsh](https://github.com/rrvsh): +- Add custom snippet support to `vim.snippets.luasnip` - Fix namespace of python-lsp-server by changing it to python3Packages [Noah765](https://github.com/Noah765): diff --git a/modules/plugins/snippets/luasnip/config.nix b/modules/plugins/snippets/luasnip/config.nix index 11be37c1..5f2abdf0 100644 --- a/modules/plugins/snippets/luasnip/config.nix +++ b/modules/plugins/snippets/luasnip/config.nix @@ -1,11 +1,48 @@ { config, lib, + pkgs, ... }: let inherit (lib.modules) mkIf; + inherit (lib.lists) replicate; + inherit + (lib.strings) + optionalString + removeSuffix + concatStrings + stringAsChars + concatMapStringsSep + ; + inherit (lib.attrsets) mapAttrsToList; + inherit (pkgs) writeTextFile; cfg = config.vim.snippets.luasnip; + # LuaSnip freaks out if the indentation is wrong in snippets + indent = n: s: let + indentString = concatStrings (replicate n " "); + sep = "\n" + indentString; + in + indentString + + stringAsChars (c: + if c == "\n" + then sep + else c) (removeSuffix "\n" s); + customSnipmateSnippetFiles = + mapAttrsToList ( + name: value: + writeTextFile { + name = "${name}.snippets"; + text = + concatMapStringsSep "\n" (x: '' + snippet ${x.trigger} ${x.description} + ${indent 2 x.body} + '') + value; + destination = "/snippets/${name}.snippets"; + } + ) + cfg.customSnippets.snipmate; in { config = mkIf cfg.enable { vim = { @@ -19,11 +56,16 @@ in { after = cfg.loaders; }; - startPlugins = cfg.providers; + startPlugins = cfg.providers ++ customSnipmateSnippetFiles; autocomplete.nvim-cmp = mkIf config.vim.autocomplete.nvim-cmp.enable { sources = {luasnip = "[LuaSnip]";}; sourcePlugins = ["cmp-luasnip"]; }; + snippets.luasnip.loaders = '' + ${optionalString ( + cfg.customSnippets.snipmate != {} + ) "require('luasnip.loaders.from_snipmate').lazy_load()"} + ''; }; }; } diff --git a/modules/plugins/snippets/luasnip/luasnip.nix b/modules/plugins/snippets/luasnip/luasnip.nix index 6b189b61..601dc109 100644 --- a/modules/plugins/snippets/luasnip/luasnip.nix +++ b/modules/plugins/snippets/luasnip/luasnip.nix @@ -1,6 +1,6 @@ {lib, ...}: let inherit (lib.options) mkEnableOption mkOption literalExpression literalMD; - inherit (lib.types) listOf lines; + inherit (lib.types) listOf lines submodule str attrsOf; inherit (lib.nvim.types) pluginType mkPluginSetupOption; in { options.vim.snippets.luasnip = { @@ -36,5 +36,61 @@ in { setupOpts = mkPluginSetupOption "LuaSnip" { enable_autosnippets = mkEnableOption "autosnippets"; }; + + customSnippets.snipmate = mkOption { + type = attrsOf ( + listOf (submodule { + options = { + trigger = mkOption { + type = str; + description = '' + The trigger used to activate this snippet. + ''; + }; + description = mkOption { + type = str; + default = ""; + description = '' + The description shown for this snippet. + ''; + }; + body = mkOption { + type = str; + description = '' + [LuaSnip Documentation]: https://github.com/L3MON4D3/LuaSnip#add-snippets + The body of the snippet in SnipMate format (see [LuaSnip Documentation]). + ''; + }; + }; + }) + ); + default = {}; + example = '' + { + all = [ + { + trigger = "if"; + body = "if $1 else $2"; + } + ]; + nix = [ + { + trigger = "mkOption"; + body = ''' + mkOption { + type = $1; + default = $2; + description = $3; + example = $4; + } + '''; + } + ]; + } + ''; + description = '' + A list containing custom snippets in the SnipMate format to be loaded by LuaSnip. + ''; + }; }; }