{ config, lib, pkgs, ... }: let inherit (lib.nix2lua) LuaNil scope lset pipe1 call call1; cfg = config.plugins.snippet.luasnip; jump = lib.mkOption { type = with lib.types; nullOr number; default = null; description = '' This determines when this node will be jumped to. `:help luasnip-insertnode` `:help luasnip-basics-jump-index` ''; }; unwrapJump = index: if index == null then LuaNil else index; nodes = lib.mkOption { type = with lib.types; listOf (submodule snippetNodeOpts); }; unwrapNodes = map (n: n.genConfig); genConfig = lib.mkOption { type = lib.types.attrs; internal = true; }; snippetNodeOpts = { config, ... }: { options = with lib; with types; { text = mkOption { type = nullOr (either str (listOf str)); default = null; }; insert = mkOption { type = nullOr (either number (submodule ({ ... }: { options = { inherit jump; text = mkOption { type = nullOr (either str (listOf str)); default = null; description = '' A single string for just one line, a list with entries for multiple lines. This text will be SELECTed when the `insertNode` is jumped into. `:help luasnip-insertnode` ''; }; }; }))); default = null; }; choice = mkOption { type = nullOr (submodule ({ ... }: { options = { inherit jump nodes; }; })); default = null; }; snippet = mkOption { type = nullOr (submodule ({ ... }: { options = { inherit jump nodes; indent = mkOption { type = types.str; default = ""; }; }; })); default = null; }; inherit genConfig; }; config = { genConfig = let ins = config.insert; ch = config.choice; sn = config.snippet; in if config.text != null then call1 "t" config.text else if ins != null then if builtins.isInt ins then call "i" [ ins ] else call "i" [ (unwrapJump ins.jump) ins.text ] else if ch != null then call "c" [ (unwrapJump ch.jump) (unwrapNodes ch.nodes) ] else if sn != null then if sn.indent != "" then call "isn" [ (unwrapJump sn.jump) (unwrapNodes sn.nodes) sn.indent ] else call "sn" [ (unwrapJump sn.jump) (unwrapNodes sn.nodes) ] else null; }; }; snippetOpts = { name, ... } @ sub: { options = with lib; with types; { context = mkOption { type = either str attrs; description = '' `:help luasnip-snippets'; ''; }; nodes = nodes // { default = [ ]; }; inherit genConfig; }; config = { context = lib.mkDefault name; genConfig = call "s" [ sub.config.context (unwrapNodes sub.config.nodes) ]; }; }; snippetGroupOpts = { ... } @ sub: { options = with lib; { filetype = mkOption { type = types.str; }; opts = { type = mkOption { type = types.nullOr (types.enum [ "snippets" "autosnippets" ]); default = null; }; key = mkOption { type = types.nullOr types.str; default = null; }; override_priority = mkOption { type = types.nullOr types.number; default = null; description = '' Set priority for all snippets. `:help luasnip-api` ''; }; default_priority = mkOption { type = types.nullOr types.number; default = null; description = '' Set priority only for snippets without snippet priority. `:help luasnip-api` ''; }; }; snippets = mkOption { type = types.attrsOf (types.submodule snippetOpts); default = { }; }; inherit genConfig; }; config = { genConfig = let plugin = config.plugin.luasnip; in let inherit (sub.config) filetype snippets opts; in pipe1 plugin.var (call "add_snippets" [ filetype (map (s: s.genConfig) (builtins.attrValues snippets)) opts ]); }; }; in { options.plugins.snippet.luasnip = with lib; { enable = mkEnableOption "luasnip"; package = mkPackageOption pkgs.vimPlugins "luasnip" { }; settings = mkOption { type = types.attrs; default = { }; }; snippetGroups = mkOption { type = types.listOf (types.submodule snippetGroupOpts); default = [ ]; }; }; config = lib.mkIf cfg.enable { plugin.luasnip = rec { inherit (cfg) package; varName = "luasnip"; setupSettings = cfg.settings; extraImports = lib.mkIf (cfg.snippetGroups != [ ]) { luasnip_types = "luasnip.util.types"; }; afterSetup = lib.mkIf (cfg.snippetGroups != [ ]) [ (scope (lib.flatten [ (lib.mapAttrsToList (k: v: lset k (pipe1 varName v)) { s = "snippet"; sn = "snippet_node"; isn = "indent_snippet_node"; t = "text_node"; i = "insert_node"; f = "function_node"; c = "choice_node"; d = "dynamic_node"; r = "restore_node"; }) (map (sg: sg.genConfig) cfg.snippetGroups) ])) ]; }; }; }