diff --git a/plugins/by-name/luasnip/default.nix b/plugins/by-name/luasnip/default.nix index 21d48c46b..1c080d4a4 100644 --- a/plugins/by-name/luasnip/default.nix +++ b/plugins/by-name/luasnip/default.nix @@ -1,13 +1,7 @@ -{ - lib, - helpers, - config, - pkgs, - ... -}: -with lib; +{ lib, ... }: let - cfg = config.plugins.luasnip; + inherit (lib) mkOption types; + inherit (lib.nixvim) defaultNullOpts literalLua toLuaObject; loaderSubmodule = types.submodule { options = { @@ -21,7 +15,7 @@ let # TODO: add option to also include the default runtimepath paths = - helpers.mkNullOrOption + lib.nixvim.mkNullOrOption ( with lib.types; oneOf [ @@ -39,54 +33,265 @@ let List of paths to load. ''; - exclude = helpers.mkNullOrOption (with lib.types; maybeRaw (listOf (maybeRaw str))) '' + exclude = lib.nixvim.mkNullOrOption (with lib.types; maybeRaw (listOf (maybeRaw str))) '' List of languages to exclude, by default is empty. ''; - include = helpers.mkNullOrOption (with lib.types; maybeRaw (listOf (maybeRaw str))) '' + include = lib.nixvim.mkNullOrOption (with lib.types; maybeRaw (listOf (maybeRaw str))) '' List of languages to include, by default is not set. ''; }; }; in -{ - imports = - let - basePluginPath = [ - "plugins" - "luasnip" - ]; - in - [ - # TODO introduced 2024-08-04. Remove after 24.11 - (lib.mkRenamedOptionModule (basePluginPath ++ [ "extraConfig" ]) (basePluginPath ++ [ "settings" ])) - ]; +lib.nixvim.neovim-plugin.mkNeovimPlugin { + name = "luasnip"; + package = "luasnip"; + setup = ".config.setup"; - options.plugins.luasnip = { - enable = mkEnableOption "luasnip"; + maintainers = [ lib.maintainers.HeitorAugustoLN ]; - package = lib.mkPackageOption pkgs "luasnip" { - default = [ - "vimPlugins" - "luasnip" - ]; - }; + settingsOptions = { + keep_roots = defaultNullOpts.mkBool false '' + Whether snippet-roots should be linked. + ''; - settings = mkOption { - type = with types; attrsOf anything; - description = '' - Options provided to the `require('luasnip').config.setup()` function.", - ''; - example = { - enable_autosnippets = true; - store_selection_keys = ""; - }; - default = { }; - }; + link_roots = defaultNullOpts.mkBool false '' + Whether snippet-roots should be linked. + ''; + + exit_roots = defaultNullOpts.mkBool true '' + Whether snippet-roots should exit at reaching at their last node, $0. + This setting is only valid for root snippets, not child snippets. + This setting may avoid unexpected behavior by disallowing to jump earlier (finished) snippets. + ''; + + link_children = defaultNullOpts.mkBool false '' + Whether children should be linked. + ''; + + update_events = + defaultNullOpts.mkNullableWithRaw (with types; either str (listOf str)) "InsertLeave" + '' + Choose which events trigger an update of the active nodes' dependents. + ''; + + region_check_events = + defaultNullOpts.mkNullableWithRaw (with types; either str (listOf str)) (literalLua "nil") + '' + Events on which to leave the current snippet-root if the cursor is outside its' 'region'. Disabled by default. + ''; + + delete_check_events = + defaultNullOpts.mkNullableWithRaw (with types; either str (listOf str)) (literalLua "nil") + '' + When to check if the current snippet was deleted, and if so, remove it from the history. Off by default. + ''; + + cut_selection_keys = defaultNullOpts.mkStr (literalLua "nil") '' + Mapping for populating TM_SELECTED_TEXT and related variables (not set by default). + ''; + + enable_autosnippets = defaultNullOpts.mkBool false '' + Autosnippets are disabled by default to minimize performance penalty if unused. Set to true to enable. + ''; + + ext_opts = + defaultNullOpts.mkAttrsOf (with types; attrsOf (attrsOf anything)) + { + "types.textNode" = { + active = { + hl_group = "LuasnipTextNodeActive"; + }; + passive = { + hl_group = "LuasnipTextNodePassive"; + }; + visited = { + hl_group = "LuasnipTextNodeVisited"; + }; + unvisited = { + hl_group = "LuasnipTextNodeUnvisited"; + }; + snippet_passive = { + hl_group = "LuasnipTextNodeSnippetPassive"; + }; + }; + "types.insertNode" = { + active = { + hl_group = "LuasnipInsertNodeActive"; + }; + passive = { + hl_group = "LuasnipInsertNodePassive"; + }; + visited = { + hl_group = "LuasnipInsertNodeVisited"; + }; + unvisited = { + hl_group = "LuasnipInsertNodeUnvisited"; + }; + snippet_passive = { + hl_group = "LuasnipInsertNodeSnippetPassive"; + }; + }; + "types.exitNode" = { + active = { + hl_group = "LuasnipExitNodeActive"; + }; + passive = { + hl_group = "LuasnipExitNodePassive"; + }; + visited = { + hl_group = "LuasnipExitNodeVisited"; + }; + unvisited = { + hl_group = "LuasnipExitNodeUnvisited"; + }; + snippet_passive = { + hl_group = "LuasnipExitNodeSnippetPassive"; + }; + }; + "types.functionNode" = { + active = { + hl_group = "LuasnipFunctionNodeActive"; + }; + passive = { + hl_group = "LuasnipFunctionNodePassive"; + }; + visited = { + hl_group = "LuasnipFunctionNodeVisited"; + }; + unvisited = { + hl_group = "LuasnipFunctionNodeUnvisited"; + }; + snippet_passive = { + hl_group = "LuasnipFunctionNodeSnippetPassive"; + }; + }; + "types.snippetNode" = { + active = { + hl_group = "LuasnipSnippetNodeActive"; + }; + passive = { + hl_group = "LuasnipSnippetNodePassive"; + }; + visited = { + hl_group = "LuasnipSnippetNodeVisited"; + }; + unvisited = { + hl_group = "LuasnipSnippetNodeUnvisited"; + }; + snippet_passive = { + hl_group = "LuasnipSnippetNodeSnippetPassive"; + }; + }; + "types.choiceNode" = { + active = { + hl_group = "LuasnipChoiceNodeActive"; + }; + passive = { + hl_group = "LuasnipChoiceNodePassive"; + }; + visited = { + hl_group = "LuasnipChoiceNodeVisited"; + }; + unvisited = { + hl_group = "LuasnipChoiceNodeUnvisited"; + }; + snippet_passive = { + hl_group = "LuasnipChoiceNodeSnippetPassive"; + }; + }; + "types.dynamicNode" = { + active = { + hl_group = "LuasnipDynamicNodeActive"; + }; + passive = { + hl_group = "LuasnipDynamicNodePassive"; + }; + visited = { + hl_group = "LuasnipDynamicNodeVisited"; + }; + unvisited = { + hl_group = "LuasnipDynamicNodeUnvisited"; + }; + snippet_passive = { + hl_group = "LuasnipDynamicNodeSnippetPassive"; + }; + }; + } + '' + Additional options passed to extmarks. Can be used to add passive/active highlight on a per-node-basis. + ''; + + ext_base_prio = defaultNullOpts.mkInt 200 '' + Base priority for extmarks. + ''; + + ext_prio_increase = defaultNullOpts.mkInt 9 '' + Priority increase for extmarks. + ''; + parser_nested_assembler = + defaultNullOpts.mkRaw + '' + function(pos, snip) + local iNode = require("luasnip.nodes.insertNode") + local cNode = require("luasnip.nodes.choiceNode") + + modify_nodes(snip) + snip:init_nodes() + snip.pos = nil + + return cNode.C(pos, { snip, iNode.I(nil, { "" }) }) + end + '' + '' + Override the default behavior of inserting a choiceNode containing the nested snippet and an empty insertNode for nested placeholders. + ''; + + ft_func = + defaultNullOpts.mkRaw + '' + require("luasnip.extras.filetype_functions").from_filetype + '' + '' + Source of possible filetypes for snippets. + Defaults to a function, which returns vim.split(vim.bo.filetype, ".", true), + but check filetype_functions or the Extras-Filetype-Functions-section for more options. + ''; + + load_ft_func = + defaultNullOpts.mkRaw + '' + require("luasnip.extras.filetype_functions").from_filetype_load + '' + '' + Function to determine which filetypes belong to a given buffer (used for lazy_loading). fn(bufnr) -> filetypes (string[]). + Again, there are some examples in filetype_functions. + ''; + + loaders_store_source = defaultNullOpts.mkBool false '' + Whether loaders should store the source of the loaded snippets. + Enabling this means that the definition of any snippet can be jumped to via Extras-Snippet-Location, + but also entails slightly increased memory consumption (and load-time, but it's not really noticeable). + ''; + }; + + settingsExample = { + update_events = [ + "TextChanged" + "TextChangedI" + ]; + keep_roots = true; + link_roots = true; + exit_roots = false; + enable_autosnippets = true; + }; + + extraOptions = { fromVscode = mkOption { + type = types.listOf loaderSubmodule; default = [ ]; - example = literalExpression '' + example = lib.literalExpression '' [ { } { paths = ./path/to/snippets; } @@ -104,7 +309,6 @@ in require("luasnip.loaders.from_vscode").lazy_load({['paths'] = {'/nix/store/.../path/to/snippets'}}) ``` ''; - type = types.listOf loaderSubmodule; }; fromSnipmate = mkOption { @@ -114,7 +318,7 @@ in `./{ft}.snippets` and `./{ft}/*.snippets` will be loaded. See for lots of examples. ''; - example = literalExpression '' + example = lib.literalExpression '' [ { } { paths = ./path/to/snippets; } @@ -128,7 +332,7 @@ in Load lua snippets with the lua loader. Check for the necessary file structure. ''; - example = literalExpression '' + example = lib.literalExpression '' [ {} { @@ -161,49 +365,41 @@ in }; }; - config = + extraConfig = + cfg: let loaderConfig = - trivial.pipe + lib.pipe { vscode = cfg.fromVscode; snipmate = cfg.fromSnipmate; lua = cfg.fromLua; } [ - # Convert loader options to [{ name = "vscode"; loader = ...; }] - (attrsets.mapAttrsToList (name: loaders: lists.map (loader: { inherit name loader; }) loaders)) - lists.flatten - - (lists.map ( + (lib.mapAttrsToList (name: loaders: map (loader: { inherit name loader; }) loaders)) + lib.flatten + (map ( pair: let inherit (pair) name loader; - options = attrsets.getAttrs [ + options = lib.getAttrs [ "paths" "exclude" "include" ] loader; in '' - require("luasnip.loaders.from_${name}").${optionalString loader.lazyLoad "lazy_"}load(${lib.nixvim.toLuaObject options}) + require("luasnip.loaders.from_${name}").${lib.optionalString loader.lazyLoad "lazy_"}load(${toLuaObject options}) '' )) ]; - filetypeExtendConfig = mapAttrsToList (n: v: '' - require("luasnip").filetype_extend("${n}", ${lib.nixvim.toLuaObject v}) + filetypeExtendConfig = lib.mapAttrsToList (name: value: '' + require("luasnip").filetype_extend("${name}", ${toLuaObject value}) '') cfg.filetypeExtend; - - extraConfig = [ - '' - require("luasnip").config.setup(${lib.nixvim.toLuaObject cfg.settings}) - '' - ]; in - mkIf cfg.enable { - extraPlugins = [ cfg.package ]; + { extraLuaPackages = ps: [ ps.jsregexp ]; - extraConfigLua = concatStringsSep "\n" (extraConfig ++ loaderConfig ++ filetypeExtendConfig); + plugins.luasnip.luaConfig.content = lib.concatLines (loaderConfig ++ filetypeExtendConfig); }; }