diff --git a/plugins/by-name/startup/default.nix b/plugins/by-name/startup/default.nix index f44d9e1e..fedb3ad0 100644 --- a/plugins/by-name/startup/default.nix +++ b/plugins/by-name/startup/default.nix @@ -1,257 +1,19 @@ -{ - lib, - helpers, - config, - pkgs, - ... -}: -with lib; -let - cfg = config.plugins.startup; -in -{ - meta.maintainers = [ maintainers.GaetanLepage ]; +{ lib, ... }: +lib.nixvim.plugins.mkNeovimPlugin { + name = "startup"; + package = "startup-nvim"; + description = "A highly configurable Neovim startup screen."; + maintainers = [ ]; - options.plugins.startup = lib.nixvim.plugins.neovim.extraOptionsOptions // { - enable = mkEnableOption "startup.nvim"; + # Plugin uses 2 functions to setup... + callSetup = false; - package = lib.mkPackageOption pkgs "startup.nvim" { - default = [ - "vimPlugins" - "startup-nvim" - ]; - }; + # TODO: introduced 2025-10-17: remove after 26.05 + inherit (import ./deprecations.nix lib) deprecateExtraOptions optionsRenamedToSettings imports; - theme = helpers.defaultNullOpts.mkStr "dashboard" '' - Use a pre-defined theme. - ''; - - sections = - let - sectionType = - with types; - submodule { - options = { - type = - helpers.defaultNullOpts.mkEnumFirstDefault - [ - "text" - "mapping" - "oldfiles" - ] - '' - - "text" -> text that will be displayed - - "mapping" -> create mappings for commands that can be used. - use `mappings.executeCommand` on the commands to execute. - - "oldfiles" -> display oldfiles (can be opened with `mappings.openFile`/`openFileSplit`) - ''; - - oldfilesDirectory = helpers.defaultNullOpts.mkBool false '' - if the oldfiles of the current directory should be displayed. - ''; - - align = - helpers.defaultNullOpts.mkEnumFirstDefault - [ - "center" - "left" - "right" - ] - '' - How to align the section. - ''; - - foldSection = helpers.defaultNullOpts.mkBool false '' - Whether to fold or not. - ''; - - title = helpers.defaultNullOpts.mkStr "title" '' - Title for the folded section. - ''; - - margin = - helpers.defaultNullOpts.mkNullable (with types; either (numbers.between 0.0 1.0) ints.positive) 5 - '' - The margin for left or right alignment. - - if < 1 fraction of screen width - - if > 1 numbers of column - ''; - - content = - helpers.mkNullOrOption - ( - with types; - oneOf [ - # for "text" "mapping" - (listOf (either str (listOf str))) - rawLua - # for "oldfiles" sections - (enum [ "" ]) - ] - ) - '' - The type of `content` depends on the section `type`: - - "text" -> a list of strings or a function (`rawLua`) that requires a function that returns a table of strings - - "mapping" -> a list of list of strings in the format: - ```nix - [ - [ ] - [ ] - ] - ``` - Example: `[" Find File" "Telescope find_files" "ff"]` - - "oldfiles" -> `""` - ''; - - highlight = helpers.mkNullOrOption types.str '' - Highlight group in which the section text should be highlighted. - ''; - - defaultColor = helpers.defaultNullOpts.mkStr "#FF0000" '' - A hex color that gets used if you don't specify `highlight`. - ''; - - oldfilesAmount = helpers.defaultNullOpts.mkUnsignedInt 5 '' - The amount of oldfiles to be displayed. - ''; - }; - }; - in - mkOption { - type = with types; attrsOf sectionType; - default = { }; - description = ''''; - example = { - header = { - type = "text"; - align = "center"; - foldSection = false; - title = "Header"; - margin = 5; - content.__raw = "require('startup.headers').hydra_header"; - highlight = "Statement"; - defaultColor = ""; - oldfilesAmount = 0; - }; - body = { - type = "mapping"; - align = "center"; - foldSection = true; - title = "Basic Commands"; - margin = 5; - content = [ - [ - " Find File" - "Telescope find_files" - "ff" - ] - [ - "󰍉 Find Word" - "Telescope live_grep" - "lg" - ] - [ - " Recent Files" - "Telescope oldfiles" - "of" - ] - [ - " File Browser" - "Telescope file_browser" - "fb" - ] - [ - " Colorschemes" - "Telescope colorscheme" - "cs" - ] - [ - " New File" - "lua require'startup'.new_file()" - "nf" - ] - ]; - highlight = "String"; - defaultColor = ""; - oldfilesAmount = 0; - }; - }; - }; - - options = { - mappingKeys = helpers.defaultNullOpts.mkBool true '' - Display mapping (e.g. `ff`). - ''; - - cursorColumn = - helpers.defaultNullOpts.mkNullable (with types; either (numbers.between 0.0 1.0) ints.positive) 0.5 - '' - - if < 1, fraction of screen width - - if > 1 numbers of column - ''; - - after = helpers.defaultNullOpts.mkLuaFn "nil" '' - A function that gets executed at the end. - ''; - - emptyLinesBetweenMappings = helpers.defaultNullOpts.mkBool true '' - Add an empty line between mapping/commands. - ''; - - disableStatuslines = helpers.defaultNullOpts.mkBool true '' - Disable status-, buffer- and tablines. - ''; - - paddings = helpers.defaultNullOpts.mkListOf types.ints.unsigned [ ] '' - Amount of empty lines before each section (must be equal to amount of sections). - ''; - }; - - mappings = { - executeCommand = helpers.defaultNullOpts.mkStr "" '' - Keymapping to execute a command. - ''; - - openFile = helpers.defaultNullOpts.mkStr "o" '' - Keymapping to open a file. - ''; - - openFileSplit = helpers.defaultNullOpts.mkStr "" '' - Keymapping to open a file in a split. - ''; - - openSection = helpers.defaultNullOpts.mkStr "" '' - Keymapping to open a section. - ''; - - openHelp = helpers.defaultNullOpts.mkStr "?" '' - Keymapping to open help. - ''; - }; - - colors = { - background = helpers.defaultNullOpts.mkStr "#1f2227" '' - The background color. - ''; - - foldedSection = helpers.defaultNullOpts.mkStr "#56b6c2" '' - The color of folded sections. - This can also be changed with the `StartupFoldedSection` highlight group. - ''; - }; - - parts = mkOption { - type = with types; listOf str; - default = [ ]; - description = "List all sections in order."; - example = [ - "section_1" - "section_2" - ]; - }; - - userMappings = mkOption { - type = with types; attrsOf str; + extraOptions = { + userMappings = lib.mkOption { + type = with lib.types; attrsOf str; description = "Add your own mappings as key-command pairs."; default = { }; example = { @@ -261,84 +23,35 @@ in }; }; - config = mkIf cfg.enable { - assertions = - let - sectionNames = attrNames cfg.sections; - numSections = length sectionNames; - in - lib.nixvim.mkAssertions "plugins.startup" [ - { - assertion = (cfg.options.paddings == null) || (length cfg.options.paddings) == numSections; - message = '' - Make sure that `plugins.startup.options.paddings` has the same - number of elements as there are sections. - ''; - } - { - assertion = - ((length cfg.parts) <= numSections) && (all (part: hasAttr part cfg.sections) cfg.parts); - message = '' - You should not have more section names in `plugins.startup.parts` than you have sections defined. - ''; - } - ]; - extraPlugins = [ cfg.package ]; + settingsExample = { + theme = "dashboard"; + options = { + mapping_keys = true; + cursor_column = 0.5; + after = null; + empty_lines_between_mappings = true; + disable_statuslines = true; + paddings = lib.nixvim.nestedLiteral (lib.literalExpression "lib.nixvim.utils.emptyTable"); + }; + mappings = { + execute_command = ""; + open_file = "o"; + open_file_split = ""; + open_section = ""; + open_help = "?"; + }; + colors = { + background = "#1f2227"; + folded_section = "#56b6c2"; + }; + }; - extraConfigLua = - let - sections = mapAttrs ( - name: sectionAttrs: with sectionAttrs; { - inherit type; - oldfiles_directory = oldfilesDirectory; - inherit align; - fold_section = foldSection; - inherit - title - margin - content - highlight - ; - default_color = defaultColor; - oldfiles_amount = oldfilesAmount; - } - ) cfg.sections; - - options = - with cfg.options; - { - mapping_keys = mappingKeys; - cursor_column = cursorColumn; - inherit after; - empty_lines_between_mappings = emptyLinesBetweenMappings; - disable_statuslines = disableStatuslines; - inherit paddings; - } - // cfg.extraOptions; - - setupOptions = { - inherit (cfg) theme; - inherit options; - mappings = with cfg.mappings; { - execute_command = executeCommand; - open_file = openFile; - open_file_split = openFileSplit; - open_section = openSection; - open_help = openHelp; - }; - colors = with cfg.colors; { - inherit background; - folded_section = foldedSection; - }; - inherit (cfg) parts; - } - // sections; - in - '' - require('startup').setup(${lib.nixvim.toLuaObject setupOptions}) - '' - + (optionalString ( - cfg.userMappings != { } - ) "require('startup').create_mappings(${lib.nixvim.toLuaObject cfg.userMappings})"); + extraConfig = cfg: { + extraConfigLua = '' + require('startup').setup(${lib.nixvim.toLuaObject cfg.settings}) + '' + + (lib.optionalString ( + cfg.userMappings != { } + ) "require('startup').create_mappings(${lib.nixvim.toLuaObject cfg.userMappings})"); }; } diff --git a/plugins/by-name/startup/deprecations.nix b/plugins/by-name/startup/deprecations.nix new file mode 100644 index 00000000..2c4cc9f2 --- /dev/null +++ b/plugins/by-name/startup/deprecations.nix @@ -0,0 +1,50 @@ +lib: { + deprecateExtraOptions = true; + + optionsRenamedToSettings = map (lib.splitString ".") [ + "theme" + + "options.mappingKeys" + "options.cursorColumn" + "options.after" + "options.emptyLinesBetweenMappings" + "options.disableStatuslines" + "options.paddings" + + "mappings.executeCommand" + "mappings.openFile" + "mappings.openFileSplit" + "mappings.openSection" + "mappings.openHelp" + + "colors.background" + "colors.foldedSection" + + "parts" + ]; + + imports = [ + ( + let + inherit (lib) mapAttrs mapAttrs' nameValuePair; + inherit (lib.nixvim) ifNonNull' toSnakeCase; + basePathAnd = lib.concat [ + "plugins" + "startup" + ]; + oldOptPath = basePathAnd [ "sections" ]; + in + lib.mkChangedOptionModule oldOptPath + (basePathAnd [ + "settings" + ]) + ( + config: + let + old = lib.getAttrFromPath oldOptPath config; + in + ifNonNull' old (mapAttrs (_: (mapAttrs' (n: nameValuePair (toSnakeCase n)))) old) + ) + ) + ]; +} diff --git a/tests/test-sources/plugins/by-name/startup/default.nix b/tests/test-sources/plugins/by-name/startup/default.nix index cd2bf72e..e4b4e564 100644 --- a/tests/test-sources/plugins/by-name/startup/default.nix +++ b/tests/test-sources/plugins/by-name/startup/default.nix @@ -6,27 +6,29 @@ builtin-theme = { plugins.startup = { enable = true; - theme = "dashboard"; + settings = { + theme = "dashboard"; - # Default options - options = { - mappingKeys = true; - cursorColumn = 0.5; - after = null; - emptyLinesBetweenMappings = true; - disableStatuslines = true; - paddings = [ ]; - }; - mappings = { - executeCommand = ""; - openFile = "o"; - openFileSplit = ""; - openSection = ""; - openHelp = "?"; - }; - colors = { - background = "#1f2227"; - foldedSection = "#56b6c2"; + # Default options + options = { + mapping_keys = true; + cursor_column = 0.5; + after = null; + empty_lines_between_mappings = true; + disable_statuslines = true; + paddings.__empty = { }; + }; + mappings = { + execute_command = ""; + open_file = "o"; + open_file_split = ""; + open_section = ""; + open_help = "?"; + }; + colors = { + background = "#1f2227"; + folded_section = "#56b6c2"; + }; }; userMappings = { "ff" = "Telescope find_files"; @@ -40,34 +42,34 @@ plugins.startup = { enable = true; - sections = { + settings = { header = { type = "text"; align = "center"; - foldSection = false; + fold_section = false; title = "Header"; margin = 5; content.__raw = "require('startup.headers').hydra_header"; highlight = "Statement"; - defaultColor = ""; - oldfilesAmount = 0; + default_color = ""; + oldfiles_amount = 0; }; header_2 = { type = "text"; - oldfilesDirectory = false; + oldfiles_directory = false; align = "center"; - foldSection = false; + fold_section = false; title = "Quote"; margin = 5; content.__raw = "require('startup.functions').quote()"; highlight = "Constant"; - defaultColor = ""; - oldfilesAmount = 0; + default_color = ""; + oldfiles_amount = 0; }; body = { type = "mapping"; align = "center"; - foldSection = true; + fold_section = true; title = "Basic Commands"; margin = 5; content = [ @@ -103,32 +105,32 @@ ] ]; highlight = "String"; - defaultColor = ""; - oldfilesAmount = 0; + default_color = ""; + oldfiles_amount = 0; }; body_2 = { type = "oldfiles"; - oldfilesDirectory = true; + oldfiles_directory = true; align = "center"; - foldSection = true; + fold_section = true; title = "Oldfiles of Directory"; margin = 5; - content = [ ]; + content.__empty = { }; highlight = "String"; - defaultColor = "#FFFFFF"; - oldfilesAmount = 5; + default_color = "#FFFFFF"; + oldfiles_amount = 5; }; footer = { type = "oldfiles"; - oldfilesDirectory = false; + oldfiles_directory = false; align = "center"; - foldSection = true; + fold_section = true; title = "Oldfiles"; margin = 5; content = [ "startup.nvim" ]; highlight = "TSString"; - defaultColor = "#FFFFFF"; - oldfilesAmount = 5; + default_color = "#FFFFFF"; + oldfiles_amount = 5; }; clock = { type = "text"; @@ -139,61 +141,61 @@ return { clock, date } end ''; - oldfilesDirectory = false; + oldfiles_directory = false; align = "center"; - foldSection = false; + fold_section = false; title = ""; margin = 5; highlight = "TSString"; - defaultColor = "#FFFFFF"; - oldfilesAmount = 10; + default_color = "#FFFFFF"; + oldfiles_amount = 10; }; footer_2 = { type = "text"; content.__raw = "require('startup.functions').packer_plugins()"; - oldfilesDirectory = false; + oldfiles_directory = false; align = "center"; - foldSection = false; + fold_section = false; title = ""; margin = 5; highlight = "TSString"; - defaultColor = "#FFFFFF"; - oldfilesAmount = 10; + default_color = "#FFFFFF"; + oldfiles_amount = 10; }; - }; - options = { - after = '' - function() - require("startup.utils").oldfiles_mappings() - end - ''; - mappingKeys = true; - cursorColumn = 0.5; - emptyLinesBetweenMappings = true; - disableStatuslines = true; - paddings = [ - 2 - 2 - 2 - 2 - 2 - 2 - 2 + options = { + after = '' + function() + require("startup.utils").oldfiles_mappings() + end + ''; + mapping_keys = true; + cursor_column = 0.5; + empty_lines_between_mappings = true; + disable_statuslines = true; + paddings = [ + 2 + 2 + 2 + 2 + 2 + 2 + 2 + ]; + }; + colors = { + background = "#1f2227"; + folded_section = "#56b6c2"; + }; + parts = [ + "header" + "header_2" + "body" + "body_2" + "footer" + "clock" + "footer_2" ]; }; - colors = { - background = "#1f2227"; - foldedSection = "#56b6c2"; - }; - parts = [ - "header" - "header_2" - "body" - "body_2" - "footer" - "clock" - "footer_2" - ]; }; }; }