feat(snippets/luasnip): allow custom snippets

This commit is contained in:
Mohammad Rafiq 2025-06-17 11:23:43 +08:00
commit 8c7fdc0f5d
No known key found for this signature in database
3 changed files with 101 additions and 2 deletions

View file

@ -352,6 +352,7 @@
[rrvsh](https://github.com/rrvsh): [rrvsh](https://github.com/rrvsh):
- Add custom snippet support to `vim.snippets.luasnip`
- Fix namespace of python-lsp-server by changing it to python3Packages - Fix namespace of python-lsp-server by changing it to python3Packages
[Noah765](https://github.com/Noah765): [Noah765](https://github.com/Noah765):

View file

@ -1,11 +1,48 @@
{ {
config, config,
lib, lib,
pkgs,
... ...
}: let }: let
inherit (lib.modules) mkIf; 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; 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 { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {
@ -19,11 +56,16 @@ in {
after = cfg.loaders; after = cfg.loaders;
}; };
startPlugins = cfg.providers; startPlugins = cfg.providers ++ customSnipmateSnippetFiles;
autocomplete.nvim-cmp = mkIf config.vim.autocomplete.nvim-cmp.enable { autocomplete.nvim-cmp = mkIf config.vim.autocomplete.nvim-cmp.enable {
sources = {luasnip = "[LuaSnip]";}; sources = {luasnip = "[LuaSnip]";};
sourcePlugins = ["cmp-luasnip"]; sourcePlugins = ["cmp-luasnip"];
}; };
snippets.luasnip.loaders = ''
${optionalString (
cfg.customSnippets.snipmate != {}
) "require('luasnip.loaders.from_snipmate').lazy_load()"}
'';
}; };
}; };
} }

View file

@ -1,6 +1,6 @@
{lib, ...}: let {lib, ...}: let
inherit (lib.options) mkEnableOption mkOption literalExpression literalMD; 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; inherit (lib.nvim.types) pluginType mkPluginSetupOption;
in { in {
options.vim.snippets.luasnip = { options.vim.snippets.luasnip = {
@ -36,5 +36,61 @@ in {
setupOpts = mkPluginSetupOption "LuaSnip" { setupOpts = mkPluginSetupOption "LuaSnip" {
enable_autosnippets = mkEnableOption "autosnippets"; 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.
'';
};
}; };
} }