Merge remote-tracking branch 'refs/remotes/origin/master'

This commit is contained in:
Kyure_A 2024-07-30 21:30:59 +09:00
commit 3aba34f8cb
37 changed files with 1501 additions and 1205 deletions

View file

@ -2,11 +2,11 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1721379653, "lastModified": 1722062969,
"narHash": "sha256-8MUgifkJ7lkZs3u99UDZMB4kbOxvMEXQZ31FO3SopZ0=", "narHash": "sha256-QOS0ykELUmPbrrUGmegAUlpmUFznDQeR4q7rFhl8eQg=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "1d9c2c9b3e71b9ee663d11c5d298727dace8d374", "rev": "b73c2221a46c13557b1b3be9c2070cc42cf01eb3",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -198,9 +198,19 @@ function setFlakeAttribute() {
;; ;;
*) *)
local name="$USER" local name="$USER"
local hostnameArray=()
# FQDN lookup can fail depending on the resolver.
local fqdn
fqdn="$(hostname -f 2> /dev/null)"
if [[ $? -eq 0 ]]; then
hostnameArray+=( "$USER@$fqdn" )
fi
# Check FQDN, long, and short hostnames; long first to preserve # Check FQDN, long, and short hostnames; long first to preserve
# pre-existing behaviour in case both happen to be defined. # pre-existing behaviour in case both happen to be defined.
for n in "$USER@$(hostname -f)" "$USER@$(hostname)" "$USER@$(hostname -s)"; do hostnameArray+=( "$USER@$(hostname)" "$USER@$(hostname -s)" )
for n in "${hostnameArray[@]}"; do
if [[ "$(nix eval "$flake#homeConfigurations" --apply "x: x ? \"$n\"")" == "true" ]]; then if [[ "$(nix eval "$flake#homeConfigurations" --apply "x: x ? \"$n\"")" == "true" ]]; then
name="$n" name="$n"
if [[ -v VERBOSE ]]; then if [[ -v VERBOSE ]]; then

View file

@ -67,7 +67,7 @@ let
}; };
in { in {
meta.maintainers = [ maintainers.polykernel maintainers.league ]; meta.maintainers = [ maintainers.league ];
imports = [ imports = [
(mkAliasOptionModule [ "xsession" "pointerCursor" "package" ] [ (mkAliasOptionModule [ "xsession" "pointerCursor" "package" ] [

View file

@ -49,6 +49,12 @@
github = "bertof"; github = "bertof";
githubId = 9915675; githubId = 9915675;
}; };
bricked = {
name = "Bricked";
email = "hello@bricked.dev";
github = "brckd";
githubId = 92804487;
};
CarlosLoboxyz = { CarlosLoboxyz = {
name = "Carlos Lobo"; name = "Carlos Lobo";
email = "86011416+CarlosLoboxyz@users.noreply.github.com"; email = "86011416+CarlosLoboxyz@users.noreply.github.com";

View file

@ -311,5 +311,5 @@ in {
}) })
]); ]);
meta.maintainers = [ maintainers.polykernel ]; meta.maintainers = [ ];
} }

View file

@ -56,5 +56,5 @@ in {
}; };
}; };
meta.maintainers = [ maintainers.polykernel ]; meta.maintainers = [ ];
} }

View file

@ -5,6 +5,7 @@ with lib;
let let
cfg = config.programs.eww; cfg = config.programs.eww;
ewwCmd = "${cfg.package}/bin/eww";
in { in {
meta.maintainers = [ hm.maintainers.mainrs ]; meta.maintainers = [ hm.maintainers.mainrs ];
@ -30,10 +31,40 @@ in {
{file}`$XDG_CONFIG_HOME/eww`. {file}`$XDG_CONFIG_HOME/eww`.
''; '';
}; };
enableBashIntegration = mkEnableOption "Bash integration" // {
default = true;
};
enableZshIntegration = mkEnableOption "Zsh integration" // {
default = true;
};
enableFishIntegration = mkEnableOption "Fish integration" // {
default = true;
};
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
xdg.configFile."eww".source = cfg.configDir; xdg.configFile."eww".source = cfg.configDir;
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
if [[ $TERM != "dumb" ]]; then
eval "$(${ewwCmd} shell-completions --shell bash)"
fi
'';
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
if [[ $TERM != "dumb" ]]; then
eval "$(${ewwCmd} shell-completions --shell zsh)"
fi
'';
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
if test "$TERM" != "dumb"
eval "$(${ewwCmd} shell-completions --shell fish)"
end
'';
}; };
} }

View file

@ -1,945 +1,51 @@
{ config, lib, pkgs, ... }: { lib, ... }:
with lib; with lib;
let let
inherit (pkgs.stdenv.hostPlatform) isDarwin; modulePath = [ "programs" "firefox" ];
cfg = config.programs.firefox; moduleName = concatStringsSep "." modulePath;
jsonFormat = pkgs.formats.json { }; mkFirefoxModule = import ./firefox/mkFirefoxModule.nix;
mozillaConfigPath =
if isDarwin then "Library/Application Support/Mozilla" else ".mozilla";
firefoxConfigPath = if isDarwin then
"Library/Application Support/Firefox"
else
"${mozillaConfigPath}/firefox";
profilesPath =
if isDarwin then "${firefoxConfigPath}/Profiles" else firefoxConfigPath;
nativeMessagingHostsPath = if isDarwin then
"${mozillaConfigPath}/NativeMessagingHosts"
else
"${mozillaConfigPath}/native-messaging-hosts";
nativeMessagingHostsJoined = pkgs.symlinkJoin {
name = "ff_native-messaging-hosts";
paths = [
# Link a .keep file to keep the directory around
(pkgs.writeTextDir "lib/mozilla/native-messaging-hosts/.keep" "")
# Link package configured native messaging hosts (entire Firefox actually)
cfg.finalPackage
]
# Link user configured native messaging hosts
++ cfg.nativeMessagingHosts;
};
# The extensions path shared by all profiles; will not be supported
# by future Firefox versions.
extensionPath = "extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
profiles = flip mapAttrs' cfg.profiles (_: profile:
nameValuePair "Profile${toString profile.id}" {
Name = profile.name;
Path = if isDarwin then "Profiles/${profile.path}" else profile.path;
IsRelative = 1;
Default = if profile.isDefault then 1 else 0;
}) // {
General = { StartWithLastProfile = 1; };
};
profilesIni = generators.toINI { } profiles;
userPrefValue = pref:
builtins.toJSON (if isBool pref || isInt pref || isString pref then
pref
else
builtins.toJSON pref);
mkUserJs = prefs: extraPrefs: bookmarks:
let
prefs' = lib.optionalAttrs ([ ] != bookmarks) {
"browser.bookmarks.file" = toString (firefoxBookmarksFile bookmarks);
"browser.places.importBookmarksHTML" = true;
} // prefs;
in ''
// Generated by Home Manager.
${concatStrings (mapAttrsToList (name: value: ''
user_pref("${name}", ${userPrefValue value});
'') prefs')}
${extraPrefs}
'';
mkContainersJson = containers:
let
containerToIdentity = _: container: {
userContextId = container.id;
name = container.name;
icon = container.icon;
color = container.color;
public = true;
};
in ''
${builtins.toJSON {
version = 4;
lastUserContextId =
elemAt (mapAttrsToList (_: container: container.id) containers) 0;
identities = mapAttrsToList containerToIdentity containers ++ [
{
userContextId = 4294967294; # 2^32 - 2
name = "userContextIdInternal.thumbnail";
icon = "";
color = "";
accessKey = "";
public = false;
}
{
userContextId = 4294967295; # 2^32 - 1
name = "userContextIdInternal.webextStorageLocal";
icon = "";
color = "";
accessKey = "";
public = false;
}
];
}}
'';
firefoxBookmarksFile = bookmarks:
let
indent = level:
lib.concatStringsSep "" (map (lib.const " ") (lib.range 1 level));
bookmarkToHTML = indentLevel: bookmark:
''
${indent indentLevel}<DT><A HREF="${
escapeXML bookmark.url
}" ADD_DATE="1" LAST_MODIFIED="1"${
lib.optionalString (bookmark.keyword != null)
" SHORTCUTURL=\"${escapeXML bookmark.keyword}\""
}${
lib.optionalString (bookmark.tags != [ ])
" TAGS=\"${escapeXML (concatStringsSep "," bookmark.tags)}\""
}>${escapeXML bookmark.name}</A>'';
directoryToHTML = indentLevel: directory: ''
${indent indentLevel}<DT>${
if directory.toolbar then
''
<H3 ADD_DATE="1" LAST_MODIFIED="1" PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Toolbar''
else
''<H3 ADD_DATE="1" LAST_MODIFIED="1">${escapeXML directory.name}''
}</H3>
${indent indentLevel}<DL><p>
${allItemsToHTML (indentLevel + 1) directory.bookmarks}
${indent indentLevel}</DL><p>'';
itemToHTMLOrRecurse = indentLevel: item:
if item ? "url" then
bookmarkToHTML indentLevel item
else
directoryToHTML indentLevel item;
allItemsToHTML = indentLevel: bookmarks:
lib.concatStringsSep "\n"
(map (itemToHTMLOrRecurse indentLevel) bookmarks);
bookmarkEntries = allItemsToHTML 1 bookmarks;
in pkgs.writeText "firefox-bookmarks.html" ''
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks Menu</H1>
<DL><p>
${bookmarkEntries}
</DL>
'';
mkNoDuplicateAssertion = entities: entityKind:
(let
# Return an attribute set with entity IDs as keys and a list of
# entity names with corresponding ID as value. An ID is present in
# the result only if more than one entity has it. The argument
# entities is a list of AttrSet of one id/name pair.
findDuplicateIds = entities:
filterAttrs (_entityId: entityNames: length entityNames != 1)
(zipAttrs entities);
duplicates = findDuplicateIds (mapAttrsToList
(entityName: entity: { "${toString entity.id}" = entityName; })
entities);
mkMsg = entityId: entityNames:
" - ID ${entityId} is used by " + concatStringsSep ", " entityNames;
in {
assertion = duplicates == { };
message = ''
Must not have a Firefox ${entityKind} with an existing ID but
'' + concatStringsSep "\n" (mapAttrsToList mkMsg duplicates);
});
wrapPackage = package:
let
# The configuration expected by the Firefox wrapper.
fcfg = { enableGnomeExtensions = cfg.enableGnomeExtensions; };
# A bit of hackery to force a config into the wrapper.
browserName =
package.browserName or (builtins.parseDrvName package.name).name;
# The configuration expected by the Firefox wrapper builder.
bcfg = setAttrByPath [ browserName ] fcfg;
in if package == null then
null
else if isDarwin then
package
else if versionAtLeast config.home.stateVersion "19.09" then
package.override (old: {
cfg = old.cfg or { } // fcfg;
extraPolicies = (old.extraPolicies or { }) // cfg.policies;
})
else
(pkgs.wrapFirefox.override { config = bcfg; }) package { };
in { in {
meta.maintainers = [ maintainers.rycee maintainers.kira-bruneau ]; meta.maintainers =
[ maintainers.rycee maintainers.kira-bruneau hm.maintainers.bricked ];
imports = [ imports = [
(mkRemovedOptionModule [ "programs" "firefox" "extensions" ] '' (mkFirefoxModule {
inherit modulePath;
name = "Firefox";
wrappedPackageName = "firefox";
unwrappedPackageName = "firefox-unwrapped";
visible = true;
platforms.linux = rec {
vendorPath = ".mozilla";
configPath = "${vendorPath}/firefox";
};
platforms.darwin = {
vendorPath = "Library/Application Support/Mozilla";
configPath = "Library/Application Support/Firefox";
};
})
(mkRemovedOptionModule (modulePath ++ [ "extensions" ]) ''
Extensions are now managed per-profile. That is, change from Extensions are now managed per-profile. That is, change from
programs.firefox.extensions = [ foo bar ]; ${moduleName}.extensions = [ foo bar ];
to to
programs.firefox.profiles.myprofile.extensions = [ foo bar ];'') ${moduleName}.profiles.myprofile.extensions = [ foo bar ];'')
(mkRemovedOptionModule [ "programs" "firefox" "enableAdobeFlash" ] (mkRemovedOptionModule (modulePath ++ [ "enableAdobeFlash" ])
"Support for this option has been removed.") "Support for this option has been removed.")
(mkRemovedOptionModule [ "programs" "firefox" "enableGoogleTalk" ] (mkRemovedOptionModule (modulePath ++ [ "enableGoogleTalk" ])
"Support for this option has been removed.") "Support for this option has been removed.")
(mkRemovedOptionModule [ "programs" "firefox" "enableIcedTea" ] (mkRemovedOptionModule (modulePath ++ [ "enableIcedTea" ])
"Support for this option has been removed.") "Support for this option has been removed.")
]; ];
options = {
programs.firefox = {
enable = mkEnableOption "Firefox";
package = mkOption {
type = with types; nullOr package;
default = if versionAtLeast config.home.stateVersion "19.09" then
pkgs.firefox
else
pkgs.firefox-unwrapped;
defaultText = literalExpression "pkgs.firefox";
example = literalExpression ''
pkgs.firefox.override {
# See nixpkgs' firefox/wrapper.nix to check which options you can use
nativeMessagingHosts = [
# Gnome shell native connector
pkgs.gnome-browser-connector
# Tridactyl native connector
pkgs.tridactyl-native
];
}
'';
description = ''
The Firefox package to use. If state version  19.09 then
this should be a wrapped Firefox package. For earlier state
versions it should be an unwrapped Firefox package.
Set to `null` to disable installing Firefox.
'';
};
nativeMessagingHosts = mkOption {
type = types.listOf types.package;
default = [ ];
description = ''
Additional packages containing native messaging hosts that should be
made available to Firefox extensions.
'';
};
finalPackage = mkOption {
type = with types; nullOr package;
readOnly = true;
description = "Resulting Firefox package.";
};
policies = mkOption {
type = types.attrsOf jsonFormat.type;
default = { };
description =
"[See list of policies](https://mozilla.github.io/policy-templates/).";
example = {
DefaultDownloadDirectory = "\${home}/Downloads";
BlockAboutConfig = true;
};
};
profiles = mkOption {
type = types.attrsOf (types.submodule ({ config, name, ... }: {
options = {
name = mkOption {
type = types.str;
default = name;
description = "Profile name.";
};
id = mkOption {
type = types.ints.unsigned;
default = 0;
description = ''
Profile ID. This should be set to a unique number per profile.
'';
};
settings = mkOption {
type = types.attrsOf (jsonFormat.type // {
description =
"Firefox preference (int, bool, string, and also attrs, list, float as a JSON string)";
});
default = { };
example = literalExpression ''
{
"browser.startup.homepage" = "https://nixos.org";
"browser.search.region" = "GB";
"browser.search.isUS" = false;
"distribution.searchplugins.defaultLocale" = "en-GB";
"general.useragent.locale" = "en-GB";
"browser.bookmarks.showMobileBookmarks" = true;
"browser.newtabpage.pinned" = [{
title = "NixOS";
url = "https://nixos.org";
}];
}
'';
description = ''
Attribute set of Firefox preferences.
Firefox only supports int, bool, and string types for
preferences, but home-manager will automatically
convert all other JSON-compatible values into strings.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra preferences to add to {file}`user.js`.
'';
};
userChrome = mkOption {
type = types.lines;
default = "";
description = "Custom Firefox user chrome CSS.";
example = ''
/* Hide tab bar in FF Quantum */
@-moz-document url("chrome://browser/content/browser.xul") {
#TabsToolbar {
visibility: collapse !important;
margin-bottom: 21px !important;
}
#sidebar-box[sidebarcommand="treestyletab_piro_sakura_ne_jp-sidebar-action"] #sidebar-header {
visibility: collapse !important;
}
}
'';
};
userContent = mkOption {
type = types.lines;
default = "";
description = "Custom Firefox user content CSS.";
example = ''
/* Hide scrollbar in FF Quantum */
*{scrollbar-width:none !important}
'';
};
bookmarks = mkOption {
type = let
bookmarkSubmodule = types.submodule ({ config, name, ... }: {
options = {
name = mkOption {
type = types.str;
default = name;
description = "Bookmark name.";
};
tags = mkOption {
type = types.listOf types.str;
default = [ ];
description = "Bookmark tags.";
};
keyword = mkOption {
type = types.nullOr types.str;
default = null;
description = "Bookmark search keyword.";
};
url = mkOption {
type = types.str;
description = "Bookmark url, use %s for search terms.";
};
};
}) // {
description = "bookmark submodule";
};
bookmarkType = types.addCheck bookmarkSubmodule (x: x ? "url");
directoryType = types.submodule ({ config, name, ... }: {
options = {
name = mkOption {
type = types.str;
default = name;
description = "Directory name.";
};
bookmarks = mkOption {
type = types.listOf nodeType;
default = [ ];
description = "Bookmarks within directory.";
};
toolbar = mkOption {
type = types.bool;
default = false;
description = ''
Make this the toolbar directory. Note, this does _not_
mean that this directory will be added to the toolbar,
this directory _is_ the toolbar.
'';
};
};
}) // {
description = "directory submodule";
};
nodeType = types.either bookmarkType directoryType;
in with types;
coercedTo (attrsOf nodeType) attrValues (listOf nodeType);
default = [ ];
example = literalExpression ''
[
{
name = "wikipedia";
tags = [ "wiki" ];
keyword = "wiki";
url = "https://en.wikipedia.org/wiki/Special:Search?search=%s&go=Go";
}
{
name = "kernel.org";
url = "https://www.kernel.org";
}
{
name = "Nix sites";
toolbar = true;
bookmarks = [
{
name = "homepage";
url = "https://nixos.org/";
}
{
name = "wiki";
tags = [ "wiki" "nix" ];
url = "https://wiki.nixos.org/";
}
];
}
]
'';
description = ''
Preloaded bookmarks. Note, this may silently overwrite any
previously existing bookmarks!
'';
};
path = mkOption {
type = types.str;
default = name;
description = "Profile path.";
};
isDefault = mkOption {
type = types.bool;
default = config.id == 0;
defaultText = "true if profile ID is 0";
description = "Whether this is a default profile.";
};
search = {
force = mkOption {
type = with types; bool;
default = false;
description = ''
Whether to force replace the existing search
configuration. This is recommended since Firefox will
replace the symlink for the search configuration on every
launch, but note that you'll lose any existing
configuration by enabling this.
'';
};
default = mkOption {
type = with types; nullOr str;
default = null;
example = "DuckDuckGo";
description = ''
The default search engine used in the address bar and search bar.
'';
};
privateDefault = mkOption {
type = with types; nullOr str;
default = null;
example = "DuckDuckGo";
description = ''
The default search engine used in the Private Browsing.
'';
};
order = mkOption {
type = with types; uniq (listOf str);
default = [ ];
example = [ "DuckDuckGo" "Google" ];
description = ''
The order the search engines are listed in. Any engines
that aren't included in this list will be listed after
these in an unspecified order.
'';
};
engines = mkOption {
type = with types; attrsOf (attrsOf jsonFormat.type);
default = { };
example = literalExpression ''
{
"Nix Packages" = {
urls = [{
template = "https://search.nixos.org/packages";
params = [
{ name = "type"; value = "packages"; }
{ name = "query"; value = "{searchTerms}"; }
];
}];
icon = "''${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
definedAliases = [ "@np" ];
};
"NixOS Wiki" = {
urls = [{ template = "https://wiki.nixos.org/index.php?search={searchTerms}"; }];
iconUpdateURL = "https://wiki.nixos.org/favicon.png";
updateInterval = 24 * 60 * 60 * 1000; # every day
definedAliases = [ "@nw" ];
};
"Bing".metaData.hidden = true;
"Google".metaData.alias = "@g"; # builtin engines only support specifying one additional alias
}
'';
description = ''
Attribute set of search engine configurations. Engines
that only have {var}`metaData` specified will
be treated as builtin to Firefox.
See [SearchEngine.jsm](https://searchfox.org/mozilla-central/rev/669329e284f8e8e2bb28090617192ca9b4ef3380/toolkit/components/search/SearchEngine.jsm#1138-1177)
in Firefox's source for available options. We maintain a
mapping to let you specify all options in the referenced
link without underscores, but it may fall out of date with
future options.
Note, {var}`icon` is also a special option
added by Home Manager to make it convenient to specify
absolute icon paths.
'';
};
};
containersForce = mkOption {
type = types.bool;
default = false;
description = ''
Whether to force replace the existing containers
configuration. This is recommended since Firefox will
replace the symlink on every launch, but note that you'll
lose any existing configuration by enabling this.
'';
};
containers = mkOption {
type = types.attrsOf (types.submodule ({ name, ... }: {
options = {
name = mkOption {
type = types.str;
default = name;
description = "Container name, e.g., shopping.";
};
id = mkOption {
type = types.ints.unsigned;
default = 0;
description = ''
Container ID. This should be set to a unique number per container in this profile.
'';
};
# List of colors at
# https://searchfox.org/mozilla-central/rev/5ad226c7379b0564c76dc3b54b44985356f94c5a/toolkit/components/extensions/parent/ext-contextualIdentities.js#32
color = mkOption {
type = types.enum [
"blue"
"turquoise"
"green"
"yellow"
"orange"
"red"
"pink"
"purple"
"toolbar"
];
default = "pink";
description = "Container color.";
};
icon = mkOption {
type = types.enum [
"briefcase"
"cart"
"circle"
"dollar"
"fence"
"fingerprint"
"gift"
"vacation"
"food"
"fruit"
"pet"
"tree"
"chill"
];
default = "fruit";
description = "Container icon.";
};
};
}));
default = { };
example = {
"shopping" = {
id = 1;
color = "blue";
icon = "cart";
};
"dangerous" = {
id = 2;
color = "red";
icon = "fruit";
};
};
description = ''
Attribute set of container configurations. See
[Multi-Account
Containers](https://support.mozilla.org/en-US/kb/containers)
for more information.
'';
};
extensions = mkOption {
type = types.listOf types.package;
default = [ ];
example = literalExpression ''
with pkgs.nur.repos.rycee.firefox-addons; [
privacy-badger
]
'';
description = ''
List of Firefox add-on packages to install for this profile.
Some pre-packaged add-ons are accessible from the
[Nix User Repository](https://github.com/nix-community/NUR).
Once you have NUR installed run
```console
$ nix-env -f '<nixpkgs>' -qaP -A nur.repos.rycee.firefox-addons
```
to list the available Firefox add-ons.
Note that it is necessary to manually enable these extensions
inside Firefox after the first installation.
To automatically enable extensions add
`"extensions.autoDisableScopes" = 0;`
to
[{option}`programs.firefox.profiles.<profile>.settings`](#opt-programs.firefox.profiles._name_.settings)
'';
};
};
}));
default = { };
description = "Attribute set of Firefox profiles.";
};
enableGnomeExtensions = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable the GNOME Shell native host connector. Note, you
also need to set the NixOS option
`services.gnome.gnome-browser-connector.enable` to
`true`.
'';
};
};
};
config = mkIf cfg.enable {
assertions = [
(let
defaults =
catAttrs "name" (filter (a: a.isDefault) (attrValues cfg.profiles));
in {
assertion = cfg.profiles == { } || length defaults == 1;
message = "Must have exactly one default Firefox profile but found "
+ toString (length defaults) + optionalString (length defaults > 1)
(", namely " + concatStringsSep ", " defaults);
})
(let
getContainers = profiles:
flatten
(mapAttrsToList (_: value: (attrValues value.containers)) profiles);
findInvalidContainerIds = profiles:
filter (container: container.id >= 4294967294)
(getContainers profiles);
in {
assertion = cfg.profiles == { }
|| length (findInvalidContainerIds cfg.profiles) == 0;
message = "Container id must be smaller than 4294967294 (2^32 - 2)";
})
(mkNoDuplicateAssertion cfg.profiles "profile")
] ++ (mapAttrsToList
(_: profile: mkNoDuplicateAssertion profile.containers "container")
cfg.profiles);
warnings = optional (cfg.enableGnomeExtensions or false) ''
Using 'programs.firefox.enableGnomeExtensions' has been deprecated and
will be removed in the future. Please change to overriding the package
configuration using 'programs.firefox.package' instead. You can refer to
its example for how to do this.
'';
programs.firefox.finalPackage = wrapPackage cfg.package;
home.packages = lib.optional (cfg.finalPackage != null) cfg.finalPackage;
home.file = mkMerge ([{
"${firefoxConfigPath}/profiles.ini" =
mkIf (cfg.profiles != { }) { text = profilesIni; };
"${nativeMessagingHostsPath}" = {
source =
"${nativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts";
recursive = true;
};
}] ++ flip mapAttrsToList cfg.profiles (_: profile: {
"${profilesPath}/${profile.path}/.keep".text = "";
"${profilesPath}/${profile.path}/chrome/userChrome.css" =
mkIf (profile.userChrome != "") { text = profile.userChrome; };
"${profilesPath}/${profile.path}/chrome/userContent.css" =
mkIf (profile.userContent != "") { text = profile.userContent; };
"${profilesPath}/${profile.path}/user.js" = mkIf (profile.settings != { }
|| profile.extraConfig != "" || profile.bookmarks != [ ]) {
text =
mkUserJs profile.settings profile.extraConfig profile.bookmarks;
};
"${profilesPath}/${profile.path}/containers.json" =
mkIf (profile.containers != { }) {
force = profile.containersForce;
text = mkContainersJson profile.containers;
};
"${profilesPath}/${profile.path}/search.json.mozlz4" = mkIf
(profile.search.default != null || profile.search.privateDefault != null
|| profile.search.order != [ ] || profile.search.engines != { }) {
force = profile.search.force;
source = let
settings = {
version = 6;
engines = let
# Map of nice field names to internal field names.
# This is intended to be exhaustive and should be
# updated at every version bump.
internalFieldNames = (genAttrs [
"name"
"isAppProvided"
"loadPath"
"hasPreferredIcon"
"updateInterval"
"updateURL"
"iconUpdateURL"
"iconURL"
"iconMapObj"
"metaData"
"orderHint"
"definedAliases"
"urls"
] (name: "_${name}")) // {
searchForm = "__searchForm";
};
processCustomEngineInput = input:
(removeAttrs input [ "icon" ])
// optionalAttrs (input ? icon) {
# Convenience to specify absolute path to icon
iconURL = "file://${input.icon}";
} // (optionalAttrs (input ? iconUpdateURL) {
# Convenience to default iconURL to iconUpdateURL so
# the icon is immediately downloaded from the URL
iconURL = input.iconURL or input.iconUpdateURL;
} // {
# Required for custom engine configurations, loadPaths
# are unique identifiers that are generally formatted
# like: [source]/path/to/engine.xml
loadPath = ''
[home-manager]/programs.firefox.profiles.${profile.name}.search.engines."${
replaceStrings [ "\\" ] [ "\\\\" ] input.name
}"'';
});
processEngineInput = name: input:
let
requiredInput = {
inherit name;
isAppProvided = input.isAppProvided or removeAttrs input
[ "metaData" ] == { };
metaData = input.metaData or { };
};
in if requiredInput.isAppProvided then
requiredInput
else
processCustomEngineInput (input // requiredInput);
buildEngineConfig = name: input:
mapAttrs' (name: value: {
name = internalFieldNames.${name} or name;
inherit value;
}) (processEngineInput name input);
sortEngineConfigs = configs:
let
buildEngineConfigWithOrder = order: name:
let
config = configs.${name} or {
_name = name;
_isAppProvided = true;
_metaData = { };
};
in config // {
_metaData = config._metaData // { inherit order; };
};
engineConfigsWithoutOrder =
attrValues (removeAttrs configs profile.search.order);
sortedEngineConfigs =
(imap buildEngineConfigWithOrder profile.search.order)
++ engineConfigsWithoutOrder;
in sortedEngineConfigs;
engineInput = profile.search.engines // {
# Infer profile.search.default as an app provided
# engine if it's not in profile.search.engines
${profile.search.default} =
profile.search.engines.${profile.search.default} or { };
} // {
${profile.search.privateDefault} =
profile.search.engines.${profile.search.privateDefault} or { };
};
in sortEngineConfigs (mapAttrs buildEngineConfig engineInput);
metaData = optionalAttrs (profile.search.default != null) {
current = profile.search.default;
hash = "@hash@";
} // optionalAttrs (profile.search.privateDefault != null) {
private = profile.search.privateDefault;
privateHash = "@privateHash@";
} // {
useSavedOrder = profile.search.order != [ ];
};
};
# Home Manager doesn't circumvent user consent and isn't acting
# maliciously. We're modifying the search outside of Firefox, but
# a claim by Mozilla to remove this would be very anti-user, and
# is unlikely to be an issue for our use case.
disclaimer = appName:
"By modifying this file, I agree that I am doing so "
+ "only within ${appName} itself, using official, user-driven search "
+ "engine selection processes, and in a way which does not circumvent "
+ "user consent. I acknowledge that any attempt to change this file "
+ "from outside of ${appName} is a malicious act, and will be responded "
+ "to accordingly.";
salt = if profile.search.default != null then
profile.path + profile.search.default + disclaimer "Firefox"
else
null;
privateSalt = if profile.search.privateDefault != null then
profile.path + profile.search.privateDefault
+ disclaimer "Firefox"
else
null;
in pkgs.runCommand "search.json.mozlz4" {
nativeBuildInputs = with pkgs; [ mozlz4a openssl ];
json = builtins.toJSON settings;
inherit salt privateSalt;
} ''
if [[ -n $salt ]]; then
export hash=$(echo -n "$salt" | openssl dgst -sha256 -binary | base64)
export privateHash=$(echo -n "$privateSalt" | openssl dgst -sha256 -binary | base64)
mozlz4a <(substituteStream json search.json.in --subst-var hash --subst-var privateHash) "$out"
else
mozlz4a <(echo "$json") "$out"
fi
'';
};
"${profilesPath}/${profile.path}/extensions" =
mkIf (profile.extensions != [ ]) {
source = let
extensionsEnvPkg = pkgs.buildEnv {
name = "hm-firefox-extensions";
paths = profile.extensions;
};
in "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
recursive = true;
force = true;
};
}));
};
} }

File diff suppressed because it is too large Load diff

View file

@ -316,7 +316,7 @@ in {
}) })
]; ];
home.packages = [ pkgs.gnome.gnome-terminal ]; home.packages = [ pkgs.gnome-terminal ];
dconf.settings = let dconfPath = "org/gnome/terminal/legacy"; dconf.settings = let dconfPath = "org/gnome/terminal/legacy";
in { in {

View file

@ -7,6 +7,11 @@ let
cfg = config.programs.jujutsu; cfg = config.programs.jujutsu;
tomlFormat = pkgs.formats.toml { }; tomlFormat = pkgs.formats.toml { };
configDir = if pkgs.stdenv.isDarwin then
"Library/Application Support"
else
config.xdg.configHome;
in { in {
meta.maintainers = [ maintainers.shikanime ]; meta.maintainers = [ maintainers.shikanime ];
@ -51,7 +56,7 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
xdg.configFile."jj/config.toml" = mkIf (cfg.settings != { }) { home.file."${configDir}/jj/config.toml" = mkIf (cfg.settings != { }) {
source = tomlFormat.generate "jujutsu-config" (cfg.settings source = tomlFormat.generate "jujutsu-config" (cfg.settings
// optionalAttrs (cfg.ediff) (let // optionalAttrs (cfg.ediff) (let
emacsDiffScript = pkgs.writeShellScriptBin "emacs-ediff" '' emacsDiffScript = pkgs.writeShellScriptBin "emacs-ediff" ''

View file

@ -5,6 +5,8 @@ let
cfg = config.programs.mcfly; cfg = config.programs.mcfly;
tomlFormat = pkgs.formats.toml { };
bashIntegration = '' bashIntegration = ''
eval "$(${getExe pkgs.mcfly} init bash)" eval "$(${getExe pkgs.mcfly} init bash)"
'' + optionalString cfg.fzf.enable '' '' + optionalString cfg.fzf.enable ''
@ -40,6 +42,37 @@ in {
options.programs.mcfly = { options.programs.mcfly = {
enable = mkEnableOption "mcfly"; enable = mkEnableOption "mcfly";
settings = mkOption {
type = tomlFormat.type;
default = { };
example = literalExpression ''
{
colors = {
menubar = {
bg = "black";
fg = "red";
};
darkmode = {
prompt = "cyan";
timing = "yellow";
results_selection_fg = "cyan";
results_selection_bg = "black";
results_selection_hl = "red";
};
};
}
'';
description = ''
Settings written to {file}`~/.config/mcfly/config.toml`.
Note, if your McFly database is currently in {file}`~/.mcfly`,
then this option has no effect.
Move the database to {file}`$XDG_DATA_DIR/mcfly/history.db` and
remove {file}`~/.mcfly` to make the settings take effect. See
<https://github.com/cantino/mcfly#database-location>.
'';
};
keyScheme = mkOption { keyScheme = mkOption {
type = types.enum [ "emacs" "vim" ]; type = types.enum [ "emacs" "vim" ];
default = "emacs"; default = "emacs";
@ -105,6 +138,11 @@ in {
{ {
home.packages = [ pkgs.mcfly ] ++ optional cfg.fzf.enable pkgs.mcfly-fzf; home.packages = [ pkgs.mcfly ] ++ optional cfg.fzf.enable pkgs.mcfly-fzf;
# Oddly enough, McFly expects this in the data path, not in config.
xdg.dataFile."mcfly/config.toml" = mkIf (cfg.settings != { }) {
source = tomlFormat.generate "mcfly-config.toml" cfg.settings;
};
programs.bash.initExtra = mkIf cfg.enableBashIntegration bashIntegration; programs.bash.initExtra = mkIf cfg.enableBashIntegration bashIntegration;
programs.zsh.initExtra = mkIf cfg.enableZshIntegration zshIntegration; programs.zsh.initExtra = mkIf cfg.enableZshIntegration zshIntegration;

View file

@ -15,6 +15,8 @@ in {
programs.micro = { programs.micro = {
enable = mkEnableOption "micro, a terminal-based text editor"; enable = mkEnableOption "micro, a terminal-based text editor";
package = mkPackageOption pkgs "micro" { };
settings = mkOption { settings = mkOption {
type = jsonFormat.type; type = jsonFormat.type;
default = { }; default = { };
@ -35,7 +37,7 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.micro ]; home.packages = [ cfg.package ];
xdg.configFile."micro/settings.json".source = xdg.configFile."micro/settings.json".source =
jsonFormat.generate "micro-settings" cfg.settings; jsonFormat.generate "micro-settings" cfg.settings;

View file

@ -14,7 +14,7 @@ let
config.xdg.configHome; config.xdg.configHome;
in { in {
meta.maintainers = [ maintainers.polykernel ]; meta.maintainers = [ ];
options.programs.watson = { options.programs.watson = {
enable = mkEnableOption "watson, a wonderful CLI to track your time"; enable = mkEnableOption "watson, a wonderful CLI to track your time";

View file

@ -398,6 +398,22 @@ in
{manpage}`zshzle(1)` for syntax. {manpage}`zshzle(1)` for syntax.
''; '';
}; };
strategy = mkOption {
type = types.listOf (types.enum [ "history" "completion" "match_prev_cmd" ]);
default = [ "history" ];
description = ''
`ZSH_AUTOSUGGEST_STRATEGY` is an array that specifies how suggestions should be generated.
The strategies in the array are tried successively until a suggestion is found.
There are currently three built-in strategies to choose from:
- `history`: Chooses the most recent match from history.
- `completion`: Chooses a suggestion based on what tab-completion would suggest. (requires `zpty` module)
- `match_prev_cmd`: Like `history`, but chooses the most recent match whose preceding history item matches
the most recently executed command. Note that this strategy won't work as expected with ZSH options that
don't preserve the history order such as `HIST_IGNORE_ALL_DUPS` or `HIST_EXPIRE_DUPS_FIRST`.
'';
};
}; };
history = mkOption { history = mkOption {
@ -610,6 +626,7 @@ in
(optionalString cfg.autosuggestion.enable '' (optionalString cfg.autosuggestion.enable ''
source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh
ZSH_AUTOSUGGEST_STRATEGY=(${concatStringsSep " " cfg.autosuggestion.strategy})
'') '')
(optionalString (cfg.autosuggestion.enable && cfg.autosuggestion.highlight != null) '' (optionalString (cfg.autosuggestion.enable && cfg.autosuggestion.highlight != null) ''
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}" ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}"

View file

@ -9,7 +9,7 @@ let
iniFormat = pkgs.formats.ini { }; iniFormat = pkgs.formats.ini { };
in { in {
meta.maintainers = with maintainers; [ polykernel ]; meta.maintainers = [ ];
options = { options = {
services.fnott = { services.fnott = {

View file

@ -110,9 +110,11 @@ in {
systemd.user.services.nix-gc = { systemd.user.services.nix-gc = {
Unit = { Description = "Nix Garbage Collector"; }; Unit = { Description = "Nix Garbage Collector"; };
Service = { Service = {
ExecStart = "${nixPackage}/bin/nix-collect-garbage ${ Type = "oneshot";
ExecStart = toString (pkgs.writeShellScript "nix-gc" ''
exec "${nixPackage}/bin/nix-collect-garbage ${
lib.optionalString (cfg.options != null) cfg.options lib.optionalString (cfg.options != null) cfg.options
}"; }"'');
}; };
}; };
systemd.user.timers.nix-gc = { systemd.user.timers.nix-gc = {

View file

@ -60,6 +60,8 @@ in {
After = [ "graphical-session.target" ]; After = [ "graphical-session.target" ];
ConditionEnvironment = "WAYLAND_DISPLAY"; ConditionEnvironment = "WAYLAND_DISPLAY";
Documentation = "man:swayosd(1)"; Documentation = "man:swayosd(1)";
StartLimitBurst = 5;
StartLimitIntervalSec = 10;
}; };
Service = { Service = {
@ -71,6 +73,7 @@ in {
+ (optionalString (cfg.topMargin != null) + (optionalString (cfg.topMargin != null)
" --top-margin ${toString cfg.topMargin}"); " --top-margin ${toString cfg.topMargin}");
Restart = "always"; Restart = "always";
RestartSec = "2s";
}; };
Install = { WantedBy = [ "graphical-session.target" ]; }; Install = { WantedBy = [ "graphical-session.target" ]; };

View file

@ -14,7 +14,7 @@ let
}; };
in attrsOf confAtom; in attrsOf confAtom;
in { in {
meta.maintainers = with maintainers; [ polykernel ]; meta.maintainers = [ ];
options = { options = {
wayland.windowManager.sway.swaynag = { wayland.windowManager.sway.swaynag = {

View file

@ -190,7 +190,7 @@ in import nmtSrc {
./modules/programs/bemenu ./modules/programs/bemenu
./modules/programs/borgmatic ./modules/programs/borgmatic
./modules/programs/boxxy ./modules/programs/boxxy
./modules/programs/firefox ./modules/programs/firefox/firefox.nix
./modules/programs/foot ./modules/programs/foot
./modules/programs/freetube ./modules/programs/freetube
./modules/programs/fuzzel ./modules/programs/fuzzel

View file

@ -1,13 +1,19 @@
modulePath:
{ config, lib, ... }: { config, lib, ... }:
{ with lib;
imports = [ ./setup-firefox-mock-overlay.nix ];
config = lib.mkIf config.test.enableBig { let
firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath;
in {
imports = [ firefoxMockOverlay ];
config = mkIf config.test.enableBig ({
test.asserts.assertions.expected = test.asserts.assertions.expected =
[ "Container id must be smaller than 4294967294 (2^32 - 2)" ]; [ "Container id must be smaller than 4294967294 (2^32 - 2)" ];
} // setAttrByPath modulePath {
programs.firefox = {
enable = true; enable = true;
profiles.my-profile = { profiles.my-profile = {
@ -22,6 +28,5 @@
}; };
}; };
}; };
}; });
};
} }

View file

@ -1,9 +0,0 @@
{
firefox-profile-settings = ./profile-settings.nix;
firefox-state-version-19_09 = ./state-version-19_09.nix;
firefox-deprecated-native-messenger = ./deprecated-native-messenger.nix;
firefox-duplicate-profile-ids = ./duplicate-profile-ids.nix;
firefox-duplicate-container-ids = ./duplicate-container-ids.nix;
firefox-container-id-out-of-range = ./container-id-out-of-range.nix;
firefox-policies = ./policies.nix;
}

View file

@ -1,21 +1,26 @@
{ config, lib, pkgs, ... }: modulePath:
{ config, lib, ... }:
with lib; with lib;
{ let
imports = [ ./setup-firefox-mock-overlay.nix ];
config = lib.mkIf config.test.enableBig { moduleName = concatStringsSep "." modulePath;
programs.firefox = {
firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath;
in {
imports = [ firefoxMockOverlay ];
config = mkIf config.test.enableBig (setAttrByPath modulePath {
enable = true; enable = true;
enableGnomeExtensions = true; enableGnomeExtensions = true;
}; } // {
test.asserts.warnings.expected = ['' test.asserts.warnings.expected = [''
Using 'programs.firefox.enableGnomeExtensions' has been deprecated and Using '${moduleName}.enableGnomeExtensions' has been deprecated and
will be removed in the future. Please change to overriding the package will be removed in the future. Please change to overriding the package
configuration using 'programs.firefox.package' instead. You can refer to configuration using '${moduleName}.package' instead. You can refer to
its example for how to do this. its example for how to do this.
'']; ''];
}; });
} }

View file

@ -1,14 +1,22 @@
modulePath:
{ config, lib, ... }: { config, lib, ... }:
{ with lib;
imports = [ ./setup-firefox-mock-overlay.nix ];
config = lib.mkIf config.test.enableBig { let
cfg = getAttrFromPath modulePath config;
firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath;
in {
imports = [ firefoxMockOverlay ];
config = mkIf config.test.enableBig ({
test.asserts.assertions.expected = ['' test.asserts.assertions.expected = [''
Must not have a Firefox container with an existing ID but Must not have a ${cfg.name} container with an existing ID but
- ID 9 is used by dangerous, shopping'']; - ID 9 is used by dangerous, shopping''];
} // setAttrByPath modulePath {
programs.firefox = {
enable = true; enable = true;
profiles = { profiles = {
@ -30,6 +38,5 @@
}; };
}; };
}; };
}; });
};
} }

View file

@ -1,14 +1,22 @@
modulePath:
{ config, lib, ... }: { config, lib, ... }:
{ with lib;
imports = [ ./setup-firefox-mock-overlay.nix ];
config = lib.mkIf config.test.enableBig { let
cfg = getAttrFromPath modulePath config;
firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath;
in {
imports = [ firefoxMockOverlay ];
config = mkIf config.test.enableBig ({
test.asserts.assertions.expected = ['' test.asserts.assertions.expected = [''
Must not have a Firefox profile with an existing ID but Must not have a ${cfg.name} profile with an existing ID but
- ID 1 is used by first, second'']; - ID 1 is used by first, second''];
} // setAttrByPath modulePath {
programs.firefox = {
enable = true; enable = true;
profiles = { profiles = {
@ -18,6 +26,5 @@
}; };
second = { id = 1; }; second = { id = 1; };
}; };
}; });
};
} }

View file

@ -0,0 +1,11 @@
let name = "firefox";
in builtins.mapAttrs (test: module: import module [ "programs" name ]) {
"${name}-profile-settings" = ./profile-settings.nix;
"${name}-state-version-19_09" = ./state-version-19_09.nix;
"${name}-deprecated-native-messenger" = ./deprecated-native-messenger.nix;
"${name}-duplicate-profile-ids" = ./duplicate-profile-ids.nix;
"${name}-duplicate-container-ids" = ./duplicate-container-ids.nix;
"${name}-container-id-out-of-range" = ./container-id-out-of-range.nix;
"${name}-policies" = ./policies.nix;
}

View file

@ -1,22 +1,29 @@
modulePath:
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
{ with lib;
imports = [ ./setup-firefox-mock-overlay.nix ];
config = lib.mkIf config.test.enableBig { let
cfg = getAttrFromPath modulePath config;
firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath;
in {
imports = [ firefoxMockOverlay ];
config = mkIf config.test.enableBig ({
home.stateVersion = "23.05"; home.stateVersion = "23.05";
} // setAttrByPath modulePath {
programs.firefox = {
enable = true; enable = true;
policies = { BlockAboutConfig = true; }; policies = { BlockAboutConfig = true; };
package = pkgs.firefox.override { package = pkgs.${cfg.wrappedPackageName}.override {
extraPolicies = { DownloadDirectory = "/foo"; }; extraPolicies = { DownloadDirectory = "/foo"; };
}; };
}; }) // {
nmt.script = '' nmt.script = ''
jq=${lib.getExe pkgs.jq} jq=${lib.getExe pkgs.jq}
config_file="${config.programs.firefox.finalPackage}/lib/firefox/distribution/policies.json" config_file="${cfg.finalPackage}/lib/${cfg.wrappedPackageName}/distribution/policies.json"
assertFileExists "$config_file" assertFileExists "$config_file"

View file

@ -1,10 +1,18 @@
modulePath:
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
{ with lib;
imports = [ ./setup-firefox-mock-overlay.nix ];
config = lib.mkIf config.test.enableBig { let
programs.firefox = {
cfg = getAttrFromPath modulePath config;
firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath;
in {
imports = [ firefoxMockOverlay ];
config = mkIf config.test.enableBig (setAttrByPath modulePath {
enable = true; enable = true;
profiles.basic.isDefault = true; profiles.basic.isDefault = true;
@ -34,8 +42,7 @@
name = "wikipedia"; name = "wikipedia";
tags = [ "wiki" ]; tags = [ "wiki" ];
keyword = "wiki"; keyword = "wiki";
url = url = "https://en.wikipedia.org/wiki/Special:Search?search=%s&go=Go";
"https://en.wikipedia.org/wiki/Special:Search?search=%s&go=Go";
} }
{ {
name = "kernel.org"; name = "kernel.org";
@ -153,25 +160,25 @@
}; };
}; };
}; };
}; } // {
nmt.script = '' nmt.script = ''
assertFileRegex \ assertFileRegex \
home-path/bin/firefox \ home-path/bin/${cfg.wrappedPackageName} \
MOZ_APP_LAUNCHER MOZ_APP_LAUNCHER
assertDirectoryExists home-files/.mozilla/firefox/basic assertDirectoryExists home-files/${cfg.configPath}/basic
assertFileContent \ assertFileContent \
home-files/.mozilla/firefox/test/user.js \ home-files/${cfg.configPath}/test/user.js \
${./profile-settings-expected-user.js} ${./profile-settings-expected-user.js}
assertFileContent \ assertFileContent \
home-files/.mozilla/firefox/containers/containers.json \ home-files/${cfg.configPath}/containers/containers.json \
${./profile-settings-expected-containers.json} ${./profile-settings-expected-containers.json}
bookmarksUserJs=$(normalizeStorePaths \ bookmarksUserJs=$(normalizeStorePaths \
home-files/.mozilla/firefox/bookmarks/user.js) home-files/${cfg.configPath}/bookmarks/user.js)
assertFileContent \ assertFileContent \
$bookmarksUserJs \ $bookmarksUserJs \
@ -179,7 +186,7 @@
bookmarksFile="$(sed -n \ bookmarksFile="$(sed -n \
'/browser.bookmarks.file/ {s|^.*\(/nix/store[^"]*\).*|\1|;p}' \ '/browser.bookmarks.file/ {s|^.*\(/nix/store[^"]*\).*|\1|;p}' \
$TESTED/home-files/.mozilla/firefox/bookmarks/user.js)" $TESTED/home-files/${cfg.configPath}/bookmarks/user.js)"
assertFileContent \ assertFileContent \
$bookmarksFile \ $bookmarksFile \
@ -197,12 +204,12 @@
} }
assertFirefoxSearchContent \ assertFirefoxSearchContent \
home-files/.mozilla/firefox/search/search.json.mozlz4 \ home-files/${cfg.configPath}/search/search.json.mozlz4 \
${./profile-settings-expected-search.json} ${./profile-settings-expected-search.json}
assertFirefoxSearchContent \ assertFirefoxSearchContent \
home-files/.mozilla/firefox/searchWithoutDefault/search.json.mozlz4 \ home-files/${cfg.configPath}/searchWithoutDefault/search.json.mozlz4 \
${./profile-settings-expected-search-without-default.json} ${./profile-settings-expected-search-without-default.json}
''; '';
}; });
} }

View file

@ -1,15 +1,23 @@
{ pkgs, ... }: modulePath:
{ config, lib, pkgs, ... }:
{ with lib;
let
cfg = getAttrFromPath modulePath config;
in {
nixpkgs.overlays = [ nixpkgs.overlays = [
(self: super: { (self: super: {
firefox-unwrapped = pkgs.runCommandLocal "firefox-0" { "${cfg.wrappedPackageName}-unwrapped" =
meta.description = "I pretend to be Firefox"; pkgs.runCommandLocal "${cfg.wrappedPackageName}-0" {
meta.description = "I pretend to be ${cfg.name}";
passthru.gtk3 = null; passthru.gtk3 = null;
} '' } ''
mkdir -p "$out"/{bin,lib} mkdir -p "$out"/{bin,lib}
touch "$out/bin/firefox" touch "$out/bin/${cfg.wrappedPackageName}"
chmod 755 "$out/bin/firefox" chmod 755 "$out/bin/${cfg.wrappedPackageName}"
''; '';
chrome-gnome-shell = chrome-gnome-shell =

View file

@ -1,19 +1,24 @@
modulePath:
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
{ let
imports = [ ./setup-firefox-mock-overlay.nix ];
config = lib.mkIf config.test.enableBig { cfg = getAttrFromPath modulePath config;
firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath;
in {
imports = [ firefoxMockOverlay ];
config = lib.mkIf config.test.enableBig ({
home.stateVersion = "19.09"; home.stateVersion = "19.09";
} // setAttrByPath modulePath { enable = true; } // {
programs.firefox.enable = true;
nmt.script = '' nmt.script = ''
assertFileRegex \ assertFileRegex \
home-path/bin/firefox \ home-path/bin/${cfg.wrappedPackageName} \
MOZ_APP_LAUNCHER MOZ_APP_LAUNCHER
''; '';
}; });
} }

View file

@ -13,9 +13,8 @@
}; };
}; };
nixpkgs.overlays = [ nixpkgs.overlays =
(self: super: { gnome.gnome-terminal = config.lib.test.mkStubPackage { }; }) [ (self: super: { gnome-terminal = config.lib.test.mkStubPackage { }; }) ];
];
test.stubs.dconf = { }; test.stubs.dconf = { };

View file

@ -49,9 +49,7 @@ with lib;
}; };
nixpkgs.overlays = [ nixpkgs.overlays = [
(self: super: { (self: super: { gnome-terminal = config.lib.test.mkStubPackage { }; })
gnome.gnome-terminal = config.lib.test.mkStubPackage { };
})
]; ];
test.stubs.dconf = { }; test.stubs.dconf = { };

View file

@ -1,11 +1,14 @@
{ ... }: { pkgs, ... }:
{ let
configDir =
if pkgs.stdenv.isDarwin then "Library/Application Support" else ".config";
in {
programs.jujutsu.enable = true; programs.jujutsu.enable = true;
test.stubs.jujutsu = { }; test.stubs.jujutsu = { };
nmt.script = '' nmt.script = ''
assertPathNotExists home-files/.config/jj/config.toml assertPathNotExists 'home-files/${configDir}/jj/config.toml'
''; '';
} }

View file

@ -1,6 +1,9 @@
{ config, ... }: { pkgs, config, ... }:
{ let
configDir =
if pkgs.stdenv.isDarwin then "Library/Application Support" else ".config";
in {
programs.jujutsu = { programs.jujutsu = {
enable = true; enable = true;
package = config.lib.test.mkStubPackage { }; package = config.lib.test.mkStubPackage { };
@ -13,9 +16,8 @@
}; };
nmt.script = '' nmt.script = ''
assertFileExists home-files/.config/jj/config.toml assertFileExists 'home-files/${configDir}/jj/config.toml'
assertFileContent \ assertFileContent 'home-files/${configDir}/jj/config.toml' \
home-files/.config/jj/config.toml \
${ ${
builtins.toFile "expected.toml" '' builtins.toFile "expected.toml" ''
[user] [user]

View file

@ -4,7 +4,7 @@
nix.gc = { nix.gc = {
automatic = true; automatic = true;
frequency = "monthly"; frequency = "monthly";
options = "--delete-older-than 30d"; options = "--delete-older-than 30d --max-freed $((64 * 1024**3))";
}; };
test.stubs.nix = { name = "nix"; }; test.stubs.nix = { name = "nix"; };

View file

@ -1,5 +1,6 @@
[Service] [Service]
ExecStart=@nix@/bin/nix-collect-garbage --delete-older-than 30d ExecStart=/nix/store/00000000000000000000000000000000-nix-gc
Type=oneshot
[Unit] [Unit]
Description=Nix Garbage Collector Description=Nix Garbage Collector

View file

@ -23,6 +23,7 @@
[Service] [Service]
ExecStart=@swayosd@/bin/swayosd-server --display DISPLAY --style '/etc/xdg/swayosd/style.css' --top-margin 0.100000 ExecStart=@swayosd@/bin/swayosd-server --display DISPLAY --style '/etc/xdg/swayosd/style.css' --top-margin 0.100000
Restart=always Restart=always
RestartSec=2s
Type=simple Type=simple
[Unit] [Unit]
@ -31,6 +32,8 @@
Description=Volume/backlight OSD indicator Description=Volume/backlight OSD indicator
Documentation=man:swayosd(1) Documentation=man:swayosd(1)
PartOf=graphical-session.target PartOf=graphical-session.target
StartLimitBurst=5
StartLimitIntervalSec=10
'' ''
} }
''; '';