├── .github └── assets │ ├── v1.0.0 │ ├── screenshot1.png │ └── screenshot2.png │ └── v2.0.0 │ ├── screenshot1.png │ └── screenshot2.png ├── .gitignore ├── .gitmodules ├── .sops.yaml ├── LICENSE ├── README.md ├── devices ├── desktop │ ├── default.nix │ ├── disk-config.nix │ ├── fastfetch │ │ ├── default.jsonc │ │ └── short.jsonc │ ├── hardware-configuration.nix │ ├── hyprland.conf │ └── mount-data.sh ├── laptop │ ├── .gitignore │ ├── default.nix │ ├── disk-config.nix │ ├── fastfetch │ │ ├── default.jsonc │ │ └── short.jsonc │ ├── hardware-configuration.nix │ └── hyprland.conf ├── raspberry-pi │ ├── default.nix │ └── fastfetch │ │ ├── default.jsonc │ │ └── short.jsonc └── wsl │ ├── default.nix │ └── fastfetch │ ├── default.jsonc │ └── short.jsonc ├── flake.lock ├── flake.nix ├── misc ├── autostart.sh ├── notification.wav └── update.sh ├── modules ├── ai-chatbot.nix ├── alacritty │ ├── alacritty.toml │ └── default.nix ├── awesome │ ├── default.nix │ ├── rc.lua │ └── themes │ │ └── mytheme │ │ ├── icons │ │ ├── awesome.png │ │ ├── cpu.png │ │ ├── mem.png │ │ ├── square_sel.png │ │ ├── square_unsel.png │ │ └── submenu.png │ │ └── theme.lua ├── base │ ├── default.nix │ ├── gui │ │ ├── default.nix │ │ └── full.nix │ ├── laptop.nix │ └── raspberry-pi.nix ├── blocky.nix ├── bluetooth.nix ├── copyq │ ├── copyq.conf │ └── default.nix ├── default.nix ├── devtools.nix ├── discord.nix ├── distributed-builds.nix ├── eww │ ├── default.nix │ ├── eww.css │ ├── eww.yuck │ └── scripts │ │ ├── battery.sh │ │ ├── logarithmic-cpu.sh │ │ ├── network.sh │ │ ├── open-everywhere.sh │ │ ├── ram-usage.sh │ │ └── workspaces │ │ ├── change-active.sh │ │ └── get-all.sh ├── fastfetch.nix ├── firefox │ ├── default.nix │ └── firefox.css ├── fish │ ├── default.nix │ └── init.fish ├── gitnuro │ ├── default.nix │ └── gitnuro.json ├── hyprland │ ├── default.nix │ ├── hyprctl-collect-clients.sh │ ├── hyprland.conf │ └── wallpaper.py ├── jetbrains │ ├── .ideavimrc │ └── default.nix ├── lamp-server │ ├── default.nix │ └── secrets.yaml ├── minecraft-server │ ├── default.nix │ └── server-icon.png ├── nautilus.nix ├── nvidia.nix ├── obsidian-livesync.nix ├── onedrive.nix ├── piper.nix ├── playerctl.nix ├── plymouth │ └── default.nix ├── rofi │ ├── default.nix │ ├── opaque.rasi │ └── transparent.rasi ├── sddm-sugar-candy │ ├── default.nix │ └── sddm-sugar-candy.conf ├── sops.nix ├── starship │ ├── default.nix │ └── starship.toml ├── steam.nix ├── studies │ ├── comarch.nix │ ├── dabank.nix │ ├── default.nix │ ├── itsarch.nix │ ├── redig.nix │ └── swsyspro.nix ├── swaylock-effects │ ├── default.nix │ └── swaylock-effects.sh ├── swaync │ ├── config.json │ ├── default.nix │ ├── inhibit-on-screenshare.sh │ └── style.css ├── vim │ ├── .vimrc │ └── default.nix ├── virt-manager.nix ├── vscodium │ ├── default.nix │ └── vscodium.json ├── website.nix ├── wsl-vpnkit.nix └── zen-browser │ ├── default.nix │ └── userChrome.css ├── packages ├── default.nix └── sddm-sugar-candy.nix ├── variables.nix └── wallpapers └── nixos ├── bc.png ├── bg.png ├── bm.png ├── br.png ├── by.png ├── cb.png ├── cg.png ├── cm.png ├── cr.png ├── cy.png ├── gb.png ├── gc.png ├── gm.png ├── gr.png ├── gy.png ├── mb.png ├── mc.png ├── mg.png ├── mr.png ├── my.png ├── rb.png ├── rc.png ├── rg.png ├── rm.png ├── ry.png ├── yb.png ├── yc.png ├── yg.png ├── ym.png └── yr.png /.github/assets/v1.0.0/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/.github/assets/v1.0.0/screenshot1.png -------------------------------------------------------------------------------- /.github/assets/v1.0.0/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/.github/assets/v1.0.0/screenshot2.png -------------------------------------------------------------------------------- /.github/assets/v2.0.0/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/.github/assets/v2.0.0/screenshot1.png -------------------------------------------------------------------------------- /.github/assets/v2.0.0/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/.github/assets/v2.0.0/screenshot2.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | misc/update/last-run-date 2 | 3 | wallpapers/login.jpg 4 | wallpapers/misc 5 | 6 | # other awesome themes 7 | awesome/themes/*/ 8 | !awesome/themes/mytheme 9 | !awesome/themes/mytheme/* -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "modules/awesome/lain"] 2 | path = modules/awesome/lain 3 | url = https://github.com/lcpz/lain.git 4 | [submodule "modules/awesome/freedesktop"] 5 | path = modules/awesome/freedesktop 6 | url = https://github.com/lcpz/awesome-freedesktop.git 7 | -------------------------------------------------------------------------------- /.sops.yaml: -------------------------------------------------------------------------------- 1 | # give every device access to sops secrets 2 | creation_rules: 3 | - key_groups: 4 | - age: # public keys generated with ssh-to-age -i ~/.ssh/id_ed25519.pub 5 | - age12zlz6lvcdk6eqaewfylg35w0syh58sm7gh53q5vvn7hd7c6nngyseftjxl # desktop 6 | - age1tm5qy7jvkhaen6s4mzf0wfmhm60w47h6mgnhl49zkettc2uye4kse0f2kj # laptop 7 | - age1qwj962m2mkzhk64t6fztw3hhh94wn82ayh9xl5u4vhajzpqa9ekqxthuaa # raspberry-pi -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [NixOS](https://nixos.org/) configuration and other dotfiles 2 | 3 | ### Credit 4 | - My [Awesome](https://awesomewm.org/) config is based on the "rainbow" theme of [awesome-copycats](https://github.com/lcpz/awesome-copycats) 5 | - My [Rofi](https://github.com/lbonn/rofi) themes are based on the "rounded" theme of [rofi-themes-collection](https://github.com/newmanls/rofi-themes-collection) 6 | - The wallpapers in `wallpapers/nixos/` are modified versions of `nix-wallpaper-nineish-dark-gray` of [nixos-artwork](https://github.com/NixOS/nixos-artwork) 7 | 8 | # Screenshots / Showcase 9 | ### [v2.0.0](https://github.com/julius-boettger/dotfiles/releases/tag/v2.0.0) 10 | https://github.com/julius-boettger/dotfiles/assets/85450899/6cf57c22-b1bf-4ba0-9eb9-cc55d3327345 11 |

12 | 13 | 14 |

15 | (also still contains the setup of v1.0.0, but with slight modifications) 16 | 17 | ### [v1.0.0](https://github.com/julius-boettger/dotfiles/releases/tag/v1.0.0) 18 | https://github.com/julius-boettger/dotfiles/assets/85450899/4f33b2a8-80b3-47ff-8cc9-b1298d3d5de2 19 |

20 | 21 | 22 |

23 | 24 | # About this repo 25 | - This repo contains configuration files I daily drive on multiple machines, including Windows ones through [WSL](https://learn.microsoft.com/en-us/windows/wsl/). Its purpose is: 26 | - providing version control for my config files 27 | - serving as documentation and inspiration for customizing your system 28 | - With this repo you get a [Flake](https://nixos.wiki/wiki/Flakes)-based [NixOS](https://nixos.org) configuration that includes... 29 | - two fully functional desktop sessions: 30 | - [Awesome](https://github.com/awesomeWM/awesome) (on Xorg) 31 | - [Hyprland](https://hyprland.org/) (on Wayland) 32 | - => See [Installation (Desktop)](#installation-desktop) 33 | - a nice [WSL](https://learn.microsoft.com/en-us/windows/wsl/) setup 34 | - => See [Installation (WSL)](#installation-wsl) 35 | - See [Content overview](#content-overview) for explanations of files and directories in this repo. 36 | - ⚠️ Basic knowledge of [NixOS](https://nixos.org/) usage, including [Nix flakes](https://nixos.wiki/wiki/Flakes), is needed for all of the provided installation guides. 37 | 38 | # Content overview 39 | 40 | ### Directory structure 41 | - `devices/` contains device-specific config 42 | - `misc/` contains... miscellaneous things 43 | - `modules/` contains Nix modules as well as config files for the software the module configures 44 | - e.g. `modules/hyprland` contains a `default.nix` to install [Hyprland](https://hyprland.org/) on [NixOS](https://nixos.org/), but also a `hyprland.conf` to configure [Hyprland](https://hyprland.org/) 45 | - `packages/` contains Nix packages that I maintain locally as they do not have an official counterpart 46 | - `wallpapers/` should be self-explanatory 47 | 48 | ### Noteworthy files 49 | 50 | | File | Description | 51 | |------|-------------| 52 | | `devices/[DEVICE]/fastfetch/` | Device-specific [fastfetch](https://github.com/fastfetch-cli/fastfetch) configurations | 53 | | `misc/update/` | Scripts to automatically update and clean up [NixOS](https://nixos.org) after a prompt every saturday | 54 | | `misc/autostart.sh` | Shell script that [Awesome](https://github.com/awesomeWM/awesome) and [Hyprland](https://hyprland.org/) run on startup | 55 | | `misc/notification.wav` | Notification sound | 56 | | `modules/alacritty/alacritty.toml` | [Alacritty](https://github.com/alacritty/alacritty) configuration | 57 | | `modules/awesome/` | [Awesome](https://github.com/awesomeWM/awesome) configuration including a custom theme based on [awesome-copycats](https://github.com/lcpz/awesome-copycats)' "rainbow" theme | 58 | | `modules/copyq/copyq.conf` | [CopyQ](https://github.com/hluk/CopyQ) configuration with custom theme | 59 | | `modules/eww/` | [Eww](https://github.com/elkowar/eww) configuration with custom widgets | 60 | | `modules/firefox/firefox.css` | `userChrome.css` for [Firefox](https://www.mozilla.org/en-US/firefox/new/) | 61 | | `modules/fish/init.fish` | `config.fish` for [Fish](https://github.com/fish-shell/fish-shell) | 62 | | `modules/gitnuro/gitnuro.json` | [Gitnuro](https://github.com/JetpackDuba/Gitnuro) theme | 63 | | `modules/hyprland/hyprland.conf` | [Hyprland](https://hyprland.org/) configuration | 64 | | `modules/jetbrains/.ideavimrc` | Like `.vimrc`, but for [IntelliJ IDEA](https://github.com/JetBrains/intellij-community) using [IdeaVim](https://github.com/JetBrains/ideavim) | 65 | | `modules/rofi/` | [Rofi](https://github.com/lbonn/rofi) (Wayland fork) themes | 66 | | `modules/sddm-sugar-candy/sddm-sugar-candy.conf` | [sddm-sugar-candy](https://github.com/Kangie/sddm-sugar-candy) configuration | 67 | | `modules/starship/starship.toml` | [Starship](https://github.com/starship/starship) configuration | 68 | | `modules/swaylock-effects/swaylock-effects.sh` | Shell script to call [Swaylock-effects](https://github.com/jirutka/swaylock-effects) with custom options | 69 | | `modules/swaync/` | [SwayNotificationCenter](https://github.com/ErikReider/SwayNotificationCenter) configuration with custom theme | 70 | | `modules/vim/.vimrc` | [Vim](https://github.com/vim/vim) configuration | 71 | | `modules/vscodium/vscodium.json` | `settings.json` for [VSCodium](https://github.com/VSCodium/vscodium) | 72 | | `wallpapers/nixos/` | [NixOS](https://nixos.org) logo wallpapers in all kinds of color combinations | 73 | 74 | # Installation (Desktop) 75 | 76 | - The following guide explains the installation of [NixOS](https://nixos.org/) with my configuration on a desktop system. 77 | - ⚠️ I try to make this config as modular and hardware independent as it makes sense for my time, but you might still have to change some things to make it work with your hardware. 78 | - If you still want to try setting this up, here you go... 79 | 80 | Download the "Minimal ISO image" of NixOS from [here](https://nixos.org/download/#nix-more), write it to a USB drive (e.g. with [USBImager](https://bztsrc.gitlab.io/usbimager/)) and boot it. If you don't have a wired internet connection, see how to set up wifi in the installer [here](https://nixos.org/manual/nixos/stable/#sec-installation-manual-networking). 81 | 82 | Next, we will continue with some commands: 83 | ```shell 84 | # you might want to change your keyboard layout, e.g. 85 | sudo loadkeys de 86 | 87 | cd /tmp 88 | # download disko disk config 89 | # you probably don't want to use my exact configuration, 90 | # see https://github.com/nix-community/disko to build your own 91 | curl -o disk-config.nix https://raw.githubusercontent.com/julius-boettger/dotfiles/main/devices/desktop/disk-config.nix 92 | # check names of available disks 93 | lsblk 94 | # adjust disk config 95 | vim disk-config.nix 96 | # run disko 97 | sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode disko /tmp/disk-config.nix 98 | # check if resulting mounts look plausible 99 | mount | grep /mnt 100 | 101 | # prepare nixos config 102 | sudo nixos-generate-config --no-filesystems --root /mnt 103 | cd /mnt/etc/nixos 104 | sudo mv /tmp/disk-config.nix . 105 | 106 | # start editing the config, keep on reading to see what you should change 107 | sudo vim configuration.nix 108 | ``` 109 | 110 | There should be a ton of commented-out code in this file that might be useful for you, feel free to comment it in. 111 | 112 | Particularly important is that your configuration contains the following: 113 | 114 | ```sh 115 | imports = [ 116 | # import disko and disk config 117 | "${builtins.fetchTarball "https://github.com/nix-community/disko/archive/master.tar.gz"}/module.nix" 118 | ./disk-config.nix 119 | # import generated hardware config 120 | ./hardware-configuration.nix 121 | ]; 122 | 123 | # set keyboard layout 124 | console.keyMap = "de"; 125 | 126 | # make sure your favorite editor is available 127 | environment.systemPackages = with pkgs; [ 128 | vim 129 | ]; 130 | ``` 131 | 132 | Save your changes and run `sudo nixos-install`. 133 | 134 | Shutdown your system, remove the USB drive and boot your newly installed operating system. 135 | 136 | Then run some more commands: 137 | 138 | ```sh 139 | # make sure git is available, e.g. with 140 | nix-shell -p git 141 | 142 | # clone this repository to obtain my configuration 143 | cd /etc 144 | # clone current commit (although you don't know what you get) 145 | git clone --recurse-submodules https://github.com/julius-boettger/dotfiles.git 146 | # clone specific release (you know what you get, but v1.0.0 might not work anymore) 147 | git clone --branch v2.0.0 --depth 1 --recurse-submodules https://github.com/julius-boettger/dotfiles.git 148 | 149 | # copy over your disk and hardware config (!) 150 | cp -f /etc/nixos/hardware-configuration.nix /etc/dotfiles/devices/desktop/ 151 | cp -f /etc/nixos/disk-config.nix /etc/dotfiles/devices/desktop/ 152 | ``` 153 | 154 | > Paths like `devices/desktop/default.nix` are referencing the content of this repo, which should now be in `/etc/dotfiles/`, so the full path in this case would be `/etc/dotfiles/devices/desktop/default.nix`. 155 | 156 | There are some files you now should take a look at and adjust them to your liking: 157 | - `variables.nix` (should explain itself) 158 | - `default.nix` and `hyprland.conf` in `devices/desktop/` contain some device- / hardware-specific configuration like setting the resolution, mounting a partition, ... You may pick and choose what seems useful to you, or just delete it. 159 | - Of course you may also want to look at and change every other file ;) 160 | 161 | ```shell 162 | # make sure the nix flake can see all your files 163 | cd /etc/dotfiles 164 | git add . 165 | 166 | # rebuild the system 167 | # after you've done this once, `flake-rebuild` should be available as a shorthand that serves the same purpose. 168 | nixos-rebuild switch --flake /etc/dotfiles#desktop --impure 169 | 170 | # set a password for your created user 171 | passwd 172 | 173 | # transfer ownership of the config to your created user to make editing it more comfortable 174 | chown -R :root /etc/dotfiles 175 | ``` 176 | 177 | Next: `reboot` for good measure. 178 | 179 | ~~Set [Gitnuro](https://github.com/JetpackDuba/Gitnuro) theme: Run Gitnuro, open the settings and click the "Open file" button next to "Custom theme". Select `modules/gitnuro/gitnuro.json` and click on "Accept".~~ (My theme is currently broken) 180 | 181 | To set a wallpaper for [SDDM](https://github.com/sddm/sddm) (the display manager) either put a `login.jpg` in `wallpapers/` or adjust the path to the wallpaper at the top of `modules/sddm-sugar-candy/sddm-sugar-candy.conf`. 182 | 183 | By default, both the Awesome and the Hyprland session use a random wallpaper out of `wallpapers/nixos/` on every reload. But there's an easy way to set up your own wallpapers on Hyprland: Put just one (or multiple!) in `wallpapers/misc/`. A random one will be selected on each reload if you have multiple. You can also configure corresponding accent colors for each wallpaper that will be used e.g. for the client border color. To do this, ajdust `modules/hyprland/wallpaper.py`. You will figure it out. 184 | 185 | If you notice that the mouse cursor looks different when hovering over some apps, try setting it with `nwg-look` (Wayland) or `lxappearance` (Xorg). 186 | 187 | And then you should be all set up! Feel free to reach out if there's something missing, misleading or incorrect in this installation guide. (Also reach out if you know how to automate any step of this setup further!) 188 | 189 | # Installation ([WSL](https://learn.microsoft.com/en-us/windows/wsl/)) 190 | 191 | > The following guide explains installation on a Windows system through [NixOS](https://nixos.org/) on [WSL](https://learn.microsoft.com/en-us/windows/wsl/). 192 | 193 | First, make sure WSL is installed and up to date: 194 | ``` 195 | wsl --install --no-distribution 196 | wsl --update 197 | ``` 198 | Also make sure to reboot your system to complete the setup (yes, that is necessary). 199 | 200 | Then [setup a NixOS distribution](https://nixos.wiki/wiki/WSL), **but** be careful when executing a command containing a path like `.\NixOS\`, you probably want to change that to an absolute path where the installed files can reside permanently, like `C:\Users\[YOUR-USER]\Documents\WSL\NixOS\`. 201 | 202 | Now enter your NixOS WSL system with `wsl -d NixOS`, or just with `wsl` if you ran `wsl --set-default NixOS` before. 203 | 204 | Run `sudo nix-channel --update`. If you run into errors like `unable to download [...]: Couldn't resolve host name`: Make sure you are not connected to some regulated company network for the rest of this guide, then edit `/etc/resolv.conf` and check that the only uncommented lines in that file are to configure nameservers, e.g. to use google nameservers: 205 | ``` 206 | nameserver 8.8.4.4 207 | nameserver 8.8.8.8 208 | ``` 209 | Then run `sudo nix-channel --update` again. 210 | 211 | Now run some more commands to setup my config: 212 | ```shell 213 | cd /etc 214 | nix-shell -p git --run "sudo git clone --recurse-submodules https://github.com/julius-boettger/dotfiles.git" 215 | ``` 216 | 217 | You now should take a look at `variables.nix`, which should explain its content itself. Of course you may also want to look at and change every other file ;) 218 | 219 | Then run some more commands: 220 | ```sh 221 | # rebuild the system 222 | # after you've done this once, `flake-rebuild` should be available as a shorthand that serves the same purpose. 223 | nix-shell -p git --run "sudo nixos-rebuild switch --flake /etc/dotfiles#wsl" 224 | 225 | # transfer ownership of the config to your created user to make editing it more comfortable 226 | chown -R :root /etc/dotfiles 227 | ``` 228 | 229 | To see the effects, exit your current WSL session (e.g. with `exit`), force WSL to shutdown (to achieve a restart) with `wsl --shutdown` and then start a new session (e.g. with `wsl -d NixOS`). 230 | 231 | You should be greeted by a nice little `fastfetch` now! 232 | 233 | At this point it should also be fine to connect to a regulated company network again, reaching the internet should still be possible. 234 | 235 | If using your companys VPN ever causes networking issues, use `vpn-start`/`vpn-stop` to start/stop [`wsl-vpnkit`](https://github.com/sakai135/wsl-vpnkit) (`vpn-status` is also available). -------------------------------------------------------------------------------- /devices/desktop/default.nix: -------------------------------------------------------------------------------- 1 | args@{ config, pkgs, variables, ... }: 2 | { 3 | imports = [ ../../modules/studies ]; 4 | 5 | local = { 6 | base.gui.full.enable = true; 7 | nvidia.enable = true; 8 | steam.enable = true; 9 | piper.enable = true; 10 | playerctl.enable = true; 11 | }; 12 | 13 | # for focusrite usb audio interface (get with `dmesg | grep Focusrite`) 14 | boot.extraModprobeConfig = "options snd_usb_audio vid=0x1235 pid=0x8211 device_setup=1"; 15 | 16 | environment.systemPackages = with pkgs; [ 17 | alsa-scarlett-gui # control center for focusrite usb audio interface 18 | liquidctl # liquid cooler control 19 | # to mount encrypted data partition 20 | zenity # password prompt 21 | cryptsetup # unlock luks 22 | dunst # send notifications 23 | ]; 24 | 25 | # remove background noise from mic 26 | programs.noisetorch.enable = true; 27 | 28 | # symlink to home folder 29 | home-manager.users.${variables.username} = { config, ... }: { 30 | home.file."Library".source = config.lib.file.mkOutOfStoreSymlink "/mnt/data/Library"; 31 | }; 32 | 33 | # monitor config with xrandr command 34 | services.xserver.displayManager.setupCommands = "${pkgs.xorg.xrandr}/bin/xrandr --output HDMI-0 --mode 1920x1080 --pos 0x100 --rate 60 --output DP-0 --mode 2560x1440 --pos 1920x0 --rate 144 --primary --preferred"; 35 | # mouse sens config 36 | services.libinput.mouse.accelSpeed = "-0.7"; 37 | 38 | systemd.services.liquidctl = { 39 | enable = true; 40 | description = "set liquid cooler pump speed curve"; 41 | serviceConfig = { 42 | User = "root"; 43 | Type = "oneshot"; 44 | ExecStart = [ 45 | "${pkgs.liquidctl}/bin/liquidctl initialize all" 46 | "${pkgs.liquidctl}/bin/liquidctl --match kraken set pump speed 30 55 40 100" 47 | ]; 48 | }; 49 | wantedBy = [ "default.target" ]; 50 | }; 51 | 52 | # openrgb 53 | services.hardware.openrgb = { 54 | enable = true; 55 | motherboard = "amd"; 56 | }; 57 | systemd.services.openrgb-sleep-wrapper = { 58 | enable = true; 59 | description = "turn off rgb before entering sleep and turn it back on when waking up"; 60 | unitConfig = { 61 | Before = "sleep.target"; 62 | StopWhenUnneeded = "yes"; 63 | }; 64 | serviceConfig = { 65 | User = variables.username; 66 | Type = "oneshot"; 67 | RemainAfterExit = "yes"; 68 | ExecStart = "-${pkgs.openrgb}/bin/openrgb -p off"; 69 | ExecStop = "-${pkgs.openrgb}/bin/openrgb -p default"; 70 | }; 71 | wantedBy = [ "sleep.target" ]; 72 | }; 73 | } -------------------------------------------------------------------------------- /devices/desktop/disk-config.nix: -------------------------------------------------------------------------------- 1 | # disk config using disko 2 | # https://github.com/nix-community/disko 3 | { 4 | disko.devices.disk = { 5 | # operating system disk 6 | nixos = { 7 | type = "disk"; 8 | device = "/dev/nvme1n1"; # newer ssd 9 | content = { 10 | type = "gpt"; 11 | partitions = { 12 | # efi system partition 13 | esp = { 14 | type = "EF00"; 15 | size = "1G"; 16 | content = { 17 | type = "filesystem"; 18 | format = "vfat"; 19 | mountpoint = "/boot"; 20 | }; 21 | }; 22 | main = { 23 | size = "100%"; 24 | content = { 25 | type = "btrfs"; 26 | extraArgs = [ "-f" ]; # override existing partition 27 | subvolumes = { 28 | "/main" = { 29 | mountpoint = "/"; 30 | swap.".swapfile".size = "8G"; 31 | }; 32 | "/home" = { 33 | mountpoint = "/home"; 34 | }; 35 | "/nix" = { 36 | mountpoint = "/nix"; 37 | # don't save last access time 38 | mountOptions = [ "noatime" ]; 39 | }; 40 | }; 41 | }; 42 | }; 43 | }; 44 | }; 45 | }; 46 | # encrypted data disk 47 | data = { 48 | type = "disk"; 49 | device = "/dev/nvme0n1"; # older ssd 50 | content = { 51 | type = "gpt"; 52 | partitions.luks = { 53 | size = "100%"; 54 | content = { 55 | type = "luks"; 56 | name = "encrypted"; 57 | askPassword = true; # set password when running disko 58 | initrdUnlock = false; # don't prompt passphrase on boot 59 | settings.allowDiscards = true; # recommended for ssd 60 | content = { 61 | type = "btrfs"; 62 | extraArgs = [ "-f" ]; 63 | }; 64 | }; 65 | }; 66 | }; 67 | }; 68 | }; 69 | } 70 | -------------------------------------------------------------------------------- /devices/desktop/fastfetch/default.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", 3 | "display": { 4 | "percent": { 5 | "type": 1 6 | } 7 | }, 8 | "modules": [ 9 | "title", 10 | "break", // empty line 11 | // software 12 | { 13 | "type": "os", 14 | "format": "{2} {8} @ {12}" 15 | }, 16 | { 17 | "type": "kernel", 18 | "format": "{1} {2}" 19 | }, 20 | "packages", 21 | "lm", 22 | "wm", 23 | "shell", 24 | "terminal", 25 | "theme", 26 | "icons", 27 | // hardware 28 | "cpu", 29 | "gpu", 30 | { 31 | "type": "board", 32 | "format": "{1}" 33 | }, 34 | "memory", 35 | { 36 | "type": "display", 37 | "preciseRefreshRate": false, 38 | "format": "{1}x{2} @ {3}Hz" 39 | }, 40 | "break", // empty line 41 | "colors" 42 | 43 | //"separator", // dotted line 44 | //"font", 45 | //"cursor", 46 | //"processes" 47 | //"chassis", 48 | //"sound", 49 | //"terminalfont", 50 | //"uptime", 51 | //"host", 52 | //// shows nothing on hyprland desktop pc 53 | //"de", 54 | //"wmtheme", 55 | //"battery", 56 | //"poweradapter", 57 | ] 58 | } -------------------------------------------------------------------------------- /devices/desktop/fastfetch/short.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", 3 | "logo": { 4 | "type": "data", 5 | "source": " \\\\ \\\\ //\n ==\\\\__\\\\/ //\n // \\\\//\n==// //==\n //\\\\___//\n// /\\\\ \\\\==\n // \\\\ \\\\" 6 | }, 7 | "modules": [ 8 | "title", 9 | { 10 | "type": "os", 11 | "format": "{3}" 12 | }, 13 | { 14 | "type": "kernel", 15 | "format": "{2}" 16 | }, 17 | "wm", 18 | { 19 | "type": "shell", 20 | "format": "{3}" 21 | }, 22 | { 23 | "type": "terminal", 24 | "format": "{5}" 25 | }, 26 | { 27 | "type": "colors", 28 | "symbol": "circle" 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /devices/desktop/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { config, lib, pkgs, modulesPath, ... }: 5 | 6 | { 7 | imports = 8 | [ (modulesPath + "/installer/scan/not-detected.nix") 9 | ]; 10 | 11 | boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ]; 12 | boot.initrd.kernelModules = [ ]; 13 | boot.kernelModules = [ "kvm-amd" ]; 14 | boot.extraModulePackages = [ ]; 15 | 16 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 17 | # (the default) this is the recommended approach. When using systemd-networkd it's 18 | # still possible to use this option, but it's recommended to use it in conjunction 19 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 20 | networking.useDHCP = lib.mkDefault true; 21 | # networking.interfaces.enp42s0.useDHCP = lib.mkDefault true; 22 | 23 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 24 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 25 | } 26 | -------------------------------------------------------------------------------- /devices/desktop/hyprland.conf: -------------------------------------------------------------------------------- 1 | #----- configure monitor setup 2 | # https://wiki.hyprland.org/Configuring/Monitors/ 3 | # configuring monitors with "bitdepth, 10" can help with screenshare, but can also cause issues for screenshot/screenshare, try it out yourself. 4 | # see https://gist.github.com/PowerBall253/2dea6ddf6974ba4e5d26c3139ffb7580?permalink_comment_id=4720563#gistcomment-4720563 5 | # and https://github.com/hyprwm/Hyprland/issues/4791 6 | 7 | monitor = HDMI-A-1, 1920x1080@60, 0x0, 1#, bitdepth, 10 8 | monitor = DP-1, 2560x1440@144, 1920x0, 1#, bitdepth, 10 9 | 10 | # hide buggy nonexistent monitor 11 | monitor = Unknown-1, disabled 12 | 13 | #----- nvidia gpu config 14 | env = LIBVA_DRIVER_NAME,nvidia 15 | env = XDG_SESSION_TYPE,wayland 16 | env = GBM_BACKEND,nvidia-drm 17 | env = __GLX_VENDOR_LIBRARY_NAME,nvidia 18 | # attempt to fix cursor showing on screenshots 19 | cursor:use_cpu_buffer = true 20 | 21 | #----- input settings 22 | input { 23 | sensitivity = -0.7 24 | } 25 | 26 | #----- key binds 27 | # mount encrypted data partition 28 | bind = SUPER CTRL SHIFT, M, exec, /etc/dotfiles/devices/desktop/mount-data.sh -------------------------------------------------------------------------------- /devices/desktop/mount-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # luks encrypted data partition 4 | partition="disk/by-uuid/4a4090eb-701d-4eb3-bb9f-d417091c872f" 5 | 6 | # exit early if already unlocked and mounted 7 | mount | grep "/dev/mapper/data on /mnt/data" 8 | if [[ $? == 0 ]]; then 9 | dunstify "already mounted" "encrypted data partition" 10 | exit 11 | fi 12 | 13 | # gui prompt passphrase 14 | passphrase=$(zenity --entry --title="Mount encrypted data partition" --text="Enter passphrase:" --hide-text) 15 | # exit if prompt was canceled 16 | if [[ $? != 0 ]]; then exit; fi 17 | 18 | # gui prompt password 19 | password=$(zenity --password) 20 | # exit if prompt was canceled 21 | if [[ $? != 0 ]]; then exit; fi 22 | # test if password is correct 23 | echo -n $password | sudo -S true 24 | if [[ $? != 0 ]]; then 25 | dunstify "mount failed" "password incorrect" 26 | exit 27 | fi 28 | # sudo should now just work for some time, 29 | # as it was executed succesfully once 30 | 31 | # try to unlock partition 32 | echo -n $passphrase | sudo cryptsetup luksOpen /dev/$partition data 33 | if [[ $? != 0 ]]; then 34 | dunstify "mount failed" "passphrase of encrypted data partition incorrect" 35 | exit 36 | fi 37 | 38 | # try to mount partition 39 | sudo mount /dev/mapper/data /mnt/data 40 | if [[ $? != 0 ]]; then 41 | dunstify "mount failed" "at actual mount of unlocked partition" 42 | fi 43 | 44 | dunstify "mount successful" "of encrypted data partition" -------------------------------------------------------------------------------- /devices/laptop/.gitignore: -------------------------------------------------------------------------------- 1 | /copilot.png 2 | -------------------------------------------------------------------------------- /devices/laptop/default.nix: -------------------------------------------------------------------------------- 1 | args@{ pkgs, inputs, device, ... }: 2 | let 3 | mesa-pkgs = 4 | pkgs; 5 | #inputs.hyprland.inputs.nixpkgs.legacyPackages.${device.system}; 6 | in 7 | { 8 | local = { 9 | base.gui.full.enable = true; 10 | base.laptop.enable = true; 11 | steam.enable = true; 12 | }; 13 | 14 | # monitor config with xrandr command 15 | services.xserver.displayManager.setupCommands = "${pkgs.xorg.xrandr}/bin/xrandr --output eDP --mode 1920x1200 --rate 120"; 16 | 17 | # amd gpu 18 | hardware.amdgpu.initrd.enable = true; 19 | hardware.graphics = { 20 | package = mesa-pkgs .mesa; 21 | package32 = mesa-pkgs.pkgsi686Linux.mesa; 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /devices/laptop/disk-config.nix: -------------------------------------------------------------------------------- 1 | # disk config using disko 2 | # https://github.com/nix-community/disko 3 | { 4 | disko.devices.disk.main = { 5 | type = "disk"; 6 | device = "/dev/nvme0n1"; 7 | content = { 8 | type = "gpt"; 9 | partitions = { 10 | # efi system partition 11 | esp = { 12 | type = "EF00"; 13 | size = "1G"; 14 | content = { 15 | type = "filesystem"; 16 | format = "vfat"; 17 | mountpoint = "/boot"; 18 | }; 19 | }; 20 | luks = { 21 | size = "100%"; 22 | content = { 23 | type = "luks"; 24 | name = "encrypted"; 25 | askPassword = true; # set password when running disko 26 | settings.allowDiscards = true; # recommended for ssd 27 | content = { 28 | type = "btrfs"; 29 | extraArgs = [ "-f" ]; # override existing partition 30 | subvolumes = { 31 | "/main" = { 32 | mountpoint = "/"; 33 | swap.".swapfile".size = "4G"; 34 | }; 35 | "/home" = { 36 | mountpoint = "/home"; 37 | }; 38 | "/nix" = { 39 | mountpoint = "/nix"; 40 | # don't save last access time 41 | mountOptions = [ "noatime" ]; 42 | }; 43 | }; 44 | }; 45 | }; 46 | }; 47 | }; 48 | }; 49 | }; 50 | } -------------------------------------------------------------------------------- /devices/laptop/fastfetch/default.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", 3 | "display": { 4 | "percent": { 5 | "type": 1 6 | } 7 | }, 8 | "modules": [ 9 | "title", 10 | "break", // empty line 11 | "host", 12 | // software 13 | { 14 | "type": "os", 15 | "format": "{2} {8} @ {12}" 16 | }, 17 | { 18 | "type": "kernel", 19 | "format": "{1} {2}" 20 | }, 21 | "packages", 22 | "lm", 23 | "wm", 24 | "shell", 25 | "terminal", 26 | "theme", 27 | "icons", 28 | // hardware 29 | { 30 | "type": "board", 31 | "format": "{1}" 32 | }, 33 | "cpu", 34 | "gpu", 35 | "memory", 36 | { 37 | "type": "display", 38 | "preciseRefreshRate": false, 39 | "format": "{1}x{2} @ {3}Hz" 40 | }, 41 | "break", // empty line 42 | "colors" 43 | 44 | //"separator", // dotted line 45 | //"font", 46 | //"cursor", 47 | //"processes" 48 | //"chassis", 49 | //"sound", 50 | //"terminalfont", 51 | //"uptime", 52 | //"de", 53 | //"wmtheme", 54 | //"battery", 55 | //"poweradapter", 56 | ] 57 | } -------------------------------------------------------------------------------- /devices/laptop/fastfetch/short.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", 3 | "logo": { 4 | "type": "data", 5 | "source": " \\\\ \\\\ //\n ==\\\\__\\\\/ //\n // \\\\//\n==// //==\n //\\\\___//\n// /\\\\ \\\\==\n // \\\\ \\\\" 6 | }, 7 | "display": { 8 | "size": { 9 | "binaryPrefix": "si" 10 | }, 11 | "percent": { 12 | "type": 1, 13 | "color": { 14 | "green": "white", 15 | "yellow": "white", 16 | "red": "white" 17 | } 18 | } 19 | }, 20 | "modules": [ 21 | "title", 22 | { 23 | "type": "os", 24 | "format": "{3}" 25 | }, 26 | { 27 | "type": "kernel", 28 | "format": "{2}" 29 | }, 30 | "wm", 31 | { 32 | "type": "shell", 33 | "format": "{3}" 34 | }, 35 | { 36 | "type": "battery", 37 | "format": "{4}", 38 | "key": "Battery" 39 | }, 40 | { 41 | "type": "colors", 42 | "symbol": "circle" 43 | } 44 | ] 45 | } -------------------------------------------------------------------------------- /devices/laptop/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { config, lib, pkgs, modulesPath, ... }: 5 | 6 | { 7 | imports = 8 | [ (modulesPath + "/installer/scan/not-detected.nix") 9 | ]; 10 | 11 | boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usbhid" "usb_storage" "sd_mod" ]; 12 | boot.initrd.kernelModules = [ ]; 13 | boot.kernelModules = [ "kvm-amd" ]; 14 | boot.extraModulePackages = [ ]; 15 | 16 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 17 | # (the default) this is the recommended approach. When using systemd-networkd it's 18 | # still possible to use this option, but it's recommended to use it in conjunction 19 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 20 | networking.useDHCP = lib.mkDefault true; 21 | # networking.interfaces.wlp97s0.useDHCP = lib.mkDefault true; 22 | 23 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 24 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 25 | } 26 | -------------------------------------------------------------------------------- /devices/laptop/hyprland.conf: -------------------------------------------------------------------------------- 1 | monitor = eDP-1, 1920x1200@120, 0x0, 1 2 | #monitor = eDP-1, 2880x1800@120, 0x0, 1.5 3 | 4 | # mirror to unconfigured monitors 5 | monitor = , preferred, auto, 1, mirror, eDP-1 6 | 7 | # override with config generated by nwg-displays 8 | source = ~/.config/hypr/monitors.conf 9 | 10 | # adjust keyboard backlight brightness (holdable) 11 | binde = SUPER CTRL SHIFT, down, exec, brightnessctl -d platform::kbd_backlight s 1- 12 | binde = SUPER CTRL SHIFT, up , exec, brightnessctl -d platform::kbd_backlight s 1+ 13 | 14 | ### copilot key 15 | # open ai chat 16 | #bind = SUPER SHIFT, code:201, exec, xdg-open https://chatgpt.com 17 | # open fullscreen image 18 | bind = SUPER SHIFT, code:201, exec, [fullscreen] qview /etc/dotfiles/devices/laptop/copilot.png 19 | 20 | input { 21 | touchpad { 22 | scroll_factor = 0.2 23 | natural_scroll = true 24 | } 25 | } -------------------------------------------------------------------------------- /devices/raspberry-pi/default.nix: -------------------------------------------------------------------------------- 1 | args@{ pkgs, ... }: 2 | { 3 | imports = [ ../../modules/base/raspberry-pi.nix ]; 4 | 5 | # static ipv4 address over ethernet 6 | networking = { 7 | interfaces.end0.ipv4.addresses = [ { 8 | address = "192.168.178.254"; 9 | prefixLength = 24; 10 | } ]; 11 | # copied from automatically configured values 12 | nameservers = [ "192.168.178.1" ]; 13 | defaultGateway = { 14 | address = "192.168.178.1"; 15 | interface = "end0"; 16 | metric = 100; 17 | }; 18 | }; 19 | 20 | local = { 21 | # host some stuff 22 | #blocky.enable = true; 23 | website.enable = true; 24 | #ai-chatbot.enable = true; 25 | lamp-server.enable = true; 26 | minecraft-server.enable = true; 27 | obsidian-livesync.enable = true; 28 | }; 29 | 30 | environment.systemPackages = with pkgs; [ 31 | htop # process viewer 32 | # monitor networking 33 | bmon 34 | nload 35 | ]; 36 | } -------------------------------------------------------------------------------- /devices/raspberry-pi/fastfetch/default.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", 3 | "display": { 4 | "size": { 5 | "binaryPrefix": "si" 6 | }, 7 | "percent": { 8 | "type": 1, 9 | "color": { 10 | "green": "white", 11 | "yellow": "white", 12 | "red": "white" 13 | } 14 | } 15 | }, 16 | "modules": [ 17 | "break", // empty line 18 | "break", // empty line 19 | 20 | "title", 21 | "break", // empty line 22 | // software 23 | "host", 24 | { 25 | "type": "os", 26 | "format": "{2} {8} @ {12}" 27 | }, 28 | { 29 | "type": "kernel", 30 | "format": "{1} {2}" 31 | }, 32 | "packages", 33 | "shell", 34 | "lm", 35 | "processes", 36 | "uptime", 37 | // hardware 38 | "cpu", 39 | { 40 | "type": "board", 41 | "format": "{1}" 42 | }, 43 | "memory", 44 | { 45 | "type": "display", 46 | "preciseRefreshRate": false, 47 | "format": "{1}x{2} @ {3}Hz" 48 | }, 49 | "disk", 50 | "break", // empty line 51 | "colors" 52 | 53 | //// boring 54 | //"separator", // dotted line 55 | //"terminal", 56 | 57 | //// shows nothing on raspberry pi 58 | //"battery", 59 | //"terminalfont", 60 | //"theme", 61 | //"icons", 62 | //"wm", 63 | //"sound", 64 | //"gpu", 65 | //"font", 66 | //"cursor", 67 | //"chassis", 68 | //"de", 69 | //"wmtheme", 70 | //"poweradapter" 71 | ] 72 | } 73 | -------------------------------------------------------------------------------- /devices/raspberry-pi/fastfetch/short.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", 3 | "logo": { 4 | "type": "data", 5 | "source": " \\\\ \\\\ //\n ==\\\\__\\\\/ //\n // \\\\//\n==// //==\n //\\\\___//\n// /\\\\ \\\\==\n // \\\\ \\\\" 6 | }, 7 | "display": { 8 | "size": { 9 | "binaryPrefix": "si" 10 | }, 11 | "percent": { 12 | "type": 1, 13 | "color": { 14 | "green": "white", 15 | "yellow": "white", 16 | "red": "white" 17 | } 18 | } 19 | }, 20 | "modules": [ 21 | "title", 22 | 23 | "host", 24 | { 25 | "type": "os", 26 | "format": "{2} {8} @ {12}" 27 | }, 28 | { 29 | "type": "kernel", 30 | "format": "{2}" 31 | }, 32 | "memory", 33 | "disk", 34 | 35 | { 36 | "type": "colors", 37 | "symbol": "circle" 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /devices/wsl/default.nix: -------------------------------------------------------------------------------- 1 | args@{ lib, pkgs, inputs, variables, ... }: 2 | { 3 | imports = [ 4 | inputs.nixos-wsl.nixosModules.wsl 5 | inputs.vscode-server.nixosModules.default 6 | ]; 7 | 8 | wsl = { 9 | enable = true; 10 | defaultUser = variables.username; 11 | }; 12 | 13 | # usually enabled in modules/base/default.nix, doesnt work here 14 | boot.loader.systemd-boot.enable = lib.mkForce false; 15 | 16 | # for issues with company network/vpn 17 | local.wsl-vpnkit.enable = true; 18 | 19 | # git gui (yes, that works with wsl!) 20 | local.gitnuro.enable = true; 21 | 22 | # automatic nix garbage collect 23 | programs.nh.clean.dates = "daily"; 24 | 25 | # connect vscode on windows to nixos wsl 26 | # https://github.com/nix-community/nixos-vscode-server/issues/70 27 | services.vscode-server = { 28 | enable = true; 29 | nodejsPackage = pkgs.nodePackages_latest.nodejs; 30 | }; 31 | } -------------------------------------------------------------------------------- /devices/wsl/fastfetch/default.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", 3 | "display": { 4 | "size": { 5 | "binaryPrefix": "si" 6 | }, 7 | "percent": { 8 | "type": 1, 9 | "color": { 10 | "green": "white", 11 | "yellow": "white", 12 | "red": "white" 13 | } 14 | } 15 | }, 16 | "modules": [ 17 | "title", 18 | "break", // empty line 19 | // software 20 | { 21 | "type": "os", 22 | "format": "{2} {8} @ {12}" 23 | }, 24 | { 25 | "type": "kernel", 26 | "format": "{1} {2}" 27 | }, 28 | "host", 29 | "packages", 30 | "shell", 31 | "terminal", 32 | "terminalfont", 33 | "theme", 34 | "icons", 35 | // hardware 36 | "cpu", 37 | { 38 | "type": "board", 39 | "format": "{1}" 40 | }, 41 | "memory", 42 | { 43 | "type": "display", 44 | "preciseRefreshRate": false, 45 | "format": "{1}x{2} @ {3}Hz" 46 | }, 47 | "battery", 48 | "break", // empty line 49 | "colors" 50 | 51 | //"separator", // dotted line 52 | //"lm", 53 | //"wm", 54 | //"processes", 55 | //"sound", 56 | //"uptime" 57 | //"gpu", 58 | //// shows nothing on wsl 59 | //"font", 60 | //"cursor", 61 | //"chassis", 62 | //"de", 63 | //"wmtheme", 64 | //"poweradapter" 65 | ] 66 | } -------------------------------------------------------------------------------- /devices/wsl/fastfetch/short.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", 3 | "logo": { 4 | "type": "data", 5 | "source": " \\\\ \\\\ //\n ==\\\\__\\\\/ //\n // \\\\//\n==// //==\n //\\\\___//\n// /\\\\ \\\\==\n // \\\\ \\\\" 6 | }, 7 | "display": { 8 | "size": { 9 | "binaryPrefix": "si" 10 | }, 11 | "percent": { 12 | "type": 1, 13 | "color": { 14 | "green": "white", 15 | "yellow": "white", 16 | "red": "white" 17 | } 18 | } 19 | }, 20 | "modules": [ 21 | "break", 22 | "title", 23 | { 24 | "type": "os", 25 | "format": "{3}" 26 | }, 27 | "shell", 28 | { 29 | "type": "battery", 30 | "format": "{4}" 31 | }, 32 | { 33 | "type": "colors", 34 | "symbol": "circle" 35 | } 36 | //{ 37 | // "key": "Font", 38 | // "type": "terminalfont", 39 | // "format": "{2}" 40 | //}, 41 | //{ 42 | // "type": "memory", 43 | // "format": "{3} ({1})" 44 | //}, 45 | //{ 46 | // "type": "kernel", 47 | // "format": "{2}" 48 | //}, 49 | //{ 50 | // "type": "terminal", 51 | // "format": "{5}" 52 | //}, 53 | ] 54 | } -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | # entry point of my nixos configuration 2 | { 3 | inputs = { 4 | # main inputs for packages update channel version here vvvvv (see variables.nix for state version) 5 | nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-25.05"; 6 | home-manager = { url = "github:nix-community/home-manager?ref=release-25.05"; 7 | inputs.nixpkgs.follows = "nixpkgs"; }; 8 | # for occasional unstable packages 9 | nixpkgs-unstable.url = "github:nixos/nixpkgs?ref=nixos-unstable"; 10 | # run nixos on raspberry pi 11 | raspberry-pi-nix.url = "github:nix-community/raspberry-pi-nix?ref=v0.4.1"; 12 | # nixpkgs to avoid expensive cache misses of couchdb and dependencies on aarch64 13 | couchdb-aarch64-nixpkgs.url = "github:nixos/nixpkgs?rev=71a6392e367b08525ee710a93af2e80083b5b3e2"; 14 | # control govee rgb lamp 15 | lamp-server.url = "github:julius-boettger/lamp-server-rust"; 16 | # host minecraft server 17 | nix-minecraft.url = "github:Infinidoge/nix-minecraft"; 18 | # hyprland (to manage version independently of other packages) 19 | hyprland.url = "git+https://github.com/hyprwm/Hyprland?submodules=1&ref=refs/tags/v0.49.0"; 20 | # hyprland plugin for better multi-monitor workspaces, matching hyprland version: ^v^v^v^ 21 | hyprsplit = { url = "github:shezdy/hyprsplit?ref=v0.49.0"; 22 | inputs.hyprland.follows = "hyprland"; }; 23 | # nix user repository (more packages) 24 | nur = { url = "github:nix-community/NUR"; 25 | inputs.nixpkgs.follows = "nixpkgs"; }; 26 | # secret management with sops 27 | sops-nix = { url = "github:Mic92/sops-nix"; 28 | inputs.nixpkgs.follows = "nixpkgs"; }; 29 | # host own website 30 | website = { url = "github:julius-boettger/website"; 31 | inputs.nixpkgs.follows = "nixpkgs"; }; 32 | # declarative disk management 33 | disko = { url = "github:nix-community/disko"; 34 | inputs.nixpkgs.follows = "nixpkgs"; }; 35 | # declarative database for command-not-found 36 | programs-sqlite = { url = "github:wamserma/flake-programs-sqlite"; 37 | inputs.nixpkgs.follows = "nixpkgs-unstable"; }; 38 | # wsl utils 39 | nixos-wsl = { url = "github:nix-community/NixOS-WSL"; 40 | inputs.nixpkgs.follows = "nixpkgs"; }; 41 | # to connect vscode on windows with nixos wsl 42 | vscode-server = { url = "github:nix-community/nixos-vscode-server"; 43 | inputs.nixpkgs.follows = "nixpkgs"; }; 44 | # declarative discord config 45 | nixcord = { url = "github:kaylorben/nixcord"; 46 | inputs.nixpkgs.follows = "nixpkgs"; }; 47 | # for more vscode extensions 48 | nix-vscode-extensions = { url = "github:nix-community/nix-vscode-extensions"; 49 | inputs.nixpkgs.follows = "nixpkgs-unstable"; }; 50 | # zen browser 51 | zenix = { url = "github:anders130/zenix"; 52 | inputs.nixpkgs.follows = "nixpkgs"; 53 | inputs.home-manager.follows = "home-manager"; }; 54 | }; 55 | 56 | # take inputs as arguments 57 | outputs = inputs@{ self, ... }: 58 | let 59 | variables = import ./variables.nix; 60 | 61 | ### process nixosConfigs in variables.nix 62 | # map a high-level attribute set to a lib.nixosSystem 63 | mkNixosConfig = device@{ 64 | ### required 65 | # name of corresponding device directory, e.g. "desktop" for ./devices/desktop/ 66 | internalName, 67 | ### optional 68 | # device architecture 69 | system ? "x86_64-linux", 70 | # networking hostname 71 | hostName ? "nixos", 72 | }: 73 | let 74 | # config to use for all nixpkgs 75 | pkgs-config = { 76 | inherit system; 77 | config.allowUnfree = true; 78 | 79 | # for open-webui on aarch64 https://github.com/NixOS/nixpkgs/issues/312068#issuecomment-2365236799 80 | overlays = [( _: prev: { pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [( _: python-prev: { 81 | rapidocr-onnxruntime = python-prev.rapidocr-onnxruntime.overridePythonAttrs (self: { 82 | pythonImportsCheck = if python-prev.stdenv.isAarch64 then [] else ["rapidocr_onnxruntime"]; 83 | doCheck = !(python-prev.stdenv.isAarch64); 84 | meta = self.meta // { badPlatforms = []; }; 85 | }); 86 | chromadb = python-prev.chromadb.overridePythonAttrs (self: { 87 | pythonImportsCheck = if python-prev.stdenv.isAarch64 then [] else ["chromadb"]; 88 | doCheck = !(python-prev.stdenv.isAarch64); 89 | meta = self.meta // { broken = false; }; 90 | }); 91 | })]; })]; 92 | }; 93 | 94 | pkgs = import inputs.nixpkgs pkgs-config; 95 | pkgs-unstable = import inputs.nixpkgs-unstable pkgs-config; 96 | pkgs-local = import ./packages { inherit pkgs; }; 97 | 98 | # add some helper functions to lib 99 | lib = inputs.nixpkgs.lib.extend (final: prev: inputs.home-manager.lib // { 100 | getNixpkgs = input: import inputs.${input} pkgs-config; 101 | getPkgs = input: inputs.${input}.packages.${system}; 102 | writeScript = pkgs.writeShellScriptBin; 103 | writeScriptFile = name: path: pkgs.writeShellScriptBin name (builtins.readFile(path)); 104 | importIfExists = path: if builtins.pathExists path then import path else {}; 105 | mkModule = name: currentConfig: newConfig: { 106 | # apply newConfig if module is enabled in currentConfig 107 | options.local.${name}.enable = lib.mkEnableOption "whether to enable ${name}"; 108 | config = lib.mkIf currentConfig.local.${name}.enable newConfig; 109 | }; 110 | }); 111 | 112 | # attributes of this set can be taken as function arguments in modules like modules/base/default.nix 113 | specialArgs = { 114 | inherit inputs variables lib; 115 | # device specific variables (with weird fix for optionals) 116 | device = { inherit system hostName; } // device; 117 | }; 118 | in 119 | lib.nixosSystem { 120 | # make specialArgs available for nixos system 121 | inherit system specialArgs; 122 | # include nix config 123 | modules = [ 124 | # module definitions with some default config 125 | ./modules 126 | # for specific device 127 | ./devices/${internalName} 128 | (lib.importIfExists ./devices/${internalName}/hardware-configuration.nix) 129 | (lib.importIfExists ./devices/${internalName}/disk-config.nix) 130 | # make some options available 131 | inputs.disko.nixosModules.disko # disk management 132 | inputs.nur.modules.nixos.default # NUR package overlay 133 | inputs.home-manager.nixosModules.home-manager 134 | { 135 | # make specialArgs available for home manager 136 | home-manager.extraSpecialArgs = specialArgs; 137 | # package overlays (only for stable nixpkgs) 138 | nixpkgs.overlays = [ 139 | (final: prev: { 140 | /*pkgs.*/unstable = pkgs-unstable; 141 | /*pkgs.*/local = pkgs-local; 142 | }) 143 | # for specific device 144 | (if builtins.pathExists ./devices/${internalName}/overlays.nix 145 | then import ./devices/${internalName}/overlays.nix specialArgs 146 | else _: _: {}) 147 | # from inputs 148 | inputs.zenix.overlays.default 149 | inputs.nix-vscode-extensions.overlays.default 150 | ]; 151 | } 152 | ]; 153 | }; 154 | # take a nixosConfigs list like 155 | # [{ internalName="desktop"; hostName="nixos"; }] 156 | # then maps each config to a set using internalName like 157 | # { "desktop"={ internalName="desktop"; hostName="nixos; }; } 158 | # then maps each set to a lib.nixosSystem using mkNixosConfig like 159 | # { "desktop"=lib.nixosSystem {...}; } 160 | mkNixosConfigs = nixosConfigs: 161 | builtins.mapAttrs (ignored: namedConfig: mkNixosConfig namedConfig) ( 162 | builtins.listToAttrs ( 163 | builtins.map (config: { 164 | value = config; 165 | name = config.internalName; 166 | }) nixosConfigs 167 | ) 168 | ); 169 | in 170 | { 171 | nixosConfigurations = variables.nixosConfigs { inherit mkNixosConfigs inputs; }; 172 | }; 173 | } 174 | -------------------------------------------------------------------------------- /misc/autostart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # only run commands if they are not running 4 | run_once() { 5 | # if there is no process running under the name [first argument] 6 | if ! pgrep -f "$1"; then 7 | "$@" & # execute all arguments 8 | fi 9 | } 10 | 11 | ### only run some commands on xorg 12 | # check if number of arguments is >= 1 13 | if [ $# -ge 1 ]; then 14 | if [ "$1" = "xorg" ]; then 15 | # focus primary screen on awesome 16 | printf "awful=require('awful')\nawful.screen.focus(1)" | awesome-client & 17 | run_once unclutter --start-hidden --jitter 0 --timeout 3 18 | run_once nm-applet 19 | fi 20 | fi 21 | 22 | ### run display server agnostic commands 23 | # run programs in background 24 | run_once lxpolkit > /dev/null 25 | run_once flameshot # not necessary, but makes startup faster 26 | 27 | # running with "run_once" is kind of not reliable + 28 | # has built-in prevention for running more than once 29 | copyq --start-server hide &> /dev/null & 30 | 31 | # set default rgb profile (nothing happens if the command is not found) 32 | openrgb --profile default > /dev/null & 33 | 34 | ### set up virtual microphone with noise reduction 35 | NOISETORCH_MIC="alsa_input.usb-Focusrite_Scarlett_Solo_USB_Y7BVH9Y0B69B0A-00.HiFi__Mic1__source" 36 | set_mic() { 37 | # set $1 as default mic with 100% volume using wireplumber id 38 | id=$(wpctl status | sed '/Sources:/,$ { /Streams:/q; p }' | grep -m 1 "$1" | sed "s/[^0-9]*\([0-9]\{2,\}\).*/\1/") 39 | if [ -z "$id" ]; then 40 | echo "couldnt get id for microphone '$1'" 41 | return 42 | fi 43 | wpctl set-default $id 44 | wpctl set-volume $id 100% 45 | } 46 | # only execute if noisetorch is not yet active (grep finds <= 1 results) 47 | if [ "$(wpctl status | grep -c 'NoiseTorch Microphone')" -le 1 ]; then 48 | # wait for mics to be detected correctly 49 | sleep 1 50 | # default mic (source) to apply noise reduction to 51 | set_mic $NOISETORCH_MIC 52 | # init noisetorch for default mic 53 | noisetorch -i 54 | if [[ $? == 0 ]]; then 55 | echo "noisetorch activated" 56 | else 57 | echo "noisetorch couldnt be activated" 58 | fi 59 | # set noisetorch mic as default 60 | set_mic "NoiseTorch Microphone" 61 | else 62 | echo "noisetorch already active" 63 | fi -------------------------------------------------------------------------------- /misc/notification.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/misc/notification.wav -------------------------------------------------------------------------------- /misc/update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | 3 | nix flake update --flake /etc/dotfiles 4 | 5 | set_color green 6 | echo "inputs updated." 7 | set_color white 8 | 9 | flake-rebuild $argv 10 | if test $status != 0 11 | exit 12 | end 13 | 14 | set_color green 15 | echo "rebuild completed." 16 | set_color white 17 | 18 | read --silent --prompt-str "reboot? (y/n) " -n 1 response 19 | if test "$response" != "y" 20 | echo "okay :( you should reboot though! but maybe later :)" 21 | exit 22 | end 23 | 24 | reboot -------------------------------------------------------------------------------- /modules/ai-chatbot.nix: -------------------------------------------------------------------------------- 1 | # self-hosted alternative to chatgpt with ollama + open-webui 2 | args@{ config, lib, pkgs, ... }: 3 | let 4 | frontendPort = 3210; 5 | backendPort = 11434; # ollama default 6 | in 7 | lib.mkModule "ai-chatbot" config { 8 | 9 | services.ollama = { 10 | enable = true; 11 | port = backendPort; 12 | package = pkgs.unstable.ollama; 13 | loadModels = [ 14 | "deepseek-r1:8b" 15 | "qwen2.5:7b" 16 | "mistral:7b" 17 | "gemma3:4b" 18 | "qwen2.5:0.5b" 19 | ]; 20 | environmentVariables = { 21 | # only keep last x models in ram 22 | OLLAMA_MAX_LOADED_MODELS = "2"; 23 | # only keep last x conversations in ram 24 | OLLAMA_NUM_PARALLEL = "1"; 25 | # dont auto-unload models 26 | OLLAMA_KEEP_ALIVE = "-1"; 27 | }; 28 | }; 29 | 30 | services.open-webui = { 31 | enable = true; 32 | port = frontendPort; 33 | package = pkgs.unstable.open-webui; 34 | environment = { 35 | OLLAMA_BASE_URL = "http://127.0.0.1:${toString backendPort}"; 36 | TASK_MODEL = "qwen2.5:0.5b"; # model for generating chat titles, ... 37 | ENABLE_TAGS_GENERATION = "False"; 38 | ENABLE_RETRIEVAL_QUERY_GENERATION = "False"; 39 | ENABLE_SEARCH_QUERY_GENERATION = "False"; 40 | ENABLE_AUTOCOMPLETE_GENERATION = "False"; 41 | }; 42 | }; 43 | 44 | local.website.extraConfig = '' 45 | chat.juliusboettger.com { 46 | reverse_proxy :${toString frontendPort} 47 | } 48 | ''; 49 | } -------------------------------------------------------------------------------- /modules/alacritty/alacritty.toml: -------------------------------------------------------------------------------- 1 | # color scheme based on vscodium theme "monokai pro (filter spectrum)" 2 | [colors.primary] 3 | background = "#262527" 4 | foreground = "#F7F1FF" 5 | [colors.normal] 6 | black = "#262527" 7 | blue = "#5AA0E6" 8 | cyan = "#5AD4E6" 9 | green = "#7BD88F" 10 | magenta = "#948AE3" 11 | red = "#FC618D" 12 | white = "#F7F1FF" 13 | yellow = "#FD9353" 14 | [colors.bright] 15 | black = "#99979B" 16 | blue = "#2180DE" 17 | cyan = "#37CBE1" 18 | green = "#4ECA69" 19 | magenta = "#7C6FDC" 20 | red = "#FB376F" 21 | white = "#FFFFFF" 22 | yellow = "#FD721C" 23 | 24 | [font.normal] 25 | family = "JetBrainsMonoNL Nerd Font" 26 | style = "Regular" 27 | [font.italic] 28 | style = "Italic" 29 | [font.bold] 30 | style = "Bold" 31 | [font.bold_italic] 32 | style = "Bold Italic" 33 | 34 | [env] 35 | # fix interactive features on remote ssh sessions that dont know about alacritty 36 | TERM = "xterm-256color" 37 | 38 | [scrolling] 39 | multiplier = 5 40 | 41 | [window] 42 | dynamic_title = true 43 | opacity = 0.35 44 | 45 | [window.padding] 46 | x = 7 47 | y = 7 -------------------------------------------------------------------------------- /modules/alacritty/default.nix: -------------------------------------------------------------------------------- 1 | # terminal 2 | args@{ config, lib, pkgs, variables, ... }: 3 | lib.mkModule "alacritty" config { 4 | environment.systemPackages = [ pkgs.unstable.alacritty ]; 5 | 6 | # make some stuff in alacritty look better...? probably subjective 7 | fonts.fontconfig = { 8 | subpixel.rgba = "vrgb"; 9 | hinting.style = "full"; # may cause loss of shape, try lower value? 10 | }; 11 | 12 | # symlink config to ~/.config 13 | home-manager.users.${variables.username} = { config, ... }: { 14 | xdg.configFile."alacritty/alacritty.toml".source = 15 | config.lib.file.mkOutOfStoreSymlink "/etc/dotfiles/modules/alacritty/alacritty.toml"; 16 | }; 17 | } -------------------------------------------------------------------------------- /modules/awesome/default.nix: -------------------------------------------------------------------------------- 1 | # xorg tiling window manager 2 | args@{ config, lib, variables, ... }: 3 | lib.mkModule "awesome" config { 4 | services.xserver = { 5 | enable = true; 6 | xkb.layout = config.console.keyMap; 7 | windowManager.awesome.enable = true; 8 | }; 9 | 10 | # symlink config to ~/.config 11 | home-manager.users.${variables.username} = { config, ... }: { 12 | xdg.configFile."awesome" = { 13 | source = config.lib.file.mkOutOfStoreSymlink "/etc/dotfiles/modules/awesome"; 14 | recursive = true; 15 | }; 16 | }; 17 | } -------------------------------------------------------------------------------- /modules/awesome/themes/mytheme/icons/awesome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/modules/awesome/themes/mytheme/icons/awesome.png -------------------------------------------------------------------------------- /modules/awesome/themes/mytheme/icons/cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/modules/awesome/themes/mytheme/icons/cpu.png -------------------------------------------------------------------------------- /modules/awesome/themes/mytheme/icons/mem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/modules/awesome/themes/mytheme/icons/mem.png -------------------------------------------------------------------------------- /modules/awesome/themes/mytheme/icons/square_sel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/modules/awesome/themes/mytheme/icons/square_sel.png -------------------------------------------------------------------------------- /modules/awesome/themes/mytheme/icons/square_unsel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/modules/awesome/themes/mytheme/icons/square_unsel.png -------------------------------------------------------------------------------- /modules/awesome/themes/mytheme/icons/submenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/modules/awesome/themes/mytheme/icons/submenu.png -------------------------------------------------------------------------------- /modules/awesome/themes/mytheme/theme.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 3 | Theme of github.com/julius-boettger 4 | Based on: Rainbow Awesome WM theme 2.0 of github.com/lcpz 5 | 6 | --]] 7 | 8 | -- color scheme based on vscode theme "monokai pro (filter spectrum)" 9 | local colors = { 10 | r = "#FC618D", 11 | g = "#7BD88F", 12 | y = "#FD9353", 13 | b = "#5AA0E6", 14 | m = "#948AE3", 15 | c = "#5AD4E6" 16 | } 17 | 18 | -- available .png wallpapers in themedir/wallpapers/ 19 | local wallpapers = { 20 | "rg", "gr", 21 | "ry", "yr", 22 | "rb", "br", 23 | "rm", "mr", 24 | "rc", "cr", 25 | "gy", "yg", 26 | "gb", "bg", 27 | "gm", "mg", 28 | "gc", "cg", 29 | "yb", "by", 30 | "ym", "my", 31 | "yc", "cy", 32 | "bm", "mb", 33 | "bc", "cb", 34 | "mc", "cm", 35 | } 36 | 37 | -- set random seed based on time 38 | math.randomseed(os.time()) 39 | -- choose random theming variant 40 | local variant = { 41 | -- random wallpaper 42 | wallpaper = wallpapers[math.random(1, #wallpapers)] 43 | } 44 | 45 | -- get array of color names (keys of color table) 46 | local color_names = {} 47 | for key, _ in pairs(colors) do 48 | table.insert(color_names, key) 49 | end 50 | 51 | -- choose a random accent color 52 | -- until its not in the wallpaper 53 | while true do 54 | -- choose a random color 55 | local color_name = color_names[math.random(1, #color_names)] 56 | -- if its not in the wallpaper 57 | if not string.find(variant.wallpaper, color_name) then 58 | -- use it as accent color 59 | variant.accent_color = colors[color_name] 60 | -- stop loop 61 | break 62 | end 63 | end 64 | 65 | local lain = require("lain") 66 | local gears = require("gears") 67 | local awful = require("awful") 68 | local wibox = require("wibox") 69 | local naughty = require("naughty") 70 | local dpi = require("beautiful.xresources").apply_dpi 71 | 72 | local os = os 73 | local my_table = awful.util.table or gears.table -- 4.{0,1} compatibility 74 | 75 | local theme = {} 76 | theme.default_dir = require("awful.util").get_themes_dir() .. "default" 77 | theme.dir = os.getenv("HOME") .. "/.config/awesome/themes/mytheme" 78 | theme.wallpaper = "/etc/dotfiles/wallpapers/nixos/" .. variant.wallpaper .. ".png" 79 | theme.notification_sound = "/etc/dotfiles/misc/notification.wav" 80 | theme.font = "JetBrainsMonoNL Nerd Font 12" 81 | theme.border_focus = variant.accent_color 82 | theme.bg_urgent = "#FFFFFF" 83 | theme.taglist_fg_focus = "#F7F1FF" 84 | theme.fg_focus = "#F7F1FF" 85 | theme.fg_normal = "#8C8A8F" 86 | theme.bg_normal = "#262527" 87 | theme.bg_focus = "#262527" 88 | theme.border_normal = "#262527" 89 | theme.taglist_bg_focus = "#262527" 90 | theme.fg_urgent = "#201F21" 91 | theme.border_width = dpi(2) 92 | theme.systray_icon_spacing = dpi(5) 93 | theme.useless_gap = dpi(5) 94 | theme.menu_height = dpi(16) 95 | theme.menu_width = dpi(140) 96 | theme.notification_icon_size = dpi(100) 97 | theme.notification_spacing = dpi(14) 98 | theme.notification_bg = theme.bg_normal .. "66" -- lower opacity 99 | theme.notification_fg = theme.fg_focus 100 | theme.notification_border_color = colors[variant.wallpaper:sub(2, 2)] -- use second color from background 101 | theme.notification_shape = gears.shape.rounded_rect 102 | theme.ocol = "" 103 | theme.tasklist_floating = theme.ocol .. "*" 104 | theme.tasklist_maximized = theme.ocol .. "+" 105 | theme.tasklist_maximized_horizontal = theme.ocol .. "+" 106 | theme.tasklist_maximized_vertical = theme.ocol .. "+" 107 | theme.tasklist_sticky = theme.ocol .. "[s] " 108 | theme.tasklist_ontop = theme.ocol .. "[t] " 109 | theme.tasklist_disable_icon = true 110 | theme.awesome_icon = theme.dir .."/icons/awesome.png" 111 | theme.menu_submenu_icon = theme.dir .."/icons/submenu.png" 112 | theme.taglist_squares_sel = theme.dir .. "/icons/square_sel.png" 113 | theme.taglist_squares_unsel = theme.dir .. "/icons/square_unsel.png" 114 | theme.widget_cpu = theme.dir .. "/icons/cpu.png" 115 | theme.widget_mem = theme.dir .. "/icons/mem.png" 116 | theme.layout_txt_tile = "[t]" 117 | theme.layout_txt_tileleft = "[l]" 118 | theme.layout_txt_tilebottom = "[b]" 119 | theme.layout_txt_tiletop = "[tt]" 120 | theme.layout_txt_fairv = "[fv]" 121 | theme.layout_txt_fairh = "[fh]" 122 | theme.layout_txt_spiral = "[s]" 123 | theme.layout_txt_dwindle = "[d]" 124 | theme.layout_txt_max = "[m]" 125 | theme.layout_txt_fullscreen = "[F]" 126 | theme.layout_txt_magnifier = "[M]" 127 | theme.layout_txt_floating = "[*]" 128 | theme.titlebar_close_button_normal = theme.default_dir.."/titlebar/close_normal.png" 129 | theme.titlebar_close_button_focus = theme.default_dir.."/titlebar/close_focus.png" 130 | theme.titlebar_minimize_button_normal = theme.default_dir.."/titlebar/minimize_normal.png" 131 | theme.titlebar_minimize_button_focus = theme.default_dir.."/titlebar/minimize_focus.png" 132 | theme.titlebar_ontop_button_normal_inactive = theme.default_dir.."/titlebar/ontop_normal_inactive.png" 133 | theme.titlebar_ontop_button_focus_inactive = theme.default_dir.."/titlebar/ontop_focus_inactive.png" 134 | theme.titlebar_ontop_button_normal_active = theme.default_dir.."/titlebar/ontop_normal_active.png" 135 | theme.titlebar_ontop_button_focus_active = theme.default_dir.."/titlebar/ontop_focus_active.png" 136 | theme.titlebar_sticky_button_normal_inactive = theme.default_dir.."/titlebar/sticky_normal_inactive.png" 137 | theme.titlebar_sticky_button_focus_inactive = theme.default_dir.."/titlebar/sticky_focus_inactive.png" 138 | theme.titlebar_sticky_button_normal_active = theme.default_dir.."/titlebar/sticky_normal_active.png" 139 | theme.titlebar_sticky_button_focus_active = theme.default_dir.."/titlebar/sticky_focus_active.png" 140 | theme.titlebar_floating_button_normal_inactive = theme.default_dir.."/titlebar/floating_normal_inactive.png" 141 | theme.titlebar_floating_button_focus_inactive = theme.default_dir.."/titlebar/floating_focus_inactive.png" 142 | theme.titlebar_floating_button_normal_active = theme.default_dir.."/titlebar/floating_normal_active.png" 143 | theme.titlebar_floating_button_focus_active = theme.default_dir.."/titlebar/floating_focus_active.png" 144 | theme.titlebar_maximized_button_normal_inactive = theme.default_dir.."/titlebar/maximized_normal_inactive.png" 145 | theme.titlebar_maximized_button_focus_inactive = theme.default_dir.."/titlebar/maximized_focus_inactive.png" 146 | theme.titlebar_maximized_button_normal_active = theme.default_dir.."/titlebar/maximized_normal_active.png" 147 | theme.titlebar_maximized_button_focus_active = theme.default_dir.."/titlebar/maximized_focus_active.png" 148 | 149 | -- lain related 150 | theme.layout_txt_cascade = "[cascade]" 151 | theme.layout_txt_cascadetile = "[cascadetile]" 152 | theme.layout_txt_centerwork = "[centerwork]" 153 | theme.layout_txt_termfair = "[termfair]" 154 | theme.layout_txt_centerfair = "[centerfair]" 155 | 156 | local markup = lain.util.markup 157 | 158 | -- play sound on notification 159 | function naughty.config.notify_callback(args) 160 | awful.spawn.with_shell("aplay " .. theme.notification_sound) 161 | return args 162 | end 163 | 164 | -- set notification spacing 165 | naughty.config.padding = theme.notification_spacing 166 | naughty.config.spacing = theme.notification_spacing 167 | 168 | -- Textclock 169 | local mytextclock = wibox.widget.textclock(markup(theme.fg_focus, "%H:%M")) 170 | mytextclock.font = theme.font 171 | 172 | -- Calendar 173 | theme.cal = lain.widget.cal({ 174 | attach_to = { mytextclock }, 175 | notification_preset = { 176 | font = theme.font, 177 | fg = theme.fg_focus, 178 | bg = theme.bg_normal, 179 | position = "top_right" 180 | } 181 | }) 182 | 183 | -- Mail IMAP check 184 | --[[ commented because it needs to be set before use 185 | theme.mail = lain.widget.imap({ 186 | timeout = 180, 187 | server = "server", 188 | mail = "mail", 189 | password = "keyring get mail", 190 | settings = function() 191 | mail_notification_preset.fg = theme.fg_focus 192 | 193 | mail = "" 194 | count = "" 195 | 196 | if mailcount > 0 then 197 | mail = "Mail " 198 | count = mailcount .. " " 199 | end 200 | 201 | widget:set_markup(markup.font(theme.font, markup(theme.fg_normal, mail) .. markup(theme.fg_focus, count))) 202 | end 203 | }) 204 | --]] 205 | 206 | -- MPD 207 | --theme.mpd = lain.widget.mpd({ 208 | -- settings = function() 209 | -- mpd_notification_preset.fg = theme.fg_focus 210 | -- 211 | -- artist = mpd_now.artist .. " " 212 | -- title = mpd_now.title .. " " 213 | -- 214 | -- if mpd_now.state == "pause" then 215 | -- artist = "mpd " 216 | -- title = "paused " 217 | -- elseif mpd_now.state == "stop" then 218 | -- artist = "" 219 | -- title = "" 220 | -- end 221 | -- 222 | -- widget:set_markup(markup.font(theme.font, markup(theme.fg_normal, artist) .. markup(theme.fg_focus, title))) 223 | -- end 224 | --}) 225 | 226 | -- /home fs 227 | --[[ commented because it needs Gio/Glib >= 2.54 228 | theme.fs = lain.widget.fs({ 229 | notification_preset = { fg = theme.fg_focus, bg = theme.bg_normal, font = "JetBrainsMonoNL Nerd Font 10.5" }, 230 | settings = function() 231 | local fs_header, fs_p = "", "" 232 | 233 | if fs_now["/home"].percentage >= 90 then 234 | fs_header = " Hdd " 235 | fs_p = fs_now["/home"].percentage 236 | end 237 | 238 | widget:set_markup(markup.font(theme.font, markup(theme.fg_normal, fs_header) .. markup(theme.fg_focus, fs_p))) 239 | end 240 | }) 241 | --]] 242 | 243 | -- ALSA volume bar 244 | theme.volume = lain.widget.alsabar({ 245 | ticks = true, 246 | width = dpi(56), 247 | ticks_size = dpi(10), 248 | margins = 1, 249 | notification_preset = { font = theme.font }, 250 | colors = { 251 | background = theme.bg_normal, 252 | mute = theme.fg_normal, 253 | unmute = variant.accent_color 254 | } 255 | }) 256 | -- doesnt work? 257 | --theme.volume.tooltip.wibox.fg = "#00ff00" 258 | --theme.volume.tooltip.wibox.bg = "#ff00ff" 259 | theme.volume.tooltip.wibox.font = theme.font 260 | theme.volume.bar:buttons(my_table.join( 261 | awful.button({}, 1, function() 262 | --awful.spawn(string.format("%s -e alsamixer", terminal)) 263 | -- copied functionality of right-click 264 | os.execute(string.format("%s set %s toggle", theme.volume.cmd, theme.volume.togglechannel or theme.volume.channel)) 265 | theme.volume.update() 266 | end), 267 | awful.button({}, 2, function() 268 | os.execute(string.format("%s set %s 50%%", theme.volume.cmd, theme.volume.channel)) 269 | theme.volume.update() 270 | end), 271 | awful.button({}, 3, function() 272 | os.execute(string.format("%s set %s toggle", theme.volume.cmd, theme.volume.togglechannel or theme.volume.channel)) 273 | theme.volume.update() 274 | end), 275 | awful.button({}, 4, function() 276 | os.execute(string.format("%s set %s 5%%+", theme.volume.cmd, theme.volume.channel)) 277 | theme.volume.update() 278 | end), 279 | awful.button({}, 5, function() 280 | os.execute(string.format("%s set %s 5%%-", theme.volume.cmd, theme.volume.channel)) 281 | theme.volume.update() 282 | end) 283 | )) 284 | local volumebg = wibox.container.background(theme.volume.bar, theme.fg_normal, gears.shape.rectangle) 285 | local volumewidget = wibox.container.rotate(wibox.container.margin(volumebg, dpi(7), dpi(7), dpi(5), dpi(5)), "south") 286 | 287 | -- Weather 288 | --[[ to be set before use 289 | theme.weather = lain.widget.weather({ 290 | --APPID = 291 | city_id = 2643743, -- placeholder (London) 292 | notification_preset = { font = theme.font, fg = theme.fg_focus } 293 | }) 294 | --]] 295 | 296 | -- Separators 297 | local first = wibox.widget.textbox(markup.font("JetBrainsMonoNL Nerd Font 4", " ")) 298 | local spr = wibox.widget.textbox(" ") 299 | local bar = wibox.widget.textbox(markup.fontfg(theme.font, theme.fg_focus, "|")) 300 | 301 | local function update_txt_layoutbox(s) 302 | -- Writes a string representation of the current layout in a textbox widget 303 | local txt_l = theme["layout_txt_" .. awful.layout.getname(awful.layout.get(s))] or "" 304 | s.mytxtlayoutbox:set_text(txt_l) 305 | end 306 | 307 | local widget_timeout = 1 308 | -- Memory 309 | local memicon = wibox.container.margin(wibox.widget.imagebox(theme.widget_mem), 0, 0, dpi(4), dpi(4)) 310 | local memory = lain.widget.mem({ 311 | timeout = widget_timeout, 312 | settings = function() 313 | -- calculate MB from MiB 314 | local mem = math.floor(mem_now.used * ((2^20) / (10^6))) 315 | widget:set_markup(markup.font(theme.font, markup(theme.fg_focus, mem) .. "MB")) 316 | end 317 | }) 318 | -- CPU 319 | local cpuicon = wibox.container.margin(wibox.widget.imagebox(theme.widget_cpu), 0, 0, dpi(5), dpi(5)) 320 | local cpu = lain.widget.cpu({ 321 | timeout = widget_timeout, 322 | settings = function() 323 | local current_load = tonumber(cpu_now.usage) 324 | if not current_load then current_load = 0 end 325 | if current_load > 99 then current_load = 99 end 326 | local text = markup(theme.fg_focus, current_load) 327 | if current_load < 10 then 328 | text = "0" .. text 329 | end 330 | widget:set_markup(markup.font(theme.font, text .. "%")) 331 | end 332 | }) 333 | 334 | function theme.at_screen_connect(s) 335 | 336 | -- Quake application 337 | s.quake = lain.util.quake({ app = awful.util.terminal }) 338 | 339 | -- If wallpaper is a function, call it with the screen 340 | local wallpaper = theme.wallpaper 341 | if type(wallpaper) == "function" then 342 | wallpaper = wallpaper(s) 343 | end 344 | gears.wallpaper.maximized(wallpaper, s, true) 345 | 346 | -- Tags 347 | awful.tag(awful.util.tagnames, s, awful.layout.layouts[1]) 348 | 349 | -- Create a promptbox for each screen 350 | s.mypromptbox = awful.widget.prompt({ 351 | prompt = "> ", 352 | --with_shell = true 353 | }) 354 | 355 | -- Textual layoutbox 356 | s.mytxtlayoutbox = wibox.widget.textbox(theme["layout_txt_" .. awful.layout.getname(awful.layout.get(s))]) 357 | awful.tag.attached_connect_signal(s, "property::selected", function () update_txt_layoutbox(s) end) 358 | awful.tag.attached_connect_signal(s, "property::layout", function () update_txt_layoutbox(s) end) 359 | s.mytxtlayoutbox:buttons(my_table.join( 360 | awful.button({}, 1, function() awful.layout.inc(1) end), 361 | awful.button({}, 2, function () awful.layout.set( awful.layout.layouts[1] ) end), 362 | awful.button({}, 3, function() awful.layout.inc(-1) end), 363 | awful.button({}, 4, function() awful.layout.inc(1) end), 364 | awful.button({}, 5, function() awful.layout.inc(-1) end))) 365 | 366 | -- Create a taglist widget 367 | s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, awful.util.taglist_buttons) 368 | 369 | -- Create a tasklist widget 370 | s.mytasklist = awful.widget.tasklist( 371 | s, 372 | awful.widget.tasklist.filter.currenttags, 373 | awful.util.tasklist_buttons, 374 | { 375 | align = "left", 376 | bg_normal = theme.fg_urgent, 377 | bg_focus = theme.fg_urgent, 378 | shape = gears.shape.rectangle, 379 | shape_border_color = theme.bg_normal, 380 | shape_border_width = theme.border_width, 381 | } 382 | ) 383 | 384 | -- Create the wibox 385 | s.mywibox = awful.wibar({ position = "top", screen = s, height = dpi(25), bg = theme.bg_normal, fg = theme.fg_normal }) 386 | 387 | -- Add widgets to the wibox 388 | s.mywibox:setup { 389 | layout = wibox.layout.align.horizontal, 390 | { -- Left widgets 391 | layout = wibox.layout.fixed.horizontal, 392 | 393 | first, 394 | s.mytaglist, 395 | 396 | spr, 397 | 398 | cpuicon, spr, 399 | cpu.widget, 400 | 401 | spr, spr, spr, 402 | 403 | memicon, spr, 404 | memory.widget, 405 | 406 | spr, spr, 407 | 408 | s.mypromptbox, 409 | }, 410 | s.mytasklist, -- Middle widget 411 | { -- Right widgets 412 | spr, 413 | 414 | layout = wibox.layout.fixed.horizontal, 415 | 416 | spr, 417 | 418 | wibox.container.margin(wibox.widget.systray(), 0, 0, dpi(3), dpi(3)), 419 | --theme.mpd.widget, 420 | --theme.mail.widget, 421 | --theme.fs.widget, 422 | 423 | spr, 424 | 425 | --s.mytxtlayoutbox, 426 | volumewidget, 427 | mytextclock, 428 | 429 | spr, spr 430 | }, 431 | } 432 | end 433 | 434 | return theme 435 | -------------------------------------------------------------------------------- /modules/base/default.nix: -------------------------------------------------------------------------------- 1 | args@{ lib, pkgs, variables, device, ... }: 2 | { 3 | # other base modules can be enabled if desired 4 | imports = [ 5 | ./gui 6 | ./gui/full.nix 7 | ./laptop.nix 8 | ]; 9 | 10 | ######################################################### 11 | ### most basic configuration every device should have ### 12 | ######################################################### 13 | 14 | # self-explaining one-liners 15 | time.timeZone = "Europe/Berlin"; 16 | nixpkgs.config.allowUnfree = true; 17 | system.stateVersion = variables.version; 18 | nix.settings.experimental-features = [ "nix-command" "flakes" "pipe-operators" ]; 19 | 20 | boot.loader = { 21 | efi.canTouchEfiVariables = true; 22 | timeout = 0; # only show when pressing keys during boot 23 | systemd-boot = { 24 | enable = true; 25 | configurationLimit = 20; # number of generations to show 26 | }; 27 | }; 28 | 29 | console = { 30 | earlySetup = true; 31 | keyMap = "de"; 32 | colors = [ 33 | "000000" "FC618D" "7BD88F" "FD9353" "5AA0E6" "948AE3" "5AD4E6" "F7F1FF" 34 | "99979B" "FB376F" "4ECA69" "FD721C" "2180DE" "7C6FDC" "37CBE1" "FFFFFF" 35 | ]; 36 | }; 37 | 38 | networking = { 39 | hostName = device.hostName; 40 | networkmanager.enable = true; 41 | firewall = { 42 | enable = true; 43 | allowedTCPPorts = []; 44 | allowedUDPPorts = []; 45 | }; 46 | }; 47 | 48 | i18n.defaultLocale = "en_US.UTF-8"; 49 | i18n.extraLocaleSettings = { 50 | LC_IDENTIFICATION = "de_DE.UTF-8"; 51 | LC_MEASUREMENT = "de_DE.UTF-8"; 52 | LC_TELEPHONE = "de_DE.UTF-8"; 53 | LC_MONETARY = "de_DE.UTF-8"; 54 | LC_ADDRESS = "de_DE.UTF-8"; 55 | LC_PAPER = "de_DE.UTF-8"; 56 | LC_NAME = "de_DE.UTF-8"; 57 | }; 58 | 59 | # database for command-not-found in a declarative way without channels 60 | # https://blog.nobbz.dev/2023-02-27-nixos-flakes-command-not-found/ 61 | environment.etc."programs.sqlite".source = 62 | (lib.getPkgs "programs-sqlite").programs-sqlite; 63 | programs.command-not-found.dbPath = "/etc/programs.sqlite"; 64 | 65 | ### user account and groups 66 | # create new group with username 67 | users.groups.${variables.username} = {}; 68 | # create user 69 | users.users.${variables.username} = { 70 | isNormalUser = true; 71 | description = variables.username; 72 | extraGroups = [ # add user to groups (if they exist) 73 | variables.username 74 | "users" 75 | "wheel" 76 | "networkmanager" 77 | ]; 78 | }; 79 | 80 | environment.systemPackages = with pkgs; [ 81 | wget 82 | bash 83 | jq # process json 84 | lsd # better ls 85 | bat # better cat 86 | fzf # fast fuzzy finder 87 | tldr # summarize man pages 88 | zoxide # better cd 89 | nomino # file renaming 90 | hyperfine # benchmarking tool 91 | unstable.numbat # cli calculator 92 | fortune # random quote 93 | librespeed-cli # speedtest 94 | nix-output-monitor # prettier output of nix commands 95 | cbonsai # ascii art bonsai 96 | asciiquarium-transparent # ascii art aquarium 97 | ]; 98 | 99 | local = { 100 | vim.enable = true; 101 | fish.enable = true; 102 | sops.enable = true; 103 | starship.enable = true; 104 | fastfetch.enable = true; 105 | devtools.python.enable = true; 106 | distributed-builds.enable = true; 107 | }; 108 | 109 | # for secret storing stuff 110 | services.gnome.gnome-keyring.enable = true; 111 | 112 | # load dev environment from directory 113 | programs.direnv.enable = true; 114 | 115 | # run dynamically-linked binaries not meant for NixOS 116 | programs.nix-ld.enable = true; 117 | 118 | # ensure /bin/bash exists to make 119 | # #!/bin/bash script shebangs working 120 | system.activationScripts.binbash.text = 121 | "ln -sf /run/current-system/sw/bin/bash /bin/bash"; 122 | 123 | # nix helper (prettier/better nix commands) 124 | programs.nh = { 125 | enable = true; 126 | package = pkgs.unstable.nh; 127 | # automatic nix garbage collect 128 | clean = { 129 | enable = true; 130 | dates = lib.mkDefault "monthly"; 131 | # always keep 2 generations 132 | extraArgs = "--keep 2"; 133 | }; 134 | }; 135 | 136 | # more nix cache 137 | nix.settings = { 138 | extra-substituters = [ "https://nix-community.cachix.org" ]; 139 | extra-trusted-public-keys = [ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ]; 140 | }; 141 | 142 | # disable hibernation 143 | systemd.sleep.extraConfig = '' 144 | AllowHibernation=no 145 | AllowHybridSleep=no 146 | AllowSuspendThenHibernate=no 147 | ''; 148 | 149 | # for git authentication with ssh keys 150 | programs.ssh = { 151 | startAgent = true; 152 | # in order of preference 153 | hostKeyAlgorithms = [ "ssh-ed25519" "ssh-rsa" ]; 154 | pubkeyAcceptedKeyTypes = [ "ssh-ed25519" "ssh-rsa" ]; 155 | }; 156 | 157 | # some environment variables 158 | environment.variables = { 159 | EDITOR = "vim"; 160 | # colorize man pages with bat 161 | MANPAGER = "sh -c 'col -bx | bat --language man --plain'"; 162 | MANROFFOPT = "-c"; 163 | # current device to use for flake-rebuild 164 | NIX_FLAKE_CURRENT_DEVICE = device.internalName; 165 | # use --impure for flake-rebuild by default (if configured) 166 | NIX_FLAKE_ALLOW_IMPURE_BY_DEFAULT = lib.mkIf variables.allowImpureByDefault 1; 167 | }; 168 | 169 | ### manage stuff in /home/$USER/ 170 | home-manager.useGlobalPkgs = true; 171 | home-manager.useUserPackages = true; 172 | home-manager.backupFileExtension = "hm-bak"; 173 | home-manager.users.${variables.username} = { config, ... }: 174 | { 175 | home.stateVersion = variables.version; 176 | 177 | # i dont know what this does? 178 | programs.home-manager.enable = true; 179 | 180 | programs.git = { 181 | enable = true; 182 | extraConfig.init.defaultBranch = "main"; 183 | userName = variables.git.name; 184 | userEmail = variables.git.email; 185 | }; 186 | }; 187 | } -------------------------------------------------------------------------------- /modules/base/gui/default.nix: -------------------------------------------------------------------------------- 1 | # basic gui config (without unrelated programs) 2 | args@{ config, lib, pkgs, variables, ... }: 3 | { 4 | options.local.base.gui.enable = lib.mkEnableOption "whether to enable basic gui config"; 5 | 6 | config = lib.mkIf config.local.base.gui.enable { 7 | 8 | # latest kernel 9 | boot.kernelPackages = lib.mkDefault pkgs.unstable.linuxPackages_latest; 10 | 11 | # hardware accelerated graphics drivers 12 | hardware.graphics = { 13 | enable = true; 14 | enable32Bit = true; 15 | }; 16 | 17 | # sound with pipewire 18 | security.rtkit.enable = true; 19 | services.pipewire = { 20 | enable = true; 21 | pulse.enable = true; 22 | alsa.enable = true; 23 | alsa.support32Bit = true; 24 | }; 25 | 26 | ########################################## 27 | ########################################## 28 | ################ PACKAGES ################ 29 | ########################################## 30 | ########################################## 31 | 32 | fonts.packages = with pkgs; [ 33 | noto-fonts # ~200 standard modern fonts for all kinds of languages 34 | noto-fonts-cjk-sans # for asian characters 35 | nerd-fonts.jetbrains-mono # good for code 36 | ]; 37 | 38 | environment.systemPackages = with pkgs; [ 39 | ### gui 40 | gparted # partition manager, use with sudo -E gparted 41 | unstable.resources # system monitor (best overall) 42 | #monitor # system monitor (best process view) (broken) 43 | vlc # video player 44 | qview # image viewer 45 | audacious # audio player 46 | snapshot # camera 47 | signal-desktop # messenger 48 | networkmanagerapplet # tray icon for networking connection 49 | xarchiver # archive manager 50 | baobab # disk usage analyzer 51 | gnome-disk-utility 52 | unstable.obsidian # PROPRIETARY notes 53 | spotify # PROPRIETARY 54 | # gtk theme 55 | (orchis-theme.override { border-radius = 10; }) 56 | gnome-themes-extra # just having this installed avoids warnings in some apps 57 | # icon themes 58 | adwaita-icon-theme # just having this installed fixes issues in some apps 59 | (papirus-icon-theme.override { /*folder-*/color = "black"; }) 60 | 61 | ### cli 62 | alsa-utils # control volume 63 | lm_sensors # system temperature sensor info 64 | lxde.lxmenu-data # required to discover applications 65 | lxde.lxsession # just needed for lxpolkit (an authentication agent) 66 | 67 | ### only used on xorg 68 | lxappearance # manage gtk theming stuff if homemanager fails 69 | unclutter-xfixes # hide mouse on inactivity 70 | pick-colour-picker 71 | 72 | ### only used on wayland 73 | swww # wallpaper switching with animations 74 | nwg-look # manage gtk theming stuff if homemanager fails 75 | hyprpicker # color picker 76 | wev ydotool # find out / send keycodes 77 | wl-clipboard # interact with clipboard 78 | unstable.swayosd # osd for volume changes 79 | ]; 80 | 81 | ########################################### 82 | ########################################### 83 | ########### PROGRAMS / SERVICES ########### 84 | ########################################### 85 | ########################################### 86 | 87 | local = { 88 | vscodium.enable = true; 89 | alacritty.enable = true; 90 | hyprland.enable = true; 91 | awesome.enable = true; 92 | copyq.enable = true; 93 | eww.enable = true; 94 | rofi.enable = true; 95 | sddm-sugar-candy.enable = true; 96 | swaylock-effects.enable = true; 97 | swaync.enable = true; 98 | zen-browser.enable = true; 99 | gitnuro.enable = true; 100 | nautilus.enable = true; 101 | bluetooth.enable = true; 102 | discord.enable = true; 103 | }; 104 | 105 | services.displayManager.sddm.enable = true; 106 | 107 | # configure various app settings 108 | programs.dconf.enable = true; 109 | 110 | # what to do when pressing power button 111 | services.logind = { 112 | powerKeyLongPress = "poweroff"; 113 | # do nothing :) suspend manually if you want 114 | powerKey = "ignore"; 115 | }; 116 | 117 | # qt theming (based on gtk theming) 118 | qt = { 119 | enable = true; 120 | style = "gtk2"; 121 | platformTheme = "gtk2"; 122 | }; 123 | 124 | # use keyd to emulate ctrl+alt being equal to altgr, 125 | # like it is using a german keyboard layout on windows 126 | services.keyd.enable = true; 127 | services.keyd.keyboards.default = { 128 | ids = [ "*" ]; 129 | settings."control+alt" = { 130 | "7" = "G-7"; # C-A-7 => { 131 | "8" = "G-8"; # C-A-8 => [ 132 | "9" = "G-9"; # C-A-9 => ] 133 | "0" = "G-0"; # C-A-0 => } 134 | "-" = "G--"; # C-A-ß => \ 135 | "]" = "G-]"; # C-A-+ => ~ 136 | }; 137 | }; 138 | 139 | ############################################ 140 | ############################################ 141 | ############### HOME-MANAGER ############### 142 | ############################################ 143 | ############################################ 144 | home-manager.users.${variables.username} = { config, ... }: { 145 | ### theming 146 | gtk.enable = true; 147 | # gtk dark mode 148 | dconf.settings."org/gnome/desktop/interface".color-scheme = "prefer-dark"; 149 | # gtk theme 150 | gtk.theme.name = "Orchis-Dark"; 151 | # icon theme 152 | gtk.iconTheme.name = "Papirus-Dark"; 153 | # font config 154 | gtk.font.name = "Noto Sans"; 155 | gtk.font.size = 10; 156 | # cursor theme 157 | home.pointerCursor = { 158 | gtk.enable = true; 159 | x11.enable = true; 160 | package = pkgs.capitaine-cursors; 161 | name = "capitaine-cursors"; 162 | size = 32; 163 | }; 164 | gtk.cursorTheme = { 165 | name = "capitaine-cursors"; 166 | size = 32; 167 | }; 168 | 169 | # automatically mount usb sticks with notification and tray icon 170 | services.udiskie = { 171 | enable = true; 172 | automount = true; 173 | tray = "never"; # necessary when not having a tray 174 | notify = true; 175 | }; 176 | 177 | # flameshot (screenshot tool) 178 | services.flameshot = { 179 | enable = true; 180 | # wayland support 181 | package = pkgs.flameshot.override { enableWlrSupport = true; }; 182 | settings.General = { 183 | uiColor = "#5AD4E6"; 184 | contrastUiColor = "#FC618D"; 185 | contrastOpacity = 64; 186 | showHelp = false; 187 | startupLaunch = false; 188 | disabledTrayIcon = true; 189 | disabledGrimWarning = true; 190 | }; 191 | }; 192 | }; 193 | }; 194 | } -------------------------------------------------------------------------------- /modules/base/gui/full.nix: -------------------------------------------------------------------------------- 1 | # more gui config i don't want on every device 2 | args@{ config, lib, pkgs, ... }: 3 | { 4 | options.local.base.gui.full.enable = lib.mkEnableOption "whether to enable full gui config"; 5 | 6 | config = lib.mkIf config.local.base.gui.full.enable { 7 | 8 | local.base.gui.enable = true; 9 | 10 | environment.systemPackages = with pkgs; [ 11 | ### gui 12 | onlyoffice-bin_latest # office suite 13 | gimp-with-plugins # image editor 14 | darktable # photo editor and raw developer 15 | inkscape-with-extensions # vector graphic editor 16 | veracrypt # disk encryption 17 | freefilesync # file backup 18 | foliate # ebook reader 19 | bottles # run windows software easily 20 | (prismlauncher.override { jdks = [ jdk ]; }) # minecraft 21 | #usbimager # if ventoy causes problems 22 | #obs-studio # video recording 23 | #font-manager # font manager 24 | #pitivi # video editor 25 | #tenacity # audio recorder and editor 26 | 27 | ### cli 28 | dunst # for better notify-send with dunstify 29 | gphoto2fs # mount camera 30 | ]; 31 | }; 32 | } -------------------------------------------------------------------------------- /modules/base/laptop.nix: -------------------------------------------------------------------------------- 1 | # useful config for laptops 2 | args@{ config, lib, pkgs, variables, ... }: 3 | { 4 | options.local.base.laptop.enable = lib.mkEnableOption "whether to enable laptop config"; 5 | 6 | config = lib.mkIf config.local.base.laptop.enable { 7 | 8 | local = { 9 | base.gui.enable = true; 10 | plymouth.enable = true; 11 | }; 12 | 13 | # set env var to tell eww that this is a laptop 14 | environment.variables.IS_LAPTOP = 1; 15 | 16 | # enable touchpad support 17 | services.libinput.enable = true; 18 | 19 | # probably useful 20 | hardware.enableAllFirmware = true; 21 | 22 | environment.systemPackages = with pkgs; [ 23 | acpi # get battery info like remaining time to (dis)charge 24 | nwg-displays # control (external) display configuration 25 | brightnessctl # control display brightness 26 | ]; 27 | 28 | # autologin hyprland 29 | services.displayManager.sddm.settings.Autologin = { 30 | User = variables.username; 31 | Session = "hyprland.desktop"; 32 | }; 33 | 34 | ### improve battery life 35 | services.auto-cpufreq.enable = true; 36 | # recommended by auto-cpufreq 37 | services.thermald.enable = true; 38 | # reference: https://github.com/AdnanHodzic/auto-cpufreq#example-config-file-contents 39 | services.auto-cpufreq.settings = { 40 | battery = { 41 | governor = "powersave"; 42 | platform_profile = "low-power"; 43 | turbo = "never"; 44 | }; 45 | charger = { 46 | governor = "performance"; 47 | platform_profile = "balanced"; 48 | turbo = "auto"; 49 | }; 50 | }; 51 | 52 | # suspend when closing laptop lid 53 | services = { 54 | # stop default behavior, not reliable 55 | logind = { 56 | lidSwitch = "ignore"; 57 | lidSwitchDocked = "ignore"; 58 | }; 59 | # run own script 60 | acpid = { 61 | enable = true; 62 | lidEventCommands = '' 63 | PATH=/run/current-system/sw/bin 64 | if [[ $(awk '{print$NF}' /proc/acpi/button/lid/LID0/state) == "closed" ]]; then 65 | systemctl suspend 66 | fi 67 | ''; 68 | }; 69 | }; 70 | 71 | # notifications for low battery 72 | home-manager.users.${variables.username} = { config, ... }: { 73 | services.batsignal.enable = true; 74 | }; 75 | }; 76 | } -------------------------------------------------------------------------------- /modules/base/raspberry-pi.nix: -------------------------------------------------------------------------------- 1 | ### useful config for raspberry pi (5) 2 | # not a toggleable module because raspberry-pi-nix should not be imported for all devices as it can cause a lot of conflicts. 3 | # build an sd card image on the pi (running any os with nix) as a remote builder for the first installation with a command like 4 | # nix build /etc/dotfiles#nixosConfigurations.DEVICE.config.system.build.sdImage --store ssh-ng://USER@IP 5 | # then copy the built image from the remote pi to your local machine with scp. see more at 6 | # https://wiki.nixos.org/wiki/NixOS_on_ARM/Raspberry_Pi_5#Using_the_Pi_5_as_a_remote_builder_to_build_native_ARM_packages_for_the_Pi_5 7 | args@{ config, lib, pkgs, inputs, variables, ... }: 8 | { 9 | ### fixes for default config 10 | # usually enabled in modules/base/default.nix, doesnt work here 11 | boot.loader.systemd-boot.enable = lib.mkForce false; 12 | # dont install networkmanager plugins because of 13 | # build failures and expensive cache misses 14 | networking.networkmanager.plugins = lib.mkForce []; 15 | 16 | imports = [ inputs.raspberry-pi-nix.nixosModules.raspberry-pi ]; 17 | raspberry-pi-nix = { 18 | board = "bcm2712"; # raspberry pi 5 19 | uboot.enable = false; # disable uboot as it just gets stuck 20 | }; 21 | 22 | # avoid password prompts when remote rebuilding 23 | # https://github.com/NixOS/nixpkgs/issues/118655#issuecomment-1537131599 24 | security.sudo.extraRules = [ { 25 | users = [ variables.username ]; 26 | commands = [ 27 | { command = "/run/current-system/sw/bin/env"; options = [ "NOPASSWD" ]; } 28 | { command = "/run/current-system/sw/bin/nix-env"; options = [ "NOPASSWD" ]; } 29 | { command = "/run/current-system/sw/bin/systemd-run"; options = [ "NOPASSWD" ]; } 30 | ]; 31 | } ]; 32 | 33 | # set initial passwords of users to their names (dont forget to change!) 34 | users.users = { 35 | ${variables.username}.initialPassword = variables.username; 36 | root.initialPassword = "root"; 37 | }; 38 | 39 | services.openssh = { 40 | enable = true; 41 | settings.PermitRootLogin = "no"; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /modules/blocky.nix: -------------------------------------------------------------------------------- 1 | # dns proxy to block ads and trackers 2 | args@{ config, lib, ... }: 3 | lib.mkModule "blocky" config { 4 | 5 | # open dns ports 6 | networking.firewall = { 7 | allowedTCPPorts = [ 53 ]; 8 | allowedUDPPorts = [ 53 ]; 9 | }; 10 | 11 | services.blocky = { 12 | enable = true; 13 | settings = { 14 | upstreams = { 15 | init.strategy = "failOnError"; 16 | groups.default = [ "192.168.178.1" ]; 17 | }; 18 | 19 | blocking = { 20 | clientGroupsBlock.default = [ "general" ]; 21 | blackLists.general = [ 22 | "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" 23 | ]; 24 | }; 25 | }; 26 | }; 27 | } -------------------------------------------------------------------------------- /modules/bluetooth.nix: -------------------------------------------------------------------------------- 1 | # bluetooth support including gui for configuration 2 | args@{ config, lib, variables, ... }: 3 | lib.mkModule "bluetooth" config { 4 | hardware.bluetooth = { 5 | enable = true; 6 | settings.General = { 7 | Experimental = "true"; # necessary for some functionality 8 | FastConnectable = "true"; # connect faster but draw more power 9 | }; 10 | }; 11 | 12 | # bluetooth gui 13 | services.blueman.enable = true; 14 | home-manager.users.${variables.username} = { config, ... }: { 15 | # disable notifications when a device (dis)connects 16 | dconf.settings."org/blueman/general".plugin-list = [ "!ConnectionNotifier" ]; 17 | }; 18 | } -------------------------------------------------------------------------------- /modules/copyq/copyq.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | plugin_priority=itemimage, itemencrypted, itemfakevim, itemnotes, itempinned, itemsync, itemtags, itemtext 3 | 4 | [Options] 5 | activate_closes=true 6 | activate_focuses=true 7 | activate_item_with_single_click=true 8 | activate_pastes=true 9 | always_on_top=false 10 | autocompletion=true 11 | autostart=false 12 | change_clipboard_owner_delay_ms=150 13 | check_clipboard=true 14 | check_selection=false 15 | clipboard_notification_lines=0 16 | clipboard_tab=&clipboard 17 | close_on_unfocus=true 18 | close_on_unfocus_delay_ms=500 19 | command_history_size=100 20 | confirm_exit=true 21 | copy_clipboard=true 22 | copy_selection=false 23 | disable_tray=true 24 | edit_ctrl_return=true 25 | editor=codium %1 26 | expire_tab=0 27 | filter_case_insensitive=true 28 | filter_regular_expression=false 29 | hide_main_window=false 30 | hide_main_window_in_task_bar=false 31 | hide_tabs=true 32 | hide_toolbar=true 33 | hide_toolbar_labels=true 34 | item_data_threshold=1024 35 | item_popup_interval=0 36 | language=en 37 | max_process_manager_rows=1000 38 | maxitems=50 39 | move=true 40 | native_menu_bar=true 41 | native_notifications=false 42 | native_tray_menu=false 43 | notification_horizontal_offset=10 44 | notification_maximum_height=100 45 | notification_maximum_width=300 46 | notification_position=3 47 | notification_vertical_offset=10 48 | number_search=false 49 | open_windows_on_current_screen=true 50 | restore_geometry=true 51 | row_index_from_one=true 52 | run_selection=true 53 | save_delay_ms_on_item_added=300000 54 | save_delay_ms_on_item_edited=1000 55 | save_delay_ms_on_item_modified=300000 56 | save_delay_ms_on_item_moved=1800000 57 | save_delay_ms_on_item_removed=600000 58 | save_filter_history=false 59 | save_on_app_deactivated=true 60 | script_paste_delay_ms=250 61 | show_advanced_command_settings=false 62 | show_simple_items=false 63 | show_tab_item_count=false 64 | style= 65 | tab_tree=false 66 | tabs=&clipboard 67 | text_tab_width=8 68 | text_wrap=true 69 | transparency=0 70 | transparency_focused=0 71 | tray_commands=true 72 | tray_images=true 73 | tray_item_paste=true 74 | tray_items=5 75 | tray_menu_open_on_left_click=false 76 | tray_tab= 77 | tray_tab_is_current=true 78 | update_clipboard_owner_delay_ms=-1 79 | vi=true 80 | window_key_press_time_ms=50 81 | window_paste_with_ctrl_v_regex= 82 | window_wait_after_raised_ms=50 83 | window_wait_before_raise_ms=20 84 | window_wait_for_modifier_released_ms=2000 85 | window_wait_raised_ms=150 86 | 87 | [Plugins] 88 | itemencrypted\enabled=true 89 | itemencrypted\encrypt_tabs= 90 | itemfakevim\enabled=true 91 | itemfakevim\really_enable=false 92 | itemfakevim\source_file= 93 | itemimage\enabled=true 94 | itemimage\image_editor= 95 | itemimage\max_image_height=240 96 | itemimage\max_image_width=320 97 | itemimage\svg_editor= 98 | itemnotes\enabled=false 99 | itemnotes\notes_at_bottom=false 100 | itemnotes\notes_beside=false 101 | itemnotes\show_tooltip=false 102 | itempinned\enabled=false 103 | itemsync\enabled=false 104 | itemsync\format_settings=@Invalid() 105 | itemsync\sync_tabs=@Invalid() 106 | itemtags\enabled=false 107 | itemtags\tags=@Invalid() 108 | itemtext\default_style_sheet= 109 | itemtext\enabled=true 110 | itemtext\max_height=0 111 | itemtext\max_lines=20 112 | itemtext\use_rich_text=false 113 | 114 | [Shortcuts] 115 | about= 116 | change_tab_icon= 117 | commands= 118 | copy_selected_items= 119 | delete_item=del 120 | edit=f2 121 | edit_notes=shift+f2 122 | editor=ctrl+e 123 | editor_background= 124 | editor_bold= 125 | editor_cancel=esc 126 | editor_erase_style= 127 | editor_font= 128 | editor_foreground= 129 | editor_italic= 130 | editor_redo=ctrl+shift+z 131 | editor_save=f2 132 | editor_search=ctrl+f 133 | editor_strikethrough= 134 | editor_underline= 135 | editor_undo=ctrl+z 136 | exit=ctrl+q 137 | export= 138 | find_items=f3 139 | help= 140 | import= 141 | item-menu=shift+f10 142 | move_down=ctrl+down 143 | move_to_bottom=ctrl+end 144 | move_to_clipboard= 145 | move_to_top=ctrl+home 146 | move_up=ctrl+up 147 | new=ctrl+n 148 | new_tab= 149 | next_tab= 150 | paste_selected_items= 151 | preferences= 152 | previous_tab= 153 | process_manager= 154 | remove_tab= 155 | rename_tab= 156 | reverse_selected_items= 157 | show-log= 158 | show_clipboard_content= 159 | show_item_content=f4 160 | show_item_preview=f7 161 | sort_selected_items= 162 | system-run= 163 | toggle_clipboard_storing= 164 | 165 | [Tabs] 166 | 1\icon= 167 | 1\max_item_count=0 168 | 1\name=&clipboard 169 | 1\store_items=false 170 | size=1 171 | 172 | [Theme] 173 | alt_bg=#262527 174 | alt_item_css= 175 | bg=#262527 176 | css= 177 | css_template_items=items 178 | css_template_main_window=main_window 179 | css_template_menu=menu 180 | css_template_notification=notification 181 | cur_item_css="\n ;border: transparent" 182 | edit_bg=#262527 183 | edit_fg=#F7F1FF 184 | edit_font="JetBrainsMonoNL Nerd Font,10,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,Regular" 185 | fg=#F7F1FF 186 | find_bg=#5AA0E6 187 | find_fg=#F7F1FF 188 | find_font="JetBrainsMonoNL Nerd Font,10,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,Regular" 189 | font="JetBrainsMonoNL Nerd Font,12,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,Regular" 190 | font_antialiasing=true 191 | hover_item_css= 192 | icon_size=16 193 | item_css= 194 | item_spacing=0 195 | menu_bar_css="\n ;background: ${bg}\n ;color: ${fg}\n ;font-family: 'JetBrainsMonoNL Nerd Font'" 196 | menu_bar_disabled_css="\n ;color: ${bg - #666}" 197 | menu_bar_selected_css="\n ;background: ${sel_bg}\n ;color: ${sel_fg}" 198 | menu_css="\n ;border: 1px solid ${sel_bg}\n ;background: ${bg}\n ;color: ${fg}\n ;font-family: 'JetBrainsMonoNL Nerd Font'" 199 | notes_bg=#262527 200 | notes_css= 201 | notes_fg=#F7F1FF 202 | notes_font="JetBrainsMonoNL Nerd Font,10,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,Regular" 203 | notification_bg=#000000 204 | notification_fg=#F7F1FF 205 | notification_font="JetBrainsMonoNL Nerd Font,10,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,Regular" 206 | num_fg=#8C8A8F 207 | num_font="JetBrainsMonoNL Nerd Font,10,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,Regular" 208 | num_margin=2 209 | search_bar="\n ;background: ${edit_bg}\n ;color: ${edit_fg}\n ;border: 1px solid ${alt_bg}\n ;margin: 2px" 210 | search_bar_focused="\n ;border: 1px solid ${sel_bg}" 211 | sel_bg=#333135 212 | sel_fg=#F7F1FF 213 | sel_item_css= 214 | show_number=false 215 | show_scrollbars=false 216 | style_main_window=true 217 | tab_bar_css="\n ;background: ${bg - #222}" 218 | tab_bar_item_counter="\n ;color: ${fg - #044 + #400}\n ;font-size: 6pt" 219 | tab_bar_scroll_buttons_css="\n ;background: ${bg - #222}\n ;color: ${fg}\n ;border: 0" 220 | tab_bar_sel_item_counter="\n ;color: ${sel_bg - #044 + #400}" 221 | tab_bar_tab_selected_css="\n ;padding: 0.5em\n ;background: ${bg}\n ;border: 0.05em solid ${bg}\n ;color: ${fg}" 222 | tab_bar_tab_unselected_css="\n ;border: 0.05em solid ${bg}\n ;padding: 0.5em\n ;background: ${bg - #222}\n ;color: ${fg - #333}" 223 | tab_tree_css="\n ;color: ${fg}\n ;background-color: ${bg}" 224 | tab_tree_item_counter="\n ;color: ${fg - #044 + #400}\n ;font-size: 6pt" 225 | tab_tree_sel_item_counter="\n ;color: ${sel_fg - #044 + #400}" 226 | tab_tree_sel_item_css="\n ;color: ${sel_fg}\n ;background-color: ${sel_bg}\n ;border-radius: 2px" 227 | tool_bar_css="\n ;color: ${fg}\n ;background-color: ${bg}\n ;border: 0" 228 | tool_button_css="\n ;color: ${fg}\n ;background: ${bg}\n ;border: 0\n ;border-radius: 2px" 229 | tool_button_pressed_css="\n ;background: ${sel_bg}" 230 | tool_button_selected_css="\n ;background: ${sel_bg - #222}\n ;color: ${sel_fg}\n ;border: 1px solid ${sel_bg}" 231 | use_system_icons=true 232 | -------------------------------------------------------------------------------- /modules/copyq/default.nix: -------------------------------------------------------------------------------- 1 | # clipboard manager 2 | args@{ config, lib, pkgs, variables, ... }: 3 | lib.mkModule "copyq" config { 4 | environment.systemPackages = [ pkgs.copyq ]; 5 | 6 | # symlink config to ~/.config 7 | home-manager.users.${variables.username} = { config, ... }: { 8 | xdg.configFile."copyq/copyq.conf".source = 9 | config.lib.file.mkOutOfStoreSymlink "/etc/dotfiles/modules/copyq/copyq.conf"; 10 | }; 11 | } -------------------------------------------------------------------------------- /modules/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | imports = [ 3 | ./alacritty 4 | ./awesome 5 | ./base 6 | ./copyq 7 | ./eww 8 | ./firefox 9 | ./fish 10 | ./gitnuro 11 | ./hyprland 12 | ./jetbrains 13 | ./lamp-server 14 | ./minecraft-server 15 | ./plymouth 16 | ./rofi 17 | ./sddm-sugar-candy 18 | ./starship 19 | ./swaylock-effects 20 | ./vim 21 | ./swaync 22 | ./vscodium 23 | ./zen-browser 24 | ./ai-chatbot.nix 25 | ./blocky.nix 26 | ./bluetooth.nix 27 | ./devtools.nix 28 | ./discord.nix 29 | ./distributed-builds.nix 30 | ./fastfetch.nix 31 | ./nautilus.nix 32 | ./nvidia.nix 33 | ./obsidian-livesync.nix 34 | ./onedrive.nix 35 | ./piper.nix 36 | ./playerctl.nix 37 | ./sops.nix 38 | ./steam.nix 39 | ./virt-manager.nix 40 | ./website.nix 41 | ./wsl-vpnkit.nix 42 | ]; 43 | } -------------------------------------------------------------------------------- /modules/devtools.nix: -------------------------------------------------------------------------------- 1 | # development tools like compilers, build management, containerization, ... 2 | args@{ config, lib, pkgs, ... }: 3 | let 4 | cfg = config.local.devtools; 5 | in 6 | { 7 | options.local.devtools = { 8 | java .enable = lib.mkEnableOption "whether to enable java devtools"; 9 | docker.enable = lib.mkEnableOption "whether to enable docker devtools"; 10 | python.enable = lib.mkEnableOption "whether to enable python devtools"; 11 | }; 12 | 13 | config = { 14 | # python 15 | environment.systemPackages = lib.optionals cfg.python.enable [ 16 | (pkgs.python3.withPackages (p: with p; [ virtualenv ])) 17 | ]; 18 | 19 | # java 20 | programs.java = lib.mkIf cfg.java.enable { 21 | enable = true; 22 | package = pkgs.unstable.jdk; 23 | }; 24 | 25 | # docker 26 | virtualisation.docker = lib.mkIf cfg.docker.enable { 27 | enable = true; 28 | # better for security than adding user to "docker" group 29 | rootless = { 30 | enable = true; 31 | # make rootless instance the default 32 | setSocketVariable = true; 33 | }; 34 | }; 35 | }; 36 | } -------------------------------------------------------------------------------- /modules/discord.nix: -------------------------------------------------------------------------------- 1 | # discord 2 | args@{ config, lib, pkgs, inputs, variables, ... }: 3 | let 4 | discord-pkgs = pkgs.unstable; 5 | in 6 | lib.mkModule "discord" config { 7 | # nixcord for declarative config 8 | home-manager.sharedModules = [ inputs.nixcord.homeModules.nixcord ]; 9 | home-manager.users.${variables.username} = { config, ... }: { 10 | programs.nixcord = { 11 | enable = true; 12 | # disable discord (enabled by default) 13 | discord = { 14 | enable = false; 15 | openASAR.enable = false; 16 | vencord = { 17 | enable = false; 18 | # still relevant for vesktop even if not enabled here 19 | package = discord-pkgs.vencord; 20 | }; 21 | }; 22 | # use vesktop instead (wayland optimized discord client) 23 | vesktop = { 24 | enable = true; 25 | package = discord-pkgs.vesktop; 26 | }; 27 | 28 | config.plugins = { 29 | fakeNitro.enable = true; 30 | friendsSince.enable = true; 31 | crashHandler.enable = true; 32 | volumeBooster.enable = true; 33 | notificationVolume.enable = true; 34 | webScreenShareFixes.enable = true; 35 | }; 36 | }; 37 | }; 38 | } -------------------------------------------------------------------------------- /modules/distributed-builds.nix: -------------------------------------------------------------------------------- 1 | # nix builds on remote machines 2 | # https://wiki.nixos.org/wiki/Distributed_build 3 | args@{ config, lib, variables, ... }: 4 | lib.mkModule "distributed-builds" config { 5 | nix = { 6 | distributedBuilds = true; 7 | settings = { 8 | trusted-users = [ variables.username ]; 9 | # useful when remote has faster internet than local machine 10 | builders-use-substitutes = true; 11 | }; 12 | buildMachines = [ 13 | { 14 | hostName = "raspberry-pi"; 15 | system = "aarch64-linux"; 16 | protocol = "ssh-ng"; # nix' custom ssh variant 17 | supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ]; 18 | } 19 | ]; 20 | }; 21 | 22 | # convenient ssh hostnames 23 | # dont forget `ssh-copy-id HOST`! 24 | programs.ssh.extraConfig = '' 25 | Host raspberry-pi 26 | Hostname 192.168.178.254 27 | User ${variables.username} 28 | ''; 29 | } -------------------------------------------------------------------------------- /modules/eww/default.nix: -------------------------------------------------------------------------------- 1 | # build custom widgets 2 | args@{ config, lib, pkgs, variables, ... }: 3 | lib.mkModule "eww" config { 4 | environment.systemPackages = with pkgs; [ 5 | unstable.eww 6 | # for hyprland + eww integration 7 | unstable.hyprland-workspaces 8 | # open eww desktop widget on all monitors 9 | (lib.writeScriptFile "eww-open-everywhere" ./scripts/open-everywhere.sh) 10 | ]; 11 | 12 | # symlink config to ~/.config 13 | home-manager.users.${variables.username} = { config, ... }: { 14 | xdg.configFile."eww" = { 15 | source = config.lib.file.mkOutOfStoreSymlink "/etc/dotfiles/modules/eww"; 16 | recursive = true; 17 | }; 18 | }; 19 | } -------------------------------------------------------------------------------- /modules/eww/eww.css: -------------------------------------------------------------------------------- 1 | window { 2 | border-radius: 15px; 3 | border: 4px solid rgba(255, 255, 255, 0.05); 4 | background-color: rgba(26, 25, 26, 0.15); 5 | font-family: "JetBrainsMonoNL Nerd Font"; 6 | font-size: 22.5px; 7 | color: #F7F1FF; 8 | } 9 | 10 | .circle-condition-text { 11 | font-size: 15px; 12 | margin-top: 2.5px; 13 | } 14 | 15 | .main-box { 16 | margin: 20px; 17 | } 18 | 19 | .time { 20 | font-size: 100px; 21 | } 22 | 23 | .inner-circle { 24 | color: transparent; 25 | } 26 | 27 | .outer-circle { 28 | background: rgba(255, 255, 255, 0.2); 29 | } -------------------------------------------------------------------------------- /modules/eww/eww.yuck: -------------------------------------------------------------------------------- 1 | ; all labels have `:show-truncated false` because of 2 | ; https://github.com/elkowar/eww/issues/1083 3 | 4 | ; optimize for laptop usage (based on env var) 5 | (defvar is-laptop {get_env("IS_LAPTOP") == "1"}) 6 | 7 | (defpoll date :interval "1m" 8 | ; json string which eww can parse automatically (` = ' = ") 9 | :initial '{"date":"01.01.2000","day":"Monday"}' 10 | `LC_TIME=en_US.UTF-8 date '+{"date":"%d.%m.%y","day":"%A"}'`) 11 | 12 | (defpoll ram :interval "1s" 13 | ; in MB and percent 14 | :initial '{"total":0,"used":0,"used_percent":0}' 15 | "~/.config/eww/scripts/ram-usage.sh") 16 | 17 | (defpoll logarithmic-cpu :interval "1s" 18 | ; in percent 19 | :initial 0 20 | "~/.config/eww/scripts/logarithmic-cpu.sh") 21 | 22 | (defpoll battery :interval "5s" 23 | ; charge in percent 24 | :initial '{"charge":0,"time_remaining":"unknown","charging":false}' 25 | "~/.config/eww/scripts/battery.sh") 26 | 27 | (defpoll network :interval "5s" 28 | ; signal strength in percent 29 | :initial '{"internet":false,"wired":false,"signal_strength":0,"wifi_name":""}' 30 | "~/.config/eww/scripts/network.sh") 31 | 32 | (deflisten workspaces 33 | ; active and occupied hyprland workspaces for each monitor, 34 | ; e.g. {"HDMI-A-1":{"1":true},"DP-1":{"1":true}} 35 | :initial '{}' 36 | "~/.config/eww/scripts/workspaces/get-all.sh") 37 | 38 | ; monitor: name of monitor to watch workspaces, e.g. DP-1 39 | ; elevate: elevate the widget if true 40 | (defwindow desktop [monitor elevate] 41 | :stacking {elevate ? "overlay" : "bottom"} 42 | :exclusive false ; dont reserve WM space 43 | :focusable false ; does not need keyboard input 44 | :namespace "eww-desktop-widget" 45 | :geometry (geometry 46 | :anchor "center" 47 | ; small window, stretches to fit content 48 | :width "1%" 49 | :height "1%") 50 | (desktop :monitor monitor)) 51 | 52 | ; monitor: name of monitor to watch workspaces, e.g. DP-1 53 | (defwidget desktop [monitor] 54 | (box 55 | :class "main-box" 56 | :orientation "v" 57 | :space-evenly false 58 | :spacing -10 59 | (box 60 | :space-evenly false 61 | :spacing 15 62 | (eventbox 63 | :onscroll 'eww update is-laptop=${!is-laptop}' 64 | (box 65 | :space-evenly false 66 | :spacing 25 67 | (circular-battery) 68 | (circular-network) 69 | (circular-cpu) 70 | (circular-ram))) 71 | (label 72 | :show-truncated false 73 | :class "time" 74 | :text {formattime(EWW_TIME, "%R")} 75 | :tooltip {formattime(EWW_TIME, "%T")}) 76 | (box 77 | :orientation "v" 78 | :spacing -50 79 | (overlay 80 | ; overlay with transparent longest possible value 81 | ; => visible box size always stays the same 82 | ; => no centering problems 83 | (label :show-truncated false :text "Wednesday" :style "color: transparent") 84 | (label :show-truncated false :text {date.day})) 85 | (label :show-truncated false :text {date.date}))) 86 | (workspaces :monitor monitor))) 87 | 88 | ; monitor: name of monitor to watch workspaces, e.g. DP-1 89 | (defwidget workspaces [monitor] 90 | (eventbox 91 | ; scroll through workspaces with direction like up/down and currently active workspace on that monitor 92 | :onscroll '~/.config/eww/scripts/workspaces/change-active.sh {} ${jq(workspaces[monitor], "to_entries | map(select(.value == true)) | .[0].key")}' 93 | (box 94 | :halign "center" 95 | :style "margin-left: -1px" ; better centering below ":" of time 96 | :space-evenly false 97 | :spacing 38 98 | ; for all workspaces per monitor 99 | (for i in '[1,2,3,4,5,6,7,8,9]' 100 | (eventbox 101 | :onclick 'hyprctl dispatch split:workspace ${i}' 102 | :tooltip {i} 103 | :class "workspace" 104 | (label 105 | :show-truncated false 106 | :style "padding-right: 0.25em" 107 | :text {workspaces[monitor][i] == "true" ? "󰟒" : 108 | workspaces[monitor][i] == "false" ? "󰝥" : "󰄰"})))))) ; nerdfont characters 109 | 110 | (defwidget circular-cpu [] 111 | (circular-progress-fancy 112 | :visible {!is-laptop} 113 | :tooltip '${round(EWW_CPU.avg, 2)}%' 114 | :value logarithmic-cpu 115 | :text "" :style "padding-right: 0.35em" ; cpu nerdfont character 116 | :condition {EWW_CPU.avg < 10} 117 | :condition-text '${round(EWW_CPU.avg, 1)}')) 118 | 119 | (defwidget circular-ram [] 120 | (circular-progress-fancy 121 | :visible {!is-laptop} 122 | :tooltip '${ram.used} / ${ram.total} MB' 123 | :value {ram.used_percent} 124 | :text "" :style "padding-right: 0.3em" ; memory chip nerdfont character 125 | :condition {ram.used < 1000} 126 | :condition-text {ram.used})) 127 | 128 | (defwidget circular-battery [] 129 | (circular-progress-fancy 130 | :visible {is-laptop} 131 | :tooltip '${battery.charge}% (${battery.time_remaining} left${battery.charging ? " to charge" : ""})' 132 | :value {battery.charge} 133 | :style {battery.charging ? "padding-left: 0.1em" : ""} 134 | ; a lot of battery nerdfont characters incoming 135 | :text {battery.charging ? ( 136 | battery.charge < 10 ? "󰢟" : 137 | battery.charge < 20 ? "󰢜" : 138 | battery.charge < 30 ? "󰂆" : 139 | battery.charge < 40 ? "󰂇" : 140 | battery.charge < 50 ? "󰂈" : 141 | battery.charge < 60 ? "󰢝" : 142 | battery.charge < 70 ? "󰂉" : 143 | battery.charge < 80 ? "󰢞" : 144 | battery.charge < 90 ? "󰂊" : 145 | battery.charge < 95 ? "󰂋" : "󰂅" 146 | ) : ( 147 | battery.charge < 10 ? "󰂎" : 148 | battery.charge < 20 ? "󰁺" : 149 | battery.charge < 30 ? "󰁻" : 150 | battery.charge < 40 ? "󰁼" : 151 | battery.charge < 50 ? "󰁽" : 152 | battery.charge < 60 ? "󰁾" : 153 | battery.charge < 70 ? "󰁿" : 154 | battery.charge < 80 ? "󰂀" : 155 | battery.charge < 90 ? "󰂁" : 156 | battery.charge < 95 ? "󰂂" : "󰁹" )})) 157 | 158 | (defwidget circular-network [] 159 | (circular-progress-fancy 160 | :visible {is-laptop} 161 | :tooltip {!network.internet ? "no connection" : ( 162 | network.wired ? "wired connection" : 163 | 'connected to ${network.wifi_name} (${network.signal_strength}% signal strength)')} 164 | :value {network.signal_strength} 165 | :style 'padding-right: 0.${network.internet && !network.wired ? 3 : 2}em' 166 | ; network nerdfont characters incoming 167 | :text {!network.internet ? "" : ( 168 | network.wired ? "󰈀" : ( 169 | network.signal_strength < 20 ? "󰤯" : 170 | network.signal_strength < 40 ? "󰤟" : 171 | network.signal_strength < 60 ? "󰤢" : 172 | network.signal_strength < 80 ? "󰤥" : "󰤨" ))})) 173 | 174 | (defwidget circular-progress-fancy [value text ?tooltip ?condition ?condition-text ?style ?visible] 175 | (overlay 176 | :visible {visible ?: true} 177 | :tooltip tooltip 178 | (circular-progress 179 | :class "inner-circle" 180 | :value 100 181 | :thickness 25) 182 | (circular-progress 183 | :class "outer-circle" 184 | :value value 185 | :start-at 75 186 | :thickness 3) 187 | (revealer 188 | :reveal {!(condition ?: false)} 189 | (label 190 | :show-truncated false 191 | :text text 192 | :style style)) 193 | (revealer 194 | :reveal {condition ?: false} 195 | (label 196 | :show-truncated false 197 | :text condition-text 198 | :class "circle-condition-text")))) -------------------------------------------------------------------------------- /modules/eww/scripts/battery.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | charge=$(cat /sys/class/power_supply/BAT0/capacity) 4 | if [[ $? != 0 ]]; then 5 | charge="100" 6 | fi 7 | 8 | status=$(cat /sys/class/power_supply/BAT0/status) 9 | if [[ $? != 0 ]]; then 10 | status="Charging" 11 | fi 12 | 13 | if [[ "$status" == "Charging" ]]; then 14 | charging="true" 15 | else 16 | charging="false" 17 | fi 18 | 19 | time_remaining=$(acpi | grep -oP '\d\d(:\d\d){2}') 20 | if [[ $? != 0 ]]; then 21 | time_remaining="unknown time" 22 | fi 23 | 24 | echo "{\"charge\":$charge,\"time_remaining\":\"$time_remaining\",\"charging\":$charging}" -------------------------------------------------------------------------------- /modules/eww/scripts/logarithmic-cpu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # takes about 1 second to run 3 | 4 | # cpu usage percent as integer from 0 to 100 5 | actual=$(vmstat 1 2 | tail -1 | awk '{print $15}' | { read idle; echo $((100 - $idle)); }) 6 | # logarithmic value with base 10 (still integer from 0 to 100) 7 | offset=1 # add to actual and max (100) so result is never 0 8 | echo $(python -c "import math; print(round(math.log10((($actual+$offset)/((100+$offset)/9)+1))*100))") -------------------------------------------------------------------------------- /modules/eww/scripts/network.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # try to reach internet (rethinkdns servers) 4 | ping -q -c 1 -W 1 max.rethinkdns.com &> /dev/null 5 | if [[ $? != 0 ]]; then 6 | echo '{"internet":false,"wired":false,"signal_strength":0,"wifi_name":""}' 7 | exit 8 | fi 9 | 10 | # test for wired connection 11 | nmcli device | grep ethernet | grep connected &> /dev/null 12 | if [[ $? == 0 ]]; then 13 | wired="true" 14 | signal_strength=100 15 | else 16 | wired="false" 17 | # get wifi name and signal strength 18 | wifi_name=$(nmcli d | grep wifi | grep connected | sed 's/^.*connected\s*//' | head -n 1) 19 | signal_strength=$(nmcli d wifi | grep "^* " | sed 's/^.*\/s\s*//' | awk '{print $1}') 20 | # if signal strength still unknown => 0 21 | if [ -z "$signal_strength" ]; then 22 | signal_strength=0 23 | fi 24 | fi 25 | 26 | echo "{\"internet\":true,\"wired\":$wired,\"signal_strength\":$signal_strength,\"wifi_name\":\"$wifi_name\"}" -------------------------------------------------------------------------------- /modules/eww/scripts/open-everywhere.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # open eww desktop widget on every monitor recognized by hyprland 3 | # no arguments: open widget in background 4 | # argument "true": open widget elevated 5 | # argument "toggle": toggle widget elevation 6 | 7 | if [ "$1" = "toggle" ]; then 8 | # opposite of current state 9 | elevate=$(hyprctl layers -j | jq -c '[ to_entries | .[].value.levels."1"[] | select(.namespace == "eww-desktop-widget") | 0 ] != []') 10 | elif [ "$1" = "true" ]; then 11 | elevate="true" 12 | else 13 | elevate="false" 14 | fi 15 | 16 | hyprctl monitors -j | jq -c '.[] | {"name": .name, "model": .model}' | while read -r monitor; do 17 | name=$(jq -r '.name' <<< "$monitor") 18 | 19 | eww open desktop \ 20 | --screen "$(jq -r '.model' <<< "$monitor")" \ 21 | --id "$name" \ 22 | --arg "monitor=$name" \ 23 | --arg "elevate=$elevate" 24 | done -------------------------------------------------------------------------------- /modules/eww/scripts/ram-usage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # calculation inspired by https://github.com/lcpz/lain/blob/0a2ff9e1dea4093088c30af0b75ccd94a4f700ad/widget/mem.lua 3 | 4 | nums=$(cat /proc/meminfo \ 5 | | grep -e MemTotal -e MemFree -e Buffers -e Cached -e SReclaimable \ 6 | | awk '{print $2}') 7 | 8 | # in MB 9 | total=$(echo $nums | awk '{print $1}' | { read kb; echo $((kb / 1000)); }) 10 | free=$(echo $nums | awk '{print $2}' | { read kb; echo $((kb / 1000)); }) 11 | buffers=$(echo $nums | awk '{print $3}' | { read kb; echo $((kb / 1000)); }) 12 | cached=$(echo $nums | awk '{print $4}' | { read kb; echo $((kb / 1000)); }) 13 | srec=$(echo $nums | awk '{print $5}' | { read kb; echo $((kb / 1000)); }) 14 | 15 | used=$(($total - $free - $buffers - $cached - $srec)) 16 | 17 | # percent value between 0 and 100, logarithmic scale with base 10 18 | offset=250 # subtract from used and total as both values never go below this 19 | used_percent=$(python -c "import math; print(round(math.log10((($used-$offset)/(($total-$offset)/9)+1))*100))") 20 | 21 | echo "{\"total\":$total,\"used\":$used,\"used_percent\":$used_percent}" -------------------------------------------------------------------------------- /modules/eww/scripts/workspaces/change-active.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # originally from https://wiki.hyprland.org/0.34.0/Useful-Utilities/Status-Bars/#configuration 3 | # modified to work with hyprsplit workspaces 1-9 4 | 5 | range() { 6 | min=$1 7 | max=$2 8 | val=$3 9 | if [ "$val" -lt "$min" ]; then 10 | echo "$max" 11 | elif [ "$val" -gt "$max" ]; then 12 | echo "$min" 13 | else 14 | echo "$val" 15 | fi 16 | } 17 | 18 | direction=$1 19 | 20 | # for hyprsplit 21 | LAST=9 22 | current=$2 23 | 24 | if [ "$direction" = "down" ]; then 25 | hyprctl dispatch split:workspace $(range 1 $LAST $(($current + 1))) 26 | elif [ "$direction" = "up" ]; then 27 | hyprctl dispatch split:workspace $(range 1 $LAST $(($current - 1))) 28 | fi -------------------------------------------------------------------------------- /modules/eww/scripts/workspaces/get-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # output json string of active and occupied hyprsplit workspaces for each monitor on hyprland, e.g. 3 | # {"HDMI-A-1":{"1":false,"2":true},"DP-1":{"3":true}} 4 | # only active and occupied workspaces are listed, "true" meaning the workspace is active. 5 | # each monitor will have exactly one (last) active workspace. 6 | # all workspace IDs are between 1 and 9 for hyprsplit workspaces. 7 | # uses hyprland-workspaces https://github.com/FieldofClay/hyprland-workspaces. 8 | 9 | # json string with active hyprsplit workspace for each monitor 10 | # with initial value like { "DP-1": 1, "HDMI-A-1": 1 } (1-9) 11 | active=$(hyprctl monitors -j | jq -cM 'map({ (.name): 1 }) | add') 12 | 13 | hyprland-workspaces _ | while read -r line; do 14 | # like { "DP-1": 1 } (1-9) 15 | current_active=$(jq -cM 'map( 16 | { (.name): (.workspaces[] | select(.active).id % 10) } 17 | ) | add' <<< "$line") 18 | 19 | # update active with current_active 20 | active=$(jq -cM '. + $arg' --argjson arg "$current_active" <<< "$active") 21 | 22 | jq -c --argjson active "$active" ' 23 | map({ 24 | (.name): ( 25 | (.workspaces | map( 26 | { (.id % 10 | tostring): .active } 27 | ) | add) 28 | * { ($active[.name] | tostring): true } 29 | ) 30 | }) | add' <<< "$line" 31 | done -------------------------------------------------------------------------------- /modules/fastfetch.nix: -------------------------------------------------------------------------------- 1 | # neofetch but fast 2 | args@{ config, lib, pkgs, variables, device, ... }: 3 | let 4 | configPath = "/etc/dotfiles/devices/${device.internalName}/fastfetch"; 5 | in 6 | lib.mkModule "fastfetch" config { 7 | environment.systemPackages = [ pkgs.fastfetch ]; 8 | 9 | # shell alias for shorter fastfetch (which uses device-specific config) 10 | environment.shellAliases.fastfetch-short = "fastfetch -c ${configPath}/short.jsonc"; 11 | 12 | # symlink device-specific config to ~/.config 13 | home-manager.users.${variables.username} = { config, ... }: { 14 | xdg.configFile."fastfetch/config.jsonc".source = 15 | config.lib.file.mkOutOfStoreSymlink "${configPath}/default.jsonc"; 16 | }; 17 | } -------------------------------------------------------------------------------- /modules/firefox/default.nix: -------------------------------------------------------------------------------- 1 | # browser 2 | args@{ config, lib, variables, ... }: 3 | lib.mkModule "firefox" config { 4 | home-manager.users.${variables.username} = { config, ... }: { 5 | programs.firefox = { 6 | enable = true; 7 | # allow custom css 8 | profiles.default.settings."toolkit.legacyUserProfileCustomizations.stylesheets" = true; 9 | }; 10 | 11 | # symlink custom css to ~ 12 | home.file.".mozilla/firefox/default/chrome/userChrome.css".source = 13 | config.lib.file.mkOutOfStoreSymlink "/etc/dotfiles/modules/firefox/firefox.css"; 14 | }; 15 | } -------------------------------------------------------------------------------- /modules/firefox/firefox.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --my-bg: #29282a; 3 | --my-bg-dark: #1F1E20; 4 | --arrowpanel-background: var(--my-bg) !important; 5 | --toolbar-bgcolor: var(--my-bg) !important; 6 | --urlbar-box-bgcolor: transparent !important; 7 | --urlbar-box-focus-bgcolor: transparent !important; 8 | } 9 | 10 | :root[sizemode="normal"] body { 11 | border-bottom-left-radius: 10px !important; 12 | border-bottom-right-radius: 10px !important; 13 | } 14 | 15 | #nav-bar { 16 | box-shadow: none !important; 17 | } 18 | 19 | #navigator-toolbox { 20 | background-color: var(--my-bg-dark) !important; 21 | } 22 | 23 | #urlbar[open] > #urlbar-background 24 | { 25 | background-color: var(--my-bg) !important; 26 | } 27 | 28 | #urlbar-background { 29 | background-color: transparent !important; 30 | outline: none !important; 31 | } 32 | 33 | #navigator-toolbox, 34 | #urlbar-background, 35 | #tabbrowser-tabs 36 | { 37 | border: none !important; 38 | } 39 | 40 | hbox.titlebar-spacer, 41 | hbox.titlebar-buttonbox-container, 42 | #alltabs-button, 43 | #identity-icon-label 44 | { 45 | display: none !important; 46 | } -------------------------------------------------------------------------------- /modules/fish/default.nix: -------------------------------------------------------------------------------- 1 | # 2 | args@{ config, lib, pkgs, variables, ... }: 3 | lib.mkModule "fish" config { 4 | # fish shell 5 | users.defaultUserShell = pkgs.fish; 6 | programs.fish.enable = true; 7 | environment.variables = { 8 | fish_color_param = "normal"; 9 | fish_color_error = "yellow"; 10 | fish_color_option = "cyan"; 11 | fish_color_command = "green"; 12 | fish_color_autosuggestion = "brblack"; 13 | }; 14 | 15 | # symlink startup script to ~/.config 16 | home-manager.users.${variables.username} = { config, ... }: { 17 | xdg.configFile."fish/config.fish".source = 18 | config.lib.file.mkOutOfStoreSymlink "/etc/dotfiles/modules/fish/init.fish"; 19 | }; 20 | } -------------------------------------------------------------------------------- /modules/fish/init.fish: -------------------------------------------------------------------------------- 1 | # greeting (only in interactive shell) 2 | function fish_greeting 3 | set key_color $(shuf -n 1 -e cyan magenta blue yellow green red) 4 | set title_color $(shuf -n 1 -e cyan magenta blue yellow green red) 5 | set logo_color $(shuf -n 1 -e cyan magenta blue yellow green red) 6 | fastfetch-short --color-keys $key_color --color-title $title_color --logo-color-1 $logo_color 7 | fortune -sn 200 8 | end 9 | 10 | # other stuff to do only in interactive shells 11 | if status is-interactive 12 | # setup zoxide to provide z as better cd 13 | zoxide init fish | source 14 | # use starship prompt 15 | starship init fish | source 16 | # setup direnv to load dev environment from directory 17 | direnv hook fish | source 18 | 19 | ### vim 20 | fish_vi_key_bindings 21 | set fish_vi_force_cursor 22 | set fish_cursor_insert line 23 | ### keybinds for default/visual mode 24 | bind -M default ö beginning-of-line 25 | bind -M visual ö beginning-of-line 26 | bind -M default ä end-of-line 27 | bind -M visual ä end-of-line 28 | ### keybinds for insert mode 29 | # ctrl+c => switch to default mode 30 | bind -M insert -m default \cc repaint-mode 31 | # ctrl+backspace => delete input 32 | bind -M insert \b kill-whole-line 33 | # ctrl+space => go through options 34 | bind -M insert -k nul complete 35 | # tab => accept suggestion 36 | bind -M insert \t accept-autosuggestion 37 | 38 | ### aliases 39 | alias cd z 40 | alias ls lsd 41 | alias cat bat 42 | alias aquarium "asciiquarium --transparent" 43 | alias flake-update "/etc/dotfiles/misc/update.sh" 44 | 45 | # easier numbat access 46 | function calc 47 | numbat -e "$argv" 48 | end 49 | 50 | # test command for maximum memory usage and runtime 51 | function memtime 52 | if test -z "$argv" 53 | set_color red 54 | echo -n "Error: " 55 | set_color normal 56 | echo "no command given!" 57 | return 1 58 | end 59 | set_color --bold 60 | echo -n "Maximum memory usage" 61 | set_color normal 62 | echo -n " (RSS): " 63 | set_color green --bold 64 | command time -v $argv > /dev/null 2>| \ 65 | grep "Maximum resident set size" | \ 66 | awk '{print $6 "K"}' | \ 67 | numfmt --from si --to si 68 | set_color normal 69 | hyperfine --shell none "$argv" 70 | end 71 | 72 | # alias some nix commands 73 | function nix 74 | # to nom (prettier output) 75 | if begin test "$argv[1]" = "shell"; 76 | or test "$argv[1]" = "develop"; 77 | or test "$argv[1]" = "build"; 78 | end 79 | nom $argv 80 | # to nh (prettier, faster and more convenient) 81 | else if test "$argv[1]" = "search" 82 | nh $argv 83 | # to original 84 | else 85 | # use "command" to avoid recursion of this function 86 | command nix $argv 87 | end 88 | end 89 | end 90 | 91 | # use like "flake-rebuild [--impure] [(other options)]" 92 | function flake-rebuild 93 | # exit with error message if current device is not set 94 | if test "x$NIX_FLAKE_CURRENT_DEVICE" = "x" 95 | set_color red 96 | echo -n "error: " 97 | set_color normal 98 | echo '$NIX_FLAKE_CURRENT_DEVICE is not set!' 99 | return 1 100 | end 101 | 102 | # use --impure if NIX_FLAKE_ALLOW_IMPURE_BY_DEFAULT is set 103 | if test "$NIX_FLAKE_ALLOW_IMPURE_BY_DEFAULT" = "1" 104 | set impure "--impure" 105 | end 106 | 107 | # rebuild with nh (for prettier output), current device, 108 | # --impure (if set) and other given args 109 | nh os switch -H $NIX_FLAKE_CURRENT_DEVICE /etc/dotfiles -- $impure $argv 110 | return $status 111 | end 112 | 113 | # like flake-rebuild, but for remote rebuilds 114 | # use like "flake-rebuild-remote HOSTNAME [--impure] [(other options)]" 115 | function flake-rebuild-remote 116 | # exit with error message if hostname wasnt given as first arg 117 | if test "x$argv[1]" = "x" 118 | set_color red 119 | echo -n "error: " 120 | set_color normal 121 | echo "no hostname given!" 122 | return 1 123 | end 124 | 125 | # use --impure if NIX_FLAKE_ALLOW_IMPURE_BY_DEFAULT is set 126 | if test "$NIX_FLAKE_ALLOW_IMPURE_BY_DEFAULT" = "1" 127 | set impure "--impure" 128 | end 129 | 130 | # rebuild with hostname, --impure (if set), other given args and nom (for prettier output) 131 | nixos-rebuild switch --fast --use-remote-sudo \ 132 | --flake /etc/dotfiles\#$argv[1] \ 133 | --target-host $argv[1] \ 134 | --build-host $argv[1] \ 135 | $impure $argv[2..-1] \ 136 | &| nom 137 | return $status 138 | end 139 | 140 | # pull dotfiles before running flake-rebuild 141 | function flake-rebuild-pull 142 | git -C /etc/dotfiles pull --rebase --autostash 143 | set git_status $status 144 | if test $git_status != 0 145 | return $git_status 146 | end 147 | flake-rebuild $argv 148 | return $status 149 | end -------------------------------------------------------------------------------- /modules/gitnuro/default.nix: -------------------------------------------------------------------------------- 1 | # git gui 2 | args@{ config, lib, pkgs, ... }: 3 | lib.mkModule "gitnuro" config { 4 | environment.systemPackages = [ (pkgs.unstable.gitnuro.overrideAttrs (attrs: rec { 5 | version = "1.4.2"; 6 | src = pkgs.fetchurl { 7 | url = "https://github.com/JetpackDuba/Gitnuro/releases/download/v${version}/Gitnuro-linux-x86_64-${version}.jar"; 8 | hash = "sha256-1lwuLPR6b1+I2SWaYaVrZkMcYVRAf1R7j/AwjQf03UM="; 9 | }; 10 | })) ]; 11 | } -------------------------------------------------------------------------------- /modules/gitnuro/gitnuro.json: -------------------------------------------------------------------------------- 1 | { 2 | "primary": "FF5AA0E6", 3 | "primaryVariant": "FF5AA0E6", 4 | "secondary": "FF5AA0E6", 5 | "hoverScrollbar": "FF5AA0E6", 6 | "modifiedFile": "FF5AA0E6", 7 | "addFile": "FF7BD88F", 8 | "diffLineAdded": "777BD88F", 9 | "conflictingFile": "FFFD9353", 10 | "error": "FFFC618D", 11 | "deletedFile": "FFFC618D", 12 | "diffLineRemoved": "77FC618D", 13 | "onBackground": "FFFFFFFF", 14 | "onBackgroundSecondary": "FFFFFFFF", 15 | "normalScrollbar": "FF403E42", 16 | "backgroundSelected": "FF403E42", 17 | "secondarySurface": "FF403E42", 18 | "surface": "FF333135", 19 | "tertiarySurface": "FF262527", 20 | "background": "FF262527", 21 | "dialogOverlay": "88000000", 22 | "onPrimary": "FF000000", 23 | "onError": "FF000000", 24 | "isLight": false 25 | } -------------------------------------------------------------------------------- /modules/hyprland/default.nix: -------------------------------------------------------------------------------- 1 | # hyprland (tiling wayland compositor) 2 | args@{ config, lib, pkgs, variables, device, ... }: 3 | let 4 | hypr-pkgs = (lib.getPkgs "hyprland"); 5 | plugins = [ 6 | # better multi-monitor workspaces 7 | (lib.getPkgs "hyprsplit").hyprsplit 8 | ]; 9 | in 10 | lib.mkModule "hyprland" config { 11 | programs.hyprland = { 12 | enable = true; 13 | package = hypr-pkgs.hyprland; 14 | portalPackage = hypr-pkgs.xdg-desktop-portal-hyprland; 15 | }; 16 | services.displayManager.defaultSession = "hyprland"; 17 | 18 | # make chromium / electron apps use wayland 19 | environment.variables.NIXOS_OZONE_WL = "1"; 20 | 21 | # use gtk desktop portal 22 | # (recommended for usage alongside hyprland desktop portal) 23 | xdg.portal = { 24 | enable = true; 25 | extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; 26 | }; 27 | 28 | environment.systemPackages = with pkgs; [ 29 | # must-haves according to hyprland wiki 30 | libsForQt5.qt5.qtwayland 31 | qt6.qtwayland 32 | # move all hyprland clients to a single workspace 33 | (lib.writeScriptFile "hyprctl-collect-clients" ./hyprctl-collect-clients.sh) 34 | ]; 35 | 36 | # use cached hyprland flake builds 37 | nix.settings = { 38 | substituters = [ "https://hyprland.cachix.org" ]; 39 | trusted-public-keys = [ "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" ]; 40 | }; 41 | 42 | # home manager module 43 | home-manager.users.${variables.username} = { config, ... }: { 44 | wayland.windowManager.hyprland = { 45 | enable = true; 46 | package = hypr-pkgs.hyprland; 47 | inherit plugins; 48 | # write config file that imports real config 49 | extraConfig = '' 50 | source = /etc/dotfiles/devices/${device.internalName}/hyprland.conf 51 | source = /etc/dotfiles/modules/hyprland/hyprland.conf 52 | ''; 53 | # tell systemd to import environment by default 54 | # this e.g. can fix screenshare by making sure hyprland desktop portal gets its required variables 55 | systemd.variables = [ "--all" ]; 56 | }; 57 | 58 | # lock before/after entering sleep with swaylock-effects 59 | services.hypridle = { 60 | enable = true; 61 | settings = { 62 | general = { 63 | # set command for loginctl 64 | lock_cmd = "swaylock-effects"; 65 | } // (if device.internalName == "laptop" then { 66 | # for laptops: lock before going to sleep, which shows the lockscreen 67 | # shortly, but you dont see it if you close the laptop lid 68 | before_sleep_cmd = "loginctl lock-session"; 69 | } else { 70 | # otherwise: lock after resuming from sleep, so you dont 71 | # see the lockscreen before entering sleep 72 | 73 | # after resuming, there is split second of time before 74 | # after_sleep_cmd is run. to secure this, inhibit input 75 | # with a hyprland keybind submap for this time 76 | before_sleep_cmd = "hyprctl dispatch submap inhibit-input"; 77 | after_sleep_cmd = "loginctl lock-session; hyprctl dispatch submap reset"; 78 | }); 79 | 80 | listener = (if device.internalName == "laptop" then { 81 | # turn off monitor when discharging and inactive 82 | timeout = 120; # seconds 83 | on-timeout = "cat /sys/class/power_supply/BAT0/status | grep Discharging && hyprctl dispatch dpms off"; 84 | on-resume = "hyprctl dispatch dpms on"; 85 | } else { 86 | # hypridle complains if there are no listeners, 87 | # so i made this one which does nothing 88 | timeout = 999999999999999999; 89 | on-timeout = ""; 90 | on-resume = ""; 91 | }); 92 | }; 93 | }; 94 | }; 95 | } -------------------------------------------------------------------------------- /modules/hyprland/hyprctl-collect-clients.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # move all hyprland clients to the current workspace 3 | 4 | target_workspace=$(hyprctl monitors -j | jq '.[] | select(.focused == true) | .activeWorkspace.id') 5 | 6 | # result string for hyptctl --batch 7 | result="" 8 | 9 | # for every hyprland client address 10 | for address in $(hyprctl clients -j | jq -r ".[] | select (.workspace.id != $target_workspace and .workspace.id != -1) | .address"); do 11 | # append hyprctl command to execute with address 12 | result="$result dispatch movetoworkspacesilent $target_workspace,address:$address;" 13 | done 14 | 15 | # execute commands 16 | hyprctl --batch $result -------------------------------------------------------------------------------- /modules/hyprland/hyprland.conf: -------------------------------------------------------------------------------- 1 | #----- environment variables 2 | env = XDG_CURRENT_DESKTOP,Hyprland 3 | # bigger cursor 4 | env = XCURSOR_SIZE,32 5 | # wallpaper animation settings 6 | env = SWWW_TRANSITION,wipe 7 | env = SWWW_TRANSITION_FPS,144 8 | env = SWWW_TRANSITION_STEP,255 9 | env = SWWW_TRANSITION_ANGLE,45 10 | 11 | #----- start background processes 12 | exec-once = /etc/dotfiles/misc/autostart.sh 13 | # for volume osd 14 | exec-once = swayosd-server --top-margin 0.925 15 | # open desktop widget on all monitors 16 | exec-once = sleep 0.75 && eww-open-everywhere 17 | # notifications with swaync 18 | exec-once = swaync 19 | exec-once = /etc/dotfiles/modules/swaync/inhibit-on-screenshare.sh 20 | # for wallpapers 21 | exec-once = swww-daemon --no-cache && swww clear 000000 22 | # set wallpaper and border color with swww 23 | $wallpaper-cmd = python /etc/dotfiles/modules/hyprland/wallpaper.py 24 | exec-once = sleep 0.1 && $wallpaper-cmd 25 | # close copyq which currently fails to hide itself on command 26 | exec-once = sleep 0.4 && hyprctl dispatch closewindow initialclass:^com\.github\.hluk.copyq\$ 27 | 28 | #----- window rules 29 | # https://wiki.hyprland.org/Configuring/Window-Rules/ 30 | 31 | windowrulev2 = tile, class:^(com-jetpackduba-gitnuro-MainKt)$ 32 | windowrulev2 = float, class:^(com.github.hluk.copyq)$ 33 | 34 | # opacity 35 | windowrulev2 = opacity 0.90, class:^(codium)$ 36 | windowrulev2 = opacity 0.90, class:^(jetbrains-.*)$ 37 | windowrulev2 = opacity 0.85, class:^(com-jetpackduba-gitnuro-MainKt)$ 38 | windowrulev2 = opacity 0.80, class:^(gcr-prompter)$ 39 | windowrulev2 = opacity 0.80, class:^(Lxpolkit)$ 40 | windowrulev2 = opacity 0.75, class:^(obsidian)$ 41 | windowrulev2 = opacity 0.70, class:^(org.gnome.Nautilus)$ 42 | windowrulev2 = opacity 0.70, initialTitle:^(Spotify Premium)$ 43 | 44 | # flameshot (https://github.com/flameshot-org/flameshot/issues/2978#issuecomment-2543984205) 45 | windowrulev2 = noanim, class:^(flameshot)$ 46 | windowrulev2 = float, class:^(flameshot)$ 47 | windowrulev2 = noinitialfocus, class:^(flameshot)$ 48 | windowrulev2 = move 0 0,class:^(flameshot)$ 49 | windowrulev2 = suppressevent fullscreen,class:^(flameshot)$ 50 | windowrulev2 = stayfocused,class:^(flameshot)$ 51 | windowrulev2 = noborder,class:^(flameshot)$ 52 | windowrulev2 = pin, class:^(flameshot)$ 53 | windowrulev2 = monitor 0, class:^(flameshot)$ 54 | 55 | ### layer rules 56 | # swaync notification center 57 | layerrule = blur, ^(swaync-control-center)$ 58 | layerrule = ignorezero, ^(swaync-control-center)$ 59 | # swaync notifications (ignorealpha for smoother notification fade-out) 60 | layerrule = blur, ^(swaync-notification-window)$ 61 | layerrule = ignorealpha 0.25, ^(swaync-notification-window)$ 62 | # rofi 63 | layerrule = blur, ^(rofi)$ 64 | layerrule = ignorezero, ^(rofi)$ 65 | # eww 66 | layerrule = blur, ^(eww-desktop-widget)$ 67 | layerrule = ignorezero, ^(eww-desktop-widget)$ 68 | 69 | #----- variables 70 | # https://wiki.hyprland.org/Configuring/Variables/ 71 | 72 | general { 73 | gaps_in = 5 74 | gaps_out = 10 75 | border_size = 3 76 | col.active_border = rgb(363537) # will be overridden by python script 77 | col.inactive_border = rgb(363537) 78 | layout = dwindle 79 | # resize on borders 80 | resize_on_border = true 81 | extend_border_grab_area = 10 82 | hover_icon_on_border = false 83 | } 84 | 85 | input { 86 | kb_layout = de 87 | mouse_refocus = false # only change mouse focus when crossing borders 88 | follow_mouse = 1 89 | } 90 | 91 | cursor { 92 | inactive_timeout = 3 # seconds 93 | # keep mouse in center when zooming 94 | zoom_rigid = true 95 | } 96 | 97 | decoration { 98 | rounding = 10 99 | blur { 100 | enabled = true 101 | ignore_opacity = true 102 | passes = 3 103 | size = 9 104 | # rightclick menus 105 | popups = true 106 | popups_ignorealpha = 0.15 # looks best in nautilus 107 | } 108 | # disable all shadow stuff 109 | shadow { 110 | enabled = false 111 | range = 0 112 | render_power = 1 113 | ignore_window = false 114 | color = rgba(00000000) 115 | scale = 0.0 116 | } 117 | } 118 | 119 | gestures { 120 | workspace_swipe = false 121 | } 122 | 123 | animations { 124 | # https://wiki.hyprland.org/Configuring/Animations/ 125 | enabled = true 126 | 127 | # curves from https://easings.net/ 128 | bezier = easeInQuart, 0.50, 0, 0.75, 0 129 | bezier = easeOutQuart, 0.25, 1, 0.50, 1 # pretty similar to default 130 | bezier = easeInOutQuart, 0.76, 0, 0.24, 1 131 | 132 | # border color change 133 | animation = border, 1, 10, default 134 | # border gradient angle change 135 | animation = borderangle, 1, 10, default 136 | # switch workspace 137 | animation = workspaces, 1, 3, easeInOutQuart, fade 138 | # switch to special workspace? 139 | #animation = specialWorkspace, 1, 5, easeOutQuart, slidevert 140 | 141 | # default for window animations 142 | #animation = windows, 1, 5, easeOutQuart 143 | # window open 144 | animation = windowsIn, 1, 5, easeOutQuart, popin 75% 145 | # window close 146 | animation = windowsOut, 1, 5, easeOutQuart, popin 90% 147 | # automatic window move/resize/... (style doesnt matter?) 148 | animation = windowsMove, 1, 3.5, easeOutQuart 149 | 150 | # default for fade animations 151 | animation = fade, 1, 3.5, easeOutQuart 152 | # open layer/window 153 | #animation = fadeIn, 1, 3.5, easeOutQuart 154 | # close layer/window 155 | #animation = fadeOut, 1, 3.5, easeOutQuart 156 | # opacity change 157 | #animation = fadeSwitch, 1, 3.5, easeOutQuart 158 | # shadow change...? 159 | #animation = fadeShadow, 1, 3.5, easeOutQuart 160 | # inactive window dimming 161 | #animation = fadeDim, 1, 3.5, easeOutQuart 162 | } 163 | 164 | dwindle { 165 | # https://wiki.hyprland.org/Configuring/Dwindle-Layout/ 166 | # more control over split direction based on cursor position 167 | smart_split = true 168 | } 169 | 170 | binds { 171 | workspace_center_on = 1 # focus last active window on workspace switch 172 | } 173 | 174 | misc { 175 | new_window_takes_over_fullscreen = 2 176 | mouse_move_enables_dpms = true 177 | # black background by default 178 | force_default_wallpaper = 0 179 | disable_hyprland_logo = true 180 | background_color = rgb(000000) 181 | } 182 | 183 | ecosystem { 184 | no_update_news = true 185 | } 186 | 187 | #----- plugins 188 | plugin { 189 | # ensure eww/hyprland-workspaces work correctly 190 | hyprsplit { 191 | num_workspaces = 10 192 | # only output workspaces with hyprland-workspaces if they 193 | # are active or have windows on them, not all the time 194 | persistent_workspaces = false 195 | } 196 | } 197 | 198 | #----- keybinds 199 | # https://wiki.hyprland.org/Configuring/Binds/ 200 | $mod = SUPER 201 | 202 | # submap to ignore all kinds of input 203 | submap = inhibit-input 204 | bindi = , catchall, exec, 205 | submap = reset 206 | 207 | # run programs 208 | bind = $mod , return, exec, alacritty 209 | bind = $mod , E , exec, GTK_THEME=Orchis-Green-Dark nautilus -w 210 | bind = $mod , B , exec, zen 211 | bind = $mod , C , exec, codium 212 | bind = $mod , G , exec, gitnuro 213 | bind = $mod , O , exec, obsidian 214 | 215 | # DE-like stuff (application launcher, screenshot, notification center, ...) 216 | bindr = $mod , Super_L, exec, pgrep rofi && pkill rofi || rofi -show drun -show-icons 217 | bind = $mod , period , exec, rofi -modi emoji:rofimoji -show emoji 218 | bind = $mod , N , exec, swaync-client -t -sw 219 | bind = $mod , V , exec, copyq toggle 220 | bind = $mod , W , exec, $wallpaper-cmd 221 | bind = $mod SHIFT, V , exec, wl-paste | swappy -f - 222 | bind = $mod SHIFT, C , exec, hyprpicker | wl-copy 223 | bind = $mod SHIFT, S , exec, flameshot gui 224 | bind = $mod CTRL , L , exec, swaylock-effects 225 | bind = $mod CTRL , R , exec, eww-open-everywhere && $wallpaper-cmd 226 | bind = $mod CTRL , return , exec, hyprctl-collect-clients 227 | # elevate eww desktop widget 228 | bind = $mod , tab , exec, eww-open-everywhere true 229 | bindr = $mod , tab , exec, eww-open-everywhere 230 | bind = $mod CTRL , tab , exec, eww-open-everywhere toggle 231 | # magnifying glasses around cursor (holdable) 232 | # increase/decrease magnification by 10% of current value (but never get below 1) 233 | binde = $mod , plus , exec, hyprctl keyword cursor:zoom_factor "$(hyprctl getoption cursor:zoom_factor | grep float | awk '{print $2* 1.1}')" 234 | binde = $mod , minus, exec, hyprctl keyword cursor:zoom_factor "$(hyprctl getoption cursor:zoom_factor | grep float | awk '{print ($2*(1/1.1) < 1) ? 1 : $2*(1/1.1)}')" 235 | # media player control 236 | bind = , print, exec, playerctl next 237 | bind = , pause, exec, playerctl play-pause 238 | # adjust volume (holdable) 239 | binde = $mod , up , exec, swayosd-client --output-volume +5 && aplay /etc/dotfiles/misc/notification.wav 240 | binde = $mod , down, exec, swayosd-client --output-volume -5 && aplay /etc/dotfiles/misc/notification.wav 241 | bindl = $mod CTRL , M , exec, swayosd-client --output-volume -125 242 | # adjust brightness (holdable) 243 | binde = $mod CTRL , up , exec, swayosd-client --brightness +5 244 | binde = $mod CTRL , down, exec, swayosd-client --brightness -5 245 | # power state stuff 246 | bind = $mod CTRL SHIFT, L, exit, 247 | bindl = $mod CTRL SHIFT, S, exec, systemctl suspend 248 | # toggle power state of all monitors 249 | bind = $mod CTRL SHIFT, P, exec, hyprctl monitors -j | jq -e '.[0].dpmsStatus' && { hyprctl dispatch dpms off; openrgb -p off; } || { hyprctl dispatch dpms on; openrgb -p default; } 250 | 251 | # just Hyprland stuff 252 | bind = $mod , Q , killactive, 253 | bind = $mod , space , togglefloating, 254 | bind = $mod , F , fullscreen, 0 255 | bind = $mod , M , fullscreen, 1 # maximize 256 | bind = $mod , mouse:274, fullscreen, 1 # maximize on mouse wheel press 257 | # scroll through workspaces on monitor while holding $mod 258 | bind = $mod , mouse_down, workspace, m-1 259 | bind = $mod , mouse_up , workspace, m+1 260 | # move/resize windows with mouse buttons while holding $mod 261 | bindm = $mod , mouse:272, movewindow 262 | bindm = $mod , mouse:273, resizewindow 263 | # move focus 264 | bind = $mod , h, movefocus, l 265 | bind = $mod , l, movefocus, r 266 | bind = $mod , k, movefocus, u 267 | bind = $mod , j, movefocus, d 268 | # swap window 269 | bind = $mod SHIFT, h, swapwindow, l 270 | bind = $mod SHIFT, l, swapwindow, r 271 | bind = $mod SHIFT, k, swapwindow, u 272 | bind = $mod SHIFT, j, swapwindow, d 273 | 274 | #----- unique workspace per monitor with hyprsplit 275 | # switch workspace 276 | bind = $mod , 1, split:workspace, 1 277 | bind = $mod , 2, split:workspace, 2 278 | bind = $mod , 3, split:workspace, 3 279 | bind = $mod , 4, split:workspace, 4 280 | bind = $mod , 5, split:workspace, 5 281 | bind = $mod , 6, split:workspace, 6 282 | bind = $mod , 7, split:workspace, 7 283 | bind = $mod , 8, split:workspace, 8 284 | bind = $mod , 9, split:workspace, 9 285 | # move window to workspace 286 | bind = $mod SHIFT, 1, split:movetoworkspacesilent, 1 287 | bind = $mod SHIFT, 2, split:movetoworkspacesilent, 2 288 | bind = $mod SHIFT, 3, split:movetoworkspacesilent, 3 289 | bind = $mod SHIFT, 4, split:movetoworkspacesilent, 4 290 | bind = $mod SHIFT, 5, split:movetoworkspacesilent, 5 291 | bind = $mod SHIFT, 6, split:movetoworkspacesilent, 6 292 | bind = $mod SHIFT, 7, split:movetoworkspacesilent, 7 293 | bind = $mod SHIFT, 8, split:movetoworkspacesilent, 8 294 | bind = $mod SHIFT, 9, split:movetoworkspacesilent, 9 -------------------------------------------------------------------------------- /modules/hyprland/wallpaper.py: -------------------------------------------------------------------------------- 1 | import random, subprocess, time, sys, os 2 | 3 | # make sure script is only running once 4 | running_scripts = len(subprocess.run(["pgrep", "-f", __file__], capture_output=True).stdout.splitlines()) 5 | if running_scripts > 1: 6 | print("script already running! exiting...") 7 | sys.exit(1) 8 | 9 | # color scheme to use 10 | colors = { 11 | # color format for hyprland 12 | "r": "rgb(FC618D)", 13 | "g": "rgb(7BD88F)", 14 | "y": "rgb(FD9353)", 15 | "b": "rgb(5AA0E6)", 16 | "m": "rgb(948AE3)", 17 | "c": "rgb(5AD4E6)" 18 | } 19 | 20 | # directory of unsorted wallpapers to pick at random 21 | OTHER_WALLPAPER_PATH = "/etc/dotfiles/wallpapers/misc/" 22 | 23 | # if directory exists and is not empty: use random wallpaper from it 24 | if os.path.isdir(OTHER_WALLPAPER_PATH) and len(os.listdir(OTHER_WALLPAPER_PATH)) != 0: 25 | # interpret all files in the directory as wallpapers 26 | wallpapers = os.listdir(OTHER_WALLPAPER_PATH) 27 | # choose a random one 28 | wallpaper = random.choice(wallpapers) 29 | wallpaper_path = OTHER_WALLPAPER_PATH + wallpaper 30 | 31 | # set 4 accent colors in order for each wallpaper 32 | color_table = { 33 | "calm_meadow.png": ["r", "y", "m", "g"], 34 | "dawn.jpg": ["b", "c", "m", "g"], 35 | "dead_waters.jpg": ["y", "m", "g", "b"], 36 | "diamond_afternoon.jpg": ["m", "r", "y", "b"], 37 | "distant_garden.jpg": ["g", "y", "c", "r"], 38 | "enigmatic.jpg": ["b", "g", "m", "r"], 39 | "fields_of_bronze.jpg": ["y", "m", "b", "g"], 40 | "frontier_skies.jpg": ["c", "g", "y", "b"], 41 | "i_of_the_trident.jpg": ["r", "y", "g", "b"], 42 | "long_way_to_eden.jpg": ["m", "b", "g", "r"], 43 | "missed_my_ride.jpg": ["y", "c", "y", "r"], 44 | "my_sky.jpg": ["g", "c", "y", "b"], 45 | "night_sky.jpg": ["g", "m", "y", "r"], 46 | "paths_less_travelled.jpg": ["y", "g", "r", "m"], 47 | "place_out_of_place.jpg": ["c", "g", "y", "b"], 48 | "purple_mountain.jpg": ["b", "g", "c", "y"], 49 | "red_plants.jpg": ["r", "m", "g", "c"], 50 | "river_and_sky.jpg": ["r", "y", "m", "g"], 51 | "scarecrow.jpg": ["m", "r", "g", "b"], 52 | "scifi-planet.jpg": ["c", "b", "g", "m"], 53 | "stargazer.jpg": ["r", "y", "g", "c"], 54 | "the_ritual.jpg": ["y", "r", "g", "m"], 55 | "untamed.jpg": ["b", "r", "y", "m"], 56 | "valley_with_tree.jpg": ["g", "c", "r", "m"], 57 | # currently not used 58 | "field_and_sky.jpg": ["m", "r", "g", "b"], 59 | "dawn_on_mountain.jpg": ["y", "r", "c", "g"], 60 | "valley_with_beacon.jpg": ["y", "r", "g", "b"], 61 | "dawn_on_mountain_with_tree.jpg": ["b", "g", "r", "y"], 62 | } 63 | 64 | # use colors from table if possible 65 | if wallpaper in color_table.keys(): 66 | table_entry = color_table[wallpaper] 67 | color1 = colors[table_entry[0]] 68 | color2 = colors[table_entry[1]] 69 | color3 = colors[table_entry[2]] 70 | color4 = colors[table_entry[3]] 71 | else: # use default colors 72 | color1 = colors["c"] 73 | color2 = colors["g"] 74 | color3 = colors["r"] 75 | color4 = colors["m"] 76 | 77 | # use random color variant of nixos wallpaper 78 | else: 79 | NIXOS_WALLPAPER_FORMAT = "/etc/dotfiles/wallpapers/nixos/{}.png" 80 | NIXOS_WALLPAPERS = [ 81 | "rg", "gr", 82 | "ry", "yr", 83 | "rb", "br", 84 | "rm", "mr", 85 | "rc", "cr", 86 | "gy", "yg", 87 | "gb", "bg", 88 | "gm", "mg", 89 | "gc", "cg", 90 | "yb", "by", 91 | "ym", "my", 92 | "yc", "cy", 93 | "bm", "mb", 94 | "bc", "cb", 95 | "mc", "cm", 96 | ] 97 | 98 | # choose random wallpaper and format path to it 99 | wallpaper = random.choice(NIXOS_WALLPAPERS) 100 | wallpaper_path = NIXOS_WALLPAPER_FORMAT.format(wallpaper) 101 | # get all 4 colors not in the wallpaper in random order 102 | available_color_keys = list(set(colors.keys()) - set(wallpaper)) 103 | random.shuffle(available_color_keys) 104 | available_colors = [colors[c] for c in available_color_keys] 105 | # set them as accent colors 106 | color1 = available_colors[0] 107 | color2 = available_colors[1] 108 | color3 = available_colors[2] 109 | color4 = available_colors[3] 110 | 111 | # set wallpaper 112 | subprocess.run(["swww", "img", wallpaper_path]) 113 | # wait a bit 114 | time.sleep(2.5) 115 | # set active border color to gradient between color1 and color2 116 | subprocess.run(["hyprctl", "keyword", "general:col.active_border", color1, color2, "45deg"]) -------------------------------------------------------------------------------- /modules/jetbrains/.ideavimrc: -------------------------------------------------------------------------------- 1 | """ Map leader to space --------------------- 2 | let mapleader=" " 3 | 4 | """ Plugins -------------------------------- 5 | set surround 6 | set multiple-cursors 7 | 8 | """ Plugin settings ------------------------- 9 | let g:argtextobj_pairs="[:],(:),<:>" 10 | 11 | """ Common settings ------------------------- 12 | set nu 13 | set hls 14 | set so=5 15 | set showmode 16 | set incsearch 17 | 18 | """ Idea specific settings ------------------ 19 | set ideajoin 20 | set ideastatusicon=gray 21 | set idearefactormode=keep 22 | 23 | """ Mappings with leader -------------------- 24 | map d (Debug) 25 | map r (RenameElement) 26 | map c (Stop) 27 | map z (ToggleDistractionFreeMode) 28 | 29 | map s (SelectInProjectView) 30 | map a (Annotate) 31 | map h (Vcs.ShowTabbedFileHistory) 32 | map (GotoNextError) 33 | 34 | map b (ToggleLineBreakpoint) 35 | map o (FileStructurePopup) 36 | 37 | """ Mappings without leader ----------------- 38 | " normal mode 39 | nnoremap K ok 40 | nnoremap >> 41 | nnoremap << 42 | " visual mode 43 | vnoremap "+y 44 | vnoremap > 45 | vnoremap < 46 | " normal and visual mode 47 | nnoremap ß :noh 48 | vnoremap ß :noh 49 | 50 | nnoremap ü :tabp 51 | vnoremap ü :tabp 52 | 53 | nnoremap + :tabn 54 | vnoremap + :tabn 55 | 56 | nnoremap ö ^ 57 | vnoremap ö ^ 58 | 59 | nnoremap ä $ 60 | vnoremap ä $ 61 | -------------------------------------------------------------------------------- /modules/jetbrains/default.nix: -------------------------------------------------------------------------------- 1 | # jetbrains ide's 2 | args@{ config, lib, pkgs, variables, ... }: 3 | lib.mkModule "jetbrains" config { 4 | environment.systemPackages = with pkgs.jetbrains; [ 5 | pycharm-community 6 | #idea-community 7 | #rust-rover 8 | #rider 9 | ]; 10 | 11 | # symlink ideavim config to ~ 12 | home-manager.users.${variables.username} = { config, ... }: { 13 | home.file.".ideavimrc".source = 14 | config.lib.file.mkOutOfStoreSymlink "/etc/dotfiles/modules/jetbrains/.ideavimrc"; 15 | }; 16 | } -------------------------------------------------------------------------------- /modules/lamp-server/default.nix: -------------------------------------------------------------------------------- 1 | # server to control govee rgb lamp 2 | args@{ config, lib, variables, device, ... }: 3 | let 4 | port = 9000; # currently hard-coded in server 5 | lamp-server-pkg = (lib.getPkgs "lamp-server").lamp-server; 6 | in 7 | lib.mkModule "lamp-server" config { 8 | 9 | environment.systemPackages = [ lamp-server-pkg ]; 10 | networking.firewall.allowedTCPPorts = [ port ]; 11 | 12 | systemd.services.lamp-server = { 13 | enable = true; 14 | description = "server to control govee rgb lamp"; 15 | serviceConfig = { 16 | User = variables.username; 17 | ExecStart = "${lamp-server-pkg}/bin/lamp-server"; 18 | }; 19 | wantedBy = [ "multi-user.target" ]; 20 | }; 21 | 22 | local.website.extraConfig = '' 23 | lamp.juliusboettger.com { 24 | reverse_proxy :${toString port} 25 | } 26 | ''; 27 | 28 | # configure secrets 29 | sops = { 30 | # get govee api secrets from local sops file secrets.yaml 31 | secrets = { 32 | govee_api_key = { sopsFile = ./secrets.yaml; }; 33 | govee_device = { sopsFile = ./secrets.yaml; }; 34 | govee_model = { sopsFile = ./secrets.yaml; }; 35 | }; 36 | # write config file for with secrets 37 | templates."lamp-server.yaml" = { 38 | path = "/home/${variables.username}/.config/lamp-server.yaml"; 39 | owner = variables.username; 40 | content = '' 41 | govee_api_key: "${config.sops.placeholder.govee_api_key}" 42 | govee_device: "${config.sops.placeholder.govee_device}" 43 | govee_model: "${config.sops.placeholder.govee_model}" 44 | ''; 45 | }; 46 | }; 47 | } -------------------------------------------------------------------------------- /modules/lamp-server/secrets.yaml: -------------------------------------------------------------------------------- 1 | govee_api_key: ENC[AES256_GCM,data:a34rPD4NGWSSU6E5s1Nfi0O9/nZSlCzZpbzcDFRdjvJlftFD,iv:MnWdVMKIdIcbr42LPJzkzT8//X8SLHYJgeqLDxmVSwU=,tag:w415jXYaOEssRUy4fKXkBA==,type:str] 2 | govee_device: ENC[AES256_GCM,data:c52VG7UQIq3tlc5V+16KElz8gV/yC/M=,iv:vwsUh+RAa4LCBXWe/n92iJHg4nbgS83ILCXokbdt+F0=,tag:G4Jk2DtXw1kfbJpHVz6rxw==,type:str] 3 | govee_model: ENC[AES256_GCM,data:/VevHe8=,iv:Yqxb5jK6P8Vy3jy1iUZ7B/jkjoYFuDXLwiLjrJoRjAk=,tag:yOQUNzY9IqsaJI6pcBMKnw==,type:str] 4 | sops: 5 | kms: [] 6 | gcp_kms: [] 7 | azure_kv: [] 8 | hc_vault: [] 9 | age: 10 | - recipient: age12zlz6lvcdk6eqaewfylg35w0syh58sm7gh53q5vvn7hd7c6nngyseftjxl 11 | enc: | 12 | -----BEGIN AGE ENCRYPTED FILE----- 13 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwRXhiVXl6TlA0K2ttL0Nr 14 | TTUyUTczdFJrNXVQOUFPYUZvblhKZ1pzVnhRCklvQTJQeW5TZEYxZkRzTFNRZ2g5 15 | NVBMb1hmaldWa003MEY2ZjVvY29WcEUKLS0tIDFSejkzS1M4YStVeE9aNk5rQ1cw 16 | azV2dTZlcTN1c2VmTFFqMWtwaEdycHMK5p0O5OTcYn8Mqa/VCPUUyiaNFmI+/afP 17 | FhDI0+CtbR+bnCS5WyWbbMXsEP/QVRahc4ufETiCskebCj0Zdjd/kA== 18 | -----END AGE ENCRYPTED FILE----- 19 | - recipient: age1tm5qy7jvkhaen6s4mzf0wfmhm60w47h6mgnhl49zkettc2uye4kse0f2kj 20 | enc: | 21 | -----BEGIN AGE ENCRYPTED FILE----- 22 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKaTVOTEZTUG5OcjVUc3ZM 23 | M0g0VFYxcVlWMjBObEMyekY0RXgxNFlSM1U4CjdRS0ZjaE9sRFJKRmpMSmkxN0pi 24 | Z2w0NFBWbWdmOHFXUStJTE1qL3MvU00KLS0tIEFJOVRIaUJjaW1BZ2Y2RlNDSDJ1 25 | VWROOVBYeGVMZ01DYnJua3VLQmFSbk0Kq3h8NMZTj3fgrmeSKj4auqkNHTgivxyU 26 | b7TMupN/5z+eg9OsrzFDgBHluCe7b21YfIASBOCwn7CoqxYUv4yx7Q== 27 | -----END AGE ENCRYPTED FILE----- 28 | - recipient: age1qwj962m2mkzhk64t6fztw3hhh94wn82ayh9xl5u4vhajzpqa9ekqxthuaa 29 | enc: | 30 | -----BEGIN AGE ENCRYPTED FILE----- 31 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0SUI0V2hncVQvbU1vdnFT 32 | c3h1S1FJZTdsT3RseXVUeHVmZ2xSNGswZFNZCnptcEMxdWFzdUpueHJLQUoybk9t 33 | eEZDMGpLVndRWGdqTVJpY1hLS0RnLzAKLS0tIE9VQVUxdGl6WXV3aytQUWRmS0xv 34 | VTNkcGsvME9iL1VBc1IwOVRSL1ovSjgKdrBieNCXQVWo6oVH4apf9KJsScPKvYNV 35 | jiuhEeN72crx014t5fSyCLUvTF21NH+y4R2qxoU9gT0IKd3yxSfbOQ== 36 | -----END AGE ENCRYPTED FILE----- 37 | lastmodified: "2024-12-21T08:53:48Z" 38 | mac: ENC[AES256_GCM,data:XHYmWZiN2Cn74RmAcR18NOqnwg8DZubPgTPmHYvYezT7de/hYhWU1HYmuj7dYWOgU3aZtsAMwS2pVMb6+HYq9cuYsWGMOWpl4tAQh9rsnrdiXgD8CxTAtrDW9nhP8GS2esiIDzII0d4bDAi4QY4+WcyYRcsI5GQ/qfctauiDFGE=,iv:t2K6SC7aQdD209+5eA4rck44nNn6938I+nvbkoCoWtk=,tag:He8CZIwzR/rev8tW1ba16A==,type:str] 39 | pgp: [] 40 | unencrypted_suffix: _unencrypted 41 | version: 3.9.2 42 | -------------------------------------------------------------------------------- /modules/minecraft-server/default.nix: -------------------------------------------------------------------------------- 1 | # host minecraft server 2 | args@{ config, lib, inputs, device, ... }: 3 | let 4 | server-pkgs = inputs.nix-minecraft.legacyPackages.${device.system}.minecraftServers; 5 | in 6 | { 7 | options.local.minecraft-server.enable = lib.mkEnableOption "whether to enable minecraft-server"; 8 | imports = [ inputs.nix-minecraft.nixosModules.minecraft-servers ]; 9 | config = lib.mkIf config.local.minecraft-server.enable { 10 | 11 | services.minecraft-servers = { 12 | enable = true; 13 | eula = true; 14 | openFirewall = true; 15 | dataDir = "/srv/minecraft"; 16 | 17 | servers.default = { 18 | enable = true; 19 | files."server-icon.png" = ./server-icon.png; 20 | package = server-pkgs.fabric-1_21_5; 21 | 22 | serverProperties = { 23 | white-list = true; 24 | # default, also needs to be open on router! 25 | server-port = 25565; 26 | 27 | max-players = 8; 28 | view-distance = 10; 29 | simulation-distance = 10; 30 | jvmOpts = "-Xms1G -Xmx7G"; # min/max memory 31 | # different quotes to avoid double backspaces for escaping 32 | motd = ''\u00a73\u00a7lJulius\u00a7b\u00a7l Server\u00a7r\n\u00a7f\u263a \ud83d\udd14 \ud83c\udfa3 \u2600 \u26cf \ud83e\uddea \u266b''; 33 | }; 34 | }; 35 | }; 36 | }; 37 | } -------------------------------------------------------------------------------- /modules/minecraft-server/server-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/modules/minecraft-server/server-icon.png -------------------------------------------------------------------------------- /modules/nautilus.nix: -------------------------------------------------------------------------------- 1 | # file manager 2 | args@{ config, lib, pkgs, ... }: 3 | lib.mkModule "nautilus" config { 4 | environment.systemPackages = with pkgs; [ 5 | unstable.nautilus 6 | sushi # thumbnails in nautilus 7 | ]; 8 | 9 | # needed for trash to work in nautilus 10 | services.gvfs.enable = true; 11 | 12 | # set default application for opening directories 13 | xdg.mime.defaultApplications."inode/directory" = "nautilus.desktop"; 14 | 15 | programs.nautilus-open-any-terminal = { 16 | enable = true; 17 | terminal = "alacritty"; 18 | }; 19 | } -------------------------------------------------------------------------------- /modules/nvidia.nix: -------------------------------------------------------------------------------- 1 | # for nvidia gpu 2 | args@{ config, lib, pkgs, ... }: 3 | lib.mkModule "nvidia" config { 4 | services.xserver.videoDrivers = [ "nvidia" ]; 5 | hardware.nvidia = { 6 | modesetting.enable = true; 7 | nvidiaSettings = false; 8 | # pin driver version https://www.nvidia.com/en-us/drivers/unix/ 9 | # https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/nvidia-x11/default.nix 10 | package = config.boot.kernelPackages.nvidiaPackages.mkDriver { 11 | version = "570.153.02"; 12 | sha256_64bit = "sha256-FIiG5PaVdvqPpnFA5uXdblH5Cy7HSmXxp6czTfpd4bY="; 13 | sha256_aarch64 = "sha256-FKhtEVChfw/1sV5FlFVmia/kE1HbahDJaxTlpNETlrA="; 14 | openSha256 = "sha256-2DpY3rgQjYFuPfTY4U/5TcrvNqsWWnsOSX0f2TfVgTs="; 15 | settingsSha256 = "sha256-5m6caud68Owy4WNqxlIQPXgEmbTe4kZV2vZyTWHWe+M="; 16 | persistencedSha256 = "sha256-OSo4Od7NmezRdGm7BLLzYseWABwNGdsomBCkOsNvOxA="; 17 | patches = [( 18 | # https://github.com/NVIDIA/open-gpu-kernel-modules/issues/840 19 | pkgs.fetchpatch { 20 | url = "https://github.com/CachyOS/kernel-patches/raw/914aea4298e3744beddad09f3d2773d71839b182/6.15/misc/nvidia/0003-Workaround-nv_vm_flags_-calling-GPL-only-code.patch"; 21 | hash = "sha256-YOTAvONchPPSVDP9eJ9236pAPtxYK5nAePNtm2dlvb4="; 22 | stripLen = 1; 23 | extraPrefix = "kernel/"; 24 | } 25 | )]; 26 | }; 27 | }; 28 | 29 | boot.kernelParams = [ 30 | # for suspend/wakeup issues, recommended by https://wiki.hyprland.org/Nvidia/ 31 | "nvidia.NVreg_PreserveVideoMemoryAllocations=1" 32 | # for wayland issues, but breaks tty 33 | # see https://github.com/NixOS/nixpkgs/issues/343774#issuecomment-2370293678 34 | "initcall_blacklist=simpledrm_platform_driver_init" 35 | ]; 36 | 37 | # for suspend/wakeup issues, recommended by https://wiki.hyprland.org/Nvidia/ 38 | hardware.nvidia.powerManagement.enable = true; 39 | hardware.nvidia.open = false; 40 | 41 | environment.systemPackages = with pkgs; [ 42 | egl-wayland # recommended by https://wiki.hyprland.org/Nvidia/ 43 | nvidia-system-monitor-qt # monitor nvidia gpu stuff 44 | ]; 45 | } -------------------------------------------------------------------------------- /modules/obsidian-livesync.nix: -------------------------------------------------------------------------------- 1 | # obsidian synchronization server using couchdb 2 | # https://github.com/vrtmrz/obsidian-livesync 3 | args@{ config, lib, variables, ... }: 4 | let 5 | port = 5984; # couchdb default 6 | couchdb-pkg = (lib.getNixpkgs "couchdb-aarch64-nixpkgs").couchdb3; 7 | in 8 | lib.mkModule "obsidian-livesync" config { 9 | 10 | ### initial setup 11 | # set this temporarily and build: 12 | #services.couchdb.adminPass = ""; 13 | # visit: 14 | # hostname/_utils#setup 15 | # hostname/_utils/index.html#verifyinstall 16 | # hostname/_utils (to create new database like "obsidian") 17 | # follow: 18 | # https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/setup_own_server.md#4-client-setup 19 | # https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/quick_setup.md 20 | # dont forget to adjust the plugin settings! 21 | 22 | services.couchdb = { 23 | enable = true; 24 | inherit port; 25 | package = couchdb-pkg; 26 | # to avoid shell setup script 27 | # https://github.com/vrtmrz/obsidian-livesync/blob/main/utils/couchdb/couchdb-init.sh 28 | extraConfig = '' 29 | [chttpd] 30 | require_valid_user = true 31 | enable_cors = true 32 | max_http_request_size = 4294967296 33 | 34 | [chttpd_auth] 35 | require_valid_user = true 36 | 37 | [httpd] 38 | WWW-Authenticate = Basic realm="couchdb" 39 | enable_cors = true 40 | 41 | [couchdb] 42 | max_document_size = 50000000 43 | 44 | [cors] 45 | credentials = true 46 | origins = app://obsidian.md,capacitor://localhost,http://localhost,https://localhost,capacitor://obsidian.juliusboettger.com,http://obsidian.juliusboettger.com,https://obsidian.juliusboettger.com 47 | ''; 48 | }; 49 | 50 | local.website.extraConfig = '' 51 | obsidian.juliusboettger.com { 52 | reverse_proxy :${toString port} 53 | } 54 | ''; 55 | } -------------------------------------------------------------------------------- /modules/onedrive.nix: -------------------------------------------------------------------------------- 1 | # onedrive 2 | args@{ config, lib, variables, ... }: 3 | lib.mkModule "onedrive" config { 4 | services.onedrive.enable = true; 5 | 6 | # create config file in ~/.config 7 | home-manager.users.${variables.username} = { config, ... }: { 8 | xdg.configFile."onedrive/config".text = '' 9 | # try to download changes from onedrive every x seconds 10 | monitor_interval = "6" 11 | # fully scan data for integrity every x attempt of downloading (monitor_interval) 12 | monitor_fullscan_frequency = "50" 13 | # minimum number of downloaded changes to trigger desktop notification 14 | min_notify_changes = "1" 15 | # ignore temporary stuff and weird obsidian file 16 | skip_file = "~*|.~*|*.tmp|.OBSIDIANTEST" 17 | ''; 18 | }; 19 | } -------------------------------------------------------------------------------- /modules/piper.nix: -------------------------------------------------------------------------------- 1 | # configure gaming mice graphically 2 | args@{ config, lib, pkgs, ... }: 3 | lib.mkModule "piper" config { 4 | environment.systemPackages = [ pkgs.piper ]; 5 | 6 | # runtime dependency 7 | services.ratbagd.enable = true; 8 | } -------------------------------------------------------------------------------- /modules/playerctl.nix: -------------------------------------------------------------------------------- 1 | # control media player with mpris 2 | args@{ config, lib, pkgs, variables, ... }: 3 | lib.mkModule "playerctl" config { 4 | environment.systemPackages = [ pkgs.playerctl ]; 5 | 6 | # to remember last active player 7 | home-manager.users.${variables.username} = { config, ... }: { 8 | services.playerctld.enable = true; 9 | }; 10 | } -------------------------------------------------------------------------------- /modules/plymouth/default.nix: -------------------------------------------------------------------------------- 1 | # prettier boot process with plymouth 2 | args@{ config, lib, pkgs, ... }: 3 | let 4 | theme = 5 | # built-in 6 | "breeze"; 7 | # from adi1090x-plymouth-themes 8 | #"spin"; 9 | #"circle"; 10 | #"liquid"; 11 | #"spinner_alt"; 12 | in 13 | lib.mkModule "plymouth" config { 14 | boot = { 15 | # run plymouth early (for disk encryption password) 16 | initrd.systemd.enable = true; 17 | 18 | plymouth = { 19 | enable = true; 20 | inherit theme; 21 | # bigger colored logo for built-in themes 22 | logo = "${pkgs.nixos-icons}/share/icons/hicolor/256x256/apps/nix-snowflake.png"; 23 | # more themes 24 | /*themePackages = [ 25 | (pkgs.adi1090x-plymouth-themes.override { 26 | selected_themes = [ theme ]; 27 | }) 28 | ];*/ 29 | }; 30 | 31 | # show less text during boot 32 | consoleLogLevel = 0; 33 | initrd.verbose = false; 34 | kernelParams = [ 35 | "quiet" 36 | "splash" 37 | "loglevel=3" 38 | "boot.shell_on_fail" 39 | "rd.udev.log_level=3" 40 | "udev.log_priority=3" 41 | "rd.systemd.show_status=false" 42 | ]; 43 | }; 44 | } -------------------------------------------------------------------------------- /modules/rofi/default.nix: -------------------------------------------------------------------------------- 1 | # application launcher 2 | args@{ config, lib, pkgs, variables, ... }: 3 | lib.mkModule "rofi" config { 4 | # emoji picker for rofi 5 | environment.systemPackages = [ pkgs.rofimoji ]; 6 | 7 | home-manager.users.${variables.username} = { config, ... }: { 8 | programs.rofi = { 9 | enable = true; 10 | theme = "transparent"; # own theme 11 | package = pkgs.rofi-wayland; # wayland support 12 | terminal = "${pkgs.unstable.alacritty}/bin/alacritty"; 13 | }; 14 | 15 | # write rofimoji config file 16 | xdg.configFile."rofimoji.rc".text = '' 17 | action = copy 18 | skin-tone = neutral 19 | ''; 20 | 21 | # symlink themes to ~ 22 | home.file.".local/share/rofi/themes".source = 23 | config.lib.file.mkOutOfStoreSymlink "/etc/dotfiles/modules/rofi"; 24 | }; 25 | } -------------------------------------------------------------------------------- /modules/rofi/opaque.rasi: -------------------------------------------------------------------------------- 1 | /* Inspired by rounded theme of https://github.com/lr-tech/rofi-themes-collection */ 2 | 3 | * { 4 | accent: #948AE3; 5 | color1: #262527; // <= different from transparent.rasi 6 | color2: #363537; // <= different from transparent.rasi 7 | color3: #F7F1FF; 8 | 9 | font: "JetBrainsMonoNL Nerd Font 12"; 10 | text-color: @color3; 11 | background-color: transparent; 12 | 13 | margin: 0px; 14 | padding: 0px; 15 | spacing: 0px; 16 | } 17 | 18 | window { 19 | location: center; 20 | width: 650; 21 | 22 | border-color: @accent; 23 | border-radius: 15px; 24 | border: 3px; 25 | 26 | background-color: @color1; 27 | } 28 | 29 | inputbar { 30 | border-radius: 15px; 31 | padding: 20px 20px; 32 | spacing: 8px; 33 | children: [ entry ]; 34 | } 35 | 36 | message { 37 | border-radius: 15px; 38 | border-color: @color1; 39 | } 40 | 41 | textbox { 42 | padding: 8px 24px; 43 | } 44 | 45 | listview { 46 | lines: 6; 47 | columns: 2; 48 | cycle: false; 49 | scrollbar: true; 50 | fixed-height: true; 51 | } 52 | 53 | scrollbar { 54 | cursor: pointer; 55 | handle-width: 5px; 56 | handle-color: @color2; 57 | } 58 | 59 | element { 60 | padding: 12px 16px; 61 | spacing: 8px; 62 | border-radius: 15px; 63 | } 64 | 65 | element selected normal, element selected active { 66 | background-color: @color2; 67 | } 68 | 69 | element-text { 70 | highlight: bold; 71 | } 72 | 73 | element-icon { 74 | size: 1em; 75 | vertical-align: 0.5; 76 | } -------------------------------------------------------------------------------- /modules/rofi/transparent.rasi: -------------------------------------------------------------------------------- 1 | /* Inspired by rounded theme of https://github.com/lr-tech/rofi-themes-collection */ 2 | 3 | * { 4 | accent: #948AE3; 5 | color1: #26252759; 6 | color2: #FFFFFF1A; 7 | color3: #F7F1FF; 8 | 9 | font: "JetBrainsMonoNL Nerd Font 12"; 10 | text-color: @color3; 11 | background-color: transparent; 12 | 13 | margin: 0px; 14 | padding: 0px; 15 | spacing: 0px; 16 | } 17 | 18 | window { 19 | location: center; 20 | width: 650; 21 | 22 | border-color: @accent; 23 | border-radius: 15px; 24 | border: 3px; 25 | 26 | background-color: @color1; 27 | } 28 | 29 | inputbar { 30 | border-radius: 15px; 31 | padding: 20px 20px; 32 | spacing: 8px; 33 | children: [ entry ]; 34 | } 35 | 36 | message { 37 | border-radius: 15px; 38 | border-color: @color1; 39 | } 40 | 41 | textbox { 42 | padding: 8px 24px; 43 | } 44 | 45 | listview { 46 | lines: 6; 47 | columns: 2; 48 | cycle: false; 49 | scrollbar: true; 50 | fixed-height: true; 51 | } 52 | 53 | scrollbar { 54 | cursor: pointer; 55 | handle-width: 5px; 56 | handle-color: @color2; 57 | } 58 | 59 | element { 60 | padding: 12px 16px; 61 | spacing: 8px; 62 | border-radius: 15px; 63 | } 64 | 65 | element selected normal, element selected active { 66 | background-color: @color2; 67 | } 68 | 69 | element-text { 70 | highlight: bold; 71 | } 72 | 73 | element-icon { 74 | size: 1em; 75 | vertical-align: 0.5; 76 | } -------------------------------------------------------------------------------- /modules/sddm-sugar-candy/default.nix: -------------------------------------------------------------------------------- 1 | # sddm (display manager) theme 2 | args@{ config, lib, pkgs, ... }: 3 | lib.mkModule "sddm-sugar-candy" config { 4 | services.displayManager.sddm.theme = "sugar-candy"; 5 | 6 | environment.systemPackages = with pkgs; [ 7 | local.sddm-sugar-candy 8 | libsForQt5.qt5.qtgraphicaleffects # runtime dependency 9 | ]; 10 | } -------------------------------------------------------------------------------- /modules/sddm-sugar-candy/sddm-sugar-candy.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | Background="/etc/dotfiles/wallpapers/login.jpg" 3 | ## Path relative to the theme root directory. Most standard image file formats are allowed including support for transparency. (e.g. background.jpeg/illustration.GIF/Foto.png/undraw.svgz) 4 | DimBackgroundImage="0" 5 | ## Double between 0 and 1 used for the alpha channel of a darkening overlay. Use to darken your background image on the fly. 6 | ScaleImageCropped="true" 7 | ## Whether the image should be cropped when scaled proportionally. Setting this to false will fit the whole image instead, possibly leaving white space. This can be exploited beautifully with illustrations (try it with "undraw.svg" included in the theme). 8 | ScreenWidth="2560" 9 | ScreenHeight="1440" 10 | ## Adjust to your resolution to help SDDM speed up on calculations 11 | 12 | ## [Blur Settings] 13 | FullBlur="true" 14 | PartialBlur="false" 15 | ## Enable or disable the blur effect; if HaveFormBackground is set to true then PartialBlur will trigger the BackgroundColor of the form element to be partially transparent and blend with the blur. 16 | BlurRadius="50" 17 | ## Set the strength of the blur effect. Anything above 100 is pretty strong and might slow down the rendering time. 0 is like setting false for any blur. 18 | 19 | ## [Design Customizations] 20 | HaveFormBackground="false" 21 | ## Have a full opacity background color behind the form that takes slightly more than 1/3 of screen estate; if PartialBlur is set to true then HaveFormBackground will trigger the BackgroundColor of the form element to be partially transparent and blend with the blur. 22 | FormPosition="center" 23 | ## Position of the form which takes roughly 1/3 of screen estate. Can be left, center or right. 24 | BackgroundImageHAlignment="center" 25 | ## Horizontal position of the background picture relative to its visible area. Applies when ScaleImageCropped is set to false or when HaveFormBackground is set to true and FormPosition is either left or right. Can be left, center or right; defaults to center if none is passed. 26 | BackgroundImageVAlignment="center" 27 | ## As before but for the vertical position of the background picture relative to its visible area. 28 | MainColor="#F7F1FF" 29 | ## Used for all elements when not focused/hovered etc. Usually the best effect is achieved by having this be either white or a very dark grey like #444 (not black for smoother antialias) 30 | ## Colors can be HEX or Qt names (e.g. red/salmon/blanchedalmond). See https://doc.qt.io/qt-5/qml-color.html 31 | AccentColor="#7BD88F" 32 | ## Used for elements in focus/hover/pressed. Should be contrasting to the background and the MainColor to achieve the best effect. 33 | BackgroundColor="#262527" 34 | ## Used for the user and session selection background as well as for ScreenPadding and FormBackground when either is true. If PartialBlur and FormBackground are both enabled this color will blend with the blur effect. 35 | OverrideLoginButtonTextColor="#F7F1FF" 36 | ## The text of the login button may become difficult to read depending on your color choices. Use this option to set it independently for legibility. 37 | InterfaceShadowSize="0" 38 | ## Integer used as multiplier. Size of the shadow behind the user and session selection background. Decrease or increase if it looks bad on your background. Initial render can be slow no values above 5-7. 39 | InterfaceShadowOpacity="0" 40 | ## Double between 0 and 1. Alpha channel of the shadow behind the user and session selection background. Decrease or increase if it looks bad on your background. 41 | RoundCorners="10" 42 | ## Integer in pixels. Radius of the input fields and the login button. Empty for square. Can cause bad antialiasing of the fields. 43 | ScreenPadding="0" 44 | ## Integer in pixels. Increase or delete this to have a padding of color BackgroundColor all around your screen. This makes your login greeter appear as if it was a canvas. Cool! 45 | Font="JetBrainsMonoNL Nerd Font" 46 | ## If you want to choose a custom font it will have to be available to the X root user. See https://wiki.archlinux.org/index.php/fonts#Manual_installation 47 | FontSize="15" 48 | ## Only set a fixed value if fonts are way too small for your resolution. Preferrably kept empty. 49 | 50 | ## [Interface Behavior] 51 | ForceRightToLeft="false" 52 | ## Revert the layout either because you would like the login to be on the right hand side or SDDM won't respect your language locale for some reason. This will reverse the current position of FormPosition if it is either left or right and in addition position some smaller elements on the right hand side of the form itself (also when FormPosition is set to center). 53 | ForceLastUser="true" 54 | ## Have the last successfully logged in user appear automatically in the username field. 55 | ForcePasswordFocus="true" 56 | ## Give automatic focus to the password field. Together with ForceLastUser this makes for the fastest login experience. 57 | ForceHideCompletePassword="true" 58 | ## If you don't like to see any character at all not even while being entered set this to true. 59 | ForceHideVirtualKeyboardButton="false" 60 | ## Do not show the button for the virtual keyboard at all. This will completely disable functionality for the virtual keyboard even if it is installed and activated in sddm.conf 61 | ForceHideSystemButtons="false" 62 | ## Completely disable and hide any power buttons on the greeter. 63 | AllowEmptyPassword="false" 64 | ## Enable login for users without a password. This is discouraged. Makes the login button always enabled. 65 | AllowBadUsernames="false" 66 | ## Do not change this! Uppercase letters are generally not allowed in usernames. This option is only for systems that differ from this standard! Also shows username as is instead of capitalized. 67 | 68 | ## [Locale Settings] 69 | Locale="" 70 | ## The time and date locale should usually be set in your system settings. Only hard set this if something is not working by default or you want a seperate locale setting in your login screen. 71 | HourFormat="HH:mm" 72 | ## Defaults to Locale.ShortFormat - Accepts "long" or a custom string like "hh:mm A". See http://doc.qt.io/qt-5/qml-qtqml-date.html 73 | DateFormat="dd.MM.yyyy" 74 | ## Defaults to Locale.LongFormat - Accepts "short" or a custom string like "dddd, d 'of' MMMM". See http://doc.qt.io/qt-5/qml-qtqml-date.html 75 | 76 | ## [Translations] 77 | HeaderText="" 78 | ## Header can be empty to not display any greeting at all. Keep it short. 79 | ## SDDM may lack proper translation for every element. Suger defaults to SDDM translations. Please help translate SDDM as much as possible for your language: https://github.com/sddm/sddm/wiki/Localization. These are in order as they appear on screen. 80 | TranslatePlaceholderUsername="" 81 | TranslatePlaceholderPassword="" 82 | TranslateShowPassword="" 83 | TranslateLogin="" 84 | TranslateLoginFailedWarning="" 85 | TranslateCapslockWarning="" 86 | TranslateSession="" 87 | TranslateSuspend="" 88 | TranslateHibernate="" 89 | TranslateReboot="" 90 | TranslateShutdown="" 91 | TranslateVirtualKeyboardButton="" 92 | ## These don't necessarily need to translate anything. You can enter whatever you want here. 93 | -------------------------------------------------------------------------------- /modules/sops.nix: -------------------------------------------------------------------------------- 1 | # secret management with sops 2 | args@{ config, lib, pkgs, inputs, variables, ... }: 3 | { 4 | imports = [ inputs.sops-nix.nixosModules.sops ]; 5 | 6 | options.local.sops.enable = lib.mkEnableOption "whether to enable sops"; 7 | config = lib.mkIf config.local.sops.enable { 8 | 9 | environment.systemPackages = with pkgs; [ 10 | sops 11 | ssh-to-age # convert keys 12 | ]; 13 | 14 | # should contain private key generated with 15 | # ssh-to-age -private-key -i ~/.ssh/id_ed25519 -o ~/.config/sops/age/keys.txt 16 | sops.age.keyFile = "/home/${variables.username}/.config/sops/age/keys.txt"; 17 | }; 18 | } -------------------------------------------------------------------------------- /modules/starship/default.nix: -------------------------------------------------------------------------------- 1 | # shell prompt 2 | args@{ config, lib, pkgs, ... }: 3 | lib.mkModule "starship" config { 4 | environment.systemPackages = [ pkgs.starship ]; 5 | 6 | # set config file location 7 | environment.variables.STARSHIP_CONFIG = "/etc/dotfiles/modules/starship/starship.toml"; 8 | } -------------------------------------------------------------------------------- /modules/starship/starship.toml: -------------------------------------------------------------------------------- 1 | "$schema" = "https://starship.rs/config-schema.json" 2 | 3 | format = "$all$directory$character" 4 | add_newline = false 5 | 6 | [character] 7 | # 𝈳 ᗇ ❯ 8 | success_symbol = "[❯](purple)" 9 | error_symbol = "[❯](purple)" 10 | 11 | [cmd_duration] 12 | min_time = 1000 # milliseconds 13 | format = "[[$duration](bold bright-black) execution time](bright-black)" 14 | 15 | [directory] 16 | truncation_length = 1 17 | truncate_to_repo = false 18 | read_only_style = "black" -------------------------------------------------------------------------------- /modules/steam.nix: -------------------------------------------------------------------------------- 1 | # steam (PROPRIETARY) 2 | args@{ config, lib, pkgs, ... }: 3 | lib.mkModule "steam" config { 4 | programs.steam = { 5 | enable = true; 6 | package = pkgs.unstable.steam; 7 | }; 8 | 9 | # easy ge-proton setup for steam 10 | environment.systemPackages = [ pkgs.protonup-qt ]; 11 | } -------------------------------------------------------------------------------- /modules/studies/comarch.nix: -------------------------------------------------------------------------------- 1 | args@{ pkgs, variables, ... }: 2 | { 3 | environment.systemPackages = with pkgs; [ 4 | logisim-evolution 5 | ]; 6 | } -------------------------------------------------------------------------------- /modules/studies/dabank.nix: -------------------------------------------------------------------------------- 1 | args@{ pkgs, variables, ... }: 2 | { 3 | environment.systemPackages = with pkgs; [ 4 | sqlitebrowser 5 | ]; 6 | } -------------------------------------------------------------------------------- /modules/studies/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | # not all modules, just the ones I currently use 4 | imports = []; 5 | } -------------------------------------------------------------------------------- /modules/studies/itsarch.nix: -------------------------------------------------------------------------------- 1 | # gns3 client + gns3 server (virtualbox vm) + utils 2 | args@{ pkgs, lib, variables, ... }: 3 | let 4 | # should point to nixpkgs commit dd5621df6dcb90122b50da5ec31c411a0de3e538 5 | # to get gns3-gui version 2.2.44.1 6 | gns3-gui = (lib.getNixpkgs "nixpkgs-itsarch").gns3-gui; 7 | in 8 | { 9 | environment.systemPackages = with pkgs; [ 10 | gns3-gui 11 | wireshark 12 | inetutils # for telnet 13 | gnome.vinagre # for vnc connection 14 | ]; 15 | 16 | # wireshark permissions 17 | programs.wireshark.enable = true; 18 | users.extraGroups.wireshark.members = [ variables.username ]; 19 | 20 | # virtualbox for gns3 server 21 | users.extraGroups.vboxusers.members = [ variables.username ]; 22 | virtualisation.virtualbox.host = { 23 | enable = true; 24 | enableExtensionPack = true; 25 | }; 26 | 27 | # also remember to change some GNS3 client preferences: 28 | # - console application command: alacritty -T %d -e telnet %h %p 29 | # - VNC viewer: Vinagre 30 | } -------------------------------------------------------------------------------- /modules/studies/redig.nix: -------------------------------------------------------------------------------- 1 | args@{ pkgs, variables, ... }: 2 | { 3 | environment.systemPackages = with pkgs; [ 4 | ghdl 5 | digital 6 | gtkwave 7 | ]; 8 | } -------------------------------------------------------------------------------- /modules/studies/swsyspro.nix: -------------------------------------------------------------------------------- 1 | args@{ pkgs, variables, ... }: 2 | { 3 | environment.systemPackages = with pkgs; [ 4 | jetbrains.rider 5 | dotnet-sdk_8 6 | ]; 7 | } -------------------------------------------------------------------------------- /modules/swaylock-effects/default.nix: -------------------------------------------------------------------------------- 1 | # wayland lockscreen 2 | args@{ config, lib, pkgs, ... }: 3 | lib.mkModule "swaylock-effects" config { 4 | environment.systemPackages = with pkgs; [ 5 | unstable.swaylock-effects 6 | (lib.writeScriptFile "swaylock-effects" ./swaylock-effects.sh) 7 | ]; 8 | 9 | # necessary! 10 | security.pam.services.swaylock = {}; 11 | } -------------------------------------------------------------------------------- /modules/swaylock-effects/swaylock-effects.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # wrapper around https://github.com/jirutka/swaylock-effects 3 | # uses nerdfont characters for text variables 4 | swaylock \ 5 | --screenshots \ 6 | --clock \ 7 | --datestr "" \ 8 | --timestr "" \ 9 | --text-ver "󱥸" \ 10 | --text-wrong "" \ 11 | --text-clear "󱞱" \ 12 | --indicator \ 13 | --indicator-idle-visible \ 14 | --ignore-empty-password \ 15 | --disable-caps-lock-text \ 16 | --font "JetBrainsMonoNL Nerd Font" \ 17 | --font-size 200 \ 18 | --effect-blur 12x3 \ 19 | --indicator-radius 210 \ 20 | --indicator-thickness 10 \ 21 | --line-color 26252788 \ 22 | --line-clear-color 26252788 \ 23 | --line-ver-color 26252788 \ 24 | --line-wrong-color 26252788 \ 25 | --inside-color 26252788 \ 26 | --inside-clear-color 26252788 \ 27 | --inside-ver-color 26252788 \ 28 | --inside-wrong-color 26252788 \ 29 | --text-color F7F1FF \ 30 | --text-clear-color F7F1FF \ 31 | --text-ver-color F7F1FF \ 32 | --text-wrong-color F7F1FF \ 33 | --ring-color 5AD4E6 \ 34 | --ring-clear-color 5AD4E6 \ 35 | --ring-ver-color 5AD4E6 \ 36 | --bs-hl-color FC618D \ 37 | --ring-wrong-color FC618D \ 38 | --key-hl-color 948AE3 \ 39 | --separator-color 403e42 -------------------------------------------------------------------------------- /modules/swaync/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/ErikReider/SwayNotificationCenter/4275fa3915c12ad2731ff78027188b4b7ceaad64/src/configSchema.json", 3 | 4 | "cssPriority": "user", 5 | "image-visibility": "when-available", 6 | 7 | "positionX": "center", 8 | "positionY": "top", 9 | 10 | "layer": "overlay", 11 | "control-center-layer": "overlay", 12 | 13 | "control-center-width": 800, 14 | "notification-window-width": 600, 15 | 16 | "hide-on-clear": true, 17 | "hide-on-action": false, 18 | 19 | "timeout-critical": 10, 20 | "timeout": 5, 21 | "timeout-low": 2, 22 | 23 | "script-fail-notify": false, 24 | "scripts": { 25 | "sound": { 26 | "exec": "sh -c \"[ $(swaync-client -I) == 'false' ] && aplay /etc/dotfiles/misc/notification.wav\"", 27 | "run-on": "receive" 28 | } 29 | }, 30 | 31 | "widgets": [ 32 | "title", 33 | "mpris", 34 | "notifications" 35 | ], 36 | "widget-config": { 37 | "title": { 38 | "button-text": "Clear" 39 | }, 40 | "mpris": { 41 | "image-size": 64, 42 | "image-radius": 10 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /modules/swaync/default.nix: -------------------------------------------------------------------------------- 1 | # wayland notification daemon and center 2 | args@{ config, lib, pkgs, variables, ... }: 3 | lib.mkModule "swaync" config { 4 | environment.systemPackages = with pkgs; [ 5 | unstable.swaynotificationcenter 6 | socat # to listen to hyprland events for scripting 7 | ]; 8 | 9 | # symlink config to ~/.config 10 | home-manager.users.${variables.username} = { config, ... }: { 11 | xdg.configFile."swaync".source = 12 | config.lib.file.mkOutOfStoreSymlink "/etc/dotfiles/modules/swaync"; 13 | }; 14 | } -------------------------------------------------------------------------------- /modules/swaync/inhibit-on-screenshare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # inhibit notifications when screensharing on 3 | # hyprland using xdph (xdg-desktop-portal-hyprland) 4 | 5 | socat -u UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - | while read -r line; do 6 | case $line in 7 | # when starting screenshare 8 | "screencast>>1"*) swaync-client -Ia "screenshare" ;; 9 | # when stopping screenshare 10 | "screencast>>0"*) swaync-client -Ir "screenshare" ;; 11 | esac 12 | done -------------------------------------------------------------------------------- /modules/swaync/style.css: -------------------------------------------------------------------------------- 1 | @define-color cc-bg rgba(38, 37, 39, 0.35); 2 | @define-color actual-noti-bg rgba(38, 37, 39, 0.35); 3 | @define-color mpris-player-bg rgba(38, 37, 39, 0.2); 4 | @define-color noti-close-bg-hover rgba(38, 37, 39, 0.2); 5 | @define-color noti-action-bg rgba(255, 255, 255, 0.1); 6 | @define-color noti-center-border rgba(255, 255, 255, 0.2); 7 | @define-color noti-close-bg transparent; 8 | @define-color noti-bg transparent; 9 | @define-color noti-bg-darker transparent; 10 | @define-color noti-bg-hover transparent; 11 | @define-color noti-bg-focus transparent; 12 | 13 | @define-color text-color #F7F1FF; 14 | @define-color text-color-disabled #69676C; 15 | 16 | @define-color noti-border-color #5AA0E6; 17 | @define-color bg-selected #5AA0E6; 18 | 19 | .notification { 20 | font-family: 'JetBrainsMonoNL Nerd Font'; 21 | border-radius: 15px; 22 | box-shadow: none; 23 | border: 3px solid @noti-border-color; 24 | background: @actual-noti-bg; 25 | } 26 | 27 | .notification-content { 28 | padding: 5px 8px; 29 | } 30 | 31 | /* align floating notifications with borders of hyprland clients */ 32 | .notification-row:first-child { 33 | margin-top: 7px; 34 | } 35 | 36 | .notification-group { 37 | outline: none; 38 | } 39 | 40 | .image { 41 | border-radius: 10px; 42 | } 43 | 44 | .notification-group.collapsed .notification-row:not(:last-child) .notification { 45 | transition: opacity 250ms; 46 | opacity: 0.25; 47 | } 48 | 49 | .notification *, 50 | .control-center .notification, 51 | .notification-row:focus, 52 | .notification-row:hover, 53 | .blank-window { 54 | background: transparent; 55 | } 56 | 57 | .notification-default-action, 58 | .notification-action { 59 | border: none; 60 | } 61 | 62 | .notification-action:not(:last-child) { 63 | margin-right: 3px; 64 | } 65 | 66 | .notification-action { 67 | border-radius: 10px; 68 | background: @noti-action-bg; 69 | } 70 | 71 | .time { 72 | font-size: 15px; 73 | background: transparent; 74 | margin-right: 15px; 75 | } 76 | 77 | .control-center { 78 | font-family: 'JetBrainsMonoNL Nerd Font'; 79 | border-left: 3px solid @noti-center-border; 80 | border-right: 3px solid @noti-center-border; 81 | border-radius: 0; 82 | } 83 | 84 | .control-center-list-placeholder { 85 | opacity: 0.8; 86 | } 87 | 88 | .widget-title { 89 | margin: 20px 15px 5px 15px; 90 | font-size: 30px; 91 | } 92 | .widget-title > button { 93 | font-size: 15px; 94 | background: transparent; 95 | border: none; 96 | border-radius: 10px; 97 | } 98 | .widget-title > button:hover { 99 | background: @noti-close-bg-hover; 100 | } 101 | 102 | .widget-mpris-player { 103 | padding: 8px; 104 | box-shadow: none; 105 | background: @mpris-player-bg; 106 | } 107 | .widget-mpris-player button { 108 | background: transparent; 109 | } -------------------------------------------------------------------------------- /modules/vim/.vimrc: -------------------------------------------------------------------------------- 1 | syntax enable " syntax highlighting 2 | set encoding=utf8 3 | set magic " use regex 4 | set showmatch " highlight matching brackets 5 | set ai " auto indent 6 | set si " smart indent 7 | 8 | " use 4 spaces instead of tab 9 | set expandtab " use spaces instead of tabs 10 | set smarttab " be smart idk 11 | set tabstop=4 " display tab as X spaces 12 | set shiftwidth=4 " insert X spaces when pressing tab 13 | 14 | " search 15 | set hlsearch " highlight results 16 | set ignorecase 17 | set smartcase " be smart idk 18 | set incsearch " be even smarter idk 19 | 20 | "----- key mappings 21 | " normal mode 22 | nnoremap >> 23 | nnoremap << 24 | 25 | nnoremap K ok 26 | 27 | " visual mode 28 | vnoremap > 29 | vnoremap < 30 | 31 | " normal and visual mode 32 | nnoremap ß :noh 33 | vnoremap ß :noh 34 | 35 | nnoremap ö ^ 36 | vnoremap ö ^ 37 | 38 | nnoremap ä $ 39 | vnoremap ä $ -------------------------------------------------------------------------------- /modules/vim/default.nix: -------------------------------------------------------------------------------- 1 | # terminal text editor 2 | args@{ config, lib, pkgs, variables, ... }: 3 | lib.mkModule "vim" config { 4 | environment.systemPackages = [ pkgs.vim ]; 5 | 6 | # symlink config to ~ 7 | home-manager.users.${variables.username} = { config, ... }: { 8 | home.file.".vimrc".source = 9 | config.lib.file.mkOutOfStoreSymlink "/etc/dotfiles/modules/vim/.vimrc"; 10 | }; 11 | } -------------------------------------------------------------------------------- /modules/virt-manager.nix: -------------------------------------------------------------------------------- 1 | # vm's with virt-manager + libvirtd + qemu + kvm 2 | # based on https://nixos.wiki/wiki/Virt-manager 3 | args@{ config, lib, variables, device, ... }: 4 | lib.mkModule "virt-manager" config { 5 | programs.virt-manager.enable = true; 6 | 7 | # libvirtd 8 | virtualisation.libvirtd.enable = true; 9 | users.users.${variables.username}.extraGroups = [ "libvirtd" ]; 10 | home-manager.users.${variables.username} = { config, ... }: { 11 | dconf.settings."org/virt-manager/virt-manager/connections" = { 12 | autoconnect = [ "qemu:///system" ]; 13 | uris = [ "qemu:///system" ]; 14 | }; 15 | }; 16 | } -------------------------------------------------------------------------------- /modules/vscodium/default.nix: -------------------------------------------------------------------------------- 1 | # vscodium with extensions (text editor) 2 | args@{ config, lib, pkgs, variables, ... }: 3 | let 4 | # extensions directly from nixpkgs 5 | nixpkgs-exts = pkgs.unstable.vscode-extensions; 6 | in 7 | lib.mkModule "vscodium" config { 8 | environment.systemPackages = [ 9 | (pkgs.vscode-with-extensions.override { 10 | vscode = pkgs.unstable.vscodium; 11 | vscodeExtensions = 12 | with pkgs.vscode-marketplace; 13 | #with pkgs.open-vsx; # seems to cause issues...? 14 | with pkgs.vscode-marketplace-release; 15 | with pkgs.open-vsx-release; # <-- use first if available, otherwise go up 16 | [ 17 | ### for syntax highlighting / language support 18 | dlasagno.rasi 19 | eww-yuck.yuck 20 | jnoortheen.nix-ide 21 | bmalehorn.vscode-fish 22 | 23 | # rust 24 | rust-lang.rust-analyzer 25 | tamasfe.even-better-toml 26 | nixpkgs-exts.vadimcn.vscode-lldb # debugger 27 | nolanderc.glasgow # wgsl language support, but without syntax highlighting 28 | antaalt.shader-validator # wgsl syntax highlighting 29 | 30 | # c/c++ 31 | #ms-vscode.cpptools 32 | #mesonbuild.mesonbuild 33 | 34 | # python 35 | ms-python.python 36 | ms-toolsai.jupyter 37 | detachhead.basedpyright # pylance alternative, works in jupyter notebooks 38 | 39 | ### other stuff 40 | mkhl.direnv # load dev environment from directory 41 | vscodevim.vim # vim :) 42 | eamodio.gitlens # advanced git integration 43 | esbenp.prettier-vscode # code formatter 44 | naumovs.color-highlight # highlight color codes with their color 45 | pkief.material-icon-theme # file icon theme 46 | monokai.theme-monokai-pro-vscode # color theme 47 | christian-kohler.path-intellisense # auto complete paths 48 | ]; 49 | }) 50 | ]; 51 | 52 | # symlink config to ~/.config 53 | home-manager.users.${variables.username} = { config, ... }: { 54 | xdg.configFile."VSCodium/User/settings.json".source = 55 | config.lib.file.mkOutOfStoreSymlink "/etc/dotfiles/modules/vscodium/vscodium.json"; 56 | }; 57 | } -------------------------------------------------------------------------------- /modules/vscodium/vscodium.json: -------------------------------------------------------------------------------- 1 | { 2 | // vim settings 3 | "vim.hlsearch": true, 4 | "vim.normalModeKeyBindingsNonRecursive": [ 5 | { 6 | "before": ["ß"], 7 | "commands": [":noh"] 8 | }, 9 | { 10 | "before": ["ü"], 11 | "commands": [":tabp"] 12 | }, 13 | { 14 | "before": ["+"], 15 | "commands": [":tabn"] 16 | }, 17 | { 18 | "before": ["ö"], 19 | "after": ["^"] 20 | }, 21 | { 22 | "before": ["ä"], 23 | "after": ["$"] 24 | }, 25 | { 26 | "before": ["K"], 27 | "after": ["o", "", "k"] 28 | }, 29 | { 30 | "before": [""], 31 | "after": [">", ">"] 32 | }, 33 | { 34 | "before": [""], 35 | "after": ["<", "<"] 36 | } 37 | ], 38 | "vim.visualModeKeyBindingsNonRecursive": [ 39 | { 40 | "before": ["ß"], 41 | "commands": [":noh"] 42 | }, 43 | { 44 | "before": ["ü"], 45 | "commands": [":tabp"] 46 | }, 47 | { 48 | "before": ["+"], 49 | "commands": [":tabn"] 50 | }, 51 | { 52 | "before": ["ö"], 53 | "after": ["^"] 54 | }, 55 | { 56 | "before": ["ä"], 57 | "after": ["$"] 58 | }, 59 | { 60 | "before": [""], 61 | "after": ["\"", "+", "y", ""] 62 | }, 63 | { 64 | "before": [""], 65 | "after": [">"] 66 | }, 67 | { 68 | "before": [""], 69 | "after": ["<"] 70 | } 71 | ], 72 | 73 | "leetcode.defaultLanguage": "rust", 74 | "leetcode.hint.configWebviewMarkdown": false, 75 | "leetcode.hint.commentDescription": false, 76 | "leetcode.filePath": { 77 | "rust": { 78 | "folder": "./rust/src", 79 | "filename": "${snake_case_name}.${ext}" 80 | } 81 | }, 82 | 83 | "mesonbuild.buildFolder": "build", 84 | "mesonbuild.configureOnOpen": true, 85 | "mesonbuild.downloadLanguageServer": false, 86 | "mesonbuild.languageServer": null, 87 | 88 | "rust-analyzer.check.command": "clippy", 89 | "rust-analyzer.check.features": "all", 90 | "rust-analyzer.check.allTargets": true, 91 | "rust-analyzer.check.extraArgs": ["--", "-W", "clippy::pedantic", "-W", "clippy::nursery"], 92 | 93 | "basedpyright.analysis.typeCheckingMode": "standard", 94 | "basedpyright.analysis.diagnosticSeverityOverrides": { 95 | "reportAssignmentType": "hint", // make it easier to force types onto variables 96 | }, 97 | 98 | "workbench.colorTheme": "Monokai Pro (Filter Spectrum)", 99 | "workbench.iconTheme": "material-icon-theme", 100 | 101 | "explorer.confirmDelete": false, 102 | "explorer.confirmDragAndDrop": false, 103 | 104 | "security.workspace.trust.enabled": false, 105 | "security.workspace.trust.untrustedFiles": "open", 106 | 107 | "git.openRepositoryInParentFolders": "always", 108 | "git.confirmSync": false, 109 | 110 | "editor.fontSize": 18, 111 | "terminal.integrated.fontSize": 18, 112 | "editor.fontFamily": "'JetBrainsMonoNL Nerd Font', monospace", 113 | 114 | "update.mode": "none", // don't try to update, NixOS will do it 115 | "shader-validator.validate": false, // only used for syntax highlighting 116 | "gitlens.currentLine.enabled": false, 117 | "terminal.integrated.cursorStyle": "underline", 118 | "glasgow.path": "/home/julius/.config/VSCodium/User/globalStorage/nolanderc.glasgow/glasgow_install/bin/glasgow", 119 | } -------------------------------------------------------------------------------- /modules/website.nix: -------------------------------------------------------------------------------- 1 | # host own website 2 | args@{ config, lib, variables, device, ... }: 3 | let 4 | cfg = config.local.website; 5 | in 6 | { 7 | options.local.website = { 8 | enable = lib.mkEnableOption "whether to enable website"; 9 | extraConfig = lib.mkOption { type = lib.types.lines; }; 10 | }; 11 | 12 | config = lib.mkIf cfg.enable { 13 | 14 | networking.firewall.allowedTCPPorts = [ 80 443 ]; 15 | services.caddy = { 16 | enable = true; 17 | logFormat = "level INFO"; 18 | extraConfig = '' 19 | https:// { 20 | tls /etc/ssl/certs/certificate.pem /etc/ssl/private/key.pem 21 | } 22 | 23 | juliusboettger.com, www.juliusboettger.com { 24 | root * ${(lib.getPkgs "website").website} 25 | file_server 26 | } 27 | 28 | # to easily fetch e.g. .vimrc 29 | dotfiles.juliusboettger.com { 30 | redir https://raw.githubusercontent.com/julius-boettger/dotfiles/refs/heads/main{uri} 31 | } 32 | 33 | ${cfg.extraConfig} 34 | 35 | # fallback 36 | *.juliusboettger.com { 37 | respond 404 38 | } 39 | ''; 40 | }; 41 | }; 42 | } -------------------------------------------------------------------------------- /modules/wsl-vpnkit.nix: -------------------------------------------------------------------------------- 1 | # for issues with wsl and company network/vpn 2 | args@{ config, lib, pkgs, inputs, ... }: 3 | { 4 | options.local.wsl-vpnkit.enable = lib.mkEnableOption "whether to enable wsl-vpnkit"; 5 | 6 | imports = [ inputs.nixos-wsl.nixosModules.wsl ]; 7 | 8 | config = lib.mkIf config.local.wsl-vpnkit.enable { 9 | 10 | wsl.wslConf.network.generateResolvConf = false; 11 | networking.nameservers = lib.mkDefault [ "8.8.4.4" "8.8.8.8" ]; 12 | boot.tmp.cleanOnBoot = true; 13 | 14 | environment.systemPackages = [ pkgs.unstable.wsl-vpnkit ]; 15 | environment.shellAliases = { 16 | vpn-status = "systemctl status wsl-vpnkit | sed -n '/Active: /s/Active: //p' | awk '{$1=$1};1'"; 17 | vpn-start = "sudo systemctl start wsl-vpnkit"; 18 | vpn-stop = "sudo systemctl stop wsl-vpnkit"; 19 | }; 20 | systemd.services.wsl-vpnkit = { 21 | enable = true; 22 | description = "wsl-vpnkit"; 23 | serviceConfig = { 24 | ExecStart = "${pkgs.unstable.wsl-vpnkit}/bin/wsl-vpnkit"; 25 | Type = "idle"; 26 | Restart = "always"; 27 | KillMode = "mixed"; 28 | }; 29 | }; 30 | }; 31 | } -------------------------------------------------------------------------------- /modules/zen-browser/default.nix: -------------------------------------------------------------------------------- 1 | # internet browser 2 | args@{ config, lib, pkgs, inputs, variables, ... }: 3 | let 4 | extensions = pkgs.nur.repos.rycee.firefox-addons; 5 | in 6 | lib.mkModule "zen-browser" config { 7 | home-manager.users.${variables.username} = { config, ... }: { 8 | imports = [ inputs.zenix.homeModules.default ]; 9 | 10 | programs.zenix = { 11 | enable = true; 12 | 13 | chrome = { 14 | findbar = true; # better-looking ctrl-f bar 15 | hideTitlebarButtons = true; 16 | }; 17 | 18 | profiles.default = { 19 | isDefault = true; 20 | 21 | userChrome.source = config.lib.file.mkOutOfStoreSymlink 22 | "/etc/dotfiles/modules/zen-browser/userChrome.css"; 23 | 24 | extensions.packages = with extensions; [ 25 | bitwarden 26 | qwant-search 27 | languagetool 28 | tampermonkey 29 | ublock-origin 30 | decentraleyes 31 | privacy-badger 32 | consent-o-matic 33 | return-youtube-dislikes 34 | /* HistoryBlock e.g. for search engine */ 35 | ]; 36 | 37 | extraConfig = '' 38 | user_pref("privacy.history.custom", true); 39 | user_pref("layout.spellcheckDefault", 0); 40 | user_pref("zen.tab-unloader.enabled", false); 41 | user_pref("zen.view.sidebar-expanded", false); 42 | user_pref("zen.view.use-single-toolbar", false); 43 | user_pref("zen.glance.activation-method", "shift"); 44 | user_pref("signon.rememberSignons", false); // ask to save passwords 45 | user_pref("extensions.formautofill.addresses.enabled", false); 46 | user_pref("extensions.formautofill.creditCards.enabled", false); 47 | user_pref("browser.startup.page", 1); // open previous tabs 48 | user_pref("browser.formfill.enable", false); 49 | user_pref("browser.search.suggest.enabled", true); 50 | user_pref("browser.urlbar.suggest.recentsearches", false); 51 | user_pref("browser.urlbar.showSearchSuggestionsFirst", false); 52 | user_pref("browser.newtabpage.activity-stream.showWeather", false); 53 | user_pref("browser.download.always_ask_before_handling_new_types", false); 54 | ''; 55 | }; 56 | 57 | chrome.variables = { 58 | colors = { 59 | primary = "#F7F1FF"; # for small ui elements 60 | text = "#F7F1FF"; 61 | secondary = "#FD9353"; 62 | maroon = "#FC618D"; 63 | highlight = "#5AD4E6"; 64 | base = "#262527"; 65 | mantle = "#201F21"; 66 | crust = "#1F1E20"; 67 | }; 68 | glass = { 69 | background = "rgba(38, 37, 39, 0.5)"; 70 | blurRadius = "25px"; 71 | }; 72 | }; 73 | }; 74 | }; 75 | } -------------------------------------------------------------------------------- /modules/zen-browser/userChrome.css: -------------------------------------------------------------------------------- 1 | * { 2 | /* transparent main border background */ 3 | --zen-main-browser-background: var(--zenix-glass-background) !important; 4 | /* shadow around webview container */ 5 | --zen-big-shadow: transparent !important; 6 | /* right and bottom margin of webview container */ 7 | --zen-element-separation: 0px; 8 | /* borders and separators of pop-up dialogs */ 9 | --panel-separator-color: hsla(0, 0%, 100%, 0.1) !important; 10 | --zen-appcontent-border: 1px solid var(--panel-separator-color) !important; 11 | } 12 | 13 | @media (prefers-color-scheme: dark) { 14 | /* make webview container truly transparent (only visible on startup) */ 15 | browser[transparent="true"] { 16 | background: transparent !important; 17 | } 18 | 19 | /* right click menu */ 20 | .menupopup-arrowscrollbox { 21 | /* background is blurred by hyprland, don't need to set here */ 22 | background: var(--zenix-glass-background) !important; 23 | } 24 | 25 | /* selected tab when window is focused */ 26 | :root:not(:-moz-window-inactive) [selected="true"] .tab-background 27 | { 28 | background-color: rgba(38, 37, 39, 0.25) !important; 29 | } 30 | 31 | /* especially when floating/extended */ 32 | #urlbar-background { 33 | background: var(--zenix-glass-background) !important; 34 | backdrop-filter: blur(var(--zenix-glass-blur-radius)) !important; 35 | } 36 | 37 | /* url bar background when not floating/extended */ 38 | #urlbar:not([zen-floating-urlbar="true"]):not([breakout-extend="true"]) #urlbar-background { 39 | background: transparent !important; 40 | backdrop-filter: none !important; 41 | } 42 | 43 | /* search engine indicator in url bar */ 44 | #urlbar-search-mode-indicator, 45 | /* zoom indicator in url bar */ 46 | #urlbar-zoom-button 47 | { 48 | background: transparent !important; 49 | } 50 | 51 | /* tracking protection icon in url bar */ 52 | #tracking-protection-icon-container { 53 | margin-right: 5px !important; 54 | } 55 | 56 | /* weirdly aligned bookmark button in url bar */ 57 | #star-button-box, 58 | /* weirdly aligned reader mode button in url bar */ 59 | #reader-mode-button, 60 | /* workspace indicator */ 61 | #zen-current-workspace-indicator-container 62 | { 63 | display: none; 64 | } 65 | 66 | /* pinned extension icons */ 67 | .toolbarbutton-1.panel-no-padding.webextension-browser-action.unified-extensions-item-action-button { 68 | filter: grayscale(0.75); 69 | } 70 | } -------------------------------------------------------------------------------- /packages/default.nix: -------------------------------------------------------------------------------- 1 | # build local packages 2 | { pkgs, ... }: 3 | { 4 | sddm-sugar-candy = pkgs.callPackage ./sddm-sugar-candy.nix {}; 5 | } -------------------------------------------------------------------------------- /packages/sddm-sugar-candy.nix: -------------------------------------------------------------------------------- 1 | #################### WARNING #################### 2 | # this package requires some external dependencies. 3 | # just this derivation alone will not work. 4 | # see modules/sddm-sugar-candy for more 5 | { stdenv, fetchFromGitHub }: 6 | stdenv.mkDerivation 7 | rec { 8 | pname = "sddm-sugar-candy"; 9 | version = "1.6"; 10 | 11 | src = fetchFromGitHub { 12 | owner = "Kangie"; 13 | repo = "sddm-sugar-candy"; 14 | rev = "v${version}"; 15 | hash = "sha256-p2d7I0UBP63baW/q9MexYJQcqSmZ0L5rkwK3n66gmqM="; 16 | }; 17 | 18 | installPhase = '' 19 | runHook preInstall 20 | 21 | mkdir -p $out/share/sddm/themes/sugar-candy 22 | cp -r . $out/share/sddm/themes/sugar-candy 23 | ln -sf /etc/dotfiles/modules/sddm-sugar-candy/sddm-sugar-candy.conf $out/share/sddm/themes/sugar-candy/theme.conf 24 | 25 | runHook postInstall 26 | ''; 27 | } -------------------------------------------------------------------------------- /variables.nix: -------------------------------------------------------------------------------- 1 | # config variables that are shared by all of my devices. 2 | { 3 | # nixos and home-manager state version (see top of flake.nix for channel version) 4 | version = "25.05"; 5 | # use --impure for flake-rebuild by default 6 | allowImpureByDefault = false; 7 | # username and displayname of only user 8 | username = "julius"; 9 | displayname = "Julius"; 10 | # global git config 11 | git.name = "julius-boettger"; 12 | git.email = "julius.btg@proton.me"; 13 | 14 | ### nixos configurations for different devices 15 | # documentation for possible attributes and their meanings 16 | # in flake.nix near "mkNixosConfig = device@{" 17 | nixosConfigs = { mkNixosConfigs, inputs }: mkNixosConfigs [ 18 | { internalName = "desktop"; } 19 | { internalName = "laptop"; } 20 | { 21 | internalName = "raspberry-pi"; 22 | hostName = "nixos-pi"; 23 | system = "aarch64-linux"; 24 | } 25 | { 26 | internalName = "wsl"; 27 | hostName = "wsl"; 28 | } 29 | ]; 30 | } -------------------------------------------------------------------------------- /wallpapers/nixos/bc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/bc.png -------------------------------------------------------------------------------- /wallpapers/nixos/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/bg.png -------------------------------------------------------------------------------- /wallpapers/nixos/bm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/bm.png -------------------------------------------------------------------------------- /wallpapers/nixos/br.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/br.png -------------------------------------------------------------------------------- /wallpapers/nixos/by.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/by.png -------------------------------------------------------------------------------- /wallpapers/nixos/cb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/cb.png -------------------------------------------------------------------------------- /wallpapers/nixos/cg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/cg.png -------------------------------------------------------------------------------- /wallpapers/nixos/cm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/cm.png -------------------------------------------------------------------------------- /wallpapers/nixos/cr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/cr.png -------------------------------------------------------------------------------- /wallpapers/nixos/cy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/cy.png -------------------------------------------------------------------------------- /wallpapers/nixos/gb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/gb.png -------------------------------------------------------------------------------- /wallpapers/nixos/gc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/gc.png -------------------------------------------------------------------------------- /wallpapers/nixos/gm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/gm.png -------------------------------------------------------------------------------- /wallpapers/nixos/gr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/gr.png -------------------------------------------------------------------------------- /wallpapers/nixos/gy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/gy.png -------------------------------------------------------------------------------- /wallpapers/nixos/mb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/mb.png -------------------------------------------------------------------------------- /wallpapers/nixos/mc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/mc.png -------------------------------------------------------------------------------- /wallpapers/nixos/mg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/mg.png -------------------------------------------------------------------------------- /wallpapers/nixos/mr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/mr.png -------------------------------------------------------------------------------- /wallpapers/nixos/my.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/my.png -------------------------------------------------------------------------------- /wallpapers/nixos/rb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/rb.png -------------------------------------------------------------------------------- /wallpapers/nixos/rc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/rc.png -------------------------------------------------------------------------------- /wallpapers/nixos/rg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/rg.png -------------------------------------------------------------------------------- /wallpapers/nixos/rm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/rm.png -------------------------------------------------------------------------------- /wallpapers/nixos/ry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/ry.png -------------------------------------------------------------------------------- /wallpapers/nixos/yb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/yb.png -------------------------------------------------------------------------------- /wallpapers/nixos/yc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/yc.png -------------------------------------------------------------------------------- /wallpapers/nixos/yg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/yg.png -------------------------------------------------------------------------------- /wallpapers/nixos/ym.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/ym.png -------------------------------------------------------------------------------- /wallpapers/nixos/yr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julius-boettger/dotfiles/2da931a03933ffaabf258924dc9095c9e1220806/wallpapers/nixos/yr.png --------------------------------------------------------------------------------