Compare commits

...

120 Commits

Author SHA1 Message Date
63f4c82c76 chore: update flake lockfiles 2026-01-27 16:22:13 +01:00
677b1b6666 fix: declare contents of 'setup-gnome' 2026-01-27 16:19:34 +01:00
b827b518cd refactor(statix): resolve 'statix check' issues 2026-01-27 07:34:37 +01:00
68eecd01c7 chore: update lockfile 2026-01-26 21:59:30 +01:00
8fc4e23d3b fix(nixd): properly configure 'nixd' nvim lsp 2026-01-26 21:58:09 +01:00
cf381042d0 feat: add 'gammastep' to niri deskopt 2026-01-26 21:21:49 +01:00
2303988b74 feat: add '3d' and 'photography' modules to andromache 2026-01-26 21:21:26 +01:00
791d90b703 fix: update hardware config 2026-01-26 18:47:43 +01:00
29137a8cdd chore: update lockfile 2026-01-25 15:32:53 +01:00
dd175e99b8 refactor: migrate vim.cmd to lua API in init.lua 2026-01-23 15:22:55 +01:00
3a5f1cf47e fix: remove conflicting light background setting
The bg=light setting was immediately overridden by vim.opt.background = "dark" later in the file.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-23 15:22:55 +01:00
755f1f4a06 refactor: remove duplicate 'paq-setup' require 2026-01-23 15:22:55 +01:00
1cfc049326 chore(nvim): remove redundant unused config 2026-01-23 15:22:55 +01:00
09d2832948 fix(vim.keymap): resolve duplicate 'fzf' keymap 2026-01-23 15:22:55 +01:00
85ab23eb5d fix(tmux): update tmux config 2026-01-23 15:22:55 +01:00
76a31b3051 refactor: deduplicate firefox/librewolf config 2026-01-23 15:22:55 +01:00
8e5cbe6350 fix: use 'nixGL' for kitty when available 2026-01-23 15:22:55 +01:00
e75fc95b27 feat: add 'tmux' to 'shell' module 2026-01-23 15:22:55 +01:00
24ed3f03cd refactor: extract 'dotsPath' for 'dots' path 2026-01-23 15:22:55 +01:00
b6453330bf refactor: centralize kitty config 2026-01-23 15:22:55 +01:00
bd008cde04 fix: remove 'edit_editor_config' alias 2026-01-23 15:22:55 +01:00
ffff1cfda1 refactor: modularize 'nvim' for home manager hosts 2026-01-23 15:22:55 +01:00
0f369bdf6c feat: set up colmena with hetzner stuff 2026-01-22 20:26:11 +01:00
600e55de1f feat: configure auto suspend 2026-01-22 20:25:06 +01:00
a390428ca9 feat: set up opencode (with automated API key) 2026-01-22 20:25:05 +01:00
a5aeddc5c2 feat: add 'hcloud' module 2026-01-22 20:24:36 +01:00
e9748b0236 chore: update Nix 'work' host 2026-01-22 20:22:19 +01:00
3902e2da67 chore: update lockfile 2026-01-22 20:20:30 +01:00
42af1badc4 refactor: modularize 'nvim' for home manager hosts 2026-01-19 10:12:02 +01:00
1eca0c995d feat: use shell module on work host 2026-01-19 10:03:05 +01:00
92389f7048 feat: modularize (and extend) kitty config 2026-01-19 09:45:22 +01:00
d6459d0d84 feat: add 'hcloud' module 2026-01-18 10:02:20 +01:00
00e5c92c1e fix: add 'hetzner' module 2026-01-18 09:43:45 +01:00
c19afff26a chore: update lockfile 2026-01-17 20:01:31 +01:00
8ea03f0a66 feat: automate optimising store, garbage collection and upgrades 2026-01-17 20:00:21 +01:00
8f3f6ec66d refactor(nixfmt): format 2026-01-17 19:58:27 +01:00
3401ed7424 chore: add 'andromache' ssh public keys 2026-01-17 19:50:21 +01:00
bb6a380599 refactor: simplify hosts files 2026-01-17 19:37:05 +01:00
35fd4e61e2 fix: remove xdg config 2026-01-17 18:02:17 +01:00
01542dda96 feat: replace 'sddm' with 'ly' 2026-01-17 17:51:26 +01:00
8464884fdb feat: automate SSH config ('known_hosts', 'authorized_keys' ...) 2026-01-17 17:37:37 +01:00
33b022c659 chore(nixfmt): format 2026-01-17 17:35:38 +01:00
a8f3f222b1 fix: merge 'astyanax' services configuration 2026-01-17 16:35:38 +01:00
bf9ea37280 fix: disable 'throttled' service 2026-01-17 16:34:14 +01:00
724c5c176b fix: improve niri desktop 2026-01-17 16:33:30 +01:00
49e99e9de2 fix: add anki to 'astyanax' host 2026-01-17 16:31:37 +01:00
ce0af2988a fix: move kitty tab bar to bottom 2026-01-17 15:10:28 +01:00
5a7afbfe82 fix: update font configuration 2026-01-17 15:09:57 +01:00
87afec8955 chore: update lockfile 2026-01-17 15:09:14 +01:00
2a1512f85b fix: disable 'nixos-hardware' module for astyanax (caused boot to hang on 'loading module i915') 2026-01-17 14:56:03 +01:00
313e623ec4 feat(home): add shell module 2026-01-16 15:25:29 +01:00
4f7ab88634 fix(anki): make sops optional for standalone home-manager 2026-01-16 15:25:27 +01:00
a8851e5a91 feat(home): migrate bash config to shell module 2026-01-16 15:25:25 +01:00
629f25c795 feat(nixos): pass inputs to home-manager via extraSpecialArgs 2026-01-16 15:25:23 +01:00
b52d87d30b chore(git): add .claude/ to gitignore 2026-01-16 15:25:20 +01:00
54114f99ab fix: make taskwarrior available on both NixOS and standalone home-manager 2026-01-14 22:57:27 +01:00
2fcde8ddd1 chore: update NixOS 2026-01-14 20:55:59 +01:00
a952136be1 fix: remove descriptions from 'browser' module 2026-01-14 16:45:56 +01:00
7773d2a7a0 fix: resolve nvim treesitter errors 2026-01-14 11:50:28 +01:00
c86a52e435 fix: add 'stylelint' to neovim flake 2026-01-14 11:22:01 +01:00
c99738c210 refactor(browser): create single browser module 2026-01-12 18:10:52 +01:00
8321d5e2ef chore: update Nix 'work' host 2026-01-08 11:59:54 +01:00
46477cce25 chore: update lockfile 2025-12-29 09:35:08 +01:00
4765527fa6 feat(nvim): add typescript-language-server to runtime dependencies 2025-12-24 14:46:40 +01:00
67f5aefc82 fix(nvim): ensure codecompanion config structure exists before mcphub extension loads 2025-12-24 14:43:29 +01:00
89c398a957 chore: update flake.lock with nvim mcp-hub input
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 14:14:38 +01:00
d1fc192d26 feat(nvim): add mcp-hub, fd, and delta dependencies
- add mcp-hub flake input for MCP integration
- create system-aware dependency overlays
- add mcp-hub, fd, delta to lspsAndRuntimeDeps
- remove duplicate tailwind-fold.lua file

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 14:14:10 +01:00
bc2790c7fb feat: set up 'claude-code.nvim' plugin 2025-12-18 16:01:31 +01:00
e3f55a1fbd chore: add TODO for unique 'networking.hostId' 2025-12-18 13:40:26 +01:00
c66cd0e28c refactor: use username variable consistently
Replaced hardcoded "h" username references with variables:
- hosts/vm: use username variable for secrets.username
- home configs: use username variable in bash initExtra paths
- keepassxc: update comment to use $HOME instead of /home/h

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-18 13:39:43 +01:00
d5d395ed56 fix(firefox): merge duplicate policies declarations
Second policies declaration was overwriting the first, causing
DefaultDownloadDirectory setting to be lost. Merged both into single
policies block.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-18 13:39:43 +01:00
e15f9a51cb fix: format rust using 'rustfmt' 2025-12-15 18:18:20 +01:00
acafbf9a6a refactor: decouple 'andromache' home config from 'astyanax' 2025-12-15 12:19:38 +01:00
4952ea0634 chore: update neovim flake (and main flake) 2025-12-15 12:01:19 +01:00
6e2f28d601 refactor: import shikane 'desktop/niri' instead of directly 2025-12-15 11:57:22 +01:00
143d31433f feat: add plain 'mako' service for notifications 2025-12-14 23:45:58 +01:00
a176c744f8 feat: declare anki config 2025-12-14 22:44:45 +01:00
2fa0b1f36a fix: migrate 'r5rs' script to neovim 2025-12-14 22:11:14 +01:00
520cd476fc fix: ignore directories that contain '.nobackup' in 'save-home' 2025-12-14 22:11:14 +01:00
f985df8e61 chore: format using 'black' 2025-12-14 22:11:14 +01:00
ec750ebb17 chore: clean up 'astyanax' packages 2025-12-09 23:43:56 +01:00
f3fd842692 feat: add 'fail2ban' to 'hecuba' host 2025-12-09 23:10:24 +01:00
6ff168caeb refactor: use environment variable for zettelkasten path 2025-12-09 12:43:07 +01:00
0863445dab feat: add 'rustfmt' for rust formatting 2025-12-08 20:16:18 +01:00
989a9626b3 chore: relock flake 2025-12-07 23:04:06 +01:00
7fa58a0421 feat: add 'figet.nvim' to 'nvim' flake 2025-12-07 22:59:05 +01:00
a477b2c5c3 test(nvim): try out 'm_taskwarrior_d.nvim' plugin 2025-12-07 19:16:07 +01:00
d2999ab763 fix: resolve 'nix flake check' errors 2025-12-07 17:42:18 +01:00
5d7b8d520a feat: use 'rustaceanvim' instead for rust development 2025-12-07 17:36:33 +01:00
edbbd3efd5 feat: add 'wl-clipboard' to niri desktop 2025-12-07 14:32:33 +01:00
de0b4852bf fix: work around throttled error 2025-12-07 00:13:59 +01:00
3e66197dd8 fix: declare graphics config for 'astyanax' host 2025-12-07 00:06:22 +01:00
495befc8c0 fix: resolve treesitter errors on NixOS 2025-12-07 00:05:46 +01:00
c4ccfc3a92 chore: ignore breaking changes warning for 'codecompanion.nvim' 2025-12-07 00:04:56 +01:00
02869d267a enable 'shikane' on 'astyanax' (and add 'wdisplays') 2025-12-06 23:51:50 +01:00
1e03157838 feat(nvim): set up rust lsp config 2025-12-06 23:49:29 +01:00
bc3caec6ba refactor: enable firewall explicitely for 'hecuba' host 2025-12-04 12:48:55 +01:00
2d9e1fd875 fix: remove common '.nix' suffix 2025-12-04 12:48:55 +01:00
63ef553d6b fix: update waybar to match polybar config (for the most part) 2025-12-04 12:48:55 +01:00
11ed160935 refactor: move 'wlsunset' package into home manager module 2025-12-04 12:48:55 +01:00
Hektor Misplon
7256c82b91 chore: update 'nvim' flake 2025-12-04 02:24:28 +01:00
Hektor Misplon
fcdb9d19fc fix: don't autoinstall treesitter grammars when using 'nixCats' 2025-12-04 02:21:30 +01:00
cec89af852 fix: declare 'fuzzel' config and add it to 'niri' desktop 2025-12-03 23:49:58 +01:00
8de9913ecf feat: track (currently unused) k3s module 2025-12-03 23:45:55 +01:00
d71e7d0e5d refactor: use 'default.nix' for all modules 2025-12-03 23:43:43 +01:00
e643d22eda fix: declare 'waybar' config and add it to 'niri' desktop 2025-12-03 23:36:33 +01:00
c141508203 fix: declare niri config 2025-12-03 23:36:33 +01:00
8ee1913d93 fix: try 'writeShellApplication' for 'astyanax' WOL script 2025-12-03 22:35:21 +01:00
ac4619f1a4 fix: declare 'andromache' 'eno1' interface MAC address 2025-12-03 21:40:44 +01:00
d178a03b43 feat: add 'hecuba' host config 2025-12-03 19:28:03 +01:00
063f142ae5 fix: further harden 'hardened-openssh' module 2025-12-03 17:14:08 +01:00
c90127e212 fix: replace 'gnome' desktop with 'niri' 2025-12-03 15:56:09 +01:00
f317f9409e fix: declare KeePassXC browser integration 2025-12-03 15:56:06 +01:00
c13de26ee1 chore(pkgs): add 'signal-desktop' package 2025-12-03 15:54:33 +01:00
ac5b97dba4 fix: disable kitty tab shortcut for now 2025-12-03 15:54:33 +01:00
4e2c3473e4 update bluetooth config 2025-12-03 15:54:33 +01:00
8434ceb45a refactor: move bootloader into 'modules/boot' 2025-12-03 15:54:33 +01:00
b2d1ef4bb1 refactor: move 'disko' modules into 'modules/disko' 2025-12-03 15:54:33 +01:00
c6ec0a5d1d resolve NixOS build warnings 2025-12-03 15:54:33 +01:00
d9ea9d1d27 Merge pull request 'update' (#1) from claude-code-test into main
Reviewed-on: #1
2025-12-03 15:53:43 +01:00
102 changed files with 2248 additions and 678 deletions

6
.gitignore vendored
View File

@@ -1,8 +1,10 @@
#
.claude/
home/hosts/work/packages.local.nix
# ---> Nix # ---> Nix
# Ignore build outputs from performing a nix-build or `nix build` command # Ignore build outputs from performing a nix-build or `nix build` command
result result
result-* result-*
nixos-efi-vars.fd nixos-efi-vars.fd
home/hosts/work/packages.local.nix

9
deploy/README.md Normal file
View File

@@ -0,0 +1,9 @@
# `colmena` deployments
* tags: `local`, `cloud`
* deployments can be made from `astyanax` and `andromache` hosts
## References
- [docs: `colmena`](https://colmena.cli.rs/)
- [repo: `colmena`](https://github.com/zhaofengli/colmena)

28
deploy/colmena.nix Normal file
View File

@@ -0,0 +1,28 @@
{
self,
inputs,
}:
inputs.colmena.lib.makeHive {
meta = {
nixpkgs = import inputs.nixpkgs {
system = "x86_64-linux";
};
nodeNixpkgs = builtins.mapAttrs (_: v: v.pkgs) self.nixosConfigurations;
nodeSpecialArgs = builtins.mapAttrs (_: v: v._module.specialArgs or { }) self.nixosConfigurations;
};
astyanax.deployment.tags = [ "local" ];
andromache.deployment.tags = [ "local" ];
vm.deployment.tags = [ "local" ];
hecuba.deployment = {
targetHost = "hecuba";
targetUser = "username";
targetPort = 22;
tags = [ "cloud" ];
};
}

View File

@@ -4,16 +4,3 @@
# Set NeoVim as default editor # Set NeoVim as default editor
export EDITOR=nvim export EDITOR=nvim
export SUDO_EDITOR="$EDITOR" export SUDO_EDITOR="$EDITOR"
declare -A -r EDITOR_CONFIGS=(
["nvim"]="$HOME/.config/nvim/init.lua"
["vim"]="$HOME/.vimrc"
)
edit_editor_config() {
for editor in "${!EDITOR_CONFIGS[@]}"; do
if [ "$EDITOR" = "$editor" ]; then
$EDITOR "${EDITOR_CONFIGS[$editor]}"
fi
done
}

View File

@@ -8,19 +8,24 @@ Pomodoro timer
- Notification on break finish - Notification on break finish
""" """
import os
import atexit import atexit
import os
from argparse import ArgumentParser from argparse import ArgumentParser
from time import sleep from time import sleep
from plyer import notification from plyer import notification
POMO_PATH = os.path.join(os.getenv("XDG_DATA_HOME", os.path.expanduser("~/.local/share")), "pomo") POMO_PATH = os.path.join(
os.getenv("XDG_DATA_HOME", os.path.expanduser("~/.local/share")), "pomo"
)
@atexit.register @atexit.register
def clear(): def clear():
if os.path.exists(POMO_PATH): if os.path.exists(POMO_PATH):
os.remove(POMO_PATH) os.remove(POMO_PATH)
def format_mins_secs(mins, secs): def format_mins_secs(mins, secs):
return f"{mins:02d}:{secs:02d}" return f"{mins:02d}:{secs:02d}"
@@ -34,6 +39,7 @@ def make_countdown():
os.system(f'echo -n "{time_str}" > {POMO_PATH}') os.system(f'echo -n "{time_str}" > {POMO_PATH}')
sleep(1) sleep(1)
duration -= 1 duration -= 1
return countdown return countdown
@@ -58,21 +64,23 @@ def main(args):
def handle_signal(signal, frame): def handle_signal(signal, frame):
# Wait for clear to finish # Wait for clear to finish
clear() clear()
print('Exiting') print("Exiting")
exit(0) exit(0)
if __name__ == '__main__': if __name__ == "__main__":
parser = ArgumentParser() parser = ArgumentParser()
parser.add_argument('-w', '--work-duration', type=int, parser.add_argument(
help='Session duration', default=25) "-w", "--work-duration", type=int, help="Session duration", default=25
parser.add_argument('-b', '--break-duration', type=int, )
help='Break duration', default=5) parser.add_argument(
parser.add_argument('-r', '--repeats', type=int, "-b", "--break-duration", type=int, help="Break duration", default=5
help='Numer of sessions', default=1) )
parser.add_argument('-c', '--clear', action='store_true', parser.add_argument(
help='Clear timer') "-r", "--repeats", type=int, help="Numer of sessions", default=1
)
parser.add_argument("-c", "--clear", action="store_true", help="Clear timer")
args = parser.parse_args() args = parser.parse_args()

View File

@@ -2,8 +2,8 @@
session="r5rs" session="r5rs"
tmux attach-session -t $session || tmux new-session -s $session \; \ tmux attach-session -t "$session" || tmux new-session -s "$session" \; \
split-window -h -t $session \; \ split-window -h -t $session \; \
send-keys -t 0 "vim" C-m \; \ send-keys -t 1 "nvim -c \"set ft=scheme\"" C-m \; \
send-keys -t 1 "plt-r5rs --no-prim" C-m \; \ send-keys -t 2 "plt-r5rs --no-prim" C-m \; \
select-pane -t 0 select-pane -t 1

View File

@@ -22,4 +22,5 @@ restic -r "$RESTIC_REPOSITORY:$HOSTNAME" backup \
--one-file-system \ --one-file-system \
--files-from="$HOME/.resticinclude" \ --files-from="$HOME/.resticinclude" \
--exclude-file="$HOME/.resticexclude" \ --exclude-file="$HOME/.resticexclude" \
--exclude-if-present=".nobackup" \
--verbose=3 --verbose=3

View File

@@ -1,12 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
import sys
import subprocess import subprocess
import sys
DEFAULT_TEMPERATURE = 3500 DEFAULT_TEMPERATURE = 3500
try: try:
with open('/tmp/temperature', 'r') as temp_file: with open("/tmp/temperature", "r") as temp_file:
current_temperature = int(temp_file.read()) current_temperature = int(temp_file.read())
except FileNotFoundError: except FileNotFoundError:
current_temperature = DEFAULT_TEMPERATURE current_temperature = DEFAULT_TEMPERATURE
@@ -16,7 +16,8 @@ if len(sys.argv) == 1:
print(current_temperature) print(current_temperature)
sys.exit(0) sys.exit(0)
elif len(sys.argv) != 2: elif len(sys.argv) != 2:
print(""" print(
"""
Usage: Usage:
screen-temperature screen-temperature
@@ -27,7 +28,8 @@ Usage:
screen-temperature <+|-><temperature> screen-temperature <+|-><temperature>
increase or decrease screen temperature by <temperature> increase or decrease screen temperature by <temperature>
""") """
)
sys.exit(1) sys.exit(1)
temperature_change = sys.argv[1] temperature_change = sys.argv[1]
@@ -41,11 +43,10 @@ else:
try: try:
subprocess.run(["redshift", "-O", str(new_temperature), "-P"], check=True) subprocess.run(["redshift", "-O", str(new_temperature), "-P"], check=True)
with open('/tmp/temperature', 'w') as temp_file: with open("/tmp/temperature", "w") as temp_file:
temp_file.write(str(new_temperature) + '\n') temp_file.write(str(new_temperature) + "\n")
# Send notification # Send notification
subprocess.run( subprocess.run(["notify-send", str(new_temperature) + "K"])
["notify-send", str(new_temperature) + "K"])
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
print("Error: could not set screen temperature.") print("Error: could not set screen temperature.")
sys.exit(1) sys.exit(1)

View File

@@ -1,37 +0,0 @@
#!/usr/bin/env bash
gsettings set org.gnome.desktop.background primary-color "#555555"
gsettings set org.gnome.desktop.wm.preferences workspace-names "['sh', 'www', 'dev', 'info', 'etc']"
gsettings set org.gnome.desktop.wm.keybindings close "['<Shift><Super>Delete']"
gsettings set org.gnome.desktop.wm.keybindings switch-applications "['<Super>j']"
gsettings set org.gnome.desktop.wm.keybindings switch-applications-backward "['<Super>k']"
gsettings set org.gnome.shell.keybindings toggle-application-view "['<Super>p']"
gsettings set org.gnome.mutter center-new-windows true
gsettings set org.gnome.shell.keybindings toggle-quick-settings []
gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 "['<Super>a']"
gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-2 "['<Super>s']"
gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-3 "['<Super>d']"
gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-4 "['<Super>f']"
gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-5 "['<Super>g']"
gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-1 "['<Super><Shift>a']"
gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-2 "['<Super><Shift>s']"
gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-3 "['<Super><Shift>d']"
gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-4 "['<Super><Shift>f']"
gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-5 "['<Super><Shift>g']"
gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/']"
gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ name "Kitty"
gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ command "kitty"
gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ binding "<Shift><Super>Return"
gsettings set org.gnome.shell.keybindings screenshot "['Print']"
gsettings set org.gnome.desktop.wm.preferences num-workspaces "5"
gsettings set org.gnome.mutter dynamic-workspaces "false"
gsettings set org.gnome.shell.extensions.window-list display-all-workspaces "true"
gsettings set org.gnome.shell.app-switcher current-workspace-only "true"
gsettings set org.gnome.login-screen logo ''
gsettings set org.gnome.shell favorite-apps "['firefox-developer-edition.desktop']"

View File

@@ -1,7 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
current_zettel_path="$ZK_PATH/$(cat "$ZK_PATH/current-zettel.txt")"
if [ "$TERM_PROGRAM" = tmux ]; then if [ "$TERM_PROGRAM" = tmux ]; then
cd ~/.zk && $EDITOR "$(cat ~/.zk/current-zettel.txt)" cd "$ZK_PATH" && $EDITOR "$current_zettel_path"
else else
echo 'Not in tmux' echo 'Not in tmux'
echo 'Choose an option:' echo 'Choose an option:'
@@ -18,12 +20,12 @@ else
else else
# Create session with a window named 'zk' and start nvim # Create session with a window named 'zk' and start nvim
tmux new-session -s zk -n zk -d tmux new-session -s zk -n zk -d
tmux send-keys -t zk:zk "cd ~/.zk && $EDITOR \"\$(cat ~/.zk/current-zettel.txt)\"" Enter tmux send-keys -t zk:zk "cd $ZK_PATH && $EDITOR $current_zettel_path" Enter
tmux attach -t zk tmux attach -t zk
fi fi
;; ;;
2) 2)
cd ~/.zk && $EDITOR "$(cat ~/.zk/current-zettel.txt)" cd "$ZK_PATH" && $EDITOR "$current_zettel_path"
;; ;;
*) *)
echo 'Not opening Zettelkasten' echo 'Not opening Zettelkasten'

View File

@@ -56,7 +56,7 @@ hide_window_decorations yes
#: Tab bar {{{ #: Tab bar {{{
tab_bar_edge top tab_bar_edge bottom
tab_bar_style powerline tab_bar_style powerline
tab_bar_min_tabs 1 tab_bar_min_tabs 1
tab_powerline_style slanted tab_powerline_style slanted
@@ -136,7 +136,7 @@ map f5 goto_tab 5
map f6 goto_tab 6 map f6 goto_tab 6
map f7 goto_tab 7 map f7 goto_tab 7
map f8 goto_tab 8 map f8 goto_tab 8
map kitty_mod+c new_tab # map kitty_mod+c new_tab # FIXME: conflict with 'copy'
map cmd+t map cmd+t
map kitty_mod+q map kitty_mod+q
map cmd+w map cmd+w

View File

@@ -0,0 +1,61 @@
require("claude-code").setup({
-- Terminal window settings
window = {
split_ratio = 0.3, -- Percentage of screen for the terminal window (height for horizontal, width for vertical splits)
position = "vertical", -- Position of the window: "botright", "topleft", "vertical", "float", etc.
enter_insert = true, -- Whether to enter insert mode when opening Claude Code
hide_numbers = true, -- Hide line numbers in the terminal window
hide_signcolumn = true, -- Hide the sign column in the terminal window
-- Floating window configuration (only applies when position = "float")
float = {
width = "80%", -- Width: number of columns or percentage string
height = "80%", -- Height: number of rows or percentage string
row = "center", -- Row position: number, "center", or percentage string
col = "center", -- Column position: number, "center", or percentage string
relative = "editor", -- Relative to: "editor" or "cursor"
border = "rounded", -- Border style: "none", "single", "double", "rounded", "solid", "shadow"
},
},
-- File refresh settings
refresh = {
enable = true, -- Enable file change detection
updatetime = 100, -- updatetime when Claude Code is active (milliseconds)
timer_interval = 1000, -- How often to check for file changes (milliseconds)
show_notifications = true, -- Show notification when files are reloaded
},
-- Git project settings
git = {
use_git_root = true, -- Set CWD to git root when opening Claude Code (if in git project)
},
-- Shell-specific settings
shell = {
separator = "&&", -- Command separator used in shell commands
pushd_cmd = "pushd", -- Command to push directory onto stack (e.g., 'pushd' for bash/zsh, 'enter' for nushell)
popd_cmd = "popd", -- Command to pop directory from stack (e.g., 'popd' for bash/zsh, 'exit' for nushell)
},
-- Command settings
command = "claude", -- Command used to launch Claude Code
-- Command variants
command_variants = {
-- Conversation management
continue = "--continue", -- Resume the most recent conversation
resume = "--resume", -- Display an interactive conversation picker
-- Output options
verbose = "--verbose", -- Enable verbose logging with full turn-by-turn output
},
-- Keymaps
keymaps = {
toggle = {
normal = "<C-,>", -- Normal mode keymap for toggling Claude Code, false to disable
terminal = "<C-,>", -- Terminal mode keymap for toggling Claude Code, false to disable
variants = {
continue = "<leader>cC", -- Normal mode keymap for Claude Code with continue flag
verbose = "<leader>cV", -- Normal mode keymap for Claude Code with verbose flag
},
},
window_navigation = true, -- Enable window navigation keymaps (<C-h/j/k/l>)
scrolling = true, -- Enable scrolling keymaps (<C-f/b>) for page up/down
},
})

View File

@@ -1,16 +1,22 @@
require("codecompanion").setup({ require("codecompanion").setup({
extensions = { ignore_warnings = true,
mcphub = {
callback = "mcphub.extensions.codecompanion",
opts = {
make_vars = true,
make_slash_commands = true,
show_result_in_chat = true
}
}
},
strategies = { strategies = {
chat = { adapter = "openai" }, chat = { adapter = "openai" },
inline = { adapter = "openai" }, inline = { adapter = "openai" },
}, },
}) })
-- Load mcphub extension after codecompanion is initialized
-- and ensure the config structure exists
local ok, cc_config = pcall(require, "codecompanion.config")
if ok then
cc_config.interactions = cc_config.interactions or {}
cc_config.interactions.chat = cc_config.interactions.chat or {}
cc_config.interactions.chat.tools = cc_config.interactions.chat.tools or {}
require("mcphub.extensions.codecompanion").setup({
make_vars = true,
make_slash_commands = true,
show_result_in_chat = true,
})
end

View File

@@ -13,14 +13,15 @@ require("conform").setup({
gdscript = { "gdformat" }, gdscript = { "gdformat" },
haskell = { "ormolu" }, haskell = { "ormolu" },
html = { "prettierd", "prettier", stop_after_first = true }, html = { "prettierd", "prettier", stop_after_first = true },
lua = { "stylua" }, -- configured in stylua.toml
markdown = { "prettierd", "prettier", stop_after_first = true },
nix = { "nixfmt" },
javascript = { "eslint_d", "eslint", "prettierd", "prettier", stop_after_first = true }, javascript = { "eslint_d", "eslint", "prettierd", "prettier", stop_after_first = true },
javascriptreact = { "eslint_d", "eslint", "prettierd", "prettier", stop_after_first = true }, javascriptreact = { "eslint_d", "eslint", "prettierd", "prettier", stop_after_first = true },
json = { "prettierd", "prettier", stop_after_first = true }, json = { "prettierd", "prettier", stop_after_first = true },
jsonc = { "prettierd", "prettier", stop_after_first = true }, jsonc = { "prettierd", "prettier", stop_after_first = true },
lua = { "stylua" }, -- configured in stylua.toml
markdown = { "prettierd", "prettier", stop_after_first = true },
nix = { "nixfmt" },
python = { "isort", "black" }, python = { "isort", "black" },
rust = { "rustfmt", lsp_fallback = "fallback" },
svelte = { "eslint_d", "prettierd", "prettier", stop_after_first = true }, svelte = { "eslint_d", "prettierd", "prettier", stop_after_first = true },
typescript = { "eslint_d", "prettierd", "prettier", stop_after_first = true }, typescript = { "eslint_d", "prettierd", "prettier", stop_after_first = true },
typescriptreact = { "eslint_d", "eslint", "prettierd", "prettier", stop_after_first = true }, typescriptreact = { "eslint_d", "eslint", "prettierd", "prettier", stop_after_first = true },

View File

@@ -0,0 +1 @@
require("fidget").setup()

View File

@@ -11,6 +11,6 @@ vim.keymap.set("n", "<leader>fd", fzf.diagnostics_workspace)
vim.keymap.set("n", "<leader>fhe", fzf.help_tags) vim.keymap.set("n", "<leader>fhe", fzf.help_tags)
vim.keymap.set("n", "<leader>fhi", fzf.search_history) vim.keymap.set("n", "<leader>fhi", fzf.search_history)
vim.keymap.set("n", "<leader>fma", fzf.marks) vim.keymap.set("n", "<leader>fma", fzf.marks)
vim.keymap.set("n", "<leader>fma", fzf.man_pages) vim.keymap.set("n", "<leader>fmp", fzf.man_pages)
vim.keymap.set("i", "<c-f>", fzf.complete_path) vim.keymap.set("i", "<c-f>", fzf.complete_path)

View File

@@ -1,8 +1,5 @@
require("neodev").setup() -- should setup before lspconfig require("neodev").setup() -- should setup before lspconfig
-- vim.g.coq_settings = { auto_start = 'shut-up' }
-- local capabilities = coq.lsp_ensure_capabilities()
local cmp_nvim_lsp = require("cmp_nvim_lsp") local cmp_nvim_lsp = require("cmp_nvim_lsp")
local capabilities = cmp_nvim_lsp.default_capabilities() local capabilities = cmp_nvim_lsp.default_capabilities()
@@ -64,8 +61,30 @@ local servers = {
Lua = {}, Lua = {},
}, },
}, },
-- marksman = {}, nixd = {
nixd = {}, settings = {
nixd = {
nixpkgs = {
expr = "import <nixpkgs> { }",
expr = 'import (builtins.getFlake ("git+file://" + toString ../../../../../.)).inputs.nixpkgs { }',
},
},
options = {
nixos = {
expr = '(builtins.getFlake ("git+file://" + toString ../../../../../.)).nixosConfigurations."'
.. vim.fn.hostname()
.. '".options',
},
home_manager = {
expr = '(builtins.getFlake ("git+file://" + toString ../../../../../.)).homeConfigurations."'
.. vim.fn.expand("$USER")
.. "@"
.. vim.fn.hostname()
.. '".options',
},
},
},
},
pyright = {}, pyright = {},
-- tsserver = {}, -- tsserver = {},
svelte = { svelte = {

View File

@@ -0,0 +1,9 @@
require("m_taskwarrior_d").setup()
vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost" }, {
group = vim.api.nvim_create_augroup("TWTask", { clear = true }),
pattern = "*.md",
callback = function()
vim.cmd("TWSyncTasks")
end,
})

View File

@@ -2,12 +2,15 @@ local ts = require("treesj")
local vim = vim local vim = vim
local keymap = vim.keymap local keymap = vim.keymap
local opt = vim.opt local opt = vim.opt
local treesitter_configs = require("nvim-treesitter.configs") local treesitter = require("nvim-treesitter")
treesitter_configs.setup({ local nixCatsUtils = require("nixCatsUtils")
local is_nix = nixCatsUtils.isNixCats
treesitter.setup({
-- Basically added what I might need from the docs -- Basically added what I might need from the docs
-- <https://github.com/nvim-treesitter/nvim-treesitter?tab=readme-ov-file#supported-languages> -- <https://github.com/nvim-treesitter/nvim-treesitter?tab=readme-ov-file#supported-languages>
ensure_installed = { ensure_installed = is_nix and {} or {
"awk", "awk",
"bash", "bash",
"bibtex", "bibtex",
@@ -86,7 +89,7 @@ treesitter_configs.setup({
enable = true, enable = true,
}, },
sync_install = false, sync_install = false,
auto_install = true, auto_install = not is_nix,
ignore_install = {}, ignore_install = {},
modules = {}, modules = {},
textobjects = { textobjects = {

View File

@@ -1,12 +1,52 @@
{ {
"nodes": { "nodes": {
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"mcp-hub",
"nixpkgs"
]
},
"locked": {
"lastModified": 1743550720,
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"mcp-hub": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1755841689,
"narHash": "sha256-KakvXZf0vjdqzyT+LsAKHEr4GLICGXPmxl1hZ3tI7Yg=",
"owner": "ravitemer",
"repo": "mcp-hub",
"rev": "9c7670a4c341ed3cf738a6242c0fde1cea40bccf",
"type": "github"
},
"original": {
"owner": "ravitemer",
"repo": "mcp-hub",
"type": "github"
}
},
"nixCats": { "nixCats": {
"locked": { "locked": {
"lastModified": 1763330129, "lastModified": 1769085828,
"narHash": "sha256-KbOeWIF52SV53BOeETGO2C5ewaV2Ex9iaXH7G72gOr8=", "narHash": "sha256-TjhFIAtS628+/r3IuYWPcNa++mUMMDDG8PbSfFHXBiA=",
"owner": "BirdeeHub", "owner": "BirdeeHub",
"repo": "nixCats-nvim", "repo": "nixCats-nvim",
"rev": "c81551ed87db2aefab30a12cf7425ff94dc0ad64", "rev": "43fbf4d12b0a613f1a792503da4bb2bf270173c7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -17,11 +57,27 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1763464769, "lastModified": 1743689281,
"narHash": "sha256-AJHrsT7VoeQzErpBRlLJM1SODcaayp0joAoEA35yiwM=", "narHash": "sha256-y7Hg5lwWhEOgflEHRfzSH96BOt26LaYfrYWzZ+VoVdg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2bfc080955153be0be56724be6fa5477b4eefabb",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1769433173,
"narHash": "sha256-Gf1dFYgD344WZ3q0LPlRoWaNdNQq8kSBDLEWulRQSEs=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "6f374686605df381de8541c072038472a5ea2e2d", "rev": "13b0f9e6ac78abbbb736c635d87845c4f4bee51b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -47,30 +103,14 @@
"type": "github" "type": "github"
} }
}, },
"plugins-crazy-node-movement": {
"flake": false,
"locked": {
"lastModified": 1693654676,
"narHash": "sha256-hQcQEp39zFN2zphMfcr97yRVcuHhBsSkzKO7XNloDpQ=",
"owner": "theHamsta",
"repo": "crazy-node-movement",
"rev": "d5cf01cc44c5715501d3d6fe439af7c8b7fa5df2",
"type": "github"
},
"original": {
"owner": "theHamsta",
"repo": "crazy-node-movement",
"type": "github"
}
},
"plugins-helm-ls-nvim": { "plugins-helm-ls-nvim": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1761915179, "lastModified": 1768584652,
"narHash": "sha256-W9NRa84l5Cs62OsDeqb+LMxk8oYjhVBCB3o3UmE9a0I=", "narHash": "sha256-jnMc87OjURNcqsva0npYgVyUrWc5C6L7yHpNvt9eSmg=",
"owner": "qvalentin", "owner": "qvalentin",
"repo": "helm-ls.nvim", "repo": "helm-ls.nvim",
"rev": "d6f3a8d4ad59b4f54cd734267dfb5411679ea608", "rev": "f0b9a1723890971a6d84890b50dbf5f40974ea1b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -79,14 +119,30 @@
"type": "github" "type": "github"
} }
}, },
"plugins-m-taskwarrior-d-nvim": {
"flake": false,
"locked": {
"lastModified": 1767960157,
"narHash": "sha256-ov0qi4LhIlwqrBzSbTJ6APC5qjl2d/vlKWJfW5ZiDrg=",
"owner": "huantrinh1802",
"repo": "m_taskwarrior_d.nvim",
"rev": "107247387cd81823046bc2b8e71150c8edf041d3",
"type": "github"
},
"original": {
"owner": "huantrinh1802",
"repo": "m_taskwarrior_d.nvim",
"type": "github"
}
},
"plugins-mcphub-nvim": { "plugins-mcphub-nvim": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1759035242, "lastModified": 1768730387,
"narHash": "sha256-I6EbgY/2sAdtrxtmH0qbAAQvMCHhOsfolJfblV0fXOk=", "narHash": "sha256-g9tPvjThz6EUk7zcY7lL+YH4lrT4x3FJ6jrNMHA8PAE=",
"owner": "ravitemer", "owner": "ravitemer",
"repo": "mcphub.nvim", "repo": "mcphub.nvim",
"rev": "8ff40b5edc649959bb7e89d25ae18e055554859a", "rev": "7cd5db330f41b7bae02b2d6202218a061c3ebc1f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -130,11 +186,11 @@
"plugins-tailwind-fold-nvim": { "plugins-tailwind-fold-nvim": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1752559116, "lastModified": 1766077142,
"narHash": "sha256-8uefZIVsn9USEd6FyiO3m3TRKAS/vigU4t9Tk5ijd3c=", "narHash": "sha256-SwcDLlygXUSV/dytPXA5Y45OpUhjnExc8SZg5a8MZ2k=",
"owner": "razak17", "owner": "razak17",
"repo": "tailwind-fold.nvim", "repo": "tailwind-fold.nvim",
"rev": "d9e7ca11691d252b35795726dff087bf013b2ebf", "rev": "e2ba5ee1ca9b74208709fe9d7314b8aa753b26a7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -145,11 +201,12 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"mcp-hub": "mcp-hub",
"nixCats": "nixCats", "nixCats": "nixCats",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs_2",
"plugins-beancount-nvim": "plugins-beancount-nvim", "plugins-beancount-nvim": "plugins-beancount-nvim",
"plugins-crazy-node-movement": "plugins-crazy-node-movement",
"plugins-helm-ls-nvim": "plugins-helm-ls-nvim", "plugins-helm-ls-nvim": "plugins-helm-ls-nvim",
"plugins-m-taskwarrior-d-nvim": "plugins-m-taskwarrior-d-nvim",
"plugins-mcphub-nvim": "plugins-mcphub-nvim", "plugins-mcphub-nvim": "plugins-mcphub-nvim",
"plugins-nvimkit-nvim": "plugins-nvimkit-nvim", "plugins-nvimkit-nvim": "plugins-nvimkit-nvim",
"plugins-shipwright-nvim": "plugins-shipwright-nvim", "plugins-shipwright-nvim": "plugins-shipwright-nvim",

View File

@@ -2,13 +2,14 @@
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
nixCats.url = "github:BirdeeHub/nixCats-nvim"; nixCats.url = "github:BirdeeHub/nixCats-nvim";
mcp-hub.url = "github:ravitemer/mcp-hub";
plugins-shipwright-nvim = { plugins-shipwright-nvim = {
url = "github:rktjmp/shipwright.nvim"; url = "github:rktjmp/shipwright.nvim";
flake = false; flake = false;
}; };
plugins-crazy-node-movement = { plugins-m-taskwarrior-d-nvim = {
url = "github:theHamsta/crazy-node-movement"; url = "github:huantrinh1802/m_taskwarrior_d.nvim";
flake = false; flake = false;
}; };
plugins-beancount-nvim = { plugins-beancount-nvim = {
@@ -47,8 +48,11 @@
forEachSystem = utils.eachSystem nixpkgs.lib.platforms.all; forEachSystem = utils.eachSystem nixpkgs.lib.platforms.all;
extra_pkg_config = { }; extra_pkg_config = { };
dependencyOverlays = [ mkDependencyOverlays = system: [
(utils.standardPluginOverlay inputs) (utils.standardPluginOverlay inputs)
(final: prev: {
mcp-hub = inputs.mcp-hub.packages.${system}.default;
})
]; ];
categoryDefinitions = categoryDefinitions =
@@ -62,17 +66,23 @@
black black
clang clang
clang-tools clang-tools
delta
fd
gawk gawk
gdtoolkit_4 gdtoolkit_4
isort isort
tree-sitter mcp-hub
ormolu
nodePackages.prettier
nixd nixd
nixfmt nixfmt
nodePackages.prettier
nodePackages.typescript-language-server
ormolu
prettierd prettierd
rustfmt
shellcheck-minimal shellcheck-minimal
stylelint
stylua stylua
tree-sitter
vscode-langservers-extracted vscode-langservers-extracted
]; ];
}; };
@@ -123,7 +133,6 @@
pkgs.neovimPlugins.shipwright-nvim pkgs.neovimPlugins.shipwright-nvim
lush-nvim lush-nvim
zenbones-nvim zenbones-nvim
pkgs.neovimPlugins.crazy-node-movement
nvim-treesitter.withAllGrammars nvim-treesitter.withAllGrammars
nvim-treesitter-textobjects nvim-treesitter-textobjects
# nvim-treesitter-context # nvim-treesitter-context
@@ -143,7 +152,11 @@
copilot-lua copilot-lua
copilot-cmp copilot-cmp
pkgs.neovimPlugins.helm-ls-nvim pkgs.neovimPlugins.helm-ls-nvim
pkgs.vimPlugins.kitty-scrollback-nvim kitty-scrollback-nvim
fidget-nvim
rustaceanvim
pkgs.neovimPlugins.m-taskwarrior-d-nvim
claude-code-nvim
]; ];
}; };
@@ -161,7 +174,7 @@
packageDefinitions = { packageDefinitions = {
nvim = nvim =
{ ... }: _:
{ {
settings = { settings = {
suffix-path = true; suffix-path = true;
@@ -180,6 +193,7 @@
forEachSystem ( forEachSystem (
system: system:
let let
dependencyOverlays = mkDependencyOverlays system;
nixCatsBuilder = utils.baseBuilder luaPath { nixCatsBuilder = utils.baseBuilder luaPath {
inherit inherit
nixpkgs nixpkgs
@@ -199,7 +213,7 @@
name = defaultPackageName; name = defaultPackageName;
packages = [ defaultPackage ]; packages = [ defaultPackage ];
inputsFrom = [ ]; inputsFrom = [ ];
shellHook = ''''; shellHook = "";
}; };
}; };
@@ -211,31 +225,32 @@
moduleNamespace = [ defaultPackageName ]; moduleNamespace = [ defaultPackageName ];
inherit inherit
defaultPackageName defaultPackageName
dependencyOverlays
luaPath luaPath
categoryDefinitions categoryDefinitions
packageDefinitions packageDefinitions
extra_pkg_config extra_pkg_config
nixpkgs nixpkgs
; ;
dependencyOverlays = mkDependencyOverlays;
}; };
homeModule = utils.mkHomeModules { homeModule = utils.mkHomeModules {
moduleNamespace = [ defaultPackageName ]; moduleNamespace = [ defaultPackageName ];
inherit inherit
defaultPackageName defaultPackageName
dependencyOverlays
luaPath luaPath
categoryDefinitions categoryDefinitions
packageDefinitions packageDefinitions
extra_pkg_config extra_pkg_config
nixpkgs nixpkgs
; ;
dependencyOverlays = mkDependencyOverlays;
}; };
in in
{ {
overlays = utils.makeOverlays luaPath { overlays = utils.makeOverlays luaPath {
inherit nixpkgs dependencyOverlays extra_pkg_config; inherit nixpkgs extra_pkg_config;
dependencyOverlays = mkDependencyOverlays;
} categoryDefinitions packageDefinitions defaultPackageName; } categoryDefinitions packageDefinitions defaultPackageName;
nixosModules.default = nixosModule; nixosModules.default = nixosModule;

View File

@@ -1,10 +1,7 @@
require("nixCatsUtils").setup({ non_nix_value = true }) -- https://github.com/BirdeeHub/nixCats-nvim/blob/77dffad8235eb77684fcb7599487c8e9f23d5b8f/templates/example/init.lua require("nixCatsUtils").setup({ non_nix_value = true }) -- https://github.com/BirdeeHub/nixCats-nvim/blob/77dffad8235eb77684fcb7599487c8e9f23d5b8f/templates/example/init.lua
vim.cmd([[ vim.opt.termguicolors = true
set termguicolors vim.api.nvim_set_hl(0, "Normal", { ctermbg = "NONE", bg = "NONE" })
set bg=light
hi Normal ctermbg=none guibg=NONE
]])
require("base") require("base")
require("cursor") require("cursor")
@@ -22,7 +19,5 @@ require("utils")
require("zk") require("zk")
require("reload") require("reload")
require("paq-setup") -- when not on nixCats
vim.opt.background = "dark" vim.opt.background = "dark"
vim.opt.laststatus = 3 vim.opt.laststatus = 3

View File

@@ -43,4 +43,5 @@ require("nixCatsUtils.catPacker").setup({
{ "zbirenbaum/copilot-cmp" }, { "zbirenbaum/copilot-cmp" },
{ "qvalentin/helm-ls.nvim", ft = "helm" }, { "qvalentin/helm-ls.nvim", ft = "helm" },
{ "mikesmithgh/kitty-scrollback.nvim" }, { "mikesmithgh/kitty-scrollback.nvim" },
{ "greggh/claude-code.nvim" },
}) })

View File

@@ -39,10 +39,22 @@ bind-key -T root F7 select-window -t 7
bind-key -T root F8 select-window -t 8 bind-key -T root F8 select-window -t 8
bind-key -T root F9 select-window -t 9 bind-key -T root F9 select-window -t 9
# bind-key j command-prompt -p "join pane from:" "join-pane -s '%%'"
# bind-key s command-prompt -p "send pane to:" "join-pane -t '%%'"
bind-key -T root S-F1 join-pane -s :1
bind-key -T root S-F2 join-pane -s :2
bind-key -T root S-F3 join-pane -s :3
bind-key -T root S-F4 join-pane -s :4
bind-key -T root S-F5 join-pane -s :5
bind-key -T root S-F6 join-pane -s :6
bind-key -T root S-F7 join-pane -s :7
bind-key -T root S-F8 join-pane -s :8
bind-key -T root S-F9 join-pane -s :9
# 1-based indexing makes most sense for keyboard layouts (where number row start at 1) # 1-based indexing makes most sense for keyboard layouts (where number row start at 1)
set -g base-index 1 set -g base-index 1
set -g pane-base-index 1 set -g pane-base-index 1
setw -g automatic-rename
# statusbar # statusbar
set -g status-position top set -g status-position top
@@ -75,3 +87,5 @@ set-hook -g after-new-session 'if -F "#{==:#{session_name},ssh}" "source ${XDG_C
if-shell "test '\( #{$TMUX_VERSION_MAJOR} -eq 2 -a #{$TMUX_VERSION_MINOR} -ge 4 \)'" 'bind-key -Tcopy-mode-vi v send -X begin-selection; bind-key -Tcopy-mode-vi y send -X copy-selection-and-cancel' if-shell "test '\( #{$TMUX_VERSION_MAJOR} -eq 2 -a #{$TMUX_VERSION_MINOR} -ge 4 \)'" 'bind-key -Tcopy-mode-vi v send -X begin-selection; bind-key -Tcopy-mode-vi y send -X copy-selection-and-cancel'
if-shell '\( #{$TMUX_VERSION_MAJOR} -eq 2 -a #{$TMUX_VERSION_MINOR} -lt 4\) -o #{$TMUX_VERSION_MAJOR} -le 1' 'bind-key -t vi-copy v begin-selection; bind-key -t vi-copy y copy-selection' if-shell '\( #{$TMUX_VERSION_MAJOR} -eq 2 -a #{$TMUX_VERSION_MINOR} -lt 4\) -o #{$TMUX_VERSION_MAJOR} -le 1' 'bind-key -t vi-copy v begin-selection; bind-key -t vi-copy y copy-selection'
if-shell '\( #{$TMUX_VERSION_MAJOR} -eq 2 -a #{$TMUX_VERSION_MINOR} -lt 2\) -o #{$TMUX_VERSION_MAJOR} -le 1' 'set-option -g status-utf8 on' if-shell '\( #{$TMUX_VERSION_MAJOR} -eq 2 -a #{$TMUX_VERSION_MINOR} -lt 2\) -o #{$TMUX_VERSION_MAJOR} -le 1' 'set-option -g status-utf8 on'
set -g allow-passthrough on

253
flake.lock generated
View File

@@ -1,5 +1,29 @@
{ {
"nodes": { "nodes": {
"colmena": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nix-github-actions": "nix-github-actions",
"nixpkgs": [
"nixpkgs"
],
"stable": "stable"
},
"locked": {
"lastModified": 1762034856,
"narHash": "sha256-QVey3iP3UEoiFVXgypyjTvCrsIlA4ecx6Acaz5C8/PQ=",
"owner": "zhaofengli",
"repo": "colmena",
"rev": "349b035a5027f23d88eeb3bc41085d7ee29f18ed",
"type": "github"
},
"original": {
"owner": "zhaofengli",
"repo": "colmena",
"type": "github"
}
},
"disko": { "disko": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -7,11 +31,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1746728054, "lastModified": 1768920986,
"narHash": "sha256-eDoSOhxGEm2PykZFa/x9QG5eTH0MJdiJ9aR00VAofXE=", "narHash": "sha256-CNzzBsRhq7gg4BMBuTDObiWDH/rFYHEuDRVOwCcwXw4=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "ff442f5d1425feb86344c028298548024f21256d", "rev": "de5708739256238fb912c62f03988815db89ec9a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -29,11 +53,11 @@
}, },
"locked": { "locked": {
"dir": "pkgs/firefox-addons", "dir": "pkgs/firefox-addons",
"lastModified": 1764561884, "lastModified": 1769486619,
"narHash": "sha256-vQ3iFPPhxsLqV3c5kgmYP53mVD6id6gsP0tN+oTmqok=", "narHash": "sha256-MEBKRsOj9s65KRvvugu4i7ytW2eASk67pFDgxgwsEr4=",
"owner": "rycee", "owner": "rycee",
"repo": "nur-expressions", "repo": "nur-expressions",
"rev": "aba4621459aec251d90d6452e3495b58a8a5e185", "rev": "02ae5ccdcbe8defe6047840a7b46e67e215bef69",
"type": "gitlab" "type": "gitlab"
}, },
"original": { "original": {
@@ -43,7 +67,60 @@
"type": "gitlab" "type": "gitlab"
} }
}, },
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1650374568,
"narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "b4a34015c698c7793d592d66adbab377907a2be8",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nvim",
"mcp-hub",
"nixpkgs"
]
},
"locked": {
"lastModified": 1743550720,
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": { "flake-utils": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": { "inputs": {
"systems": "systems" "systems": "systems"
}, },
@@ -68,11 +145,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764544324, "lastModified": 1769450270,
"narHash": "sha256-GVBGjO7UsmzLrlOJV8NlKSxukHaHencrJqWkCA6FkqI=", "narHash": "sha256-pdVm/zJazDUAasTyHFX/Pbrlk9Upjxi0yzgn7GjGe4g=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "e4e25a8c310fa45f2a8339c7972dc43d2845a612", "rev": "a10c1e8f5ad2589414407f4851c221cb66270257",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -81,13 +158,53 @@
"type": "github" "type": "github"
} }
}, },
"mcp-hub": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1755841689,
"narHash": "sha256-KakvXZf0vjdqzyT+LsAKHEr4GLICGXPmxl1hZ3tI7Yg=",
"owner": "ravitemer",
"repo": "mcp-hub",
"rev": "9c7670a4c341ed3cf738a6242c0fde1cea40bccf",
"type": "github"
},
"original": {
"owner": "ravitemer",
"repo": "mcp-hub",
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"colmena",
"nixpkgs"
]
},
"locked": {
"lastModified": 1729742964,
"narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "e04df33f62cdcf93d73e9a04142464753a16db67",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"type": "github"
}
},
"nix-secrets": { "nix-secrets": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1764371082, "lastModified": 1769114809,
"narHash": "sha256-yxFxEKXFuXFyFIDZY1gla2OyuqcIE3uT8KDDgTmm3cE=", "narHash": "sha256-xRZeYJAq/AcEZqsevIn1POBswP4rFYhOsQxaJP6xxpM=",
"ref": "main", "ref": "main",
"rev": "b9c2ce32cc4c95d7ff01372faea2668407ef8d27", "rev": "b14f3b416336bf44343941322745d6144582560e",
"shallow": true, "shallow": true,
"type": "git", "type": "git",
"url": "ssh://git@github.com/hektor/nix-secrets" "url": "ssh://git@github.com/hektor/nix-secrets"
@@ -101,11 +218,11 @@
}, },
"nixCats": { "nixCats": {
"locked": { "locked": {
"lastModified": 1764009888, "lastModified": 1769085828,
"narHash": "sha256-hJekfTiW1792txgRSM4LcHnz1lDSY87LYbsJEn2V378=", "narHash": "sha256-TjhFIAtS628+/r3IuYWPcNa++mUMMDDG8PbSfFHXBiA=",
"owner": "BirdeeHub", "owner": "BirdeeHub",
"repo": "nixCats-nvim", "repo": "nixCats-nvim",
"rev": "16ac3281f322ea15d39843829e42a44d22da3715", "rev": "43fbf4d12b0a613f1a792503da4bb2bf270173c7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -116,7 +233,7 @@
}, },
"nixgl": { "nixgl": {
"inputs": { "inputs": {
"flake-utils": "flake-utils", "flake-utils": "flake-utils_2",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
] ]
@@ -137,11 +254,11 @@
}, },
"nixos-hardware": { "nixos-hardware": {
"locked": { "locked": {
"lastModified": 1764440730, "lastModified": 1769302137,
"narHash": "sha256-ZlJTNLUKQRANlLDomuRWLBCH5792x+6XUJ4YdFRjtO4=", "narHash": "sha256-QEDtctEkOsbx8nlFh4yqPEOtr4tif6KTqWwJ37IM2ds=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "9154f4569b6cdfd3c595851a6ba51bfaa472d9f3", "rev": "a351494b0e35fd7c0b7a1aae82f0afddf4907aa8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -153,11 +270,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1764517877, "lastModified": 1769170682,
"narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=", "narHash": "sha256-oMmN1lVQU0F0W2k6OI3bgdzp2YOHWYUAw79qzDSjenU=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2d293cbfa5a793b4c50d17c05ef9e385b90edf6c", "rev": "c5296fdd05cfa2c187990dd909864da9658df755",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -167,15 +284,32 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_2": {
"locked": {
"lastModified": 1743689281,
"narHash": "sha256-y7Hg5lwWhEOgflEHRfzSH96BOt26LaYfrYWzZ+VoVdg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2bfc080955153be0be56724be6fa5477b4eefabb",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nvim": { "nvim": {
"inputs": { "inputs": {
"mcp-hub": "mcp-hub",
"nixCats": "nixCats", "nixCats": "nixCats",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
"plugins-beancount-nvim": "plugins-beancount-nvim", "plugins-beancount-nvim": "plugins-beancount-nvim",
"plugins-crazy-node-movement": "plugins-crazy-node-movement",
"plugins-helm-ls-nvim": "plugins-helm-ls-nvim", "plugins-helm-ls-nvim": "plugins-helm-ls-nvim",
"plugins-m-taskwarrior-d-nvim": "plugins-m-taskwarrior-d-nvim",
"plugins-mcphub-nvim": "plugins-mcphub-nvim", "plugins-mcphub-nvim": "plugins-mcphub-nvim",
"plugins-nvimkit-nvim": "plugins-nvimkit-nvim", "plugins-nvimkit-nvim": "plugins-nvimkit-nvim",
"plugins-shipwright-nvim": "plugins-shipwright-nvim", "plugins-shipwright-nvim": "plugins-shipwright-nvim",
@@ -207,30 +341,14 @@
"type": "github" "type": "github"
} }
}, },
"plugins-crazy-node-movement": {
"flake": false,
"locked": {
"lastModified": 1693654676,
"narHash": "sha256-hQcQEp39zFN2zphMfcr97yRVcuHhBsSkzKO7XNloDpQ=",
"owner": "theHamsta",
"repo": "crazy-node-movement",
"rev": "d5cf01cc44c5715501d3d6fe439af7c8b7fa5df2",
"type": "github"
},
"original": {
"owner": "theHamsta",
"repo": "crazy-node-movement",
"type": "github"
}
},
"plugins-helm-ls-nvim": { "plugins-helm-ls-nvim": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1761915179, "lastModified": 1768584652,
"narHash": "sha256-W9NRa84l5Cs62OsDeqb+LMxk8oYjhVBCB3o3UmE9a0I=", "narHash": "sha256-jnMc87OjURNcqsva0npYgVyUrWc5C6L7yHpNvt9eSmg=",
"owner": "qvalentin", "owner": "qvalentin",
"repo": "helm-ls.nvim", "repo": "helm-ls.nvim",
"rev": "d6f3a8d4ad59b4f54cd734267dfb5411679ea608", "rev": "f0b9a1723890971a6d84890b50dbf5f40974ea1b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -239,14 +357,30 @@
"type": "github" "type": "github"
} }
}, },
"plugins-m-taskwarrior-d-nvim": {
"flake": false,
"locked": {
"lastModified": 1767960157,
"narHash": "sha256-ov0qi4LhIlwqrBzSbTJ6APC5qjl2d/vlKWJfW5ZiDrg=",
"owner": "huantrinh1802",
"repo": "m_taskwarrior_d.nvim",
"rev": "107247387cd81823046bc2b8e71150c8edf041d3",
"type": "github"
},
"original": {
"owner": "huantrinh1802",
"repo": "m_taskwarrior_d.nvim",
"type": "github"
}
},
"plugins-mcphub-nvim": { "plugins-mcphub-nvim": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1759035242, "lastModified": 1768730387,
"narHash": "sha256-I6EbgY/2sAdtrxtmH0qbAAQvMCHhOsfolJfblV0fXOk=", "narHash": "sha256-g9tPvjThz6EUk7zcY7lL+YH4lrT4x3FJ6jrNMHA8PAE=",
"owner": "ravitemer", "owner": "ravitemer",
"repo": "mcphub.nvim", "repo": "mcphub.nvim",
"rev": "8ff40b5edc649959bb7e89d25ae18e055554859a", "rev": "7cd5db330f41b7bae02b2d6202218a061c3ebc1f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -290,11 +424,11 @@
"plugins-tailwind-fold-nvim": { "plugins-tailwind-fold-nvim": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1752559116, "lastModified": 1766077142,
"narHash": "sha256-8uefZIVsn9USEd6FyiO3m3TRKAS/vigU4t9Tk5ijd3c=", "narHash": "sha256-SwcDLlygXUSV/dytPXA5Y45OpUhjnExc8SZg5a8MZ2k=",
"owner": "razak17", "owner": "razak17",
"repo": "tailwind-fold.nvim", "repo": "tailwind-fold.nvim",
"rev": "d9e7ca11691d252b35795726dff087bf013b2ebf", "rev": "e2ba5ee1ca9b74208709fe9d7314b8aa753b26a7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -305,6 +439,7 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"colmena": "colmena",
"disko": "disko", "disko": "disko",
"firefox-addons": "firefox-addons", "firefox-addons": "firefox-addons",
"home-manager": "home-manager", "home-manager": "home-manager",
@@ -323,11 +458,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764483358, "lastModified": 1769469829,
"narHash": "sha256-EyyvCzXoHrbL467YSsQBTWWg4sR96MH1sPpKoSOelB4=", "narHash": "sha256-wFcr32ZqspCxk4+FvIxIL0AZktRs6DuF8oOsLt59YBU=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "5aca6ff67264321d47856a2ed183729271107c9c", "rev": "c5eebd4eb2e3372fe12a8d70a248a6ee9dd02eff",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -336,6 +471,22 @@
"type": "github" "type": "github"
} }
}, },
"stable": {
"locked": {
"lastModified": 1750133334,
"narHash": "sha256-urV51uWH7fVnhIvsZIELIYalMYsyr2FCalvlRTzqWRw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "36ab78dab7da2e4e27911007033713bab534187b",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"systems": { "systems": {
"locked": { "locked": {
"lastModified": 1681028828, "lastModified": 1681028828,

View File

@@ -5,7 +5,6 @@
}; };
nixos-hardware = { nixos-hardware = {
url = "github:NixOS/nixos-hardware/master"; url = "github:NixOS/nixos-hardware/master";
inputs.nixpkgs.follows = "nixpkgs";
}; };
disko = { disko = {
url = "github:nix-community/disko/latest"; url = "github:nix-community/disko/latest";
@@ -35,6 +34,10 @@
url = "path:./dots/.config/nvim"; url = "path:./dots/.config/nvim";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
colmena = {
url = "github:zhaofengli/colmena";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = outputs =
@@ -49,9 +52,11 @@
nixgl, nixgl,
firefox-addons, firefox-addons,
nvim, nvim,
colmena,
}@inputs: }@inputs:
let let
lib = inputs.nixpkgs.lib; inherit (self) outputs;
inherit (inputs.nixpkgs) lib;
utils = import ./utils { inherit lib; }; utils = import ./utils { inherit lib; };
hostDirNames = utils.dirNames ./hosts; hostDirNames = utils.dirNames ./hosts;
system = "x86_64-linux"; system = "x86_64-linux";
@@ -59,6 +64,7 @@
inherit system; inherit system;
overlays = [ nixgl.overlay ]; overlays = [ nixgl.overlay ];
}; };
dotsPath = ./dots;
in in
{ {
nix.nixPath = [ nix.nixPath = [
@@ -68,15 +74,26 @@
host: host:
nixpkgs.lib.nixosSystem { nixpkgs.lib.nixosSystem {
modules = [ ./hosts/${host} ]; modules = [ ./hosts/${host} ];
specialArgs = { inherit inputs; }; specialArgs = {
inherit inputs outputs dotsPath;
};
} }
); );
homeConfigurations = { homeConfigurations = {
work = home-manager.lib.homeManagerConfiguration { work = home-manager.lib.homeManagerConfiguration {
inherit pkgs; inherit pkgs;
modules = [ ./home/hosts/work ]; modules = [ ./home/hosts/work ];
extraSpecialArgs = { inherit inputs; }; extraSpecialArgs = {
inherit inputs outputs dotsPath;
}; };
}; };
}; };
colmenaHive = import ./deploy/colmena.nix {
inherit
self
inputs
;
};
};
} }

View File

@@ -6,14 +6,47 @@
... ...
}: }:
let
username = "h";
in
{ {
imports = [ imports = [
(import ../astyanax { ../../modules/desktop/niri
inherit inputs;
inherit config; ../../modules/3d
inherit pkgs; ../../modules/git.nix
}) # ../../modules/hetzner.nix
../../modules/k9s.nix
../../modules/kitty.nix
../../modules/ssh.nix
../../modules/taskwarrior.nix
../../modules/keepassxc.nix
../../modules/anki.nix
../../modules/photography
../../modules/browser
../../modules/shell
]; ];
programs.taskwarrior.config.recurrence = lib.mkForce "on"; home = {
stateVersion = "25.05";
inherit username;
homeDirectory = "/home/${username}";
};
xdg.userDirs.createDirectories = false;
xdg.userDirs.download = "${config.home.homeDirectory}/dl";
browser.primary = "librewolf";
shell.bash = {
enable = true;
aliases.lang-js = true;
};
programs = {
home-manager.enable = true;
taskwarrior.config.recurrence = lib.mkForce "on";
};
home.packages = import ../packages.nix { inherit pkgs; };
} }

View File

@@ -10,68 +10,41 @@ let
in in
{ {
imports = [ imports = [
../../modules/dconf.nix # TODO: Only enable when on Gnome? ../../modules/anki.nix
../../modules/desktop/niri
../../modules/git.nix ../../modules/git.nix
# ../../modules/hetzner.nix
../../modules/k9s.nix ../../modules/k9s.nix
(import ../../modules/taskwarrior.nix { ../../modules/kitty.nix
inherit config; ../../modules/ssh.nix
inherit pkgs; ../../modules/taskwarrior.nix
}) ../../modules/keepassxc.nix
../../modules/browser
../../modules/shell
]; ];
home.stateVersion = "25.05"; home = {
home.username = username; stateVersion = "25.05";
home.homeDirectory = "/home/${username}"; inherit username;
homeDirectory = "/home/${username}";
};
xdg.userDirs.createDirectories = false; xdg.userDirs.createDirectories = false;
xdg.userDirs.download = "${config.home.homeDirectory}/dl"; xdg.userDirs.download = "${config.home.homeDirectory}/dl";
browser.primary = "librewolf";
shell.bash = {
enable = true;
aliases.lang-js = true;
};
programs = { programs = {
bash = {
enable = true;
enableCompletion = true;
initExtra = ''
for f in /home/h/.bashrc.d/*; do
[ -f "$f" ] && source "$f"
done
source /home/h/.bash_aliases/all
source /home/h/.bash_aliases/lang-js
# host-specific config goes here
# ...
export PATH=${../../../dots/.bin}:$PATH
'';
};
firefox = import ../../modules/firefox.nix {
inherit inputs;
inherit pkgs;
inherit config;
};
fzf = {
enable = true;
enableBashIntegration = true;
};
home-manager.enable = true; home-manager.enable = true;
keepassxc = import ../../modules/keepassxc.nix;
}; };
home.packages = import ./packages.nix { home.packages = import ../packages.nix {
inherit pkgs; inherit pkgs;
inherit config; inherit config;
}; };
home.file = {
".inputrc".source = ../../../dots/.inputrc;
".bashrc.d/prompt".source = ../../../dots/.bashrc.d/prompt;
".bashrc.d/editor".source = ../../../dots/.bashrc.d/editor;
".bash_aliases/all".source = ../../../dots/.bash_aliases/all;
".bash_aliases/lang-js".source = ../../../dots/.bash_aliases/lang-js;
".config/kitty/kitty.conf".source = ../../../dots/.config/kitty/kitty.conf;
".config/kitty/themes/zenwritten_light.conf".source =
../../../dots/.config/kitty/themes/zenwritten_light.conf;
".config/kitty/themes/zenwritten_dark.conf".source =
../../../dots/.config/kitty/themes/zenwritten_dark.conf;
};
} }

View File

@@ -1,52 +0,0 @@
{ pkgs, ... }:
with pkgs;
[
bash-completion
bash-language-server
bat
brightnessctl
entr
eslint_d
feh
fzf
gh
git
haskell-language-server
haskellPackages.pandoc-crossref
haskellPackages.hadolint
htop
jq
kitty
lua-language-server
nixfmt-rfc-style
nmap
nodejs_24
nvimpager
ormolu
pandoc
parallel
pass
pnpm
ripgrep
silver-searcher
sops
sshfs
stylelint
svelte-language-server
tailwindcss-language-server
tldr
tmux
tmuxp
tree
tree-sitter
typescript-language-server
unzip
vim-language-server
vimPlugins.vim-plug
vtsls
wget
xbanish
xclip
yaml-language-server
]

35
home/hosts/packages.nix Normal file
View File

@@ -0,0 +1,35 @@
{ pkgs, ... }:
with pkgs;
[
bash-completion
bat
entr
feh
fzf
gh
git
haskellPackages.pandoc-crossref
htop
jq
nixfmt-rfc-style
nmap
nodejs_24
opencode
nvimpager
pandoc
parallel
pass
pnpm
python3
ripgrep
signal-desktop
silver-searcher
sops
sshfs
tldr
tree
unzip
vimPlugins.vim-plug
wget
]

View File

@@ -10,31 +10,60 @@ let
in in
{ {
imports = [ imports = [
inputs.sops-nix.homeManagerModules.sops
../../modules/dconf.nix ../../modules/dconf.nix
../../modules/git.nix ../../modules/git.nix
../../modules/k9s.nix ../../modules/k9s.nix
../../modules/keepassxc.nix
../../modules/kitty.nix
../../modules/nvim.nix
../../modules/browser
../../modules/shell
../../modules/taskwarrior.nix
]; ];
sops = {
age.keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
defaultSopsFile = "${inputs.nix-secrets}/secrets.yaml";
secrets = {
taskwarrior_sync_server_url = { };
taskwarrior_sync_server_client_id = { };
taskwarrior_sync_encryption_secret = { };
anki_sync_user = { };
anki_sync_key = { };
};
templates."taskrc.d/sync" = {
content = ''
sync.server.url=${config.sops.placeholder.taskwarrior_sync_server_url}
sync.server.client_id=${config.sops.placeholder.taskwarrior_sync_server_client_id}
sync.encryption_secret=${config.sops.placeholder.taskwarrior_sync_encryption_secret}
'';
};
};
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
home.stateVersion = "25.05"; home = {
home.username = username; stateVersion = "25.05";
home.homeDirectory = "/home/${username}"; inherit username;
homeDirectory = "/home/${username}";
};
targets.genericLinux.nixGL = { targets.genericLinux.nixGL = {
packages = inputs.nixgl.packages; inherit (inputs.nixgl) packages;
defaultWrapper = "mesa"; defaultWrapper = "mesa";
}; };
browser.primary = "firefox";
browser.secondary = "chromium";
shell.bash.enable = true;
starship.enable = true;
programs = { programs = {
# editorconfig.enable = true;
firefox = import ../../modules/firefox.nix {
inherit inputs;
inherit pkgs;
inherit config;
};
gh.enable = true; gh.enable = true;
keepassxc = import ../../modules/keepassxc.nix;
kubecolor.enable = true; kubecolor.enable = true;
}; };

View File

@@ -13,7 +13,4 @@ let
[ ]; [ ];
in in
(with pkgs; [ localPackages
inputs.nvim.packages.x86_64-linux.nvim
])
++ localPackages

View File

@@ -0,0 +1,11 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
bambu-studio
blender
openscad-lsp
openscad-unstable
orca-slicer
];
}

View File

@@ -1,6 +1,33 @@
{ {
config,
lib,
pkgs,
osConfig ? null,
...
}:
let
hmSopsAvailable = config ? sops && config.sops ? secrets;
osSopsAvailable = osConfig != null && osConfig ? sops && osConfig.sops ? secrets;
sopsAvailable = hmSopsAvailable || osSopsAvailable;
sopsSecrets = if hmSopsAvailable then config.sops.secrets else osConfig.sops.secrets;
in
{
warnings = lib.optional (
!sopsAvailable && config.programs.anki.enable
) "anki is enabled but sops secrets are not available. anki sync will not be configured.";
programs.anki = {
enable = true; enable = true;
# sync = { addons = with pkgs.ankiAddons; [
# username = config.sops.secrets."email/personal".path; anki-connect
# }; puppy-reinforcement
review-heatmap
];
sync = lib.mkIf sopsAvailable {
usernameFile = "${sopsSecrets."anki_sync_user".path}";
keyFile = "${sopsSecrets."anki_sync_key".path}";
};
};
} }

View File

@@ -0,0 +1,19 @@
{
nixos = {
name = "NixOS";
bookmarks = [
{
name = "wiki";
url = "https://wiki.nixos.org/wiki/NixOS_Wiki";
}
{
name = "packages";
url = "https://search.nixos.org/packages";
}
{
name = "options";
url = "https://search.nixos.org/options";
}
];
};
}

View File

@@ -0,0 +1,12 @@
{
config,
lib,
pkgs,
...
}:
{
config = lib.mkIf (config.browser.primary == "chromium" || config.browser.secondary == "chromium") {
home.packages = [ pkgs.chromium ];
};
}

View File

@@ -0,0 +1,31 @@
{ lib, ... }:
{
options.browser = {
primary = lib.mkOption {
type = lib.types.enum [
"firefox"
"chromium"
"librewolf"
];
default = "firefox";
};
secondary = lib.mkOption {
type = lib.types.nullOr (
lib.types.enum [
"firefox"
"chromium"
"librewolf"
]
);
default = null;
};
};
imports = [
./firefox.nix
./librewolf.nix
./chromium.nix
];
}

View File

@@ -1,19 +1,19 @@
{ inputs, pkgs, ... }: { inputs, pkgs }:
let
bookmarks = import ./bookmarks.nix;
in
{ {
enable = true;
nativeMessagingHosts = with pkgs; [ nativeMessagingHosts = with pkgs; [
tridactyl-native tridactyl-native
]; ];
policies = {
DefaultDownloadDirectory = "\${home}/dl";
};
profiles = { profiles = {
default = { default = {
settings = { settings = {
"signon.rememberSignons" = false; "signon.rememberSignons" = false;
"findbar.highlightAll" = true; "findbar.highlightAll" = true;
"extensions.autoDisableScopes" = 0; # Enable extensions by default <https://nix-community.github.io/home-manager/options.xhtml#opt-programs.firefox.profiles._name_.extensions.packages> "extensions.autoDisableScopes" = 0;
}; };
extensions = { extensions = {
packages = with inputs.firefox-addons.packages.${pkgs.system}; [ packages = with inputs.firefox-addons.packages.${pkgs.system}; [
@@ -33,23 +33,7 @@
{ {
toolbar = true; toolbar = true;
bookmarks = [ bookmarks = [
{ bookmarks.nixos
name = "NixOS";
bookmarks = [
{
name = "wiki";
url = "https://wiki.nixos.org/wiki/NixOS_Wiki";
}
{
name = "packages";
url = "https://search.nixos.org/packages";
}
{
name = "options";
url = "https://search.nixos.org/options";
}
];
}
]; ];
} }
]; ];
@@ -57,6 +41,7 @@
}; };
}; };
policies = { policies = {
DefaultDownloadDirectory = "\${home}/dl";
ExtensionSettings = { ExtensionSettings = {
"jid1-ZAdIEUB7XOzOJw@jetpack" = { "jid1-ZAdIEUB7XOzOJw@jetpack" = {
default_area = "navbar"; default_area = "navbar";

View File

@@ -0,0 +1,10 @@
{ config, lib, inputs, pkgs, ... }:
{
config = lib.mkIf (config.browser.primary == "firefox" || config.browser.secondary == "firefox") {
programs.firefox = {
enable = true;
}
// (import ./firefox-base.nix { inherit inputs pkgs; });
};
}

View File

@@ -0,0 +1,12 @@
{ config, lib, inputs, pkgs, ... }:
{
config =
lib.mkIf (config.browser.primary == "librewolf" || config.browser.secondary == "librewolf")
{
programs.librewolf = {
enable = true;
}
// (import ./firefox-base.nix { inherit inputs pkgs; });
};
}

View File

@@ -1,21 +1,13 @@
{ config, ... }:
let
terminal = "kitty";
browser = config.browser.primary;
in
{ {
dconf.settings = { dconf.settings = {
"org/gnome/settings-daemon/plugins/color" = {
night-light-enabled = true;
night-light-schedule-automatic = true;
};
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
};
"org/gnome/desktop/applications/terminal" = {
exec = "kitty";
exec-arg = "";
};
"org/gnome/desktop/background" = { "org/gnome/desktop/background" = {
color-shading-type = "solid"; color-shading-type = "solid";
picture-opacity = 100;
picture-options = "zoom"; picture-options = "zoom";
picture-uri = "none"; picture-uri = "none";
picture-uri-dark = "none"; picture-uri-dark = "none";
@@ -24,55 +16,54 @@
show-desktop-icons = false; show-desktop-icons = false;
}; };
# "org/gnome/desktop/input-sources" = { "org/gnome/desktop/default-applications/office/calendar" = {
# sources = [ exec = "${browser} https://calendar.proton.me";
# (mkTuple [ needs-term = false;
# "xkb" };
# "us"
# ]) "org/gnome/desktop/default-applications/office/tasks" = {
# ]; exec = "task";
# xkb-options = [ "caps:none" ]; needs-term = true;
# }; };
"org/gnome/desktop/default-applications/terminal" = {
exec = terminal;
exec-arg = "";
};
"org/gnome/desktop/input-sources" = {
xkb-options = [ "caps:none" ];
};
"org/gnome/desktop/interface" = {
clock-format = "24h";
clock-show-weekday = true;
color-scheme = "prefer-dark";
enable-hot-corners = false;
font-name = "Iosevka Term SS08 12";
locate-pointer = true;
monospace-font-name = "Iosevka Term SS08 12";
};
"org/gnome/desktop/wm/keybindings" = { "org/gnome/desktop/wm/keybindings" = {
close = [ "<Shift><Super>Delete" ]; close = [ "<Shift><Super>Delete" ];
cycle-group = [ ]; minimize = [ "<Super>h" ];
cycle-group-backward = [ ]; move-to-monitor-down = [ "<Super><Shift>Down" ];
cycle-panels = [ ]; move-to-monitor-left = [ "<Super><Shift>Left" ];
cycle-panels-backward = [ ]; move-to-monitor-right = [ "<Super><Shift>Right" ];
cycle-windows = [ ]; move-to-monitor-up = [ "<Super><Shift>Up" ];
cycle-windows-backward = [ ];
maximize = [ "<Super> " ];
minimize = [ ];
move-to-workspace-1 = [ "<Super><Shift>a" ]; move-to-workspace-1 = [ "<Super><Shift>a" ];
move-to-workspace-2 = [ "<Super><Shift>s" ]; move-to-workspace-2 = [ "<Super><Shift>s" ];
move-to-workspace-3 = [ "<Super><Shift>d" ]; move-to-workspace-3 = [ "<Super><Shift>d" ];
move-to-workspace-4 = [ "<Super><Shift>f" ]; move-to-workspace-4 = [ "<Super><Shift>f" ];
move-to-workspace-5 = [ "<Super><Shift>g" ]; move-to-workspace-5 = [ "<Super><Shift>g" ];
move-to-workspace-last = [ ];
move-to-workspace-left = [ "<Super><Shift>h" ];
move-to-workspace-right = [ "<Super><Shift>l" ];
panel-run-dialog = [ ];
switch-applications = [ "<Super>j" ]; switch-applications = [ "<Super>j" ];
switch-applications-backward = [ "<Super>k" ]; switch-applications-backward = [ "<Super>k" ];
switch-group = [ ];
switch-group-backward = [ ];
switch-input-source = [ ];
switch-input-source-backward = [ ];
switch-panels = [ ];
switch-panels-backward = [ ];
switch-to-workspace-1 = [ "<Super>a" ]; switch-to-workspace-1 = [ "<Super>a" ];
switch-to-workspace-2 = [ "<Super>s" ]; switch-to-workspace-2 = [ "<Super>s" ];
switch-to-workspace-3 = [ "<Super>d" ]; switch-to-workspace-3 = [ "<Super>d" ];
switch-to-workspace-4 = [ "<Super>f" ]; switch-to-workspace-4 = [ "<Super>f" ];
switch-to-workspace-5 = [ "<Super>g" ]; switch-to-workspace-5 = [ "<Super>g" ];
switch-to-workspace-last = [ ];
switch-to-workspace-left = [ "<Super>h" ];
switch-to-workspace-right = [ "<Super>l" ];
switch-windows = [ ];
switch-windows-backward = [ ];
toggle-maximized = [ "<Super>space" ];
unmaximize = [ ];
}; };
"org/gnome/desktop/wm/preferences" = { "org/gnome/desktop/wm/preferences" = {
@@ -86,8 +77,19 @@
]; ];
}; };
"org/gnome/mutter" = {
center-new-windows = true;
dynamic-workspaces = false;
};
"org/gnome/settings-daemon/plugins/color" = {
night-light-enabled = true;
night-light-schedule-automatic = true;
};
"org/gnome/settings-daemon/plugins/media-keys" = { "org/gnome/settings-daemon/plugins/media-keys" = {
custom-keybindings = [ custom-keybindings = [
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/"
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/" "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/"
]; ];
}; };
@@ -100,12 +102,19 @@
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1" = { "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1" = {
binding = "<Super>Return"; binding = "<Super>Return";
command = "kitty"; command = terminal;
name = "Kitty"; name = "Kitty";
}; };
"org/gnome/settings-daemon/plugins/power" = {
power-button-action = "suspend";
};
"org/gnome/shell/app-switcher" = {
current-workspace-only = true;
};
"org/gnome/shell/keybindings" = { "org/gnome/shell/keybindings" = {
screenshot = [ "Print" ];
toggle-application-view = [ "<Super>p" ]; toggle-application-view = [ "<Super>p" ];
toggle-quick-settings = [ ]; toggle-quick-settings = [ ];
}; };

View File

@@ -0,0 +1,183 @@
input {
touchpad {
tap
natural-scroll
}
mouse {
accel-profile "flat"
}
}
// NOTE: monitors are managed using `shikane` instead, as I assume this to be
// too limited for multiple multimonitor configurations. Below is an example
// for a simple, fixed, vertical dual monitor setup
// output "eDP-1" {
// position x=0 y=1440
// }
//
// output "DP-5" {
// position x=0 y=0
// }
layout {
gaps 4
struts {}
center-focused-column "never"
preset-column-widths {
proportion 0.382
proportion 0.618
proportion 1.0
}
default-column-width { }
focus-ring {
off
}
border {
width 2
active-color "#555555"
inactive-color "#55555511"
urgent-color "#ff0000"
}
shadow {
on
softness 32
spread 4
offset x=0 y=0
color "#0007"
}
}
spawn-at-startup "wlsunset -l 51.05 -L 3.72"
spawn-at-startup "waybar"
hotkey-overlay {
skip-at-startup
}
prefer-no-csd
screenshot-path "~/doc/screenshots/%Y-%m-%d %H-%M-%S.png"
// https://yalter.github.io/niri/Configuration:-Animations
animations {
slowdown 0.66
}
window-rule {
match app-id=r#"firefox$"# title="^Picture-in-Picture$"
open-floating true
}
window-rule {
match app-id=r#"^org\.keepassxc\.KeePassXC$"#
block-out-from "screen-capture"
}
window-rule {
geometry-corner-radius 0
clip-to-geometry true
}
gestures {
hot-corners {
off
}
}
binds {
Mod+Slash { show-hotkey-overlay; }
Mod+Return hotkey-overlay-title="Open a Terminal: kitty" { spawn "kitty"; }
Mod+P hotkey-overlay-title="Run an Application: fuzzel" { spawn "fuzzel"; }
Super+Alt+L hotkey-overlay-title="Lock the Screen: swaylock" { spawn "swaylock"; }
XF86AudioRaiseVolume allow-when-locked=true { spawn-sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.1+"; }
XF86AudioLowerVolume allow-when-locked=true { spawn-sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.1-"; }
XF86AudioMute allow-when-locked=true { spawn-sh "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; }
XF86AudioMicMute allow-when-locked=true { spawn-sh "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"; }
Mod+Shift+XF86Display { power-off-monitors; }
XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "+10%"; }
XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "10%-"; }
Mod+O repeat=false { toggle-overview; }
Mod+Delete repeat=false { close-window; }
Mod+H { focus-column-left; }
Mod+J { focus-window-or-workspace-down; }
Mod+K { focus-window-or-workspace-up; }
Mod+L { focus-column-right; }
Mod+Shift+H { move-column-left; }
Mod+Shift+J { move-window-down-or-to-workspace-down; }
Mod+Shift+K { move-window-up-or-to-workspace-up; }
Mod+Shift+L { move-column-right; }
Mod+Home { focus-column-first; }
Mod+End { focus-column-last; }
Mod+Ctrl+Home { move-column-to-first; }
Mod+Ctrl+End { move-column-to-last; }
Mod+Left { focus-monitor-left; }
Mod+Down { focus-monitor-down; }
Mod+Up { focus-monitor-up; }
Mod+Right { focus-monitor-right; }
Mod+Shift+Left { move-column-to-monitor-left; }
Mod+Shift+Down { move-column-to-monitor-down; }
Mod+Shift+Up { move-column-to-monitor-up; }
Mod+Shift+Right { move-column-to-monitor-right; }
Mod+Ctrl+Up { move-workspace-down; }
Mod+Ctrl+Down { move-workspace-up; }
// Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
// Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
// Mod+Shift+WheelScrollDown cooldown-ms=150 { move-window-down-or-to-workspace-down; }
// Mod+Shift+WheelScrollUp cooldown-ms=150 { move-window-up-or-to-workspace-up; }
// Mod+A { focus-workspace 1; }
// Mod+S { focus-workspace 2; }
// Mod+D { focus-workspace 3; }
// Mod+F { focus-workspace 4; }
// Mod+Shift+A { move-column-to-workspace 1; }
// Mod+Shift+S { move-column-to-workspace 2; }
// Mod+Shift+D { move-column-to-workspace 3; }
// Mod+Shift+F { move-column-to-workspace 4; }
Mod+Tab { focus-workspace-previous; }
Mod+BracketLeft { consume-or-expel-window-left; }
Mod+BracketRight { consume-or-expel-window-right; }
Mod+Comma { consume-window-into-column; }
Mod+Period { expel-window-from-column; }
Mod+N { switch-preset-column-width; }
Mod+Shift+N { switch-preset-window-height; }
Mod+Ctrl+R { reset-window-height; }
Mod+Space { maximize-column; }
Mod+Shift+Space { fullscreen-window; }
Mod+Escape { toggle-window-floating; }
Mod+Shift+Escape { switch-focus-between-floating-and-tiling; }
Mod+Ctrl+F { expand-column-to-available-width; }
Mod+C { center-column; }
Mod+Ctrl+C { center-visible-columns; }
Mod+Minus { set-column-width "-10%"; }
Mod+Equal { set-column-width "+10%"; }
Mod+Shift+Minus { set-window-height "-10%"; }
Mod+Shift+Equal { set-window-height "+10%"; }
Mod+W { toggle-column-tabbed-display; }
Print { screenshot; }
Ctrl+Print { screenshot-screen; }
Alt+Print { screenshot-window; }
Mod+Shift+Delete { quit; }
}

View File

@@ -0,0 +1,25 @@
{ pkgs, ... }:
{
imports = [
../../fuzzel
../../mako
../../shikane
../../waybar
];
home = {
file.".config/niri/config.kdl".source = ./config.kdl;
packages = with pkgs; [
wl-clipboard
wlsunset
];
};
services.gammastep = {
enable = true;
provider = "manual";
latitude = 51.05;
longitude = 3.71667;
};
}

View File

@@ -0,0 +1,28 @@
{
programs.fuzzel = {
enable = true;
settings = {
main = {
font = "Iosevka Term SS08";
horizontal-pad = 0;
vertical-pad = 0;
};
colors = {
background = "ccccccff";
text = "111111ff";
prompt = "ccccccff";
placeholder = "aaaaaaff";
input = "111111ff";
selection = "eeeeeeff";
selection-text = "111111ff";
selection-match = "333333ff";
counter = "111111ff";
border = "111111ff";
};
border = {
width = 2;
radius = 0;
};
};
};
}

View File

@@ -1,8 +1,10 @@
{ dotsPath, ... }:
{ {
programs.git.enable = true; programs.git.enable = true;
home.file = { home.file = {
".gitconfig".source = ../../dots/.gitconfig; ".gitconfig".source = dotsPath + "/.gitconfig";
".gitconfig.work".source = ../../dots/.gitconfig.work; ".gitconfig.work".source = dotsPath + "/.gitconfig.work";
".gitignore".source = ../../dots/.gitignore; ".gitignore".source = dotsPath + "/.gitignore";
}; };
} }

View File

@@ -0,0 +1,16 @@
{
lib,
osConfig ? null,
...
}:
let
isNixOS = osConfig != null;
in
{
config = {
warnings =
lib.optional (!isNixOS)
"hcloud module requires NixOS host configuration. This module will not work with standalone home-manager.";
};
}

View File

@@ -0,0 +1,7 @@
{ pkgs, ... }:
{
home = {
packages = with pkgs; [ hcloud ];
};
}

View File

@@ -1,4 +1,11 @@
{ pkgs, ... }:
{ {
programs.keepassxc = {
enable = true; enable = true;
# TODO: https://mynixos.com/home-manager/option/programs.keepassxc.settings settings = {
Browser.Enabled = true;
};
};
# programs.firefox.nativeMessagingHosts = [ pkgs.keepassxc ]; # FIXME: Resolve 'Access error for config file $HOME/.config/keepassxc/keepassxc.ini' error
} }

23
home/modules/kitty.nix Normal file
View File

@@ -0,0 +1,23 @@
{ pkgs, config, lib, dotsPath, ... }:
{
config = {
home.packages = [
(if config.lib ? nixGL
then config.lib.nixGL.wrap pkgs.kitty
else pkgs.kitty)
];
programs.bash.shellAliases = {
icat = "kitty +kitten icat";
};
home.file = {
".config/kitty/kitty.conf".source = dotsPath + "/.config/kitty/kitty.conf";
".config/kitty/nvim.conf".source = dotsPath + "/.config/kitty/nvim.conf";
".config/kitty/themes/zenwritten_light.conf".source =
dotsPath + "/.config/kitty/themes/zenwritten_light.conf";
".config/kitty/themes/zenwritten_dark.conf".source =
dotsPath + "/.config/kitty/themes/zenwritten_dark.conf";
};
};
}

View File

@@ -0,0 +1,5 @@
{
services.mako = {
enable = true;
};
}

9
home/modules/nvim.nix Normal file
View File

@@ -0,0 +1,9 @@
{ inputs, pkgs, ... }:
{
config = {
home.packages = [
inputs.nvim.packages.${pkgs.system}.nvim
];
};
}

View File

@@ -0,0 +1,7 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
darktable
];
}

View File

@@ -0,0 +1,74 @@
{
config,
lib,
pkgs,
dotsPath,
...
}:
let
cfg = config.shell.bash;
inherit (config.home) username;
in
{
options.shell.bash = {
enable = lib.mkEnableOption "bash configuration";
aliases = {
all = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable common aliases";
};
lang-js = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable JavaScript/Node.js aliases";
};
};
addBinToPath = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Add dots .bin directory to PATH";
};
extraInit = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Additional bash initialization";
};
};
config = lib.mkIf cfg.enable {
shell-utils.enable = lib.mkDefault true;
programs.bash = {
enable = true;
enableCompletion = true;
initExtra = ''
for f in /home/${username}/.bashrc.d/*; do
[ -f "$f" ] && source "$f"
done
${lib.optionalString cfg.aliases.all "source /home/${username}/.bash_aliases/all"}
${lib.optionalString cfg.aliases.lang-js "source /home/${username}/.bash_aliases/lang-js"}
${lib.optionalString cfg.addBinToPath "export PATH=${dotsPath}/.bin:$PATH"}
${cfg.extraInit}
'';
};
home.file = {
".inputrc".source = dotsPath + "/.inputrc";
".bashrc.d/prompt".source = dotsPath + "/.bashrc.d/prompt";
".bashrc.d/editor".source = dotsPath + "/.bashrc.d/editor";
}
// lib.optionalAttrs cfg.aliases.all {
".bash_aliases/all".source = dotsPath + "/.bash_aliases/all";
}
// lib.optionalAttrs cfg.aliases.lang-js {
".bash_aliases/lang-js".source = dotsPath + "/.bash_aliases/lang-js";
};
};
}

View File

@@ -0,0 +1,8 @@
{
imports = [
./bash.nix
./utils.nix
./prompt.nix
../tmux.nix
];
}

View File

@@ -0,0 +1,17 @@
{
config,
lib,
pkgs,
...
}:
{
options.starship = {
enable = lib.mkEnableOption "starship prompt";
};
config = lib.mkIf config.starship.enable {
programs.starship = {
enable = true;
};
};
}

View File

@@ -0,0 +1,26 @@
{
config,
lib,
pkgs,
...
}:
{
options.shell-utils = {
enable = lib.mkEnableOption "shell utilities";
};
config = lib.mkIf config.shell-utils.enable {
programs.fzf = {
enable = true;
enableBashIntegration = lib.mkDefault true;
};
home.packages = with pkgs; [
ripgrep
bat
jq
entr
parallel
];
};
}

View File

@@ -0,0 +1,6 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [ wdisplays ];
services.shikane.enable = true;
}

25
home/modules/ssh.nix Normal file
View File

@@ -0,0 +1,25 @@
{
outputs,
lib,
...
}:
let
nixosConfigs = builtins.attrNames outputs.nixosConfigurations;
homeConfigs = map (n: lib.last (lib.splitString "@" n)) (
builtins.attrNames outputs.homeConfigurations
);
allHosts = lib.unique (homeConfigs ++ nixosConfigs);
hostsWithKeys = lib.filter (
hostname: builtins.pathExists ../../hosts/${hostname}/ssh_host.pub
) allHosts;
in
{
programs.ssh = {
enable = true;
enableDefaultConfig = false;
matchBlocks = lib.genAttrs hostsWithKeys (hostname: {
host = hostname;
});
};
}

View File

@@ -1,31 +1,44 @@
{ {
config, config,
lib,
pkgs, pkgs,
dotsPath,
osConfig ? null,
... ...
}: }:
let
hmSopsAvailable = config ? sops && config.sops ? templates;
osSopsAvailable = osConfig != null && osConfig ? sops && osConfig.sops ? templates;
sopsAvailable = hmSopsAvailable || osSopsAvailable;
sopsTemplates = if hmSopsAvailable then config.sops.templates else osConfig.sops.templates;
in
{ {
warnings =
lib.optional (!sopsAvailable && config.programs.taskwarrior.enable)
"taskwarrior is enabled, but sops templates are not available. taskwarrior sync will not be configured.";
home.packages = with pkgs; [ home.packages = with pkgs; [
python314
libnotify libnotify
]; ];
home.file = { home.file = {
".config/task/taskrc" = { ".config/task/taskrc" = {
force = true; # overwrite when present force = true; # overwrite when present
source = ../../dots/.config/task/taskrc; source = dotsPath + "/.config/task/taskrc";
}; };
".config/task/taskrc.d/aliases".source = ../../dots/.config/task/taskrc.d/aliases; ".config/task/taskrc.d/aliases".source = dotsPath + "/.config/task/taskrc.d/aliases";
".config/task/taskrc.d/colors".source = ../../dots/.config/task/taskrc.d/colors; ".config/task/taskrc.d/colors".source = dotsPath + "/.config/task/taskrc.d/colors";
".config/task/taskrc.d/contexts".source = ../../dots/.config/task/taskrc.d/contexts; ".config/task/taskrc.d/contexts".source = dotsPath + "/.config/task/taskrc.d/contexts";
".config/task/taskrc.d/reports".source = ../../dots/.config/task/taskrc.d/reports; ".config/task/taskrc.d/reports".source = dotsPath + "/.config/task/taskrc.d/reports";
".config/task/taskrc.d/udas".source = ../../dots/.config/task/taskrc.d/udas; ".config/task/taskrc.d/udas".source = dotsPath + "/.config/task/taskrc.d/udas";
".config/task/taskrc.d/urgency".source = ../../dots/.config/task/taskrc.d/urgency; ".config/task/taskrc.d/urgency".source = dotsPath + "/.config/task/taskrc.d/urgency";
".local/share/task/hooks/on-exit.sync.py" = { ".local/share/task/hooks/on-exit.sync.py" = {
source = ../../dots/.local/share/task/hooks/on-exit.sync.py; source = dotsPath + "/.local/share/task/hooks/on-exit.sync.py";
}; };
".local/share/task/scripts/sync-and-notify.sh" = { ".local/share/task/scripts/sync-and-notify.sh" = {
source = ../../dots/.local/share/task/scripts/sync-and-notify.sh; source = dotsPath + "/.local/share/task/scripts/sync-and-notify.sh";
executable = true; executable = true;
}; };
}; };
@@ -35,17 +48,10 @@
package = taskwarrior3; package = taskwarrior3;
colorTheme = "dark-256"; colorTheme = "dark-256";
config = { config = {
# sync = {
# server.url = "${builtins.readFile config.sops.secrets."taskwarrior_sync_server_url".path}";
# server.client_id = "${builtins.readFile
# config.sops.secrets."taskwarrior_sync_server_client_id".path
# }";
# encryption_secret = "${builtins.readFile
# config.sops.secrets."taskwarrior_sync_encryption_secret".path
# }";
# };
recurrence = "off"; recurrence = "off";
}; };
extraConfig = "include ${config.sops.templates."taskrc.d/sync".path}"; extraConfig = lib.optionalString sopsAvailable ''
include ${sopsTemplates."taskrc.d/sync".path}
'';
}; };
} }

25
home/modules/tmux.nix Normal file
View File

@@ -0,0 +1,25 @@
{
pkgs,
dotsPath,
...
}:
{
config = {
home.packages = with pkgs; [
tmux
tmuxp
reptyr
];
home.file = {
".config/tmux/tmux.conf".source = dotsPath + "/.config/tmux/tmux.conf";
".config/tmux/tmux.regular.conf".source = dotsPath + "/.config/tmux/tmux.regular.conf";
".config/tmux/themes/zenwritten_light.tmux".source =
dotsPath + "/.config/tmux/themes/zenwritten_light.tmux";
".config/tmux/themes/zenwritten_dark.tmux".source =
dotsPath + "/.config/tmux/themes/zenwritten_dark.tmux";
".config/tmux/hooks/tmux.ssh.conf".source = dotsPath + "/.config/tmux/hooks/tmux.ssh.conf";
".config/tmux/hooks/tmux.regular.conf".source = dotsPath + "/.config/tmux/hooks/tmux.regular.conf";
};
};
}

View File

@@ -0,0 +1,57 @@
[
{
"height": 16,
"spacing": 4,
"modules-left": ["niri/workspaces"],
"modules-right": [
"pulseaudio",
"memory",
"cpu",
"network",
"clock",
"battery",
],
"clock": {
"format": "W{:%V %d %b %H:%M}",
"tooltip-format": "{calendar}",
"format-alt": "{:%Y-%m-%d %H:%M:%S}",
},
"battery": {
"bat": "BAT0",
"adapter": "ADP1",
"interval": 5,
"full-at": 99,
"states": {
"good": 80,
"warning": 20,
"critical": 10,
},
"format": "{capacity}%--",
"format-charging": "{capacity}%++",
"format-plugged": "{capacity}%",
"format-alt": "{time} {power}W",
},
"pulseaudio": {
"format": "VOL {volume}%",
"format-muted": "muted",
"on-click": "pavucontrol",
},
"memory": {
"interval": 2,
"format": "RAM {percentage}%",
"format-alt": "RAM {used:0.1f}G/{total:0.1f}G",
},
"cpu": {
"interval": 2,
"format": "CPU {usage}%",
"format-alt": "CPU {avg_frequency}GHz",
},
"network": {
"interval": 5,
"format-wifi": "{ifname} {ipaddr} {essid}",
"format-ethernet": "{ifname} {ipaddr}",
"format-disconnected": "{ifname} disconnected",
"tooltip-format": "{ifname}: {ipaddr}/{cidr}",
},
},
]

View File

@@ -0,0 +1,8 @@
{
programs.waybar = {
enable = true;
};
home.file.".config/waybar/config.jsonc".source = ./config.jsonc;
home.file.".config/waybar/style.css".source = ./style.css;
}

View File

@@ -0,0 +1,56 @@
* {
font-family:
Iosevka Term SS08,
monospace;
font-size: 12px;
border-radius: 0px;
}
.modules-left,
.modules-center,
.modules-right {
margin: 4px;
margin-bottom: 0;
}
window#waybar {
background-color: transparent;
}
window#waybar.hidden {
opacity: 0.2;
}
#workspaces button {
padding: 0;
background-color: transparent;
}
#workspaces button:hover {
background: #000000;
}
#workspaces button.focused,
#workspaces button.active {
background-color: #111111;
}
#workspaces button.urgent {
background-color: #eb4d4b;
}
#clock,
#battery,
#pulseaudio,
#memory,
#cpu,
#network {
padding: 0 4px;
color: #ffffff;
background-color: #111111;
}
#window,
#workspaces {
margin: 0;
}

View File

@@ -1,47 +1,61 @@
{ {
lib, lib,
inputs, inputs,
outputs,
config, config,
pkgs, pkgs,
... ...
}: }:
let let
username = "h"; username = "h";
hostName = "andromache";
wolInterfaces = import ./wol-interfaces.nix;
in in
{ {
imports = [ imports = [
../../modules/common.nix ../../modules/common
inputs.disko.nixosModules.disko
inputs.sops-nix.nixosModules.sops
inputs.home-manager.nixosModules.default
./hard.nix ./hard.nix
../../modules/bootloader.nix inputs.nixos-hardware.nixosModules.common-cpu-intel
(import ../../modules/disko.zfs-encrypted-root.nix { inputs.nixos-hardware.nixosModules.common-pc
inputs.nixos-hardware.nixosModules.common-pc-ssd
inputs.sops-nix.nixosModules.sops
../../modules/boot/bootloader.nix
(import ../../modules/disko/zfs-encrypted-root.nix {
inherit lib config;
device = "/dev/nvme1n1"; device = "/dev/nvme1n1";
inherit lib;
inherit config;
}) })
../../modules/gnome.nix ../../modules/desktops/niri
../../modules/bluetooth.nix ../../modules/bluetooth
../../modules/keyboard ../../modules/keyboard
(import ../../modules/networking.nix { hostName = "andromache"; }) (import ../../modules/networking { inherit hostName; })
../../modules/users.nix ../../modules/users
../../modules/audio.nix ../../modules/audio
../../modules/localization.nix ../../modules/localization
../../modules/fonts ../../modules/fonts
../../modules/ssh/hardened-openssh.nix ../../modules/ssh/hardened-openssh.nix
(import ../../modules/secrets { (import ../../modules/secrets { inherit lib inputs config; })
inherit lib; ../../modules/docker
inherit inputs;
inherit config;
})
../../modules/docker.nix
]; ];
home-manager.users.${username} = import ../../home/hosts/andromache {
inherit
inputs
config
pkgs
lib
;
};
networking.hostName = hostName;
ssh.username = username;
ssh.authorizedHosts = [ "astyanax" ];
secrets.username = username; secrets.username = username;
docker.user = username; docker.user = username;
nix.settings.secret-key-files = [ config.sops.secrets.nix_signing_key_andromache.path ];
disko.devices = { disko.devices = {
disk.data = { disk.data = {
type = "disk"; type = "disk";
@@ -75,57 +89,50 @@ in
}; };
}; };
environment.systemPackages = [ inputs.nvim.packages.x86_64-linux.nvim ]; environment.systemPackages = [
inputs.nvim.packages.x86_64-linux.nvim
];
home-manager = { services = {
useGlobalPkgs = true; xserver = {
useUserPackages = true;
users.${username} = import ../../home/hosts/andromache {
inherit lib;
inherit inputs;
inherit config;
inherit pkgs;
};
};
networking = {
hostId = "80eef97e";
};
services.xserver = {
videoDrivers = [ "nvidia" ]; videoDrivers = [ "nvidia" ];
}; };
services.openssh = { openssh = {
enable = true; enable = true;
harden = true; harden = true;
}; };
services.syncthing = { syncthing = {
enable = true; enable = true;
openDefaultPorts = true; openDefaultPorts = true;
settings = {
devices = {
# "device1" = {
# id = "DEVICE-ID-GOES-HERE";
# };
};
folders = { folders = {
"/home/${username}/sync" = { "/home/${username}/sync" = {
id = "sync"; id = "sync";
devices = [ ]; devices = [ ];
}; };
}; };
devices = {
# "device1" = {
# id = "DEVICE-ID-GOES-HERE";
# };
}; };
}; };
locate = {
services.locate = {
enable = true; enable = true;
package = pkgs.plocate; package = pkgs.plocate;
}; };
};
networking = { networking = {
# TODO: generate unique hostId on actual host with: head -c 8 /etc/machine-id
hostId = "80eef97e";
interfaces = { interfaces = {
eno1 = { eno1 = {
wakeOnLan.enable = true; wakeOnLan.enable = true;
inherit (wolInterfaces.eno1) macAddress;
}; };
}; };
firewall = { firewall = {

View File

@@ -14,7 +14,8 @@
(modulesPath + "/installer/scan/not-detected.nix") (modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = [ boot = {
initrd.availableKernelModules = [
"vmd" "vmd"
"xhci_pci" "xhci_pci"
"ahci" "ahci"
@@ -24,9 +25,10 @@
"uas" "uas"
"sd_mod" "sd_mod"
]; ];
boot.initrd.kernelModules = [ ]; initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ]; kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ]; extraModulePackages = [ ];
};
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's # (the default) this is the recommended approach. When using systemd-networkd it's

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG7TMnKO4EqISk2s/xy+3P2xn8XcMOuzZrSiYTZT+8m2 root@andromache

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOOXPEhdKOVnb6mkeLLUcFGt+mnUR5pMie17JtjrxwgO h@andromache

View File

@@ -0,0 +1,3 @@
{
eno1.macAddress = "02:68:b3:29:da:98";
}

View File

@@ -1,70 +1,102 @@
{ {
lib, lib,
inputs, inputs,
outputs,
config, config,
pkgs, pkgs,
... ...
}: }:
let let
username = "h"; username = "h";
hostName = "astyanax"; hostName = "astyanax";
wolInterfaces = import ../andromache/wol-interfaces.nix;
in in
{ {
imports = [ imports = [
../../modules/common.nix ../../modules/common
inputs.nixos-hardware.nixosModules.lenovo-thinkpad-e14-intel
inputs.disko.nixosModules.disko
inputs.sops-nix.nixosModules.sops
inputs.home-manager.nixosModules.default
./hard.nix ./hard.nix
../../modules/bootloader.nix inputs.nixos-hardware.nixosModules.common-pc
(import ../../modules/disko.zfs-encrypted-root.nix { inputs.nixos-hardware.nixosModules.common-pc-ssd
inherit lib; # inputs.nixos-hardware.nixosModules.lenovo-thinkpad-e14-intel-gen7 (not available yet?)
inherit config; inputs.sops-nix.nixosModules.sops
../../modules/boot/bootloader.nix
(import ../../modules/disko/zfs-encrypted-root.nix {
inherit lib config;
device = "/dev/nvme0n1"; device = "/dev/nvme0n1";
}) })
../../modules/gnome.nix ../../modules/desktops/niri
../../modules/bluetooth.nix ../../modules/bluetooth
../../modules/keyboard ../../modules/keyboard
(import ../../modules/networking.nix { hostName = hostName; }) (import ../../modules/networking { inherit hostName; })
../../modules/users.nix ../../modules/users
../../modules/audio.nix ../../modules/audio
../../modules/localization.nix ../../modules/localization
../../modules/fonts ../../modules/fonts
../../modules/ssh/hardened-openssh.nix ../../modules/ssh/hardened-openssh.nix
(import ../../modules/secrets { ../../modules/vpn/wireguard.nix
inherit lib; (import ../../modules/secrets { inherit lib inputs config; })
inherit inputs; ../../modules/docker
inherit config; ];
inherit username;
home-manager.users.${username} = import ../../home/hosts/astyanax {
inherit
inputs
config
pkgs
lib
;
};
networking.hostName = hostName;
ssh.username = username;
ssh.authorizedHosts = [ "andromache" ];
secrets.username = username;
docker.user = username;
nix.settings.secret-key-files = [ config.sops.secrets.nix_signing_key_astyanax.path ];
hardware = {
cpu.intel.updateMicrocode = true;
# https://wiki.nixos.org/wiki/Intel_Graphics
graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver
vpl-gpu-rt
];
};
};
# https://wiki.nixos.org/wiki/Intel_Graphics
environment.sessionVariables = {
LIBVA_DRIVER_NAME = "iHD";
};
environment.systemPackages = [
inputs.nvim.packages.x86_64-linux.nvim
(pkgs.writeShellApplication {
name = "wol-andromache";
runtimeInputs = [ pkgs.wakeonlan ];
text = ''
wakeonlan ${wolInterfaces.eno1.macAddress}
'';
}) })
]; ];
secrets.username = username;
environment.systemPackages = [ inputs.nvim.packages.x86_64-linux.nvim ];
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
users.${username} = import ../../home/hosts/astyanax {
inherit inputs;
inherit config;
inherit pkgs;
};
};
networking = { networking = {
# TODO: generate unique hostId on actual host with: head -c 8 /etc/machine-id
hostId = "80eef97e"; hostId = "80eef97e";
}; };
services.openssh = { services = {
fwupd.enable = true;
openssh = {
enable = true; enable = true;
harden = true; harden = true;
}; };
syncthing = {
services.syncthing = {
enable = true; enable = true;
openDefaultPorts = true; openDefaultPorts = true;
folders = { folders = {
@@ -79,9 +111,9 @@ in
# }; # };
}; };
}; };
locate = {
services.locate = {
enable = true; enable = true;
package = pkgs.plocate; package = pkgs.plocate;
}; };
};
} }

View File

@@ -14,16 +14,18 @@
(modulesPath + "/installer/scan/not-detected.nix") (modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = [ boot = {
initrd.availableKernelModules = [
"xhci_pci" "xhci_pci"
"thunderbolt" "thunderbolt"
"nvme" "nvme"
"uas" "uas"
"sd_mod" "sd_mod"
]; ];
boot.initrd.kernelModules = [ ]; initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ]; kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ]; extraModulePackages = [ ];
};
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's # (the default) this is the recommended approach. When using systemd-networkd it's

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO8+UOyZbvQeHfFfYox3SQi42KJ0S3RZj79iswSsZeFy root@nixos

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIzP1PjIDb1tN9nhPOK88HYDtTNk9SN9ZpEem2id49Fa h@astyanax

93
hosts/hecuba/default.nix Normal file
View File

@@ -0,0 +1,93 @@
{
lib,
inputs,
outputs,
config,
pkgs,
...
}:
# Also see <https://wiki.nixos.org/wiki/Install_NixOS_on_Hetzner_Cloud>
let
username = "username";
hostName = "hecuba";
in
{
imports = [
../../modules/common
./hard.nix
../../modules/ssh/hardened-openssh.nix
../../modules/docker
];
networking.hostName = hostName;
ssh.username = username;
ssh.authorizedHosts = [
"andromache"
"astyanax"
];
docker.user = username;
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/boot";
fsType = "ext4";
};
swapDevices = [
{
device = "/dev/disk/by-label/swap";
}
];
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
users.users = {
root.hashedPassword = "!";
username = {
isNormalUser = true;
extraGroups = [ "wheel" ];
};
};
security.sudo.wheelNeedsPassword = false;
networking.firewall = {
enable = true;
allowedTCPPorts = [
80
443
];
};
environment.systemPackages = with pkgs; [
vim
git
];
services.fail2ban = {
enable = true;
maxretry = 5;
};
services.openssh = {
enable = true;
harden = true;
};
nix.settings = {
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"astyanax:JY2qJkZUFSax47R3c1nq53AZ8GnLfNqz6mSnJ60cLZ4="
"andromache:XM4VLrEw63RB/3v/56OxzH/Yw+kKXKMBLKCb7UGAXzo="
];
auto-optimise-store = true;
keep-derivations = false;
keep-outputs = false;
};
}

41
hosts/hecuba/hard.nix Normal file
View File

@@ -0,0 +1,41 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot = {
initrd = {
availableKernelModules = [
"ahci"
"xhci_pci"
"virtio_pci"
"virtio_scsi"
"sd_mod"
"sr_mod"
];
kernelModules = [ ];
};
kernelModules = [ ];
extraModulePackages = [ ];
};
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPIffzYkin2QHGoaOKXbQv6pbim8SU1J+3vAf2vXerMj root@nixos

View File

@@ -1,46 +1,52 @@
{ {
lib, lib,
inputs, inputs,
outputs,
config, config,
pkgs, pkgs,
... ...
}: }:
let let
username = "h"; username = "h";
hostName = "vm";
in in
{ {
imports = [ imports = [
../../modules/common.nix ../../modules/common
inputs.disko.nixosModules.disko
inputs.sops-nix.nixosModules.sops
inputs.home-manager.nixosModules.default
./hard.nix ./hard.nix
inputs.sops-nix.nixosModules.sops
./disk.nix ./disk.nix
../../modules/bootloader.nix ../../modules/boot/bootloader.nix
../../modules/keyboard ../../modules/keyboard
(import ../../modules/networking.nix { hostName = "vm"; }) (import ../../modules/networking { inherit hostName; })
../../modules/users.nix ../../modules/users
../../modules/audio.nix ../../modules/audio
../../modules/localization.nix ../../modules/localization
../../modules/x.nix ../../modules/x
../../modules/fonts ../../modules/fonts
../../modules/ssh/hardened-openssh.nix ../../modules/ssh/hardened-openssh.nix
(import ../../modules/secrets { (import ../../modules/secrets {
inherit lib; inherit lib inputs config;
inherit inputs;
inherit config;
}) })
]; ];
secrets.username = "h"; home-manager.users.${username} = import ../../home/hosts/vm {
inherit inputs config pkgs;
};
networking.hostName = hostName;
ssh.username = username;
secrets.username = username;
environment.systemPackages = [ inputs.nvim.packages.x86_64-linux.nvim ]; environment.systemPackages = [ inputs.nvim.packages.x86_64-linux.nvim ];
disko = { disko = {
devices.disk.main.device = "/dev/vda"; devices.disk.main = {
devices.disk.main.imageName = "nixos-vm"; device = "/dev/vda";
devices.disk.main.imageSize = "32G"; imageName = "nixos-vm";
imageSize = "32G";
};
}; };
virtualisation.vmVariantWithDisko = { virtualisation.vmVariantWithDisko = {
@@ -55,21 +61,12 @@ in
}; };
}; };
home-manager = { services = {
useGlobalPkgs = true; qemuGuest.enable = true;
useUserPackages = true; spice-vdagentd.enable = true;
users.${username} = import ../../home/hosts/vm { openssh = {
inherit inputs;
inherit config;
inherit pkgs;
};
};
services.qemuGuest.enable = true;
services.spice-vdagentd.enable = true;
services.openssh = {
enable = true; enable = true;
harden = true; harden = true;
}; };
};
} }

View File

@@ -14,16 +14,20 @@
(modulesPath + "/profiles/qemu-guest.nix") (modulesPath + "/profiles/qemu-guest.nix")
]; ];
boot.initrd.availableKernelModules = [ boot = {
initrd = {
availableKernelModules = [
"ahci" "ahci"
"xhci_pci" "xhci_pci"
"virtio_pci" "virtio_pci"
"sr_mod" "sr_mod"
"virtio_blk" "virtio_blk"
]; ];
boot.initrd.kernelModules = [ ]; kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ]; };
boot.extraModulePackages = [ ]; kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
};
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's # (the default) this is the recommended approach. When using systemd-networkd it's

View File

@@ -1,12 +0,0 @@
{ ... }:
{
services.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
}

15
modules/audio/default.nix Normal file
View File

@@ -0,0 +1,15 @@
_:
{
security.rtkit.enable = true;
services = {
pulseaudio.enable = false;
pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
pulseaudio.extraConfig = "load-module module-switch-on-connect";
};
}

View File

@@ -1,3 +0,0 @@
{
hardware.bluetooth.enable = true;
}

View File

@@ -0,0 +1,15 @@
{
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General = {
Experimental = true;
FastConnectable = true;
};
Policy = {
AutoEnable = true;
};
};
};
}

View File

@@ -1,4 +1,4 @@
{ ... }: _:
{ {
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;

View File

@@ -1,10 +0,0 @@
{
system.stateVersion = "25.05";
nix.settings.experimental-features = [
"nix-command"
"flakes"
];
nixpkgs.config.allowUnfree = true;
}

View File

@@ -0,0 +1,56 @@
{
inputs,
outputs,
dotsPath,
...
}:
{
imports = [
inputs.disko.nixosModules.disko
inputs.home-manager.nixosModules.default
];
system.stateVersion = "25.05";
nix.settings.experimental-features = [
"nix-command"
"flakes"
];
nixpkgs.config.allowUnfree = true;
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = {
inherit inputs outputs dotsPath;
};
};
nix = {
optimise = {
automatic = true;
dates = [ "05:00" ];
};
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
};
system.autoUpgrade = {
enable = true;
flake = inputs.self.outPath;
operation = "switch";
flags = [
"--recreate-lock-file"
"--commit-lock-file"
"--print-build-logs"
];
dates = "05:00";
randomizedDelaySec = "45min";
allowReboot = false;
};
}

View File

@@ -0,0 +1,16 @@
{
programs.niri.enable = true;
services = {
dbus.enable = true;
logind.settings.Login = {
HandleLidSwitch = "suspend";
IdleAction = "suspend";
IdleActionSec = 1800;
};
displayManager.ly = {
enable = true;
};
};
}

View File

@@ -11,7 +11,7 @@
disk = { disk = {
root = { root = {
type = "disk"; type = "disk";
device = config.device; inherit (config) device;
content = { content = {
type = "gpt"; type = "gpt";
partitions = { partitions = {

View File

@@ -1,5 +1,16 @@
{ pkgs, ... }:
{ {
imports = [ imports = [
./iosevka.nix ./iosevka.nix
]; ];
fonts = {
# disable default font packages (see https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/config/fonts/packages.nix)
enableDefaultPackages = false;
packages = with pkgs; [
dejavu_fonts
liberation_ttf
];
};
} }

View File

@@ -1,7 +1,14 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
fonts.packages = with pkgs; [ fonts = {
packages = with pkgs; [
(iosevka-bin.override { variant = "SGr-IosevkaTermSS08"; }) (iosevka-bin.override { variant = "SGr-IosevkaTermSS08"; })
]; ];
fontconfig = {
defaultFonts = {
monospace = [ "Iosevka Term SS08" ];
};
};
};
} }

79
modules/k3s/default.nix Normal file
View File

@@ -0,0 +1,79 @@
{ pkgs, ... }:
{
# TODO: see if this works with podman
# TODO: check if docker/podman is enabled
# Rootless K3S
# FIXME
environment.systemPackages = with pkgs; [
k3s
rootlesskit
slirp4netns
];
# running K3S on rootless docker was causing the following error: "failed to find cpuset cgroup (v2)" (in `docker logs k3d-lab-server-0` output)
#
# see <https://docs.k3s.io/advanced#known-issues-with-rootless-mode>
# see <https://rootlesscontaine.rs/getting-started/common/cgroup2/>
# see <https://discourse.nixos.org/t/declarative-rootless-k3s/49839>
systemd.services."user@".serviceConfig.Delegate = "cpu cpuset io memory pids";
# taken from <https://github.com/k3s-io/k3s/blob/main/k3s-rootless.service> as described in <https://docs.k3s.io/advanced#known-issues-with-rootless-mode#Rootless>
systemd.user.services."k3s-rootless" = with pkgs; {
path = with pkgs; [
"${rootlesskit}"
"${slirp4netns}"
"${fuse-overlayfs}"
"${fuse3}"
"/run/wrappers"
];
# systemd unit file for k3s (rootless)
#
# Usage:
# - [Optional] Enable cgroup v2 delegation, see https://rootlesscontaine.rs/getting-started/common/cgroup2/ .
# This step is optional, but highly recommended for enabling CPU and memory resource limtitation.
#
# - Copy this file as `~/.config/systemd/user/k3s-rootless.service`.
# Installing this file as a system-wide service (`/etc/systemd/...`) is not supported.
# Depending on the path of `k3s` binary, you might need to modify the `ExecStart=/usr/local/bin/k3s ...` line of this file.
#
# - Run `systemctl --user daemon-reload`
#
# - Run `systemctl --user enable --now k3s-rootless`
#
# - Run `KUBECONFIG=~/.kube/k3s.yaml kubectl get pods -A`, and make sure the pods are running.
#
# Troubleshooting:
# - See `systemctl --user status k3s-rootless` to check the daemon status
# - See `journalctl --user -f -u k3s-rootless` to see the daemon log
# - See also https://rootlesscontaine.rs/
enable = true;
description = "k3s (Rootless)";
serviceConfig = {
# NOTE: Don't try to run `k3s server --rootless` on a terminal, as it doesn't enable cgroup v2 delegation.
# If you really need to try it on a terminal, prepend `systemd-run --user -p Delegate=yes --tty` to create a systemd scope.
ExecStart = "${k3s}/bin/k3s server --rootless --snapshotter=fuse-overlayfs";
ExecReload = "/run/current-system/sw/bin/kill -s HUP $MAINPID";
TimeoutSec = 0;
RestartSec = 2;
Restart = "always";
StartLimitBurst = 3;
StartLimitInterval = "60s";
LimitNOFILE = "infinity";
LimitNPROC = "infinity";
LimitCORE = "infinity";
TasksMax = "infinity";
Delegate = "yes";
Type = "simple";
KillMode = "mixed";
};
wantedBy = [ "default.target" ];
};
boot.kernel.sysctl = {
"net.ipv4.ip_forward" = 1;
};
}

View File

@@ -1,4 +1,4 @@
{ ... }: _:
{ {
time.timeZone = "Europe/Brussels"; time.timeZone = "Europe/Brussels";

View File

@@ -5,7 +5,7 @@
{ {
networking = { networking = {
hostName = hostName; inherit hostName;
wireless.iwd.enable = true; wireless.iwd.enable = true;
networkmanager.wifi.backend = "iwd"; networkmanager.wifi.backend = "iwd";
nftables.enable = true; nftables.enable = true;

View File

@@ -16,7 +16,6 @@ in
}; };
config = { config = {
sops = { sops = {
validateSopsFiles = false;
defaultSopsFile = "${builtins.toString inputs.nix-secrets}/secrets.yaml"; defaultSopsFile = "${builtins.toString inputs.nix-secrets}/secrets.yaml";
defaultSopsFormat = "yaml"; defaultSopsFormat = "yaml";
age.keyFile = "/home/${cfg.username}/.config/sops/age/keys.txt"; age.keyFile = "/home/${cfg.username}/.config/sops/age/keys.txt";
@@ -27,9 +26,16 @@ in
"taskwarrior_sync_encryption_secret".owner = config.users.users.${cfg.username}.name; "taskwarrior_sync_encryption_secret".owner = config.users.users.${cfg.username}.name;
"email_personal".owner = config.users.users.${cfg.username}.name; "email_personal".owner = config.users.users.${cfg.username}.name;
"email_work".owner = config.users.users.${cfg.username}.name; "email_work".owner = config.users.users.${cfg.username}.name;
"anki_sync_user".owner = config.users.users.${cfg.username}.name;
"anki_sync_key".owner = config.users.users.${cfg.username}.name;
"hcloud".owner = config.users.users.${cfg.username}.name;
"nix_signing_key_astyanax" = { };
"nix_signing_key_andromache" = { };
"opencode_api_key".owner = config.users.users.${cfg.username}.name;
}; };
templates."taskrc.d/sync" = { templates = {
"taskrc.d/sync" = {
owner = config.users.users.${cfg.username}.name; owner = config.users.users.${cfg.username}.name;
content = '' content = ''
sync.server.url=${config.sops.placeholder."taskwarrior_sync_server_url"} sync.server.url=${config.sops.placeholder."taskwarrior_sync_server_url"}
@@ -38,7 +44,7 @@ in
''; '';
}; };
templates.".gitconfig.email" = { ".gitconfig.email" = {
owner = config.users.users.${cfg.username}.name; owner = config.users.users.${cfg.username}.name;
path = "/home/${cfg.username}/.gitconfig.email"; path = "/home/${cfg.username}/.gitconfig.email";
content = '' content = ''
@@ -47,7 +53,7 @@ in
''; '';
}; };
templates.".gitconfig.work.email" = { ".gitconfig.work.email" = {
owner = config.users.users.${cfg.username}.name; owner = config.users.users.${cfg.username}.name;
path = "/home/${cfg.username}/.gitconfig.work.email"; path = "/home/${cfg.username}/.gitconfig.work.email";
content = '' content = ''
@@ -55,6 +61,32 @@ in
email = ${config.sops.placeholder."email_work"} email = ${config.sops.placeholder."email_work"}
''; '';
}; };
"hcloud/cli.toml" = {
owner = config.users.users.${cfg.username}.name;
path = "/home/${cfg.username}/.config/hcloud/cli.toml";
content = ''
active_context = "server"
[[contexts]]
name = "server"
token = "${config.sops.placeholder."hcloud"}"
'';
};
"opencode/auth.json" = {
owner = config.users.users.${cfg.username}.name;
path = "/home/${cfg.username}/.local/share/opencode/auth.json";
content = ''
{
"zai-coding-plan": {
"type": "api",
"key": "${config.sops.placeholder."opencode_api_key"}"
}
}
'';
};
};
}; };
}; };
} }

View File

@@ -0,0 +1,24 @@
{ lib, config, ... }:
{
options.ssh = {
authorizedHosts = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
};
username = lib.mkOption {
type = lib.types.str;
default = "h";
};
};
# auto generate authorized_keys from `authorizedHosts`
config.users.users.${config.ssh.username}.openssh.authorizedKeys.keys = lib.flatten (
map (
hostname:
let
keyFile = ../../hosts/${hostname}/ssh_user.pub;
in
lib.optionals (builtins.pathExists keyFile) (lib.splitString "\n" (builtins.readFile keyFile))
) config.ssh.authorizedHosts
);
}

View File

@@ -0,0 +1,24 @@
{ lib, config, ... }:
let
inherit (config.ssh) username;
in
{
# auto extract SSH keys
system.activationScripts.extractSshKeys = lib.stringAfter [ "etc" ] ''
HOST_KEY="/etc/ssh/ssh_host_ed25519_key.pub"
HOST_DIR="/home/${username}/nix/hosts/${config.networking.hostName}"
if [ -f "$HOST_KEY" ] && [ -d "$HOST_DIR" ]; then
cp "$HOST_KEY" "$HOST_DIR/ssh_host.pub"
chown ${username}:users "$HOST_DIR/ssh_host.pub"
chmod 644 "$HOST_DIR/ssh_host.pub"
fi
USER_KEY="/home/${username}/.ssh/id_ed25519.pub"
if [ -f "$USER_KEY" ] && [ -d "$HOST_DIR" ]; then
cp "$USER_KEY" "$HOST_DIR/ssh_user.pub"
chown ${username}:users "$HOST_DIR/ssh_user.pub"
chmod 644 "$HOST_DIR/ssh_user.pub"
fi
'';
}

View File

@@ -4,12 +4,21 @@ let
cfg = config.services.openssh; cfg = config.services.openssh;
in in
{ {
imports = [
./known-hosts.nix
./authorized-keys.nix
./extract-keys.nix
];
options.services.openssh.harden = mkEnableOption "harden ssh server configuration"; options.services.openssh.harden = mkEnableOption "harden ssh server configuration";
config = { config = {
networking.firewall.allowedTCPPorts = [ 22 ]; networking.firewall.allowedTCPPorts = [ 22 ];
services.openssh.settings = optionalAttrs cfg.harden { services.openssh.settings = optionalAttrs cfg.harden {
PermitRootLogin = "no"; PermitRootLogin = "no";
PasswordAuthentication = false; PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
ChallengeResponseAuthentication = false; ChallengeResponseAuthentication = false;
X11Forwarding = false; X11Forwarding = false;
AllowAgentForwarding = false; AllowAgentForwarding = false;

View File

@@ -0,0 +1,19 @@
{
lib,
config,
outputs,
...
}:
let
hosts = lib.attrNames outputs.nixosConfigurations;
hostsWithKeys = lib.filter (
hostname: builtins.pathExists ../../hosts/${hostname}/ssh_host.pub
) hosts;
in
{
# auto generate known_hosts for all hosts in flake
programs.ssh.knownHosts = lib.genAttrs hostsWithKeys (hostname: {
publicKeyFile = ../../hosts/${hostname}/ssh_host.pub;
extraHostNames = lib.optional (hostname == config.networking.hostName) "localhost";
});
}

Some files were not shown because too many files have changed in this diff Show More