feat: librewolf configuration

This commit is contained in:
Gustavo "Guz" L. de Mello
2024-01-13 18:58:54 -03:00
parent aad9dd1d45
commit 118a42745c
7 changed files with 504 additions and 1 deletions

39
flake.lock generated
View File

@@ -16,6 +16,44 @@
"type": "github" "type": "github"
} }
}, },
"firefox-addons": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"dir": "pkgs/firefox-addons",
"lastModified": 1705103913,
"narHash": "sha256-PX6zS6uni5IXZMUQB2DUbhj+oV7QyAfwEEenOb/DstU=",
"owner": "rycee",
"repo": "nur-expressions",
"rev": "c8e94a42015531a061a4518aff7aee03d5a4f215",
"type": "gitlab"
},
"original": {
"dir": "pkgs/firefox-addons",
"owner": "rycee",
"repo": "nur-expressions",
"type": "gitlab"
}
},
"flake-utils": {
"locked": {
"lastModified": 1629284811,
"narHash": "sha256-JHgasjPR0/J1J3DRm4KxM4zTyAj4IOJY8vIl75v/kPI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c5d161cc0af116a2e17f54316f0bf43f0819785c",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flatpaks": { "flatpaks": {
"locked": { "locked": {
"lastModified": 1704403850, "lastModified": 1704403850,
@@ -139,6 +177,7 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"firefox-addons": "firefox-addons",
"flatpaks": "flatpaks", "flatpaks": "flatpaks",
"home-manager": "home-manager", "home-manager": "home-manager",
"nix-colors": "nix-colors", "nix-colors": "nix-colors",

View File

@@ -26,6 +26,11 @@
# Used for theming the OS, see modules/home-manager/theme.nix # Used for theming the OS, see modules/home-manager/theme.nix
nix-colors.url = "github:misterio77/nix-colors"; nix-colors.url = "github:misterio77/nix-colors";
firefox-addons = {
url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons";
inputs.nixpkgs.follows = "nixpkgs";
};
# Necessary for modules/home-manager/programs/tmux.nix # Necessary for modules/home-manager/programs/tmux.nix
tmux-plugin-manager = { tmux-plugin-manager = {
url = "github:tmux-plugins/tpm"; url = "github:tmux-plugins/tpm";

View File

@@ -4,4 +4,5 @@
imports = [ imports = [
../shared-home.nix ../shared-home.nix
]; ];
librewolf.profiles.guz.isDefault = true;
} }

View File

@@ -4,6 +4,7 @@
imports = [ imports = [
../../modules/home-manager/theme.nix ../../modules/home-manager/theme.nix
../../modules/home-manager/config/terminal.nix ../../modules/home-manager/config/terminal.nix
../../modules/home-manager/programs/librewolf
./wm.nix ./wm.nix
./keybinds.nix ./keybinds.nix
]; ];
@@ -15,9 +16,32 @@
''; '';
}; };
librewolf = {
enable = true;
profiles = {
guz = {
id = 0;
settings = {
"webgl.disabled" = false;
"browser.startup.homepage" = "https://search.brave.com";
"privacy.clearOnShutdown.history" = false;
"privacy.clearOnShutdown.downloads" = false;
"extensions.activeThemeID" = "firefox-compact-dark@mozilla.org";
"privacy.clearOnShutdown.cookies" = false;
};
extensions = with inputs.firefox-addons.packages."x86_64-linux"; [
darkreader
canvasblocker
smart-referer
];
};
};
};
services.flatpak.packages = [ services.flatpak.packages = [
"nz.mega.MEGAsync" "nz.mega.MEGAsync"
"md.obsidian.Obsidian" "md.obsidian.Obsidian"
"dev.vencord.Vesktop"
]; ];
# services.flatpak.overrides = { }; # services.flatpak.overrides = { };
@@ -25,7 +49,7 @@
nixpkgs.config.allowUnfreePredicate = _: true; nixpkgs.config.allowUnfreePredicate = _: true;
home.packages = with pkgs; [ home.packages = with pkgs; [
## Programs ## Programs
firefox # firefox
# (pkgs.writeShellScriptBin "my-hello" '' # (pkgs.writeShellScriptBin "my-hello" ''
# echo "Hello, ${config.home.username}!" # echo "Hello, ${config.home.username}!"

View File

@@ -7,4 +7,23 @@
theme.accent = "94e2d5"; theme.accent = "94e2d5";
wm.wallpaper = ../../../static/guz-wallpaper-work.webp; wm.wallpaper = ../../../static/guz-wallpaper-work.webp;
librewolf.profiles.work = {
isDefault = true;
id = 1;
settings = {
"webgl.disabled" = false;
"browser.startup.homepage" = "https://github.com";
"privacy.clearOnShutdown.history" = false;
"privacy.clearOnShutdown.downloads" = false;
"extensions.activeThemeID" = "firefox-compact-dark@mozilla.org";
"privacy.clearOnShutdown.cookies" = false;
};
extensions = with inputs.firefox-addons.packages."x86_64-linux"; [
darkreader
canvasblocker
smart-referer
github-file-icons
];
};
} }

View File

@@ -0,0 +1,415 @@
/*
THIS FILE ISN'T LICENSED UNDER THE WTFPL LICENSE.
This file is copied from Home-manager's GitHub and was modified to suit my
(Gustavo "Guz" L. de Mello) personal needs. The original file can be found
here: https://github.com/nix-community/home-manager/blob/master/modules/programs/firefox.nix
Said file is licensed under the MIT License, which a copy is written below:
MIT License
Copyright (c) 2017-2023 Home Manager contributors
Copyright (c) 2023-present Gustavo "Guz" L. de Mello
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
{ inputs, config, lib, pkgs, ... }:
with lib;
let
cfg = config.librewolf;
jsonFormat = pkgs.formats.json { };
firefoxConfigPath = ".librewolf";
profilesPath = firefoxConfigPath;
# 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 = 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;
}}
'';
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);
}
);
in
{
options.librewolf = with lib; with lib.types; {
enable = mkEnableOption "Enable module";
overrides = mkOption {
default = { };
type = attrsOf (either bool (either int str));
};
profiles = mkOption {
type = attrsOf (submodule ({ config, name, ... }: {
options = {
name = mkOption {
type = str;
default = name;
};
id = mkOption {
type = ints.unsigned;
default = 0;
};
settings = mkOption {
type = attrsOf (jsonFormat.type // {
description = "";
});
default = { };
};
extraConfig = mkOption {
type = lines;
default = "";
};
userChrome = mkOption {
type = lines;
default = "";
};
userContent = mkOption {
type = lines;
default = "";
};
bookmarks = mkOption
{
type =
let
bookmarkSubmodule = submodule
({ config, name, ... }: {
options = {
name = mkOption {
type = str;
default = name;
};
tags = mkOption {
type = listOf str;
default = [ ];
};
keyword = mkOption {
type = nullOr str;
default = null;
};
url = mkOption {
type = str;
};
};
});
bookmarkType = addCheck bookmarkSubmodule (x: x ? "url");
directoryType = submodule ({ config, name, ... }: {
options = {
name = mkOption {
type = str;
default = name;
};
bookmarks = mkOption {
type = listOf nodeType;
default = [ ];
};
toolbar = mkOption {
type = bool;
default = false;
};
};
});
nodeType = either bookmarkType directoryType;
in
with types;
coercedTo (attrsOf nodeType) attrValues (listOf nodeType);
default = [ ];
};
path = mkOption {
type = str;
default = name;
};
isDefault = mkOption {
type = bool;
default = config.id == 0;
};
# For some reason Librewolf isn't working with the generated file, so
# a static one is passed as a temp fix.
search.file = mkOption {
type = path;
default = ./search.json.mozlz4;
};
/*
search = {
force = mkOption {
type = bool;
default = false;
};
default = mkOption {
type = nullOr str;
default = null;
};
privateDefault = mkOption {
type = nullOr str;
default = null;
};
order = mkOption {
type = uniq (listOf str);
default = [ ];
};
engines = mkOption {
type = attrsOf (attrsOf jsonFormat.type);
default = { };
};
};
*/
containers = mkOption {
type = attrsOf
(submodule ({ name, ... }: {
options = {
name = mkOption {
type = str;
default = name;
};
id = mkOption {
type = ints.unsigned;
default = 0;
};
color = mkOption {
type = enum [
"blue"
"turquoise"
"green"
"yellow"
"orange"
"red"
"pink"
"purple"
"toolbar"
];
default = "pink";
};
icon = mkOption {
type = enum [
"briefcase"
"cart"
"circle"
"dollar"
"fence"
"fingerprint"
"gift"
"vacation"
"food"
"fruit"
"pet"
"tree"
"chill"
];
default = "fruit";
};
};
}));
default = { };
};
extensions = mkOption {
type = listOf package;
default = [ ];
};
};
}));
default = { };
};
};
config = lib.mkIf cfg.enable {
programs.librewolf.enable = true;
programs.librewolf.settings = cfg.overrides;
home.file = mkMerge ([{
"${firefoxConfigPath}/profiles.ini" =
mkIf (cfg.profiles != { }) { text = profilesIni; force = 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 != { }) {
text = mkContainersJson profile.containers;
};
"${profilesPath}/${profile.path}/search.json.mozlz4" = {
force = true;
source = ./search.json.mozlz4; # Use static file, because for some reason this isn't working with Librewolf.
};
"${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;
};
}));
};
}