How to write DRY nix-code using predefined lists?

I want to learn to create Nix code as efficient as possible.

For example I want to install and enable gnome-shell extensions in with Home Manager. How can I rewrite this redundant code here…

{ pkgs, ... }:

{

  home.packages = [
    pkgs.gnomeExtensions.highlight-focus
    pkgs.gnomeExtensions.useless-gaps
    pkgs.gnomeExtensions.focus-changer
  ];

  dconf.settings = {
    "org/gnome/shell" = {
      enabled-extensions = [
        pkgs.gnomeExtensions.highlight-focus.extensionUuid
        pkgs.gnomeExtensions.useless-gaps.extensionUuid
        pkgs.gnomeExtensions.focus-changer.extensionUuid
      ];
    };
  };
}

To a DRY version like this below? (or is there another strategy?)

{ pkgs, ... }:

let
  gnomeExtensions = [
      pkgs.gnomeExtensions.highlight-focus
      pkgs.gnomeExtensions.useless-gaps
      pkgs.gnomeExtensions.focus-changer
    ];
in
  {
    # FUNCTION/METHOD TO POPULATE
    home.packages = [
    ];

    dconf.settings = {
      "org/gnome/shell" = {
        # FUNCTION/METHOD TO POPULATE
        enabled-extensions = [

        ];
      };
    };
  }
1 Like
let
  gnomeExtensions = [
    pkgs.gnomeExtensions.highlight-focus
    pkgs.gnomeExtensions.useless-gaps
    pkgs.gnomeExtensions.focus-changer
  ];
in
{
  home.packages = gnomeExtensions;
  dconf.settings = {
    "org/gnome/shell" = {
      enabled-extensions = map (ext: ext.extensionUuid) gnomeExtensions;
    };
  };
}
2 Likes

Can take this further by using with pkgs.gnomeExtensions; on the list in the let binding.

let
  gnomeExtensions = with pkgs.gnomeExtensions; [
    highlight-focus
    useless-gaps
    focus-changer
  ];
in
{
  home.packages = gnomeExtensions;
  dconf.settings = {
    "org/gnome/shell" = {
      enabled-extensions = map (ext: ext.extensionUuid) gnomeExtensions;
    };
  };
}

Since it is a module, we can use the passed in config fix point to access already defined configuration:

{ pkgs, config, ... }:

{

  home.packages = [
    pkgs.gnomeExtensions.highlight-focus
    pkgs.gnomeExtensions.useless-gaps
    pkgs.gnomeExtensions.focus-changer
  ];

  dconf.settings = {
    "org/gnome/shell" = {
      enabled-extensions = builtins.map (builtins.getAttr "extensionUuid") config.home.packages;
    };
  };
}

The obvious problem is of course that it implies that only gnome extension packages may be installed in home.packages (also not in other modules) or this breaks. To guard against this, you’d have to do something like:

builtins.filter (x: x != null) (builtins.map (x: x.extensionUuid or null) config.home.packages)

Would likely perform worse than just having a let binding though.

1 Like