NixOS Configuration
Table of Contents
1. Introduction
This is my NixOS configuration. It is a part of my monorepo, and this file automatically tangles to all the under the nix/ directory in my monorepo git repository. My monorepo also stores my website, as my website stores my elfeed and emacs configurations. Additionally, I want to track my emacs configuration with my Nix configuration. Having them in one repository means that my emacs configuration is pinned to my flake.
Hence, my monorepo serves a dual purpose, as do many of the files within my monorepo. They are often data files used in my configuration (i.e. emacs, elfeed, org-roam, agenda, journal, etc…) and they are webpages as well. This page is one such example of this concept.
2. Flake.nix
The flake is the entry point of the NixOS configuration. Here, I have a list of all the systems that I use with all the modules that they use. My NixOS configuration is heavily modularized, so that adding new configurations that add modifications is made simple.
{ description = "Emacs centric configurations for a complete networked system"; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; home-manager = { url = "github:nix-community/home-manager/release-24.11"; inputs.nixpkgs.follows = "nixpkgs"; }; disko = { url = "github:nix-community/disko"; inputs.nixpkgs.follows = "nixpkgs"; }; lanzaboote = { url = "github:nix-community/lanzaboote/v0.4.1"; inputs.nixpkgs.follows = "nixpkgs"; }; nur.url = "github:nix-community/NUR"; sops-nix.url = "github:Mic92/sops-nix"; scripts.url = "github:ret2pop/scripts"; wallpapers.url = "github:ret2pop/wallpapers"; sounds.url = "github:ret2pop/sounds"; }; outputs = { nixpkgs, home-manager, nur, disko, lanzaboote, sops-nix, ... }@attrs: { nixosConfigurations = { installer = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ( { pkgs, modulesPath, ... }: { imports = [ (modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix") ]; } ) ./systems/installer/default.nix ]; }; continuity = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; specialArgs = attrs; modules = [ lanzaboote.nixosModules.lanzaboote disko.nixosModules.disko home-manager.nixosModules.home-manager sops-nix.nixosModules.sops { nixpkgs.overlays = [ nur.overlays.default ]; } { home-manager.extraSpecialArgs = attrs; } ./modules/sda-simple.nix ./systems/continuity/default.nix ]; }; spontaneity = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; specialArgs = attrs; modules = []; }; affinity = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; specialArgs = attrs; modules = []; }; }; }; }
Listed here is my installer as well, which is used to install the systems in my configuration.
3. Sops Configuration
In order to use the sops configuration, you must change the age public key to the one that you own:
keys: - &primary age165ul43e8rc0qwzz2f2q9cw02psm2mkudsrwavq2e0pxs280p64yqy2z0dr creation_rules: - path_regex: secrets/secrets.yaml$ key_groups: - age: - *primary
also note that you will have to write your own secrets.yaml file, with an entry called mail
,
which is used for the imaps and smtps password.
4. Modules
4.1. Vars
Variables used for regular configuration in your system defafult.nix
file. The options are
largely self-documenting.
{ lib, ... }: { options.monorepo.vars = { hostName = lib.mkOption { type = lib.types.str; default = "continuity"; example = "hostname"; description = "system hostname"; }; userName = lib.mkOption { type = lib.types.str; default = "preston"; example = "myUser"; description = "system username"; }; fullName = lib.mkOption { type = lib.types.str; default = "Preston Pan"; example = "John Doe"; description = "Full Name"; }; gpgKey = lib.mkOption { type = lib.types.str; default = "AEC273BF75B6F54D81343A1AC1FE6CED393AE6C1"; example = "1234567890ABCDEF..."; description = "GPG key fingerprint"; }; remoteHost = lib.mkOption { type = lib.types.str; default = "nullring.xyz"; example = "example.com"; description = "Address to push to and pull from for website and git repos"; }; timeZone = lib.mkOption { type = lib.types.str; default = "America/Vancouver"; example = "America/Chicago"; description = "Linux timezone"; }; monitors = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ "HDMI-A-1" "eDP-1" "DP-2" "DP-3" "LVDS-1" ]; example = []; description = "Monitors that waybar will use"; }; }; }
4.2. Default Profile
Again, these are self documenting variables that you may see used below. These are to be used
under default.nix
in the systems
folder.
{ lib, config, pkgs, ... }: { imports = [ ./configuration.nix ./home/home.nix ./vars.nix ]; options = { monorepo = { profiles = { cuda.enable = lib.mkEnableOption "Enables CUDA support"; documentation.enable = lib.mkEnableOption "Enables documentation on system."; secureBoot.enable = lib.mkEnableOption "Enables secure boot. See sbctl."; pipewire.enable = lib.mkEnableOption "Enables pipewire low latency audio setup"; tor.enable = lib.mkEnableOption "Enables tor along with torsocks"; home.enable = lib.mkEnableOption "Enables home user"; }; }; }; config = { home-manager.users."${config.monorepo.vars.userName}" = { programs.home-manager.enable = config.monorepo.profiles.home.enable; }; environment.systemPackages = lib.mkIf config.monorepo.profiles.documentation.enable (with pkgs; [ linux-manual man-pages man-pages-posix ]); monorepo = { profiles = { documentation.enable = lib.mkDefault true; pipewire.enable = lib.mkDefault true; tor.enable = lib.mkDefault true; home.enable = lib.mkDefault true; }; }; }; }
4.3. X11
My Xorg configuration is used as a backup for when wayland applications don't work. Note that using this configuration is extremely inefficient and my i3 configuration is unoptimized. Still, it is suitable for using Krita.
{ lib, pkgs, ... }: { services.xserver = { enable = lib.mkDefault true; displayManager = { startx.enable = true; }; windowManager = { i3 = { enable = true; package = pkgs.i3-gaps; }; }; desktopManager = { runXdgAutostartIfNone = true; }; xkb = { layout = "us"; variant = ""; options = "caps:escape"; }; videoDrivers = []; }; }
You should add your own video drivers in a custom machine configuration.
4.4. Pipewire
My low latency pipewire configuration is used for music production, as well as for regular desktop usage. Pipewire is much better than pulseaudio because it supports jack with the same underlying interface and it breaks significantly less often.
{ lib, config, ... }: { services.pipewire = { enable = lib.mkDefault config.monorepo.profiles.pipewire.enable; alsa = { enable = true; support32Bit = true; }; pulse.enable = true; jack.enable = true; wireplumber.enable = true; extraConfig.pipewire-pulse."92-low-latency" = { "context.properties" = [ { name = "libpipewire-module-protocol-pulse"; args = { }; } ]; "pulse.properties" = { "pulse.min.req" = "32/48000"; "pulse.default.req" = "32/48000"; "pulse.max.req" = "32/48000"; "pulse.min.quantum" = "32/48000"; "pulse.max.quantum" = "32/48000"; }; "stream.properties" = { "node.latency" = "32/48000"; "resample.quality" = 1; }; }; }; }
4.5. SSH
My SSH daemon configuration.
{ config, ... }: { services.openssh = { enable = true; settings = { PasswordAuthentication = true; AllowUsers = [ config.monorepo.vars.userName ]; PermitRootLogin = "no"; KbdInteractiveAuthentication = false; }; }; }
4.6. Tor
This is my tor configuration, used for my cryptocurrency wallets and whatever else I want it to do.
{ config, lib, ... }: { services.tor = { enable = lib.mkDefault config.monorepo.profiles.tor.enable; openFirewall = true; client = { enable = lib.mkDefault config.monorepo.profiles.tor.enable; socksListenAddress = { IsolateDestAddr = true; addr = "127.0.0.1"; port = 9050; }; dns.enable = true; }; torsocks = { enable = lib.mkDefault config.monorepo.profiles.tor.enable; server = "127.0.0.1:9050"; }; }; }
4.7. Kubo IPFS
I use IPFS for my website and also for my ISOs for truly declarative and deterministic configuration. NixOS might be moving to IPFS for binary cache distribution and package distribution soon, and I'm waiting on that.
{ config, pkgs, ... }: { services.kubo = { enable = true; }; }
4.8. Main Configuration
This is the backbone of the all the NixOS configurations, with all these options being shared because they enhance security.
{ config, pkgs, lib, ... }: { imports = [ ./xserver.nix ./ssh.nix ./pipewire.nix ./tor.nix ./kubo.nix ]; documentation = { enable = lib.mkDefault config.monorepo.profiles.documentation.enable; man.enable = lib.mkDefault config.monorepo.profiles.documentation.enable; dev.enable = lib.mkDefault config.monorepo.profiles.documentation.enable; }; environment = { etc = { securetty.text = '' # /etc/securetty: list of terminals on which root is allowed to login. # See securetty(5) and login(1). ''; }; }; systemd = { coredump.enable = false; network.config.networkConfig.IPv6PrivacyExtensions = "kernel"; tmpfiles.settings = { "restricthome"."/home/*".Z.mode = "~0700"; "restrictetcnixos"."/etc/nixos/*".Z = { mode = "0000"; user = "root"; group = "root"; }; }; }; boot = { extraModulePackages = [ ]; initrd = { availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "sd_mod" "nvme" "sd_mod" "ehci_pci" "rtsx_pci_sdmmc" "usbhid" ]; kernelModules = [ ]; }; lanzaboote = { enable = config.monorepo.profiles.secureBoot.enable; pkiBundle = "/etc/secureboot"; }; loader = { systemd-boot.enable = lib.mkForce (! config.monorepo.profiles.secureBoot.enable); efi.canTouchEfiVariables = true; }; kernelModules = [ "snd-seq" "snd-rawmidi" "xhci_hcd" "kvm_intel" ]; kernelParams = [ "debugfs=off" "page_alloc.shuffle=1" "slab_nomerge" "page_poison=1" # madaidan "pti=on" "randomize_kstack_offset=on" "vsyscall=none" "module.sig_enforce=1" "lockdown=confidentiality" # cpu "spectre_v2=on" "spec_store_bypass_disable=on" "tsx=off" "tsx_async_abort=full,nosmt" "mds=full,nosmt" "l1tf=full,force" "nosmt=force" "kvm.nx_huge_pages=force" # hardened "extra_latent_entropy" # mineral "init_on_alloc=1" "random.trust_cpu=off" "random.trust_bootloader=off" "intel_iommu=on" "amd_iommu=force_isolation" "iommu=force" "iommu.strict=1" "init_on_free=1" "quiet" "loglevel=0" ]; blacklistedKernelModules = [ "netrom" "rose" "adfs" "affs" "bfs" "befs" "cramfs" "efs" "erofs" "exofs" "freevxfs" "f2fs" "hfs" "hpfs" "jfs" "minix" "nilfs2" "ntfs" "omfs" "qnx4" "qnx6" "sysv" "ufs" ]; kernel.sysctl = { "kernel.ftrace_enabled" = false; "net.core.bpf_jit_enable" = false; "kernel.kptr_restrict" = 2; # madaidan "vm.swappiness" = 1; "vm.unprivileged_userfaultfd" = 0; "dev.tty.ldisc_autoload" = 0; "kernel.kexec_load_disabled" = 1; "kernel.sysrq" = 4; "kernel.perf_event_paranoid" = 3; # net "net.ipv4.icmp_echo_ignore_broadcasts" = true; "net.ipv4.conf.all.accept_redirects" = false; "net.ipv4.conf.all.secure_redirects" = false; "net.ipv4.conf.default.accept_redirects" = false; "net.ipv4.conf.default.secure_redirects" = false; "net.ipv6.conf.all.accept_redirects" = false; "net.ipv6.conf.default.accept_redirects" = false; }; }; networking = { useDHCP = lib.mkDefault true; hostName = config.monorepo.vars.hostName; networkmanager = { enable = true; # wifi.macAddress = ""; }; firewall = { allowedTCPPorts = [ ]; allowedUDPPorts = [ ]; }; }; hardware = { enableAllFirmware = true; cpu.intel.updateMicrocode = true; graphics.enable = true; pulseaudio.enable = ! config.monorepo.profiles.pipewire.enable; bluetooth = { enable = true; powerOnBoot = true; }; }; services = { chrony = { enable = true; enableNTS = true; servers = [ "time.cloudflare.com" "ptbtime1.ptb.de" "ptbtime2.ptb.de" ]; }; jitterentropy-rngd.enable = true; resolved.dnssec = true; # usbguard.enable = true; usbguard.enable = false; dbus.apparmor = "enabled"; kanata.enable = true; # Misc. udev = { extraRules = ''''; packages = with pkgs; [ platformio-core platformio-core.udev openocd ]; }; printing.enable = true; udisks2.enable = true; }; programs = { nix-ld.enable = true; zsh.enable = true; light.enable = true; ssh.enableAskPassword = false; }; nixpkgs = { hostPlatform = lib.mkDefault "x86_64-linux"; config = { allowUnfree = true; cudaSupport = lib.mkDefault config.monorepo.profiles.cuda.enable; }; }; security = { apparmor = { enable = true; killUnconfinedConfinables = true; }; pam.loginLimits = [ { domain = "*"; item = "nofile"; type = "-"; value = "32768"; } { domain = "*"; item = "memlock"; type = "-"; value = "32768"; } ]; rtkit.enable = true; lockKernelModules = true; protectKernelImage = true; allowSimultaneousMultithreading = false; forcePageTableIsolation = true; tpm2 = { enable = true; pkcs11.enable = true; tctiEnvironment.enable = true; }; auditd.enable = true; audit.enable = true; chromiumSuidSandbox.enable = true; sudo.enable = true; }; xdg.portal = { enable = true; wlr.enable = true; extraPortals = with pkgs; [ xdg-desktop-portal-gtk xdg-desktop-portal xdg-desktop-portal-hyprland ]; config.common.default = "*"; }; environment.systemPackages = with pkgs; [ restic sbctl git vim curl ]; users.users = { root.openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINSshvS1N/42pH9Unp3Zj4gjqs9BXoin99oaFWYHXZDJ preston@preston-arch" ]; "${config.monorepo.vars.userName}" = { initialPassword = "${config.monorepo.vars.userName}"; isNormalUser = true; description = config.monorepo.vars.fullName; extraGroups = [ "networkmanager" "wheel" "video" "docker" "jackaudio" "tss" "dialout" ]; shell = pkgs.zsh; packages = []; }; }; nix.settings.experimental-features = "nix-command flakes"; time.timeZone = config.monorepo.vars.timeZone; i18n.defaultLocale = "en_CA.UTF-8"; system.stateVersion = "24.11"; }
4.9. Disko
This is the disko configuration for my continuity system. It features a boot and ext4 partition,
on disk /dev/sda. All my SATA disks have this location by default, but if you want to use nvme,
you will have to import that configuration in your systems/xxx/default.nix
.
{ disko.devices = { disk = { my-disk = { device = "/dev/sda"; type = "disk"; content = { type = "gpt"; partitions = { ESP = { type = "EF00"; size = "500M"; priority = 1; content = { type = "filesystem"; format = "vfat"; mountpoint = "/boot"; mountOptions = [ "umask=0077" ]; }; }; root = { size = "100%"; priority = 2; content = { type = "filesystem"; format = "ext4"; mountpoint = "/"; }; }; }; }; }; }; }; }
4.10. Home
Time for my home user configuration, which is managed by home-manager. First we start off with this module to enter us into the home-manager namespace:
{ config, sops-nix, ... }: { home-manager = { sharedModules = [ sops-nix.homeManagerModules.sops ]; useGlobalPkgs = true; useUserPackages = true; users."${config.monorepo.vars.userName}" = import ./default.nix; }; }
as you can see, we import default.nix which puts us in the home-manager namespace. Everything
in the top level from now on will implicitly be located at
users."${config.monorepo.vars.userName}".xxxxx
, and we will look at default.nix next.
4.10.1. Default Home Profile
As you can see, I have my installed home packages installed based on the profiles enabled. Also, I have many imports that we'll go through next.
{ lib, config, pkgs, ... }: { imports = [ ../vars.nix ./fcitx.nix ./secrets.nix ./emacs.nix ./firefox.nix ./git.nix ./hyprland.nix ./mpv.nix ./yt-dlp.nix ./wofi.nix ./kitty.nix ./waybar.nix ./zsh.nix ./mbsync.nix ./msmtp.nix ./gammastep.nix ./mpd.nix ./mako.nix ./user.nix ]; options = { monorepo.profiles = { enable = lib.mkEnableOption "Enables home manager desktop configuration"; # Programs lang-c.enable = lib.mkEnableOption "Enables C language support"; lang-sh.enable = lib.mkEnableOption "Enables sh language support"; lang-rust.enable = lib.mkEnableOption "Enables Rust language support"; lang-python.enable = lib.mkEnableOption "Enables python language support"; lang-sol.enable = lib.mkEnableOption "Enables solidity language support"; lang-openscad.enable = lib.mkEnableOption "Enables openscad language support"; lang-js.enable = lib.mkEnableOption "Enables javascript language support"; lang-nix.enable = lib.mkEnableOption "Enables nix language support"; lang-coq.enable = lib.mkEnableOption "Enables coq language support"; crypto.enable = lib.mkEnableOption "Enables various cryptocurrency wallets"; art.enable = lib.mkEnableOption "Enables various art programs"; music.enable = lib.mkEnableOption "Enables mpd"; hyprland = { enable = lib.mkEnableOption "Enables hyprland"; monitors = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ "HDMI-A-1" "eDP-1" "DP-2" "DP-3" "LVDS-1" ]; example = []; description = "Hyprland monitors"; }; }; email = { email = lib.mkOption { type = lib.types.str; default = "ret2pop@gmail.com"; example = "john@example.com"; description = "Email address and imaps/smtps account"; }; imapsServer = lib.mkOption { type = lib.types.str; default = "imap.gmail.com"; example = "imap.example.com"; description = "imaps server address"; }; smtpsServer = lib.mkOption { type = lib.types.str; default = "smtp.gmail.com"; example = "smtp.example.com"; description = "smtp server address"; }; enable = lib.mkEnableOption "Enables email"; }; }; }; config = { home.packages = (if config.monorepo.profiles.email.enable then [ pkgs.mu ] else []) ++ (if config.monorepo.profiles.lang-c.enable then (with pkgs; [ autobuild clang gdb gnumake bear clang-tools ]) else []) ++ (if config.monorepo.profiles.lang-js.enable then (with pkgs; [ nodejs bun yarn typescript vscode-langservers-extracted ]) else []) ++ (if config.monorepo.profiles.lang-rust.enable then (with pkgs; [ cargo rust-analyzer rustfmt ]) else []) ++ (if config.monorepo.profiles.lang-python.enable then (with pkgs; [ poetry python3 python312Packages.jedi ]) else []) ++ (if config.monorepo.profiles.lang-sol.enable then (with pkgs; [ solc ]) else []) ++ (if config.monorepo.profiles.lang-openscad.enable then (with pkgs; [ openscad openscad-lsp ]) else []) ++ (if config.monorepo.profiles.lang-sh.enable then (with pkgs; [ bash-language-server ]) else []) ++ (if config.monorepo.profiles.lang-coq.enable then (with pkgs; [ coq ]) else []) ++ (if config.monorepo.profiles.lang-nix.enable then (with pkgs; [ nil nixd nixfmt-rfc-style ]) else []) ++ (if config.monorepo.profiles.crypto.enable then (with pkgs; [ bitcoin electrum monero-cli monero-gui ]) else []) ++ (if config.monorepo.profiles.art.enable then (with pkgs; [ inkscape krita ]) else []) ++ (if config.monorepo.profiles.music.enable then (with pkgs; [ mpc-cli sox ]) else []); monorepo.profiles = { enable = lib.mkDefault true; music.enable = lib.mkDefault true; hyprland.enable = lib.mkDefault true; email.enable = lib.mkDefault true; # Programming lang-c.enable = lib.mkDefault true; lang-rust.enable = lib.mkDefault true; lang-python.enable = lib.mkDefault true; lang-sol.enable = lib.mkDefault true; lang-sh.enable = lib.mkDefault true; lang-openscad.enable = lib.mkDefault true; lang-js.enable = lib.mkDefault true; lang-nix.enable = lib.mkDefault true; lang-coq.enable = lib.mkDefault true; crypto.enable = lib.mkDefault true; art.enable = lib.mkDefault true; }; }; }
4.10.2. Firefox
I conditionally enable metamask based on the cryptocurrency option. Everything else here should be straightforward.
{ lib, config, pkgs, ... }: { programs.firefox = { enable = true; policies = { EnableTrackingProtection = true; OfferToSaveLogins = false; }; package = pkgs.firefox-wayland; profiles = { default = { id = 0; name = "default"; isDefault = true; extensions = with pkgs.nur.repos.rycee.firefox-addons; [ ublock-origin tree-style-tab firefox-color vimium ] ++ (lib.optional config.monorepo.profiles.crypto.enable pkgs.nur.repos.rycee.firefox-addons.metamask); settings = { media = { memory_cache_max_size = 65536; cache_readahead_limit = 7200; cache_resume_threshold = 3600; peerconnection.ice = { proxy_only_if_behind_proxy = true; default_address_only = true; }; }; gfx = { content.skia-font-cache-size = 20; canvas.accelerated = { cache-items = 4096; cache-size = 512; }; }; network = { http = { max-connections = 1800; max-persistent-connections-per-server = 10; max-urgent-start-excessive-connections-per-host = 5; referer.XOriginTrimmingPolicy = 2; }; buffer.cache = { size = 262144; count = 128; }; dns = { max_high_priority_threads = 8; disablePrefetch = true; }; pacing.requests.enabled = false; dnsCacheExpiration = 3600; ssl_tokens_cache_capacity = 10240; prefetch-next = false; predictor.enabled = false; cookie.sameSite.noneRequiresSecure = true; IDN_show_punycode = true; auth.subresource-http-auth-allow = 1; captive-portal-service.enabled = false; connectivity-service.enabled = false; }; browser = { download = { always_ask_before_handling_new_types = true; manager.addToRecentDocs = false; open_pdf_attachments_inline = true; start_downloads_in_tmp_dir = true; }; urlbar = { suggest.quicksuggest.sponsored = false; suggest.quicksuggest.nonsponsored = false; suggest.calculator = true; update2.engineAliasRefresh = true; unitConversion.enabled = true; trending.featureGate = false; }; search = { separatePrivateDefault.ui.enabled = true; suggest.enabled = false; }; newtabpage.activity-stream = { feeds = { topsites = false; section.topstories = false; telemetry = false; }; asrouter.userprefs.cfr = { addons = false; features = false; }; telemetry = false; }; privatebrowsing = { vpnpromourl = ""; forceMediaMemoryCache = true; }; display = { focus_ring_on_anything = true; focus_ring_style = 0; focus_ring_width = 0; }; cache.jsbc_compression_level = 3; helperApps.deleteTempFileOnExit = true; uitour.enabled = false; sessionstore.interval = 60000; formfill.enable = false; xul.error_pages.expert_bad_cert = true; contentblocking.category = "strict"; ping-centre.telemetry = false; discovery.enabled = false; shell.checkDefaultBrowser = false; preferences.moreFromMozilla = false; tabs.tabmanager.enabled = false; aboutConfig.showWarning = false; aboutwelcome.enabled = false; bookmarks.openInTabClosesMenu = false; menu.showViewImageInfo = true; compactmode.show = true; safebrowsing.downloads.remote.enabled = false; tabs.crashReporting.sendReport = false; crashReports.unsubmittedCheck.autoSubmit2 = false; privateWindowSeparation.enabled = false; }; security = { mixed_content = { block_display_content = true; upgrade_display_content = true; }; insecure_connection_text = { enabled = true; pbmode.enabled = true; }; OCSP.enabled = 0; remote_settings.crlite_filters.enabled = true; pki.crlite_mode = 2; ssl.treat_unsafe_negotiation_as_broken = true; tls.enable_0rtt_data = false; }; toolkit = { telemetry = { unified = false; enabled = false; server = "data:,"; archive.enabled = false; newProfilePing.enabled = false; shutdownPingSender.enabled = false; updatePing.enabled = false; bhrPing.enabled = false; firstShutdownPing.enabled = false; coverage.opt-out = true; }; coverage = { opt-out = true; endpoint.base = ""; }; legacyUserProfileCustomizations.stylesheets = true; }; dom = { security = { https_first = true; https_first_schemeless = true; sanitizer.enabled = true; }; enable_web_task_scheduling = true; }; layout = { css = { grid-template-masonry-value.enabled = true; has-selector.enabled = true; prefers-color-scheme.content-override = 2; }; word_select.eat_space_to_next_word = false; }; urlclassifier = { trackingSkipURLs = "*.reddit.com, *.twitter.com, *.twimg.com, *.tiktok.com"; features.socialtracking.skipURLs = "*.instagram.com, *.twitter.com, *.twimg.com"; }; privacy = { globalprivacycontrol.enabled = true; history.custom = true; userContext.ui.enabled = true; trackingprotection = { enabled = true; pbmode.enabled = true; socialtracking.enabled = true; }; }; full-screen-api = { transition-duration = { enter = "0 0"; leave = "0 0"; }; warning = { delay = -1; timeout = 0; }; }; permissions.default = { desktop-notification = 2; geo = 2; }; signon = { formlessCapture.enabled = false; privateBrowsingCapture.enabled = false; }; datareporting = { policy.dataSubmissionEnabled = false; healthreport.uploadEnabled = false; }; extensions = { pocket.enabled = false; getAddons.showPane = false; htmlaboutaddons.recommendations.enabled = false; postDownloadThirdPartyPrompt = false; }; app = { shield.optoutstudies.enabled = false; normandy.enabled = false; normandy.api_url = ""; }; image.mem.decode_bytes_at_a_time = 32768; editor.truncate_user_pastes = false; pdfjs.enableScripting = false; geo.provider.network.url = "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%"; permissions.manager.defaultsUrl = ""; webchannel.allowObject.urlWhitelist = ""; breakpad.reportURL = ""; captivedetect.canonicalURL = ""; cookiebanners.service.mode = 1; findbar.highlightAll = true; content.notify.interval = 100000; }; }; }; }; }
4.10.3. Fcitx
This is a virtual keyboard program for writing in multiple languages. I use this sometimes.
{ pkgs, ... }: { i18n.inputMethod = { enabled = "fcitx5"; fcitx5.addons = with pkgs; [ fcitx5-gtk fcitx5-chinese-addons fcitx5-configtool fcitx5-mozc fcitx5-rime ]; }; }
Note that I configure fcitx with chinese and some japanese input enabled.
4.10.4. Emacs
I install all my emacs packages within Nix so that they build deterministically with native
compilation, and because I can fetch their exact versions. Note that I have a stub
configuration here that tells emacs to load my real configuration at ~/monorepo/config/emacs.org
as an org file which gets automatically tangled to an emacs-lisp file.
{ lib, config, pkgs, ... }: { programs.emacs = { enable = true; package = pkgs.emacs29-pgtk; extraConfig = '' (setq debug-on-error t) (org-babel-load-file (expand-file-name "~/monorepo/config/emacs.org"))''; extraPackages = epkgs: [ epkgs.all-the-icons epkgs.auctex epkgs.catppuccin-theme epkgs.chatgpt-shell epkgs.company epkgs.company-solidity epkgs.counsel epkgs.dashboard epkgs.doom-modeline epkgs.elfeed epkgs.elfeed-org epkgs.elfeed-tube epkgs.elfeed-tube-mpv epkgs.ellama epkgs.elpher epkgs.ement epkgs.emmet-mode epkgs.emms epkgs.enwc epkgs.evil epkgs.evil-collection epkgs.evil-commentary epkgs.evil-org epkgs.f epkgs.flycheck epkgs.general epkgs.gptel epkgs.gruvbox-theme epkgs.htmlize epkgs.irony-eldoc epkgs.ivy epkgs.ivy-pass epkgs.latex-preview-pane epkgs.lsp-ivy epkgs.lsp-mode epkgs.lyrics-fetcher epkgs.magit epkgs.magit-delta epkgs.mu4e epkgs.nix-mode epkgs.org-fragtog epkgs.org-journal epkgs.org-roam epkgs.org-roam-ui epkgs.org-superstar epkgs.page-break-lines epkgs.password-store epkgs.pdf-tools epkgs.pinentry epkgs.platformio-mode epkgs.projectile epkgs.rustic epkgs.scad-mode epkgs.simple-httpd epkgs.solidity-flycheck epkgs.solidity-mode epkgs.sudo-edit epkgs.treemacs epkgs.treemacs-evil epkgs.treemacs-magit epkgs.treemacs-projectile epkgs.treesit-auto epkgs.typescript-mode epkgs.unicode-fonts epkgs.use-package epkgs.vterm epkgs.web-mode epkgs.websocket epkgs.which-key epkgs.writegood-mode epkgs.writeroom-mode epkgs.yaml-mode epkgs.yasnippet epkgs.yasnippet-snippets ]; }; }
4.10.5. Gammastep
This is a program like redshift for making your screen emit more red and less blue light. Here I have the long and lat set for Vancouver, but you should replace it if you live outside the timezone.
{ lib, config, ... }: { services.gammastep = { enable = true; provider = "manual"; latitude = 49.282730; longitude = -123.120735; temperature = { day = 5000; night = 3000; }; settings = { general = { adjustment-method = "wayland"; }; }; }; }
4.10.6. Git
My git configuration uses information set in the vars.nix
in order to set configuration options.
Make sure those are set correctly. I've set it to sign by default.
{ lib, config, ... }: { programs.git = { enable = true; userName = config.monorepo.vars.fullName; userEmail = config.monorepo.profiles.email.email; signing = { key = config.monorepo.vars.gpgKey; signByDefault = true; }; extraConfig = { init.defaultBranch = "main"; }; aliases = { co = "checkout"; c = "commit"; a = "add"; s = "switch"; b = "branch"; }; }; }
4.10.7. Hyprland
My compositor/window manager. This automatically starts on startup. Instructions on how to use this component will come soon.
{ lib, config, wallpapers, pkgs, scripts, ... }: { wayland.windowManager.hyprland = { enable = lib.mkDefault config.monorepo.profiles.hyprland.enable; package = pkgs.hyprland; xwayland.enable = true; systemd.enable = true; settings = { "$mod" = "SUPER"; exec-once = [ "waybar" "swww-daemon --format xrgb" "swww img ${wallpapers}/imagination.png" "fcitx5-remote -r" "fcitx5 -d --replace" "fcitx5-remote -r" "emacs" "firefox" ]; env = [ "LIBVA_DRIVER_NAME,nvidia" "XDG_SESSION_TYPE,wayland" "GBM_BACKEND,nvidia-drm" "__GLX_VENDOR_LIBRARY_NAME,nvidia" "ELECTRON_OZONE_PLATFORM_HINT,auto" ]; blurls = [ "waybar" ]; monitor = [ "Unknown-1,disable" ]; windowrule = [ "workspace 1, ^(.*emacs.*)$" "workspace 2, ^(.*firefox.*)$" "workspace 2, ^(.*Tor Browser.*)$" "workspace 2, ^(.*Chromium-browser.*)$" "workspace 2, ^(.*chromium.*)$" "workspace 3, ^(.*discord.*)$" "workspace 3, ^(.*vesktop.*)$" "workspace 3, ^(.*fluffychat.*)$" "workspace 3, ^(.*element-desktop.*)$" "workspace 4, ^(.*qpwgraph.*)$" "workspace 4, ^(.*mpv.*)$" "workspace 5, ^(.*Monero.*)$" "workspace 5, ^(.*org\.bitcoin\..*)$" "workspace 5, ^(.*Bitcoin Core - preston.*)$" "workspace 5, ^(.*org\.getmonero\..*)$" "workspace 5, ^(.*Monero - preston.*)$" "workspace 5, ^(.*electrum.*)$" "pseudo,fcitx" ]; bind = [ "$mod, F, exec, firefox" "$mod, T, exec, tor-browser" "$mod, Return, exec, kitty" "$mod, E, exec, emacs" "$mod, B, exec, bitcoin-qt" "$mod, M, exec, monero-wallet-gui" "$mod, V, exec, vesktop" "$mod, D, exec, wofi --show run" "$mod, P, exec, bash ${scripts}/powermenu.sh" "$mod, Q, killactive" "$mod SHIFT, H, movewindow, l" "$mod SHIFT, L, movewindow, r" "$mod SHIFT, K, movewindow, u" "$mod SHIFT, J, movewindow, d" "$mod, H, movefocus, l" "$mod, L, movefocus, r" "$mod, K, movefocus, u" "$mod, J, movefocus, d" ", XF86AudioPlay, exec, mpc toggle" ", Print, exec, grim" ] ++ ( builtins.concatLists (builtins.genList ( x: let ws = let c = (x + 1) / 10; in builtins.toString (x + 1 - (c * 10)); in [ "$mod, ${ws}, workspace, ${toString (x + 1)}" "$mod SHIFT, ${ws}, movetoworkspace, ${toString (x + 1)}" ] ) 10) ); bindm = [ "$mod, mouse:272, movewindow" "$mod, mouse:273, resizewindow" "$mod ALT, mouse:272, resizewindow" ]; binde = [ ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+" ", XF86AudioLowerVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%-" ", XF86AudioNext, exec, mpc next" ", XF86AudioPrev, exec, mpc prev" ", XF86MonBrightnessUp , exec, xbacklight -inc 10" ", XF86MonBrightnessDown, exec, xbacklight -dec 10" ]; decoration = { blur = { enabled = true; size = 5; passes = 2; }; rounding = 5; }; input = { kb_options = "caps:swapescape"; repeat_delay = 300; repeat_rate = 50; natural_scroll = true; touchpad = { natural_scroll = true; disable_while_typing = true; tap-to-click = true; }; }; cursor = { no_hardware_cursors = true; }; misc = { force_default_wallpaper = 0; disable_hyprland_logo = true; }; }; }; }
4.10.8. Kitty
I've set my terminal, kitty, to use catppuccin colors.
{ lib, config, ... }: { programs.kitty = { enable = lib.mkDefault config.monorepo.profiles.hyprland.enable; settings = { enable_audio_bell = false; font_family = "Iosevka Nerd Font"; font_size = 14; confirm_os_window_close = 0; background_opacity = "0.9"; # Catppuccin theme foreground = "#cdd6f4"; background = "#1e1e2e"; selection_foreground = "#1e1e2e"; selection_background = "#f5e0dc"; cursor = "#f5e0dc"; cursor_text_color = "#1e1e2e"; url_color = "#f5e0dc"; active_border_color = "#B4BEFE"; inactive_border_color = "#6C7086"; bell_border_color = "#F9E2AF"; wayland_titlebar_color = "#1E1E2E"; macos_titlebar_color = "#1E1E2E"; active_tab_foreground = "#11111B"; active_tab_background = "#CBA6F7"; inactive_tab_foreground = "#CDD6F4"; inactive_tab_background = "#181825"; tab_bar_background = "#11111B"; mark1_foreground = "#1E1E2E"; mark1_background = "#B4BEFE"; mark2_foreground = "#1E1E2E"; mark2_background = "#CBA6F7"; mark3_foreground = "#1E1E2E"; mark3_background = "#74C7EC"; color0 = "#45475A"; color8 = "#585B70"; color1 = "#F38BA8"; color9 = "#F38BA8"; color2 = "#A6E3A1"; color10 = "#A6E3A1"; color3 = "#F9E2AF"; color11 = "#F9E2AF"; color4 = "#89B4FA"; color12 = "#89B4FA"; color5 = "#F5C2E7"; color13 = "#F5C2E7"; color6 = "#94E2D5"; color14 = "#94E2D5"; color7 = "#BAC2DE"; color15 = "#A6ADC8"; }; }; }
4.10.9. Mako
This is my notification system. My flake automatically fetches the notification sound, so you are all set from the get-go!
{ lib, config, sounds, ... }: { services.mako = { enable = true; backgroundColor = "#11111bf8"; textColor = "#cdd6f4"; borderColor = "#89b4faff"; borderRadius = 1; font = "Fira Code 10"; defaultTimeout = 3000; extraConfig = '' on-notify=exec mpv ${sounds}/polite.ogg --no-config --no-video ''; }; }
4.10.10. Mbsync
Note that in order to use my email configuration, your imaps and smtps servers must be
encrypted. This module uses the vars.nix
as well as the home default.nix
options.
{ lib, config, ... }: { programs.mbsync = { enable = lib.mkDefault config.monorepo.profiles.email.enable; extraConfig = '' IMAPAccount ret2pop Host ${config.monorepo.profiles.email.imapsServer} User ${config.monorepo.profiles.email.email} PassCmd "cat ${config.sops.secrets.mail.path}" Port 993 TLSType IMAPS AuthMechs * CertificateFile /etc/ssl/certs/ca-certificates.crt IMAPStore ret2pop-remote Account ret2pop MaildirStore ret2pop-local Path ~/email/ret2pop/ Inbox ~/email/ret2pop/INBOX SubFolders Verbatim Channel ret2pop Far :ret2pop-remote: Near :ret2pop-local: Patterns * Create Near Sync All Expunge None SyncState * ''; }; }
4.10.11. MSMTP
This is the program I use to send email from emacs. It is really the same thing as above,
just set the options to the ones you want in your system default.nix
.
{ lib, config, ... }: { programs.msmtp = { enable = lib.mkDefault config.monorepo.profiles.email.enable; extraConfig = '' # Set default values for all following accounts. defaults auth on tls on tls_trust_file /etc/ssl/certs/ca-certificates.crt tls_certcheck off logfile ~/.msmtp.log # Gmail account ${config.monorepo.vars.userName} host ${config.monorepo.profiles.email.smtpsServer} port 587 from ${config.monorepo.profiles.email.email} user ${config.monorepo.profiles.email.email} passwordeval "cat ${config.sops.secrets.mail.path}" # Set a default account account default : ${config.monorepo.vars.userName} ''; }; }
4.10.12. Mpd
This mpd configuration uses pipewire by default, and it should just work if you place music
in the ~/music
directory and then run mpc add /
afterwards.
{ lib, config, ... }: { services.mpd = { enable = lib.mkDefault config.monorepo.profiles.music.enable; dbFile = "/home/${config.monorepo.vars.userName}/.config/mpd/db"; dataDir = "/home/${config.monorepo.vars.userName}/.config/mpd/"; network.port = 6600; musicDirectory = "/home/${config.monorepo.vars.userName}/music"; playlistDirectory = "/home/${config.monorepo.vars.userName}/.config/mpd/playlists"; network.listenAddress = "0.0.0.0"; extraConfig = '' audio_output { type "pipewire" name "pipewire output" } audio_output { type "httpd" name "My HTTP Stream" encoder "opus" # optional port "8000" # quality "5.0" # do not define if bitrate is defined bitrate "128000" # do not define if quality is defined format "48000:16:1" always_on "yes" # prevent MPD from disconnecting all listeners when playback is stopped. tags "yes" # httpd supports sending tags to listening streams. } ''; }; }
4.10.13. MPV
I have some emacs + yt-dlp integrations with mpv with my rss feed, and therefore we need it here:
{ lib, config, ... }: { programs.mpv = { enable = true; config = { profile = "gpu-hq"; force-window = true; ytdl-format = "bestvideo+bestaudio"; cache-default = 4000000; }; }; }
4.10.14. Secrets
This uses sops in order to declaratively create the secrets on my system by unencrypting the yaml file specified. Yes, this is safe to include in the repo.
{ config, ... }: { sops = { defaultSopsFile = ../../secrets/secrets.yaml; age = { keyFile = "/home/${config.monorepo.vars.userName}/.ssh/keys.txt"; }; secrets.mail = { format = "yaml"; path = "${config.sops.defaultSymlinkPath}/mail"; }; secrets.digikey = { format = "yaml"; path = "${config.sops.defaultSymlinkPath}/digikey"; }; defaultSymlinkPath = "/run/user/1000/secrets"; defaultSecretsMountPoint = "/run/user/1000/secrets.d"; }; }
4.10.15. Waybar
This is the bar I use for my hyprland configuration. You will need to adjust the monitors field
in the default.nix
for it to really appear.
{ lib, config, ... }: { programs.waybar = { enable = lib.mkDefault config.monorepo.profiles.hyprland.enable; style = '' * { border: none; border-radius: 0px; font-family: Iosevka Nerd Font, FontAwesome, Noto Sans CJK; font-size: 14px; font-style: normal; min-height: 0; } window#waybar { background: rgba(30, 30, 46, 0.5); border-bottom: 1px solid #45475a; color: #cdd6f4; } #workspaces { background: #45475a; margin: 5px 5px 5px 5px; padding: 0px 5px 0px 5px; border-radius: 16px; border: solid 0px #f4d9e1; font-weight: normal; font-style: normal; } #workspaces button { padding: 0px 5px; border-radius: 16px; color: #a6adc8; } #workspaces button.active { color: #f4d9e1; background-color: transparent; border-radius: 16px; } #workspaces button:hover { background-color: #cdd6f4; color: black; border-radius: 16px; } #custom-date, #clock, #battery, #pulseaudio, #network, #custom-randwall, #custom-launcher { background: transparent; padding: 5px 5px 5px 5px; margin: 5px 5px 5px 5px; border-radius: 8px; border: solid 0px #f4d9e1; } #custom-date { color: #D3869B; } #custom-power { color: #24283b; background-color: #db4b4b; border-radius: 5px; margin-right: 10px; margin-top: 5px; margin-bottom: 5px; margin-left: 0px; padding: 5px 10px; } #tray { background: #45475a; margin: 5px 5px 5px 5px; border-radius: 16px; padding: 0px 5px; /*border-right: solid 1px #282738;*/ } #clock { color: #cdd6f4; background-color: #45475a; border-radius: 0px 0px 0px 24px; padding-left: 13px; padding-right: 15px; margin-right: 0px; margin-left: 10px; margin-top: 0px; margin-bottom: 0px; font-weight: bold; /*border-left: solid 1px #282738;*/ } #battery { color: #89b4fa; } #battery.charging { color: #a6e3a1; } #battery.warning:not(.charging) { background-color: #f7768e; color: #f38ba8; border-radius: 5px 5px 5px 5px; } #backlight { background-color: #24283b; color: #db4b4b; border-radius: 0px 0px 0px 0px; margin: 5px; margin-left: 0px; margin-right: 0px; padding: 0px 0px; } #network { color: #f4d9e1; border-radius: 8px; margin-right: 5px; } #pulseaudio { color: #f4d9e1; border-radius: 8px; margin-left: 0px; } #pulseaudio.muted { background: transparent; color: #928374; border-radius: 8px; margin-left: 0px; } #custom-randwall { color: #f4d9e1; border-radius: 8px; margin-right: 0px; } #custom-launcher { color: #e5809e; background-color: #45475a; border-radius: 0px 24px 0px 0px; margin: 0px 0px 0px 0px; padding: 0 20px 0 13px; /*border-right: solid 1px #282738;*/ font-size: 20px; } #custom-launcher button:hover { background-color: #FB4934; color: transparent; border-radius: 8px; margin-right: -5px; margin-left: 10px; } #custom-playerctl { background: #45475a; padding-left: 15px; padding-right: 14px; border-radius: 16px; /*border-left: solid 1px #282738;*/ /*border-right: solid 1px #282738;*/ margin-top: 5px; margin-bottom: 5px; margin-left: 0px; font-weight: normal; font-style: normal; font-size: 16px; } #custom-playerlabel { background: transparent; padding-left: 10px; padding-right: 15px; border-radius: 16px; /*border-left: solid 1px #282738;*/ /*border-right: solid 1px #282738;*/ margin-top: 5px; margin-bottom: 5px; font-weight: normal; font-style: normal; } #window { background: #45475a; padding-left: 15px; padding-right: 15px; border-radius: 16px; /*border-left: solid 1px #282738;*/ /*border-right: solid 1px #282738;*/ margin-top: 5px; margin-bottom: 5px; font-weight: normal; font-style: normal; } #custom-wf-recorder { padding: 0 20px; color: #e5809e; background-color: #1E1E2E; } #cpu { background-color: #45475a; /*color: #FABD2D;*/ border-radius: 16px; margin: 5px; margin-left: 5px; margin-right: 5px; padding: 0px 10px 0px 10px; font-weight: bold; } #memory { background-color: #45475a; /*color: #83A598;*/ border-radius: 16px; margin: 5px; margin-left: 5px; margin-right: 5px; padding: 0px 10px 0px 10px; font-weight: bold; } #disk { background-color: #45475a; /*color: #8EC07C;*/ border-radius: 16px; margin: 5px; margin-left: 5px; margin-right: 5px; padding: 0px 10px 0px 10px; font-weight: bold; } #custom-hyprpicker { background-color: #45475a; /*color: #8EC07C;*/ border-radius: 16px; margin: 5px; margin-left: 5px; margin-right: 5px; padding: 0px 11px 0px 9px; font-weight: bold; } ''; settings = { mainBar = { layer = "top"; position = "top"; height = 50; output = config.monorepo.vars.monitors; modules-left = [ "hyprland/workspaces" ]; modules-center = [ "hyprland/window" ]; modules-right = [ "battery" "clock" ]; battery = { format = "{icon} {capacity}%"; format-icons = ["" "" "" "" "" ]; }; clock = { format = "⏰ {:%a %d, %b %H:%M}"; }; }; }; }; }
4.10.16. Wofi
This is a run launcher for wayland. I also use it for my powermenu.
{ lib, config, ... }: { programs.wofi = { enable = true; settings = { location = "bottom-right"; allow_markup = true; show = "drun"; width = 750; height = 400; always_parse_args = true; show_all = false; term = "kitty"; hide_scroll = true; print_command = true; insensitive = true; prompt = "Run what, Commander?"; columns = 2; }; style = '' @define-color rosewater #f5e0dc; @define-color rosewater-rgb rgb(245, 224, 220); @define-color flamingo #f2cdcd; @define-color flamingo-rgb rgb(242, 205, 205); @define-color pink #f5c2e7; @define-color pink-rgb rgb(245, 194, 231); @define-color mauve #cba6f7; @define-color mauve-rgb rgb(203, 166, 247); @define-color red #f38ba8; @define-color red-rgb rgb(243, 139, 168); @define-color maroon #eba0ac; @define-color maroon-rgb rgb(235, 160, 172); @define-color peach #fab387; @define-color peach-rgb rgb(250, 179, 135); @define-color yellow #f9e2af; @define-color yellow-rgb rgb(249, 226, 175); @define-color green #a6e3a1; @define-color green-rgb rgb(166, 227, 161); @define-color teal #94e2d5; @define-color teal-rgb rgb(148, 226, 213); @define-color sky #89dceb; @define-color sky-rgb rgb(137, 220, 235); @define-color sapphire #74c7ec; @define-color sapphire-rgb rgb(116, 199, 236); @define-color blue #89b4fa; @define-color blue-rgb rgb(137, 180, 250); @define-color lavender #b4befe; @define-color lavender-rgb rgb(180, 190, 254); @define-color text #cdd6f4; @define-color text-rgb rgb(205, 214, 244); @define-color subtext1 #bac2de; @define-color subtext1-rgb rgb(186, 194, 222); @define-color subtext0 #a6adc8; @define-color subtext0-rgb rgb(166, 173, 200); @define-color overlay2 #9399b2; @define-color overlay2-rgb rgb(147, 153, 178); @define-color overlay1 #7f849c; @define-color overlay1-rgb rgb(127, 132, 156); @define-color overlay0 #6c7086; @define-color overlay0-rgb rgb(108, 112, 134); @define-color surface2 #585b70; @define-color surface2-rgb rgb(88, 91, 112); @define-color surface1 #45475a; @define-color surface1-rgb rgb(69, 71, 90); @define-color surface0 #313244; @define-color surface0-rgb rgb(49, 50, 68); @define-color base #1e1e2e; @define-color base-rgb rgb(30, 30, 46); @define-color mantle #181825; @define-color mantle-rgb rgb(24, 24, 37); @define-color crust #11111b; @define-color crust-rgb rgb(17, 17, 27); * { font-family: 'Iosevka Nerd Font', monospace; font-size: 14px; } /* Window */ window { margin: 0px; padding: 10px; border: 0.16em solid @lavender; border-radius: 0.1em; background-color: @base; animation: slideIn 0.5s ease-in-out both; } /* Slide In */ @keyframes slideIn { 0% { opacity: 0; } 100% { opacity: 1; } } /* Inner Box */ #inner-box { margin: 5px; padding: 10px; border: none; background-color: @base; animation: fadeIn 0.5s ease-in-out both; } /* Fade In */ @keyframes fadeIn { 0% { opacity: 0; } 100% { opacity: 1; } } /* Outer Box */ #outer-box { margin: 5px; padding: 10px; border: none; background-color: @base; } /* Scroll */ #scroll { margin: 0px; padding: 10px; border: none; background-color: @base; } /* Input */ #input { margin: 5px 20px; padding: 10px; border: none; border-radius: 0.1em; color: @text; background-color: @base; animation: fadeIn 0.5s ease-in-out both; } #input image { border: none; color: @red; } #input * { outline: 4px solid @red!important; } /* Text */ #text { margin: 5px; border: none; color: @text; animation: fadeIn 0.5s ease-in-out both; } #entry { background-color: @base; } #entry arrow { border: none; color: @lavender; } /* Selected Entry */ #entry:selected { border: 0.11em solid @lavender; } #entry:selected #text { color: @mauve; } #entry:drop(active) { background-color: @lavender!important; } ''; }; }
4.10.17. yt-dlp
A classic program that allows you to download from youtube. Also has integrations with mpv.
{ lib, config, ... }: { programs.yt-dlp = { enable = true; settings = { embed-thumbnail = true; embed-subs = true; sub-langs = "all"; downloader = "aria2c"; downloader-args = "aria2c:'-c -x8 -s8 -k1M'"; }; }; }
4.10.18. Zsh
My zsh config has some useful aliases that one should read through. Otherwise it is pretty standard.
{ lib, config, pkgs, ... }: { programs.zsh = { enable = true; initExtra = '' umask 0077 export EXTRA_CCFLAGS="-I/usr/include" source ${pkgs.zsh-vi-mode}/share/zsh-vi-mode/zsh-vi-mode.plugin.zsh export QT_QPA_PLATFORM="wayland" ''; localVariables = { EDITOR = "emacsclient --create-frame --alternate-editor=vim"; INPUT_METHOD = "fcitx"; QT_IM_MODULE = "fcitx"; GTK_IM_MODULE = "fcitx"; XMODIFIERS = "@im=fcitx"; XIM_SERVERS = "fcitx"; WXSUPPRESS_SIZER_FLAGS_CHECK = "1"; }; shellAliases = { c = "clear"; g = "git"; v = "vim"; py = "python3"; rb = "sudo nixos-rebuild switch --flake .#continuity"; nfu = "cd ~/monorepo/nix && git add . && git commit -m \"new flake lock\" && nix flake update"; usite = "cd ~/monorepo/publish-org-roam-ui && bash local.sh && rm -rf ~/website_html/graph_view; cp -r ~/monorepo/publish-org-roam-ui/out ~/website_html/graph_view && rsync -azvP --chmod=\"Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r\" ~/website_html/ root@${config.monorepo.vars.remoteHost}:/usr/share/nginx/ret2pop/"; sai = "eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && ssh-add -l"; i3 = "exec ${pkgs.i3-gaps}/bin/i3"; }; loginExtra = '' if [[ "$(tty)" = "/dev/tty1" ]]; then exec Hyprland fi ''; }; }
4.10.19. User
This configuration is the backbone configuration for the default user. It specifies some generally useful packages and something every home should have, as well as some dependencies for these configurations.
{ lib, config, pkgs, ... }: { home = { activation.startup-files = lib.hm.dag.entryAfter [ "installPackages" ] '' if [ ! -d "/home/${config.monorepo.vars.userName}/email/ret2pop/" ]; then mkdir -p /home/${config.monorepo.vars.userName}/email/ret2pop/ fi if [ ! -d "/home/${config.monorepo.vars.userName}/music" ]; then mkdir -p /home/${config.monorepo.vars.userName}/music fi if [ ! -d /home/${config.monorepo.vars.userName}/org ]; then mkdir -p /home/${config.monorepo.vars.userName}/org fi touch /home/${config.monorepo.vars.userName}/org/agenda.org touch /home/${config.monorepo.vars.userName}/org/notes.org ''; enableNixpkgsReleaseCheck = false; username = config.monorepo.vars.userName; homeDirectory = "/home/${config.monorepo.vars.userName}"; stateVersion = "24.11"; packages = with pkgs; [ # passwords age sops # formatting ghostscript texliveFull pandoc # Emacs Deps graphviz jq # Apps octaveFull vesktop grim swww vim # Sound/media pavucontrol alsa-utils imagemagick ffmpeg helvum # Net curl rsync git # Tor torsocks tor-browser # fonts noto-fonts noto-fonts-cjk-sans noto-fonts-emoji fira-code font-awesome_6 (aspellWithDicts (dicts: with dicts; [ en en-computers en-science ])) (nerdfonts.override { fonts = [ "Iosevka" ]; }) # Misc. pinentry x11_ssh_askpass xdg-utils acpilight pfetch libnotify ]; }; services = { gpg-agent = { pinentryPackage = pkgs.pinentry-emacs; enable = true; extraConfig = '' allow-emacs-pinentry allow-loopback-pinentry ''; }; }; programs.bash.enable = true; gtk = { enable = true; theme = null; iconTheme = null; }; fonts.fontconfig.enable = true; nixpkgs.config.cudaSupport = lib.mkDefault config.monorepo.profiles.cuda.enable; }
5. Systems
5.1. Continuity
This is pretty understandable, if you understand all the above.
{ ... }: { imports = [ ../../modules/default.nix ]; }
5.2. Installer
My installer installs my systems almost completely without interaction. You can also make them install the exact version of the system that you want it to by pinning the commits to make it always work in the exact same deterministic way.
5.2.1. Commit Hash Pinning
Modify this to pin the installer image hash to make the installer image always work deterministically.
{ diskoCommitHash = "latest"; monorepoCommitHash = "HEAD"; }
5.2.2. ISO Default Profile
This contains the installation script I use to install my systems.
{ pkgs, config, ... }: let commits = import ./commits.nix; in { networking = { hostName = "nixos"; networkmanager = { enable = true; }; firewall = { allowedTCPPorts = [ ]; allowedUDPPorts = [ ]; }; wireless.enable = false; }; users.extraUsers.root.password = "nixos"; users.extraUsers.nixos.password = "nixos"; users.users = { nixos = { packages = with pkgs; [ git curl gum (writeShellScriptBin "nix_installer" '' #!/usr/bin/env bash set -euo pipefail if [ "$(id -u)" -eq 0 ]; then echo "ERROR! $(basename "$0") should be run as a regular user" exit 1 fi ping -q -c1 google.com &>/dev/null && echo "online! Proceeding with the installation..." || nmtui cd if [ ! -d "$HOME/monorepo/" ]; then git clone --recurse-submodules https://git.nullring.xyz/monorepo.git cd monorepo git checkout "${commits.monorepoCommitHash}" fi vim "$HOME/monorepo/nix/systems/continuity/default.nix" sudo nix --experimental-features "nix-command flakes" run "github:nix-community/disko/${commits.diskoCommitHash}" -- --mode destroy,format,mount "$HOME/monorepo/nix/modules/sda-simple.nix" cd /mnt sudo nixos-install --flake $HOME/monorepo/nix#continuity sudo cp -r $HOME/monorepo "/mnt/home/$(ls /mnt/home/)/" echo "rebooting..."; sleep 3; reboot '') ]; }; }; systemd = { services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ]; targets = { sleep.enable = false; suspend.enable = false; hibernate.enable = false; hybrid-sleep.enable = false; }; }; }