nix-community / nixvim

Configure Neovim with Nix! [maintainer=@GaetanLepage, @traxys, @mattsturgeon]
https://nix-community.github.io/nixvim
MIT License
1.41k stars 213 forks source link

[BUG] `toLua` does not filter null values for attrs nested in lists #1804

Closed andrevmatos closed 1 week ago

andrevmatos commented 1 week ago
Field Description
Plugin lualine
Nixpkgs unstable
Home Manager unstable

Description

lualine sections which are overridden by user end up with square separators, instead of the default;

While looking at the generated init.lua, it looks like toLua is failing to filter out the null attributes (as per removeNullAttrValues default option), and the section ends up with separator = { left = nil, right = nil} property, which is interpreted by lualine as overriding the plugin-wide default separators.

May have been caused by #1761. lualine is just how I identified the issue, but if nixvim is failing to properly clean up nil values, this could have much wider unintended effects.

Minimal, Reproducible Example (MRE)

programs.nixvim = {
  plugins.lualine = {
    enable = true;
    sections.lualine_b = [
      {name = "filename";}
    ];
  };
};

Generated init.lua snippet:

require("lualine").setup({
    options = { icons_enabled = true },
    sections = {
        lualine_b = {
            {
                "filename",
                color = nil,
                fmt = nil,
                icon = nil,
                icons_enabled = nil,
                padding = nil,
                separator = { left = nil, right = nil },
            },
        },
    },
})

Expected:

require("lualine").setup({
    options = { icons_enabled = true },
    sections = {
        lualine_b = {
            {
                "filename"
            },
        },
    },
})
andrevmatos commented 1 week ago

It seems other nil default options are properly cleaned up, so this may have to do with these overridden sections sitting inside a list?

MattSturgeon commented 1 week ago

I've played around in the repl, and I can reproduce the issue. I can't find a way to manually craft an attrset that also has the issue though.

nix-repl> :lf .
Added 25 variables.

nix-repl> helpers = outputs.lib.x86_64-linux.helpers

nix-repl> n = legacyPackages.x86_64-linux.makeNixvim {
      plugins.lualine = {
        enable = true;
        sections.lualine_b = [
          {name = "filename";}
        ];
      };
    }

nix-repl> n.config.plugins.lualine.sections
{ lualine_a = null; lualine_b = [ ... ]; lualine_c = null; lualine_x = null; lualine_y = null; lualine_z = null; }

nix-repl> builtins.head n.config.plugins.lualine.sections.lualine_b
{ color = null; extraConfig = { ... }; fmt = null; icon = null; icons_enabled = null; name = "filename"; padding = null; separator = { ... }; }

nix-repl> n.config.extraConfigLua
"require(\"lualine\").setup({ options = { icons_enabled = true }, sections = { lualine_b = { { \"filename\", color = nil, fmt = nil, icon = nil, icons_enabled = nil, padding = nil, separator = { left = nil, right = nil } } } } })\n\nvim.filetype.add({ extension = { v = \"vlang\" } })\n"

nix-repl> helpers.toLuaObject n.config.plugins.lualine.sections.lualine_b
"{ { name = \"filename\" } }"

nix-repl> helpers.toLuaObject { foo = null; }
"{ }"

nix-repl> helpers.toLuaObject { foo = null; bar = { a = null; __unkeyed = "hi"; }; }
"{ bar = { \"hi\" } }"
MattSturgeon commented 1 week ago

Ah!

nix-repl> helpers.toLuaObject { a = { b = [ { a = null; __unkeyed-1 = "hi"; c = null; } { a = null; b = "test"; c = null; } ]; c = null; }; }
"{ a = { b = { { \"hi\", a = nil, c = nil }, { a = nil, b = \"test\", c = nil } } } }"

removeEmptiesRecursive doesn't recurse into list-entries.

It should though:

https://github.com/nix-community/nixvim/blob/aff12581d8cbeb27c58b5871ebe6c1405cabd4d9/lib/to-lua.nix#L127-L128