201 lines
5 KiB
Nix
201 lines
5 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
let
|
|
inherit (lib.nix2lua) LuaNil scope lset pipe1 call call1;
|
|
cfg = config.plugins.snippet.luasnip;
|
|
|
|
nodes = lib.mkOption {
|
|
type = with lib.types; listOf (submodule snippetNodeOpts);
|
|
default = [ ];
|
|
};
|
|
unwrapNodes = map (n: n.genConfig);
|
|
|
|
|
|
genConfig = lib.mkOption {
|
|
type = lib.types.attrs;
|
|
internal = true;
|
|
};
|
|
|
|
snippetNodeOpts = { config, ... }: {
|
|
options = with lib; with types; {
|
|
kind = mkOption {
|
|
type = enum [ "text" "insert" "choice" "snippet" ];
|
|
};
|
|
|
|
text = mkOption {
|
|
type = nullOr (either str (listOf str));
|
|
default = null;
|
|
};
|
|
|
|
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`
|
|
'';
|
|
};
|
|
|
|
inherit nodes;
|
|
choices = nodes;
|
|
|
|
# only for kind=snippet
|
|
indentString = mkOption {
|
|
type = types.str;
|
|
default = "";
|
|
};
|
|
|
|
inherit genConfig;
|
|
};
|
|
|
|
config =
|
|
let
|
|
inherit (config) kind text jump nodes choices;
|
|
|
|
unwrapJump = index: if index == null then LuaNil else index;
|
|
in
|
|
{
|
|
kind = lib.mkDefault (
|
|
if choices != [ ] then "choice"
|
|
else if nodes != [ ] then "snippet"
|
|
else if jump != null then "insert"
|
|
else "text"
|
|
);
|
|
|
|
genConfig =
|
|
if kind == "text" then
|
|
if text != null then call1 "t" text
|
|
else throw "luasnip textnode require a 'text' config"
|
|
else if kind == "insert" then call "i" [ (unwrapJump jump) text ]
|
|
else if kind == "choice" then call "c" [ (unwrapJump jump) (unwrapNodes choices) ]
|
|
else if kind == "snippet" then
|
|
if config.indentString != "" then
|
|
call "isn" [ (unwrapJump jump) (unwrapNodes nodes) config.indentString ]
|
|
else
|
|
call "sn" [ (unwrapJump jump) (unwrapNodes nodes) ]
|
|
else null;
|
|
};
|
|
};
|
|
|
|
snippetOpts = { name, ... } @ sub: {
|
|
options = with lib; with types; {
|
|
context = mkOption {
|
|
type = either str attrs;
|
|
description = ''
|
|
`:help luasnip-snippets';
|
|
'';
|
|
};
|
|
|
|
inherit nodes;
|
|
|
|
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)
|
|
]))
|
|
];
|
|
};
|
|
};
|
|
}
|