From 4ec3859a0e51341ae968fbf2b5e7f5057dc547fe Mon Sep 17 00:00:00 2001 From: Janis Date: Sun, 20 Jul 2025 01:12:03 +0200 Subject: [PATCH] waybar, zsh, firefox, so much.. --- config/apps/default.nix | 2 + config/apps/firefox.nix | 97 ++++++++++++++- config/apps/sway.nix | 9 +- config/apps/waybar.nix | 233 ++++++++++++++++++++++++++++++++++++ config/apps/zsh.nix | 39 ++++++ config/configuration.nix | 4 +- config/data/theme.nix | 21 ++++ config/data/zsh-aliases.nix | 13 ++ config/hosts/common.nix | 0 config/hosts/default.nix | 3 + config/hosts/laptop.nix | 4 + config/hosts/vm.nix | 5 + config/nixos/system.nix | 9 +- config/users/alice.nix | 15 --- config/users/user.nix | 2 +- config/utils.nix | 20 ++++ config/variables.nix | 21 ++++ 17 files changed, 473 insertions(+), 24 deletions(-) create mode 100644 config/apps/waybar.nix create mode 100644 config/apps/zsh.nix create mode 100644 config/data/theme.nix create mode 100644 config/data/zsh-aliases.nix create mode 100644 config/hosts/common.nix create mode 100644 config/hosts/default.nix create mode 100644 config/hosts/laptop.nix create mode 100644 config/hosts/vm.nix create mode 100644 config/utils.nix create mode 100644 config/variables.nix diff --git a/config/apps/default.nix b/config/apps/default.nix index ca9030f..b41be50 100644 --- a/config/apps/default.nix +++ b/config/apps/default.nix @@ -2,6 +2,8 @@ imports = [ ./firefox.nix ./sway.nix + ./waybar.nix ./alacritty.nix + ./zsh.nix ]; } diff --git a/config/apps/firefox.nix b/config/apps/firefox.nix index f265027..282120b 100644 --- a/config/apps/firefox.nix +++ b/config/apps/firefox.nix @@ -3,6 +3,18 @@ in{ programs.firefox = { enable = true; + + policies = { + CaptivePortal = false; + DisablePocket = true; + DisableTelemetry = true; + DisableFirefoxStudies = true; + FirefoxHome = { + Pocket = false; + Snippets = false; + }; + }; + profiles = { default = { isDefault = true; @@ -14,13 +26,96 @@ in{ }; settings = { + # disable warning when editing about:config "browser.aboutConfig.showWarning" = false; - "browser.toolbars.bookmarks.visibility" = "never"; + # webgpu "dom.webgpu.enabled" = true; "gfx.webrender.all" = true; "signon.rememberSignons" = false; + # mozilla syncserver "identity.sync.tokenserver.uri" = "https://nirgendswo.com:8001/1.0/sync/1.5"; "services.sync.username" = user.email; + "browser.startup.page" = 3; # resume previous session + "browser.startup.homepage" = "about:home"; + "browser.toolbars.bookmarks.visibility" = "never"; + + # hardening + "browser.newtabpage.enabled" = false; + "browser.newtabpage.activity-stream.feeds.telemetry" = false; + "browser.newtabpage.activity-stream.telemetry" = false; + "browser.newtabpage.activity-stream.feeds.snippets" = false; + "browser.newtabpage.activity-stream.feeds.section.topstories" = false; + "browser.newtabpage.activity-stream.showSponsoredTopSites" = false; + "browser.newtabpage.activity-stream.showSponsored" = false; + "browser.newtabpage.activity-stream.feeds.discoverystreamfeed" = false; + "browser.newtabpage.activity-stream.default.sites" = ""; + "browser.newtab.preload" = false; + "geo.provider.network.url" = "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%"; + "geo.provider.ms-windows-location" = false; + "geo.provider.use_corelocation" = false; + "geo.provider.use_gpsd" = false; + "geo.provider.use_geoclue" = false; + "browser.region.network.url" = ""; + "browser.region.update.enabled" = false; + "intl.accept_languages" = "en-US,en-GB,en"; + "javascript.use_us_language_locale" = true; + "app.update.auto" = false; + + "extensions.discover.enabled" = false; + "extensions.htmlaboutaddons.recommendations.enabled" = false; + "extenisons.getAddons.showPane" = false; + + "datareporting.healthreport.uploadEnabled" = false; + "datareporting.policy.dataSubmissionEnabled" = false; + "toolkit.telemetry.enabled" = false; + "toolkit.telemetry.unified" = false; + "toolkit.telemetry.server" = "data:,"; + "toolkit.telemetry.archive.enabled" = false; + "toolkit.telemetry.newProfilePing.enabled" = false; + "toolkit.telemetry.shutdownPingSender.enabled" = false; + "toolkit.telemetry.updatePing.enabled" = false; + "toolkit.telemetry.bhrPing.enabled" = false; + "toolkit.telemetry.firstShutdownPing.enabled" = false; + "toolkit.telemetry.coverage.opt-out" = true; + "toolkit.coverage.opt-out" = true; + "beacon.enabled" = false; + + "app.shield.optoutstudies.enabled" = false; + + "captivedetect.canonicalURL" = ""; + "network.captive-portal-service.enabled" = false; + "network.connectivity-service.enabled" = false; + + "browser.safebrowsing.malware.enabled" = false; + "browser.safebrowsing.phishing.enabled" = false; + "browser.safebrowsing.blockedURIs.enabled" = false; + "browser.safebrowsing.provider.google4.gethashURL" = ""; + "browser.safebrowsing.provider.google4.updateURL" = ""; + "browser.safebrowsing.provider.google4.dataSharingURL" = ""; + "browser.safebrowsing.provider.google.gethashURL" = ""; + "browser.safebrowsing.provider.google.updateURL" = ""; + + "browser.safebrowsing.downloads.enabled" = false; + "browser.safebrowsing.downloads.remote.enabled" = false; + "browser.safebrowsing.downloads.remote.url" = ""; + "browser.safebrowsing.allowOverride" = false; + + "network.prefetch-next" = false; + "network.dns.disablePrefetch" = true; + "network.predictor.enabled" = false; + + "browser.fixup.alternate.enabled" = false; + "browser.urlbar.trimURLs" = false; + + "browser.contentblocking.category" = "strict"; + "privacy.partition.serviceWorkers" = true; + "privacy.partition.always_partition_third_party_non_cookie_storage" = true; + "privacy.partition.always_partition_third_party_non_cookie_storage.exempt_sessionstorage" = true; + "privacy.resistFingerprinting" = true; + "privacy.resistFingerprinting.block_mozAddonManager" = true; + + "app.normandy.enabled" = false; + "app.normandy.api_url" = ""; }; extensions.packages = with pkgs.nur.repos.rycee.firefox-addons; [ diff --git a/config/apps/sway.nix b/config/apps/sway.nix index 949ce82..0f53377 100644 --- a/config/apps/sway.nix +++ b/config/apps/sway.nix @@ -22,6 +22,10 @@ in { inner = 8; }; + bars = [{ + command = "${pkgs.waybar}/bin/waybar"; + }]; + window = { border = 3; titlebar = false; @@ -132,9 +136,4 @@ in { }; }; }; - - programs.waybar = { - enable = true; - systemd.enable = true; - }; } diff --git a/config/apps/waybar.nix b/config/apps/waybar.nix new file mode 100644 index 0000000..9b0160c --- /dev/null +++ b/config/apps/waybar.nix @@ -0,0 +1,233 @@ +{lib, config, ...}: +let + theme = import ../data/theme.nix {inherit config; }; + utils = import ../utils.nix {inherit lib; }; +in let + self = rec { + # ModuleDesc has the shape {name, config?, background?, color?, style?} + module-descs = [ + { + name = "custom/left-most"; + background = theme.background; + } + { + name = "pulseaudio"; + config = { + format = "{volume}% {icon} {format_source}"; + format-bluetooth = "{volume}% {icon} {format_source}"; + format-muted = "{format_source}"; + format-source = "{volume}% "; + format-source-muted = ""; + format-icons = { + headphones = ""; + default = ["" "" ""]; + }; + on-click = "pavucontrol"; + }; + background = theme.normal.yellow; + } + { + name = "network"; + config = { + format-wifi = "{essid} {signalStrength}% {icon}"; + format-ethernet = "{ipaddr} 󰈀"; + format-disconnected = "Disconnected 󰤮"; + tooltip-format = ''Interface: {ifname} +IP: {ipaddr} +Speed: {bandwidthUpBytes} / {bandwidthDownBytes} +Signal: {signalStrength}% +SSID: {essid} {frequency}''; + on-click = "iwgtk"; + format-icons = ["󰤯" "󰤟" "󰤢" "󰤥" "󰤨"]; + }; + background = theme.normal.green; + } + { + name = "custom/vpn"; + config = { + format = "{}"; + excape = true; + interval = 30; + exec = "nordvpn-rofi.sh --status-json"; + return-type = "json"; + on-click = "rofi -show vpn -modes 'vpn:nordvpn-rofi.sh'"; + }; + style = { + connected.color = theme.normal.black; + disconnected.color = theme.normal.yellow; + }; + background = theme.extra.teal;} + ] + ++ (if (config.has_battery) then [{ + name = "battery"; + config = { + states = { + critical = 15; + warning = 25; + good = 80; + full = 90; + }; + interval = 30; + format = "{capacity}% {icon}"; + format-charging = "{capacity}% "; + format-plugged = "{capacity}% "; + format-icons = ["" "" "" "" ""]; + }; + background = theme.extra.aqua; + }] else []) + ++ [ + { + name = "cpu"; + config = { + format = "{}% "; + }; + background = theme.extra.brown; + } + { + name = "memory"; + config = { + format = "{}% "; + }; + background = theme.extra.darkbrown; + } + { + name = "temperature"; + config = { + critical-threshold = 80; + hwmon-path = "/sys/class/hwmon/hwmon5/temp1_input"; + format = "{temperatureC}°C {icon}"; + format-icons = ["" "" ""]; + }; + background = theme.extra.darkerbrown; + } + { + name = "clock"; + config = { + format = "{:%H:%M} 󰥔"; + tooltip-format = "{calendar}"; + calendar = { + mode = "month"; + weeks-pos = "left"; + on-scroll = 1; + format = { + months = "{}"; + days = "{}"; + weekdays = "{}"; + today = "{}"; + }; + on-scroll-up = "shift_up"; + on-scroll-down = "shift_down"; + }; + }; + background = theme.normal.black; + } + {name = "tray"; config = { spacing = 10; }; background = theme.background;} + ]; + + # default style for modules + default-style = "padding-left: 8pt; padding-right: 8pt;"; + + # ModuleDesc -> Module + mkModule = desc: let + background = desc.background or theme.background; + color = desc.color or theme.foreground; + config = desc.config or {}; + # style = module.style or ""; + style = default-style; + style-name = builtins.replaceStrings ["/"] ["-"] desc.name; + in { + inherit (desc) name; + setting = { + } // config; + + style = "#${style-name} {" + default-style + ''background: ${background};color: ${color};'' + "}\n"; + }; + + mkSpacer = idx: left: right: { + name = "custom/arrow${toString idx}"; + setting = { + format = ""; + tooltip = false; + }; + style = "#custom-arrow${toString idx} {font-size: 14pt;background: ${left.background};color: ${right.background};}\n"; + }; + + # modules interlaced with spacers + # [ModuleDesc] -> [Module] + mkSpacedModules = descs: with builtins; + let + len = length descs; + in lib.lists.flatten + (lib.lists.imap0 + (n: descs: let + left = elemAt descs 0; + right = elemAt descs 1; + in if n == len then [ + (mkModule left) + (mkSpacer n left right) + (mkModule right) + ] else [ + (mkModule left) + (mkSpacer n left right) + ]) + (utils.windows 2 descs) + ); + + # Module -> {"name" = setting} + mkModuleConfig = {name, setting, ...}: lib.attrsets.optionalAttrs (!utils.isEmptySet setting) { + "${name}" = setting; + }; + + # builds bar configuration with left, center, and right modules + # right modules get spacers in between them. + # {left: [ModuleDesc], center: [ModuleDesc], right: [ModuleDesc], config: {}} -> {config, style} + mkBar = {left, center, right, config, ...}: + let + # Create modules from the descriptions + right' = mkSpacedModules right; + left' = map (module: mkModule module) left; + center' = map (module: mkModule module) center; + in let + # Create lists of module names for the config + modules-left = map (module: module.name) left'; + modules-center = map (module: module.name) center'; + modules-right = map (module: module.name) right'; + # Combine all modules into a single list + modules = lib.lists.flatten [left' center' right']; + in { + config = lib.attrsets.mergeAttrsList (lib.lists.flatten [ + { + inherit modules-left modules-center modules-right; + } + config + (map mkModuleConfig modules) + ]); + style = lib.strings.concatStringsSep "\n" (map (module: module.style) modules); + }; + }; + + bar = self.mkBar { + left = [ {name = "sway/workspaces";} {name = "sway/mode";} ]; + center = [ {name = "sway/window";} ]; + right = self.module-descs; + config = { + height = 25; + spacing = 0; + position = "top"; + }; + }; +in { + programs.waybar = { + enable = true; + + settings = { + mainBar = bar.config; + }; + + style = '' +* {border: none; border-radius: 0; min-height: 0; margin: 0; padding: 0; box-shadow: none; text-shadow: none;} +#waybar { background: rgba(40, 40, 40, 0.3); color: #ffffff; font-family: "sans-serif"; font-size: 12pt; font-weight: 500; } +'' + + bar.style; + }; +} diff --git a/config/apps/zsh.nix b/config/apps/zsh.nix new file mode 100644 index 0000000..2a9cc9f --- /dev/null +++ b/config/apps/zsh.nix @@ -0,0 +1,39 @@ +{pkgs, ...}: +let + aliases = import ../data/zsh-aliases.nix {}; +in { + home.packages = with pkgs; [ pure-prompt ]; + programs.zsh = { + enable = true; + enableCompletion = true; + shellAliases = aliases; + + history = { + size = 10000000; + save = 10000000; + findNoDups = true; + saveNoDups = true; + ignoreDups = true; + share = true; + extended = true; + append = true; + path = "$HOME/.zsh_history"; + }; + + initExtra = '' +prompt pure +zstyle :prompt:pure:path color cyan +zstyle :prompt:pure:prompt:error color red +zstyle :prompt:pure:prompt:success color green +bindkey -v +autoload -Uz edit-command-line +zle -N edit-command-line +bindkey '^X^E' edit-command-line +''; + }; + + programs.fzf = { + enable = true; + enableZshIntegration = true; + }; +} diff --git a/config/configuration.nix b/config/configuration.nix index 8bdbd48..fcf2a76 100644 --- a/config/configuration.nix +++ b/config/configuration.nix @@ -1,4 +1,4 @@ -{ ... }: +{ lib, ... }: { imports = [ # Include the results of the hardware scan. @@ -6,6 +6,8 @@ # inputs.home-manager.nixosModules.default ./nixos ./users/alice.nix + ./variables.nix + ./hosts/vm.nix ]; # to use zsh as a login shell, it has to be enabled globally. diff --git a/config/data/theme.nix b/config/data/theme.nix new file mode 100644 index 0000000..2fc5a08 --- /dev/null +++ b/config/data/theme.nix @@ -0,0 +1,21 @@ +{config, ...}: +let + theme = if config.darkMode then import ./gruvbox-dark.nix {} + else import ./gruvbox-light.nix {}; +in +{ + inherit (theme) background foreground normal bright; + + extra = { + red = "#bd574e"; + orange = "#eb8242"; + yellow = "#ede06b"; + green = "#9bb67c"; + teal = "#87a7b3"; + purple = "#ad6989"; + brown = "#ad8b73"; + darkbrown = "#85603f"; + darkerbrown = "#5e454b"; + cream = "#fefcf3"; + }; +} diff --git a/config/data/zsh-aliases.nix b/config/data/zsh-aliases.nix new file mode 100644 index 0000000..a21009c --- /dev/null +++ b/config/data/zsh-aliases.nix @@ -0,0 +1,13 @@ +{...}: { + ll = "ls -l"; + la = "ls -la"; + git-tree = "git log --graph --oneline --all"; + c = "clear"; + cl = "clear; ls --color=auto"; + q = "exit"; + ssh = "TERM=xterm-256color ssh"; + emacs = "emacs -nw"; # Use emacs in terminal mode. + + # dotfiles + dotfiles = "git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME"; +} diff --git a/config/hosts/common.nix b/config/hosts/common.nix new file mode 100644 index 0000000..e69de29 diff --git a/config/hosts/default.nix b/config/hosts/default.nix new file mode 100644 index 0000000..d854dcc --- /dev/null +++ b/config/hosts/default.nix @@ -0,0 +1,3 @@ +{...}: { + imports = []; +} diff --git a/config/hosts/laptop.nix b/config/hosts/laptop.nix new file mode 100644 index 0000000..dbb925f --- /dev/null +++ b/config/hosts/laptop.nix @@ -0,0 +1,4 @@ +{config, ...}: { + imports = [ ../variables.nix ]; + config.has_battery = true; +} diff --git a/config/hosts/vm.nix b/config/hosts/vm.nix new file mode 100644 index 0000000..dea1914 --- /dev/null +++ b/config/hosts/vm.nix @@ -0,0 +1,5 @@ +{...}: { + imports = [ ../variables.nix ]; + # config.has_battery = true; + config.vmGuest = true; +} diff --git a/config/nixos/system.nix b/config/nixos/system.nix index fc583e5..31acd03 100644 --- a/config/nixos/system.nix +++ b/config/nixos/system.nix @@ -1,7 +1,11 @@ -{pkgs, ...}: +{config, pkgs, ...}: let base = import ../options.nix {}; in { + imports = [ + ../variables.nix + ]; + system.stateVersion = "${base.stateVersion}"; nix.settings.experimental-features = [ @@ -25,6 +29,9 @@ in { # useXkbConfig = true; # use xkb.options in tty. }; + services.qemuGuest.enable = config.vmGuest; + services.spice-vdagentd.enable = config.vmGuest; + security.rtkit.enable = true; # Enable real-time scheduling for audio applications. services = { diff --git a/config/users/alice.nix b/config/users/alice.nix index 5093740..3ccfd70 100644 --- a/config/users/alice.nix +++ b/config/users/alice.nix @@ -11,21 +11,6 @@ inputs @ { pkgs, lib, ...}: let htop ]; # Default packages for the owner account. }; - - # configure the shell - programs.zsh = { - enable = true; # Enable zsh shell. - enableCompletion = true; # Enable zsh completion. - shellAliases = { - ll = "ls -l"; - la = "ls -la"; - git-tree = "git log --graph --oneline --all"; - c = "clear"; - q = "exit"; - ssh = "TERM=xterm-256color ssh"; - emacs = "emacs -nw"; # Use emacs in terminal mode. - }; - }; }; in { imports = [(lib.modules.importApply ./user.nix { diff --git a/config/users/user.nix b/config/users/user.nix index 614ab3d..18844e0 100644 --- a/config/users/user.nix +++ b/config/users/user.nix @@ -27,7 +27,7 @@ in { }; home-manager.users.${username} = {...}: { - imports = [ user.userModule ]; + imports = [ ../variables.nix user.userModule ]; # programs.home-manager.enable = true; diff --git a/config/utils.nix b/config/utils.nix new file mode 100644 index 0000000..cd69dfc --- /dev/null +++ b/config/utils.nix @@ -0,0 +1,20 @@ +{lib, ...}: rec { + min = a: b: if a < b then a else b; + max = a: b: if a > b then a else b; + # build list of `len` lists of `n` elements of `xs` + windows = with builtins; n: xs: let + len = length xs; + n' = min n len; + # when len = n, there is still one window + num-windows = max 0 (len - n' + 1); + in + genList + # for i in 0..len + (i: genList + # for j in 0..n -> xs[i + j] + (j: elemAt xs (i + j)) + n') + num-windows; + + isEmptySet = set: with builtins; length (attrNames set) == 0; +} diff --git a/config/variables.nix b/config/variables.nix new file mode 100644 index 0000000..c47bfc3 --- /dev/null +++ b/config/variables.nix @@ -0,0 +1,21 @@ +{lib, ...}: { + options = { + has_battery = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Whether the system has a battery."; + }; + + vmGuest = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Enable VM guest services."; + }; + + darkMode = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Enable dark mode for the system."; + }; + }; +}