├── .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
--------------------------------------------------------------------------------