plugins/lualine: migrate to mkNeovimPlugin

This commit is contained in:
Austin Horstman 2024-09-05 19:46:00 -05:00
parent c4135d720a
commit d12045e057
No known key found for this signature in database
4 changed files with 492 additions and 312 deletions

View file

@ -171,7 +171,7 @@ lib.nixvim.neovim-plugin.mkNeovimPlugin {
extraConfig = cfg: { extraConfig = cfg: {
plugins.airline.settings.theme = lib.mkIf cfg.setUpBar (lib.mkDefault name); plugins.airline.settings.theme = lib.mkIf cfg.setUpBar (lib.mkDefault name);
plugins.lualine.theme = lib.mkIf cfg.setUpBar (lib.mkDefault name); plugins.lualine.settings.options.theme = lib.mkIf cfg.setUpBar (lib.mkDefault name);
plugins.lightline.settings.colorscheme = lib.mkDefault null; plugins.lightline.settings.colorscheme = lib.mkDefault null;
opts.termguicolors = lib.mkDefault true; opts.termguicolors = lib.mkDefault true;

View file

@ -1,177 +1,270 @@
{ {
lib, lib,
helpers,
config,
pkgs, pkgs,
... ...
}: }:
with lib;
let let
cfg = config.plugins.lualine; inherit (lib.nixvim) defaultNullOpts mkSettingsRenamedOptionModules;
inherit (lib) types;
in
lib.nixvim.neovim-plugin.mkNeovimPlugin {
name = "lualine";
originalName = "lualine.nvim";
package = "lualine-nvim";
maintainers = [ lib.maintainers.khaneliman ];
# TODO: Added 2024-09-05, remove after 24.11
optionsRenamedToSettings = [
"extensions"
"sections"
"inactiveSections"
"tabline"
"winbar"
"inactiveWinbar"
];
imports =
let
basePluginPath = [
"plugins"
"lualine"
];
settingsPath = basePluginPath ++ [ "settings" ];
optionsPath = settingsPath ++ [ "options" ];
oldOptions = [
"theme"
"globalstatus"
"refresh"
"iconsEnabled"
"sectionSeparators"
"componentSeparators"
"disabledFiletypes"
"ignoreFocus"
"alwaysDivideMiddle"
];
in
mkSettingsRenamedOptionModules basePluginPath optionsPath oldOptions;
settingsOptions =
let
mkSeparatorsOption = mkSeparatorsOption =
{ { left, right }:
leftDefault ? " ", defaultNullOpts.mkNullableWithRaw' {
rightDefault ? " ", description = ''
}: Filetypes in which to disable lualine.
{ Allows you to specify filetypes that you want to only disable on specific components.
left = helpers.defaultNullOpts.mkStr leftDefault "Left separator";
right = helpers.defaultNullOpts.mkStr rightDefault "Right separator";
};
mkComponentOptions =
defaultName:
helpers.mkNullOrOption (
with types;
listOf (
either str (submodule {
options = {
name = mkOption {
type = types.either types.str helpers.nixvimTypes.rawLua;
description = "Component name or function";
default = defaultName;
};
icons_enabled = helpers.defaultNullOpts.mkBool true ''
Enables the display of icons alongside the component.
''; '';
pluginDefault = {
icon = helpers.mkNullOrOption ( inherit left right;
};
type =
with types; with types;
either str (submodule { either str (submodule {
freeformType = attrsOf anything; freeformType = attrsOf anything;
options = { options = {
icon = mkOption { left = defaultNullOpts.mkStr left "Left separator";
type = str; right = defaultNullOpts.mkStr right "Right separator";
description = "Icon character.";
}; };
});
}; };
})
) "Defines the icon to be displayed in front of the component.";
separator = mkSeparatorsOption { }; # NOTE: This option is used for the shared component section definitions.
# We used to transform several options for the user to handle unkeying inside an attribute set and
color = helpers.mkNullOrOption (types.attrsOf types.str) '' # merging in undefined options into the final option. Now that we have freeformType support the user can
Defines a custom color for the component. # manage this configuration exactly as the plugin expects without us transforming the values for them.
''; mkComponentOptions =
description:
padding = helpers.defaultNullOpts.mkNullable (types.either types.int ( lib.nixvim.mkNullOrOption' {
types.submodule { type =
options = { with types;
left = mkOption { let
type = types.int; # TODO: added 2024-09-05 remove after 24.11
description = "left padding"; oldAttrs = [
}; [ "name" ]
right = mkOption { [
type = types.int; "icon"
description = "left padding"; "icon"
]
[ "extraConfig" ]
];
isOldType = x: lib.any (loc: lib.hasAttrByPath loc x) oldAttrs;
oldType = addCheck (attrsOf anything) isOldType // {
description = "attribute set containing ${lib.concatMapStringsSep ", " lib.showOption oldAttrs}";
}; };
coerceFn =
attrs:
lib.pipe attrs [
# Transform old `name` attr to `__unkeyed`
(
x:
if x ? name then
lib.removeAttrs x [ "name" ]
// {
__unkeyed-1 = x.name;
}
else
x
)
# Transform old `icon.icon` attr to `__unkeyed`
(
x:
if x.icon or null ? icon then
x
// {
icon = removeAttrs x.icon [ "icon" ] // {
__unkeyed-1 = x.icon.icon;
}; };
} }
)) 1 "Adds padding to the left and right of components."; else
x
)
# Merge in old `extraConfig` attr
(x: removeAttrs x [ "extraConfig" ] // x.extraConfig or { })
];
newType = submodule {
freeformType = attrsOf anything;
fmt = helpers.mkNullOrLuaFn '' options = {
icons_enabled = defaultNullOpts.mkBool true ''
Whether to display icons alongside the component.
'';
icon = lib.nixvim.mkNullOrOption' {
type = either str (attrsOf anything);
description = "The icon to be displayed in the component.";
};
separator = mkSeparatorsOption {
left = " ";
right = " ";
};
color = defaultNullOpts.mkNullable' {
type = either attrs str;
pluginDefault = lib.literalMD "The color defined by your theme, for the respective section & mode.";
description = "Defines a custom color for the component.";
};
padding = defaultNullOpts.mkNullable (oneOf [
int
(submodule {
# In case they add support for top/bottom padding
freeformType = attrsOf (maybeRaw int);
options = {
left = defaultNullOpts.mkInt null "Left padding.";
right = defaultNullOpts.mkInt null "Right padding.";
};
})
rawLua
]) 1 "Amount of padding added to components.";
fmt = lib.nixvim.mkNullOrLuaFn' {
description = ''
A lua function to format the component string. A lua function to format the component string.
'';
Example: example = ''
```lua
function(text) function(text)
return text .. "!!!" return text .. "!!!"
end end
```
''; '';
extraConfig = mkOption {
type = types.attrs;
default = { };
description = "extra options for the component";
}; };
}; };
}) };
) in
) ""; maybeRaw (listOf (either str (lib.nixvim.transitionType oldType coerceFn (maybeRaw newType))));
inherit description;
};
mkEmptySectionOption = name: { mkEmptySectionOption = name: {
lualine_a = mkComponentOptions ""; lualine_a = mkComponentOptions "Left section on left side.";
lualine_b = mkComponentOptions ""; lualine_b = mkComponentOptions "Middle section on left side.";
lualine_c = mkComponentOptions ""; lualine_c = mkComponentOptions "Right section on left side.";
lualine_x = mkComponentOptions ""; lualine_x = mkComponentOptions "Left section on right side.";
lualine_y = mkComponentOptions ""; lualine_y = mkComponentOptions "Middle section on right side.";
lualine_z = mkComponentOptions ""; lualine_z = mkComponentOptions "Right section on right side.";
}; };
in
{ in
{
options = { options = {
plugins.lualine = { icons_enabled = defaultNullOpts.mkBool true ''
enable = mkEnableOption "lualine"; Whether to enable icons for all components.
package = lib.mkPackageOption pkgs "lualine" { This option is also available on individual components to control whether they should display icons.
default = [ '';
"vimPlugins"
"lualine-nvim"
];
};
gitPackage = lib.mkPackageOption pkgs "git" { theme = defaultNullOpts.mkNullable (
nullable = true;
};
iconsEnabled = mkOption {
type = types.bool;
description = "Whether to enable/disable icons for all components.";
default = true;
};
theme = helpers.defaultNullOpts.mkNullable (
with types; either str attrs with types; either str attrs
) "auto" "The theme to use for lualine-nvim."; ) "auto" "The theme to use for lualine-nvim.";
componentSeparators = mkSeparatorsOption { component_separators = mkSeparatorsOption {
leftDefault = ""; left = "";
rightDefault = ""; right = "";
}; };
sectionSeparators = mkSeparatorsOption { section_separators = mkSeparatorsOption {
leftDefault = ""; left = "";
rightDefault = ""; right = "";
}; };
disabledFiletypes = { disabled_filetypes = defaultNullOpts.mkNullableWithRaw' {
statusline = helpers.defaultNullOpts.mkListOf types.str [ ] '' description = ''
Only ignores the ft for statusline. Filetypes in which to disable lualine.
Allows you to specify filetypes that you want to only disable on specific components.
'';
pluginDefault = { };
type =
with types;
either (listOf (maybeRaw str)) (submodule {
freeformType = attrsOf anything;
options = {
statusline = defaultNullOpts.mkListOf str [ ] ''
Hide the statusline component on specified filetypes.
''; '';
winbar = helpers.defaultNullOpts.mkListOf types.str [ ] '' winbar = defaultNullOpts.mkListOf str [ ] ''
Only ignores the ft for winbar. Hide the winbar component on specified filetypes.
''; '';
}; };
});
};
ignoreFocus = helpers.defaultNullOpts.mkListOf types.str [ ] '' ignore_focus = defaultNullOpts.mkNullableWithRaw' {
If current filetype is in this list it'll always be drawn as inactive statusline and the type = types.listOf types.str;
last window will be drawn as active statusline. pluginDefault = [ ];
description = ''
A list of filetypes that should always show an "unfocused" statusline.
For example if you don't want statusline of your file tree / sidebar window to have active If the focused window's filetype is in this list, then the most
statusline you can add their filetypes here. recently focused window will be drawn as the active statusline.
''; '';
example = [
"neo-tree"
"nvim-tree"
"mini-files"
];
};
alwaysDivideMiddle = helpers.defaultNullOpts.mkBool true '' always_divide_middle = defaultNullOpts.mkBool true ''
When set to true, left sections i.e. 'a','b' and 'c' can't take over the entire statusline Whether to prevent left sections i.e. 'a','b' and 'c' from taking over the entire statusline
even if neither of 'x', 'y' or 'z' are present. even if neither of 'x', 'y' or 'z' are present.
''; '';
globalstatus = helpers.defaultNullOpts.mkBool false '' globalstatus = defaultNullOpts.mkBool false ''
Enable global statusline (have a single statusline at bottom of neovim instead of one for Whether to enable "global" statusline.
every window). I.e. having a single statusline at bottom of neovim, instead of one for each individual window.
This feature is only available in neovim 0.7 and higher.
''; '';
refresh = { refresh = {
statusline = helpers.defaultNullOpts.mkInt 1000 "Refresh time for the status line (ms)"; statusline = defaultNullOpts.mkInt 1000 "Refresh time for the status line (ms)";
tabline = helpers.defaultNullOpts.mkInt 1000 "Refresh time for the tabline (ms)"; tabline = defaultNullOpts.mkInt 1000 "Refresh time for the tabline (ms)";
winbar = helpers.defaultNullOpts.mkInt 1000 "Refresh time for the winbar (ms)"; winbar = defaultNullOpts.mkInt 1000 "Refresh time for the winbar (ms)";
};
}; };
sections = { sections = {
@ -184,7 +277,7 @@ in
lualine_z = mkComponentOptions "location"; lualine_z = mkComponentOptions "location";
}; };
inactiveSections = { inactive_sections = {
lualine_a = mkComponentOptions ""; lualine_a = mkComponentOptions "";
lualine_b = mkComponentOptions ""; lualine_b = mkComponentOptions "";
lualine_c = mkComponentOptions "filename"; lualine_c = mkComponentOptions "filename";
@ -195,66 +288,126 @@ in
tabline = mkEmptySectionOption "Tabline configuration"; tabline = mkEmptySectionOption "Tabline configuration";
winbar = mkEmptySectionOption "Winbar configuration"; winbar = mkEmptySectionOption "Winbar configuration.";
inactiveWinbar = mkEmptySectionOption "Inactive Winbar configuration"; inactive_winbar = mkEmptySectionOption "Winbar configuration used when inactive.";
extensions = mkOption { extensions = defaultNullOpts.mkListOf (
type = with lib.types; nullOr (listOf (either str (attrsOf anything))); with lib.types; either str (attrsOf anything)
default = null; ) [ ] "List of enabled extensions.";
example = ''[ "fzf" ]'';
description = "list of enabled extensions";
}; };
};
}; settingsExample = {
config =
let
processComponent = x: (if isAttrs x then processTableComponent else id) x;
processTableComponent =
{
name,
icons_enabled,
icon,
separator,
color,
padding,
extraConfig,
fmt,
}:
mergeAttrs {
"__unkeyed" = name;
icon = if isAttrs icon then removeAttrs (icon // { "__unkeyed" = icon.icon; }) [ "icon" ] else icon;
inherit
icons_enabled
separator
color
padding
fmt
;
} extraConfig;
processSections = mapAttrs (_: mapNullable (map processComponent));
setupOptions = {
options = { options = {
inherit (cfg) theme globalstatus refresh; disabled_filetypes = {
icons_enabled = cfg.iconsEnabled; __unkeyed-1 = "startify";
section_separators = cfg.sectionSeparators; __unkeyed-2 = "neo-tree";
component_separators = cfg.componentSeparators; statusline = [
disabled_filetypes = cfg.disabledFiletypes; "dap-repl"
ignore_focus = cfg.ignoreFocus; ];
always_divide_middle = cfg.alwaysDivideMiddle; winbar = [
"aerial"
"dap-repl"
"neotest-summary"
];
};
globalstatus = true;
};
sections = {
lualine_a = [ "mode" ];
lualine_b = [ "branch" ];
lualine_c = [
"filename"
"diff"
];
lualine_x = [
"diagnostics"
{
__unkeyed-1.__raw = ''
function()
local msg = ""
local buf_ft = vim.api.nvim_buf_get_option(0, 'filetype')
local clients = vim.lsp.get_active_clients()
if next(clients) == nil then
return msg
end
for _, client in ipairs(clients) do
local filetypes = client.config.filetypes
if filetypes and vim.fn.index(filetypes, buf_ft) ~= -1 then
return client.name
end
end
return msg
end
'';
icon = "";
color.fg = "#ffffff";
}
"encoding"
"fileformat"
"filetype"
];
lualine_y = [
{
__unkeyed-1 = "aerial";
cond.__raw = ''
function()
local buf_size_limit = 1024 * 1024
if vim.api.nvim_buf_get_offset(0, vim.api.nvim_buf_line_count(0)) > buf_size_limit then
return false
end
return true
end
'';
sep = " ) ";
depth.__raw = "nil";
dense = false;
dense_sep = ".";
colored = true;
}
];
lualine_z = [
{
__unkeyed-1 = "location";
}
];
};
tabline = {
lualine_a = [
{
__unkeyed-1 = "buffers";
symbols = {
alternate_file = "";
};
}
];
lualine_z = [ "tabs" ];
};
winbar = {
lualine_c = [
{
__unkeyed-1 = "navic";
}
];
lualine_x = [
{
__unkeyed-1 = "filename";
newfile_status = true;
path = 3;
shorting_target = 150;
}
];
};
}; };
inherit (cfg) extensions; extraOptions = {
sections = processSections cfg.sections; gitPackage = lib.mkPackageOption pkgs "git" {
inactive_sections = processSections cfg.inactiveSections; nullable = true;
tabline = processSections cfg.tabline;
winbar = processSections cfg.winbar;
inactive_winbar = processSections cfg.inactiveWinbar;
}; };
in };
mkIf cfg.enable {
extraPlugins = [ cfg.package ] ++ (optional cfg.iconsEnabled pkgs.vimPlugins.nvim-web-devicons); extraConfig = cfg: {
extraPackages = [ cfg.gitPackage ]; extraPackages = [ cfg.gitPackage ];
extraConfigLua = ''require("lualine").setup(${helpers.toLuaObject setupOptions})'';
}; };
} }

View file

@ -8,18 +8,20 @@
lualine = { lualine = {
enable = true; enable = true;
sectionSeparators = { settings = {
options = {
section_separators = {
left = ""; left = "";
right = ""; right = "";
}; };
component_separators = {
componentSeparators = {
left = ""; left = "";
right = ""; right = "";
}; };
theme = "auto"; theme = "auto";
}; };
};
};
goyo = { goyo = {
enable = true; enable = true;

View file

@ -8,23 +8,26 @@
plugins.lualine = { plugins.lualine = {
enable = true; enable = true;
iconsEnabled = true; settings = {
options = {
icons_enabled = true;
theme = "auto"; theme = "auto";
componentSeparators = { component_separators = {
left = ""; left = "";
right = ""; right = "";
}; };
sectionSeparators = { section_separators = {
left = ""; left = "";
right = ""; right = "";
}; };
alwaysDivideMiddle = true; always_divide_middle = true;
globalstatus = false; globalstatus = false;
refresh = { refresh = {
statusline = 1000; statusline = 1000;
tabline = 1000; tabline = 1000;
winbar = 1000; winbar = 1000;
}; };
};
sections = { sections = {
lualine_a = [ "mode" ]; lualine_a = [ "mode" ];
lualine_b = [ lualine_b = [
@ -41,17 +44,21 @@
lualine_y = [ "progress" ]; lualine_y = [ "progress" ];
lualine_z = [ "location" ]; lualine_z = [ "location" ];
}; };
inactiveSections = { inactive_sections = {
lualine_c = [ "filename" ]; lualine_c = [ "filename" ];
lualine_x = [ "location" ]; lualine_x = [ "location" ];
}; };
}; };
}; };
};
example = { example = {
extraPlugins = [ pkgs.vimPlugins.gruvbox-nvim ]; extraPlugins = [ pkgs.vimPlugins.gruvbox-nvim ];
plugins.lualine = { plugins.lualine = {
enable = true; enable = true;
settings = {
options = {
component_separators = "|";
theme.__raw = '' theme.__raw = ''
(function() (function()
local custom_gruvbox = require("lualine.themes.gruvbox") local custom_gruvbox = require("lualine.themes.gruvbox")
@ -59,41 +66,48 @@
return custom_gruvbox return custom_gruvbox
end)() end)()
''; '';
ignoreFocus = [ ignore_focus = [
"NvimTree" "NvimTree"
"neo-tree" "neo-tree"
]; ];
disabledFiletypes = { disabled_filetypes = {
__unkeyed-1 = "startify";
winbar = [ "neo-tree" ]; winbar = [ "neo-tree" ];
}; };
};
sections = { sections = {
lualine_a = [
{
__unkeyed-1 = "mode";
separator.left = "";
padding.left = 2;
}
];
lualine_c = [ lualine_c = [
# you can specify only the sections you want to change # you can specify only the sections you want to change
{ {
name = "filename"; __unkeyed-1 = "filename";
icon = "-"; icon = "-";
extraConfig = {
newfile_status = true; newfile_status = true;
path = 1; path = 1;
shorting_target = 60; shorting_target = 60;
};
} }
]; ];
lualine_z = [ lualine_z = [
{ name = "location"; } { __unkeyed-1 = "location"; }
{ name = "%L"; } # total lines { __unkeyed-1 = "%L"; } # total lines
]; ];
}; };
tabline = { tabline = {
lualine_a = [ lualine_a = [
{ {
name = "buffers"; __unkeyed-1 = "buffers";
icon = { icon = {
icon = "X"; __unkeyed-1 = "X";
align = "right"; align = "right";
}; };
extraConfig.mode = 4; mode = 4;
extraConfig.filetype_names = { filetype_names = {
TelescopePrompt = "Telescope"; TelescopePrompt = "Telescope";
NvimTree = "NvimTree"; NvimTree = "NvimTree";
}; };
@ -106,8 +120,8 @@
]; ];
lualine_z = [ lualine_z = [
{ {
name = "tabs"; __unkeyed-1 = "tabs";
extraConfig.mode = 2; mode = 2;
} }
]; ];
}; };
@ -125,6 +139,17 @@
]; ];
}; };
}; };
};
disabled-list = {
plugins.lualine = {
enable = true;
settings.options.disabled_filetypes = [
"neo-tree"
"startify"
];
};
};
no-packages = { no-packages = {
plugins.lualine = { plugins.lualine = {