Compare commits

...

348 Commits

Author SHA1 Message Date
3bcd4c3c13 chore: update lockfile 2026-05-06 19:41:05 +02:00
d975d49844 fix(nvim): allow unfree nvim plugins 2026-05-06 19:41:00 +02:00
1ead7fe7be chore: update lockfile 2026-04-30 18:33:01 +02:00
7dd2fc7e59 chore: update lockfile 2026-04-30 18:28:53 +02:00
95ffe7b908 refactor: derive host name solely from host directory name 2026-04-30 17:20:02 +02:00
ce02cc5538 fix(desktops): resolve xdg portal error on 'work' host 2026-04-30 15:31:07 +02:00
0dbc007a90 feat(database): add redis to database module 2026-04-30 15:07:10 +02:00
57e0d49278 fix(nvim): add missing dependencies 2026-04-30 15:06:51 +02:00
ee44b26147 feat(ai): add 'ai-tools' 'skills' submodule 2026-04-29 18:37:43 +02:00
675306ec91 refactor: modularize 'ai-tools' 2026-04-29 18:37:42 +02:00
a829f160fb fix(gnome): don't use monospace font for 'dconf' 2026-04-29 18:37:07 +02:00
4cfe0387e2 chore: update 'nvim' flake dependencies 2026-04-29 18:37:06 +02:00
2efccdb4de feat(hydra): add hydra-repl filetype integration 2026-04-26 19:07:55 +02:00
8aafaf7d35 chore: disable 'mcp-nixos' temporarily (failed test) 2026-04-26 19:07:55 +02:00
dce57f907a chore(ai): enable 'claude-code' on 'andromache,astyanax' hosts 2026-04-26 19:07:55 +02:00
1bda05280e refactor(desktops): give all desktop modules own subdirectory 2026-04-26 19:07:55 +02:00
d39071da06 refactor(desktops): extract 'logind' module 2026-04-26 19:07:55 +02:00
781f379aff refactor: simplify zk file completion 2026-04-26 19:07:55 +02:00
2203b48cde fix: scope markdown file name echo to zk 2026-04-26 19:07:55 +02:00
35f6f7890f chore: add 'nodejs_24' dependency to 'nvim' flake 2026-04-26 19:07:55 +02:00
83958847f4 fix: enable 'boot.tmp.useTmpfs' based on host 'highRam' flag 2026-04-26 15:00:57 +02:00
b66b0c4003 fix: resolve current zettel path issue 2026-04-26 14:40:26 +02:00
efd2771d8c fix: remove tmux hooks 2026-04-26 14:33:19 +02:00
94331531e2 chore: disable 'lutris' temporarily (failed openldap test) 2026-04-26 14:32:20 +02:00
5b1e7efcd2 chore: update lockfile 2026-04-26 14:32:20 +02:00
730dd23967 fix: centralize and nixifiy in 'zk' module 2026-04-26 14:32:20 +02:00
8f5caaed41 fix(nvim): disable neotest check phase 2026-04-21 22:24:48 +02:00
db2bbb86ba chore: update lockfile 2026-04-21 22:08:28 +02:00
72c3710a3c refactor(secrets): simplify secrets 2026-04-21 22:08:28 +02:00
b62f3c20ac refactor(backups): simplify backups module 2026-04-21 21:39:23 +02:00
dd31da5a8f fix: add home manager 'secrets' module to andromache 2026-04-21 21:39:17 +02:00
bc6d8b6305 fix: remove nodeNixpkgs from colmena 2026-04-21 21:38:55 +02:00
fce3aa45ec refactor: modularize utils 2026-04-21 21:37:31 +02:00
949917a809 feat(direnv): set up direnv using '.envrc' 2026-04-21 21:37:25 +02:00
0dd1ecef91 feat: set up tailscale on 'eetion' host 2026-04-21 21:37:17 +02:00
fcdb52cc42 chore: update lockfile 2026-04-21 17:14:17 +02:00
b6500b97ff refactor(stylix): extract shared stylix overrides into 'targets.nix' 2026-04-21 17:11:16 +02:00
8f756554ad refactor(stylix): do not hardcode 'dconf' font 2026-04-21 17:11:10 +02:00
583b9ea5f3 refactor(deploy): move deployment config into '<host>/meta.nix' 2026-04-21 17:11:04 +02:00
6a30a431f8 refactor: simplify 'user' options 2026-04-21 17:10:42 +02:00
38818e7508 refactor: merge '<host>/system.nix' into '<host>/meta.nix' 2026-04-21 15:51:25 +02:00
94c64e9d33 fix: remove task count limits 2026-04-21 15:51:21 +02:00
a9854ac144 feat: alias 'kubectl' to 'k' 2026-04-21 15:51:17 +02:00
8b109af08b fix: add 'devenv' to 'astyanax' and 'work' hosts 2026-04-21 15:51:12 +02:00
82dde7d749 chore: update lockfile 2026-04-17 12:47:31 +02:00
59ce48d65e fix(taskwarrior): prevent taskwarrior scroll issue 2026-04-17 12:47:26 +02:00
9b9c580a7f fix: disable xdg user dirs auto create 2026-04-17 12:47:25 +02:00
0e27b181ad fix(browser): set 'BROWSER' environment variable based on nix config 2026-04-17 12:47:24 +02:00
6b43660491 refactor: add wayland clipboard module 2026-04-17 12:47:22 +02:00
db5e8855d2 fix(nix-secrets): use simplified signing key setup 2026-04-17 12:47:21 +02:00
2f1f60b836 fix: update tailscale flags 2026-04-17 12:47:20 +02:00
a13a19e8e9 fix: allow unsigned builds on hecuba 2026-04-17 12:47:19 +02:00
fee4b43104 fix: add kitty term info to 'hecuba' host 2026-04-17 12:47:18 +02:00
faf3afad79 fix: update secrets approach to match 'nix-secrets' 2026-04-17 12:47:17 +02:00
db116cc4de fix: add 'yubikey' module to astyanax host 2026-04-17 12:47:16 +02:00
75ee011369 fix: enable tailscale module on 'astyanax' host 2026-04-17 12:47:15 +02:00
ae63c4737a fix(niri): do not enable gnome keyring or Nautilus when niri is enabled 2026-04-17 12:47:14 +02:00
d6bc3c0293 chore(ssh): rotate 'astyanax' to hardware-backed ssh key 2026-04-17 12:47:11 +02:00
fd3a38da62 chore(nvim): update 'nvim' packages 2026-04-17 12:47:10 +02:00
e30ca9d8dd refactor: move nixPath into 'common' module 2026-04-17 12:47:08 +02:00
79eb5c27e9 feat: add tailscale module 2026-04-17 12:47:07 +02:00
677728c440 fix(deploy): never build ARM on target 2026-04-17 12:47:05 +02:00
483b05fc27 fix(deploy): resolve colmena issues 2026-04-17 12:47:02 +02:00
cb4709b1a6 chore(scripts): remove 'git-cb' script 2026-04-17 12:46:58 +02:00
dc650e4722 feat(eetion): pin actualbudget to 26.4.0-alpine 2026-04-05 22:18:59 +02:00
f5dd89582d fix: improve gaming module 2026-04-05 18:13:30 +02:00
585259480e feat: add 'devenv' home manager module 2026-04-05 18:13:12 +02:00
2248d7d781 fix: resolve niri xdg portal issues 2026-04-05 16:11:41 +02:00
0b79904103 refactor: simplify host config 2026-04-05 16:01:08 +02:00
2929a10d62 feat: add 'torrenting' module 2026-04-05 15:38:23 +02:00
4cac77f4c7 chore: update lockfile 2026-04-02 23:14:12 +02:00
1586549896 fix: explicitely set 'SYSTEMD_EDITOR' env variable 2026-04-02 23:14:12 +02:00
5ae3aa4e6c fix(desktop): enable waybar systemd service 2026-04-02 23:14:12 +02:00
4aee96241c fix: conditionally enable 'mpris-proxy' in audio module 2026-04-01 21:56:28 +02:00
3478fac832 feat: add 'ticketing' module 2026-03-27 13:23:04 +01:00
e364dbe76d chore: update lockfile 2026-03-18 12:13:42 +01:00
55a69316a5 refactor(nvim): cleanup nvim config 2026-03-18 12:12:15 +01:00
41011923ac feat: add tirith to work host 2026-03-18 12:12:14 +01:00
916e732ce6 refactor: adopt modular secrets approach 2026-03-17 19:44:04 +01:00
3f9c9cd154 fix: split up 3d module 2026-03-15 20:07:44 +01:00
8c2c1a2aab feat: add font for emoji support 2026-03-14 22:45:52 +01:00
e7c6df1c9b refactor: extract 'firewall' and 'wol' modules 2026-03-14 22:17:35 +01:00
34ebb265e6 chore: update lockfile 2026-03-13 20:31:22 +01:00
b65735929c fix: prevent 'opencode' from reading SSH private keys or 'sops' secret files 2026-03-13 20:27:08 +01:00
804305abf9 fix: resolve incorrect imports 2026-03-12 09:31:57 +01:00
af8555cbe1 feat: add tirith to work host 2026-03-12 09:31:31 +01:00
210d8f3b1f refactor: merge 'audio-automation' module into 'audio' module 2026-03-11 23:53:50 +01:00
b417e67e16 docs: update README.md 2026-03-11 23:46:40 +01:00
32e928c56b refactor: extract host config into 'host.nix' files 2026-03-11 23:43:54 +01:00
12481d7468 refactor: cleanup (deadnix, nixfmt, statix) 2026-03-11 23:23:51 +01:00
7c92cc5c6a fix: use mkDefault for stateVersion to allow host overrides 2026-03-11 23:05:04 +01:00
0a568cba6f chore: update lockfile 2026-03-11 23:05:04 +01:00
43dff3e8e5 refactor: add config.host option for host variables 2026-03-11 23:04:43 +01:00
4c9db2b822 refactor(waybar): modularize waybar config 2026-03-11 21:33:29 +01:00
6389bf4e25 refactor: remove unnecessary config wrapper in nvim 2026-03-11 21:25:32 +01:00
9285e69086 refactor: remove unnecessary config wrapper in docker 2026-03-11 21:25:32 +01:00
1ecb690f0d refactor: namespace git cli options under git module 2026-03-11 21:25:32 +01:00
83cb9cdec1 refactor: move vscode.nix to vscode/default.nix 2026-03-11 21:25:32 +01:00
754deff57f refactor: move nodejs.nix to nodejs/default.nix 2026-03-11 21:25:32 +01:00
d3093b13eb chore: update lockfile 2026-03-11 21:25:32 +01:00
a2386de8ce fix: use 'colmenaHive' instead of 'colmena' 2026-03-11 21:25:32 +01:00
13cf1c296b refactor: simplify bash configuration 2026-03-11 21:25:32 +01:00
890146bc9d refactor: use 'import-as-enable' pattern 2026-03-11 21:25:32 +01:00
ed39959b61 feat(deploy): add deployment tags for each host 2026-03-11 21:25:32 +01:00
828b5d7374 refactor(hosts): use modules/ssh with sensible defaults 2026-03-11 21:25:32 +01:00
b9bdd36a05 feat(ssh): add default module with enable+harden 2026-03-11 21:25:32 +01:00
a49be3040f chore(ai): add 'mcp-nixos' 2026-03-11 21:25:32 +01:00
19617326f0 feat: add 'infra' module (and use on work host) 2026-03-11 21:25:32 +01:00
14f79f54ec fix: use correct vscode no sandbox flag 2026-03-11 21:25:32 +01:00
5b19722ab1 fix: resolve anki warning 2026-03-11 21:25:32 +01:00
4fae852ab1 feat: add database module 2026-03-11 21:25:32 +01:00
959bccc375 chore: update lockfile 2026-03-11 21:25:32 +01:00
030010a66f refactor(home): organize home manager modules 2026-03-11 21:25:32 +01:00
16d14bcb1e feat: add 'yubikey' module to 'andromache' host 2026-03-11 21:25:32 +01:00
d47e0fd6da refactor: move 'sshfs' into 'ssh' module 2026-03-11 21:25:32 +01:00
78b31a187f refactor: remove redundant 'vimPlugins.vim-plug' package 2026-03-11 21:25:32 +01:00
56efbd8ab5 chore: add 'anki' module to 'work' host 2026-03-11 21:25:32 +01:00
bfe1f82943 chore: update lockfile 2026-03-11 21:25:32 +01:00
7033407c23 fix: add /etc/xdg to XDG_CONFIG_DIRS for GNOME session 2026-03-11 21:25:32 +01:00
dd7091b10a chore(git): add includeIf for nix-dev-shells
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:25:32 +01:00
388feede95 feat: add 'secrets' module to work host 2026-03-11 21:25:32 +01:00
99a20c9ac7 refactor: simplify apps.colmena 2026-03-11 21:25:32 +01:00
2883d6f4f3 feat: add golang module to work host 2026-03-11 21:25:32 +01:00
725d2fa9c4 chore: update lockfile 2026-03-11 21:25:32 +01:00
4939523735 fix: add wrapper util for home manager modules 2026-03-11 21:25:32 +01:00
bae21e1538 fix: remove pnpm bash config 2026-03-11 21:25:32 +01:00
1bf71bf066 fix: update 'work' host modules 2026-03-11 21:25:32 +01:00
d06e8d975e feat: add 'nodejs' module (and use on 'work' host) 2026-03-11 21:25:32 +01:00
9cbd0cc316 feat: set up 'opencode' on work host 2026-03-11 21:25:32 +01:00
0089087f52 feat: add 'vscode' module to work host 2026-03-11 21:25:32 +01:00
ed193de628 fix: add pdf support to pandoc module 2026-03-11 21:25:32 +01:00
565e4573ca fix: remove default packages 2026-03-11 21:25:32 +01:00
3be3997cf6 feat: set up 'tlp' for laptop mode on 'astyanax' 2026-03-11 21:25:32 +01:00
47302d98ed feat: add notifier plugin to opencode 2026-03-11 21:25:32 +01:00
52cf601f39 fix :resolve 'andromache' syntax error 2026-03-11 21:25:32 +01:00
0a2145f063 feat: set up 'storage' module 2026-03-11 21:25:32 +01:00
e48a8de02e fix: resolve nix build warnings 2026-03-11 21:25:32 +01:00
ce1ce79f83 chore: disable syncthing module 2026-03-11 21:25:32 +01:00
df33251ada fix: remove 'nix.settings' from 'hecuba' host 2026-03-11 21:25:32 +01:00
f9ea95f346 refactor: extract 'pandoc' module 2026-03-11 21:25:32 +01:00
27b6af253f docs: update readme 2026-03-11 21:25:32 +01:00
8ddf5bf850 feat: add basic 'gaming' module to 'andromache' 2026-03-11 21:25:32 +01:00
12710cd3d5 refactor: extract 'nvidia' module 2026-03-11 21:25:32 +01:00
4363b8c88f refactor: add home 'allowedUnfree' option 2026-03-11 21:25:32 +01:00
e031da34b8 refactor: remove unused 'colmena' input 2026-03-11 21:25:32 +01:00
72876ca9f7 fix: deny opencode access to nix secret paths 2026-03-11 21:25:32 +01:00
58d4bc6f13 fix: temporarily disable 'ly' on desktop 2026-03-11 21:25:32 +01:00
ff724c51bc feat: set up openscad lsp 2026-03-11 21:25:32 +01:00
53b56a096f fix: update 'ncspot' config 2026-03-11 21:25:32 +01:00
1160b48da7 chore: remove redundant 'update-vim' script 2026-03-11 21:25:32 +01:00
1a3ae09be3 chore: update lockfile 2026-03-11 21:25:32 +01:00
7d4129b02b fix: enable colortheme for firefox-based browsers 2026-03-11 21:25:32 +01:00
750237e4c4 fix: update 'sb-pomo' script to match 'pomo' script 2026-03-11 21:25:32 +01:00
414476baf2 docs: update readme 2026-03-11 21:25:32 +01:00
b04a1ee845 chore: remove unused vpn module 2026-03-11 21:25:32 +01:00
0b853ebf4b fix: add 'lib' as default module 2026-03-11 21:25:32 +01:00
22a5026f38 feat: add home manager audio module (pulsemixer) 2026-03-11 21:25:32 +01:00
4457e2bd6d fix: add 'lib' module to astyanax host 2026-03-11 21:25:32 +01:00
93a9f7fb52 fix: color niri workspaces in waybar 2026-03-11 21:25:32 +01:00
301355a082 chore: update lockfile 2026-03-11 21:25:32 +01:00
1af04c10df chore: remove 'phone' config (skip 'nix-on-droid' for now) 2026-03-11 21:25:32 +01:00
d205b4b129 feat: set up 'eetion-02' raspberry pi host 2026-03-11 21:25:32 +01:00
3be1b5c384 flake.lock: Update
Flake lock file updates:

• Updated input 'firefox-addons':
    'gitlab:rycee/nur-expressions/c7794d3f46304de5234008c31b5b28a9d5709184?dir=pkgs/firefox-addons&narHash=sha256-0iGDl/ct3rW%2Bh6%2BsLq4RZaze/U/aQo2L5sLLuyjuVTk%3D' (2026-02-04)
  → 'gitlab:rycee/nur-expressions/65d59f814068d04e532cad2773d281e4951acd95?dir=pkgs/firefox-addons&narHash=sha256-%2BFHN9EthS%2BkHxnMoSDZEiGLoxwiIuij6ltK3aTmlLMA%3D' (2026-02-07)
• Updated input 'home-manager':
    'github:nix-community/home-manager/04e5203db66417d548ae1ff188a9f591836dfaa7?narHash=sha256-R1WFtIvp38hS9x63dnijdJw1KyIiy30KGea6e6N7LHs%3D' (2026-02-05)
  → 'github:nix-community/home-manager/6cee0821577643e0b34e2c5d9a90d0b1b5cdca70?narHash=sha256-cyxgVsNfHnJ4Zn6G1EOzfTXbjTy7Ds9zMOsZaX7VZWs%3D' (2026-02-07)
• Updated input 'nvim':
    'path:./dots/.config/nvim'
  → 'path:./dots/.config/nvim'
2026-03-11 21:25:32 +01:00
7493af6218 feat: add (but disable for now) uptime kuma module for 'hecuba' 2026-03-11 21:25:32 +01:00
b5776e547c refactor: resolve warnings/errors in checks 2026-03-11 21:25:32 +01:00
ff4e9ee337 fix: simplify syncthing module 2026-03-11 21:25:32 +01:00
c4ea029874 feat: set up 'stylix' 2026-03-11 21:25:32 +01:00
a7972e7211 test: try taskwarrior hooks to track slots 2026-03-11 21:25:32 +01:00
a93f576142 fix: make 'colmena' available 2026-03-11 21:25:32 +01:00
529d243565 test: see if this fixes auto upgrades 2026-03-11 21:25:32 +01:00
239456efbc feat: set up 'stylix' 2026-03-11 21:25:32 +01:00
d6b2ce04ef feat: colorize 'kubectl' output 2026-03-11 21:25:32 +01:00
f04730d4ff chore: gitignore '.pre-commit-config.yaml' 2026-03-11 21:25:32 +01:00
e87f85710d feat(bluetooth): add 'mpris-proxy' service 2026-03-11 21:25:32 +01:00
4840108bb0 fix: improve 'ai-tools' module (host-specific options) 2026-03-11 21:25:32 +01:00
254b6fa48f chore: disable 'm_taskwarrior_d.nvim' 2026-03-11 21:25:32 +01:00
b3247589e0 refactor(nixGL): extract 'nixGL' wrapper 2026-03-11 21:25:32 +01:00
2c36290054 feat: add 'bruno' module 2026-03-11 21:25:32 +01:00
55f2be9dbe chore: remove redundant backup files after nixification 2026-03-11 21:25:32 +01:00
7b435f09b3 feat: add 'bak' script 2026-03-11 21:25:32 +01:00
5ce228aee7 chore: update lockfile 2026-03-11 21:25:32 +01:00
f644fcbd5f fix: add 'ai-tools' module to 'andromache' 2026-03-11 21:25:32 +01:00
2207666a34 feat: set up git hooks 2026-03-11 21:25:32 +01:00
f3858f4418 fix: add ssh keys to agent for all hosts 2026-03-11 21:25:32 +01:00
554accb4aa fix: resolve proxmark firmware flashing issues 2026-03-11 21:25:32 +01:00
7155c9d126 fix: set up ipv4 forwarding 2026-03-11 21:25:32 +01:00
e16b55d155 feat: add 'brightnessctl' to niri desktop 2026-03-11 21:25:32 +01:00
8bd73165d4 flake.lock: Update
Flake lock file updates:

• Updated input 'firefox-addons':
    'gitlab:rycee/nur-expressions/4f827ff035c6ddc58d04c45abe5b777d356b926a?dir=pkgs/firefox-addons&narHash=sha256-9Sqq/hxq8ZDLRSzu%2Bedn0OfWG%2BFAPWFpwMKaJobeLec%3D' (2026-02-03)
  → 'gitlab:rycee/nur-expressions/c7794d3f46304de5234008c31b5b28a9d5709184?dir=pkgs/firefox-addons&narHash=sha256-0iGDl/ct3rW%2Bh6%2BsLq4RZaze/U/aQo2L5sLLuyjuVTk%3D' (2026-02-04)
• Updated input 'home-manager':
    'github:nix-community/home-manager/984708c34d3495a518e6ab6b8633469bbca2f77a?narHash=sha256-gj1yP3spUb1vGtaF5qPhshd2j0cg4xf51pklDsIm19Q%3D' (2026-02-01)
  → 'github:nix-community/home-manager/04e5203db66417d548ae1ff188a9f591836dfaa7?narHash=sha256-R1WFtIvp38hS9x63dnijdJw1KyIiy30KGea6e6N7LHs%3D' (2026-02-05)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/cb369ef2efd432b3cdf8622b0ffc0a97a02f3137?narHash=sha256-VKS4ZLNx4PNrABoB0L8KUpc1fE7CLpQXQs985tGfaCU%3D' (2026-02-02)
  → 'github:nixos/nixpkgs/00c21e4c93d963c50d4c0c89bfa84ed6e0694df2?narHash=sha256-AYqlWrX09%2BHvGs8zM6ebZ1pwUqjkfpnv8mewYwAo%2BiM%3D' (2026-02-04)
• Updated input 'nvim':
    'path:./dots/.config/nvim'
  → 'path:./dots/.config/nvim'
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/f990b0a334e96d3ef9ca09d4bd92778b42fd84f9?narHash=sha256-NUVGVtYBTC96WhPh4Y3SVM7vf0o1z5W4uqRBn9v1pfo%3D' (2026-02-03)
  → 'github:Mic92/sops-nix/17eea6f3816ba6568b8c81db8a4e6ca438b30b7c?narHash=sha256-ktjWTq%2BD5MTXQcL9N6cDZXUf9kX8JBLLBLT0ZyOTSYY%3D' (2026-02-03)
2026-03-11 21:25:32 +01:00
fa369973b7 feat: add helm plugins declaratively 2026-03-11 21:25:32 +01:00
ff667438a0 feat: set up 'music' module 2026-03-11 21:25:32 +01:00
ad2675829a refactor: simplify keyboard module 2026-03-11 21:25:32 +01:00
2ca4e72ad7 feat: add 'direnv' module 2026-03-11 21:25:32 +01:00
8977ed2212 feat: add nfc module (and use it on 'astyanax') 2026-03-11 21:25:32 +01:00
648c5b1dde fix: remove wlsunset spawn (replaced by gammastep service) 2026-03-11 21:25:32 +01:00
cba482d26d fix: remove duplicate waybar spawn in niri config (already managed by systemd) 2026-03-11 21:25:32 +01:00
58df524ac5 chore: update lockfile
Flake lock file updates:

• Updated input 'nvim':
    'path:./dots/.config/nvim'
  → 'path:./dots/.config/nvim'
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/1e89149dcfc229e7e2ae24a8030f124a31e4f24f?narHash=sha256-twBMKGQvaztZQxFxbZnkg7y/50BW9yjtCBWwdjtOZew%3D' (2026-02-01)
  → 'github:Mic92/sops-nix/f990b0a334e96d3ef9ca09d4bd92778b42fd84f9?narHash=sha256-NUVGVtYBTC96WhPh4Y3SVM7vf0o1z5W4uqRBn9v1pfo%3D' (2026-02-03)
2026-03-11 21:25:32 +01:00
76f4f2278e feat: mute 'astyanax' speakers when disconnecting AC 2026-03-11 21:25:32 +01:00
09909cbe42 fix: integrate keepassxc browser on all firefox-based browsers 2026-03-11 21:25:32 +01:00
dd7bc3193d feat: set up restic backups for 'andromache' and 'astyanax' 2026-03-11 21:25:32 +01:00
381f29cbea feat: set up syncthing (with e-reader) 2026-03-11 21:25:32 +01:00
8bfc6cd698 feat: set up 'paperless-ngx' (behind nginx reverse proxy) 2026-03-11 21:25:32 +01:00
6012da3ceb fix: smarten 'buildOnTarget' by using tags 2026-03-11 21:25:32 +01:00
35d495e872 fix: add python dependency to 'taskwarrior' home module 2026-03-11 21:25:32 +01:00
f4be58c648 fix: enable 'eetion' firewall 2026-03-11 21:25:32 +01:00
17ecac6524 fix: allow 'astyanax' to cross-compile to ARM (e.g. for eetion) 2026-03-11 21:25:32 +01:00
2b9dc9b7da fix: add public hostname to ssh config and refactor 2026-03-11 21:25:32 +01:00
da814d8d56 feat: host 'ActualBudget' on 'eetion' host 2026-03-11 21:25:32 +01:00
ecf481893c fix(colmena): add hostname to 'hecuba' host 2026-03-11 21:25:32 +01:00
9091d55af2 feat: add 'k8s' home module 2026-03-11 21:25:32 +01:00
23d3c5c83a feat: add 'docker' home module to 'work' host 2026-03-11 21:25:32 +01:00
60cf0651dc fix: add 'dconf2nix' package to 'dconf' module 2026-03-11 21:25:32 +01:00
8054b6f1e0 refactor: clean up packages 2026-03-11 21:25:32 +01:00
7f8d95c7c4 refactor: clean up 'flake.nix' and 'deploy/colmena.nix' 2026-03-11 21:25:32 +01:00
58642c9e15 fix(ssh): harden ARM SD installer image SSH 2026-03-11 21:25:32 +01:00
d58c4fee0d feat(host): add 'eetion' host (as a test for Orange Pi Zero2 H616) 2026-03-11 21:25:32 +01:00
159bc5c6a5 fix(deploy): add colmena to 'builder' hosts 2026-03-11 21:25:32 +01:00
6409b5425d refactor: move disko module out of 'common' module 2026-03-11 21:25:32 +01:00
c877e48e0a fix: use cross-compilation from x86 to ARM for SD card image 2026-03-11 21:25:32 +01:00
d04a6ed67e feat: add SD card image for ARM 2026-03-11 21:25:32 +01:00
5b43fde4ce feat(phone): set up 'nix-on-droid' 2026-03-11 21:25:32 +01:00
889440aef8 fix: only use 'nvim' flake as home manager module 2026-03-11 21:25:32 +01:00
e40d5b02f7 feat: add 'taskopen' to 'taskwarrior' module 2026-03-11 21:25:32 +01:00
ab87e785b6 feat: add 'comms' module 2026-03-11 21:25:32 +01:00
9cfe4d3c43 chore: temporarily disable wireguard VPN module 2026-03-11 21:25:32 +01:00
d14a33378f feat: add CLI tools to git module 2026-03-11 21:25:32 +01:00
6ef5f761d5 feat: add 'azure' cloud option (and generalized module) 2026-03-11 21:25:32 +01:00
d7f895d084 fix: update 'ai-tools' module and add to 'astyanax' host 2026-03-11 21:25:32 +01:00
583c72f6bd feat: add 'ai-tools' home module 2026-03-11 21:25:32 +01:00
79a39ee163 chore: update nvim flake dependencies 2026-03-11 21:25:32 +01:00
201db9d842 chore: update flake lockfiles 2026-03-11 21:25:32 +01:00
fc3a7dc402 fix: declare contents of 'setup-gnome' 2026-03-11 21:25:32 +01:00
1b51954bbd refactor(statix): resolve 'statix check' issues 2026-03-11 21:25:32 +01:00
cec4c12dc2 chore: update lockfile 2026-03-11 21:25:32 +01:00
c8f612e7a3 fix(nixd): properly configure 'nixd' nvim lsp 2026-03-11 21:25:32 +01:00
57121926d2 feat: add 'gammastep' to niri deskopt 2026-03-11 21:25:32 +01:00
e16bffcb07 feat: add '3d' and 'photography' modules to andromache 2026-03-11 21:25:32 +01:00
612c024965 fix: update hardware config 2026-03-11 21:25:32 +01:00
46181a340a chore: update lockfile 2026-03-11 21:25:32 +01:00
459c408bd6 refactor: migrate vim.cmd to lua API in init.lua 2026-03-11 21:25:32 +01:00
c068a44761 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-03-11 21:25:32 +01:00
aef49d9f4d refactor: remove duplicate 'paq-setup' require 2026-03-11 21:25:32 +01:00
a9f98f6927 chore(nvim): remove redundant unused config 2026-03-11 21:25:32 +01:00
4f7c4ccc0b fix(vim.keymap): resolve duplicate 'fzf' keymap 2026-03-11 21:25:32 +01:00
a84fbe2f59 fix(tmux): update tmux config 2026-03-11 21:25:32 +01:00
145351a30d refactor: deduplicate firefox/librewolf config 2026-03-11 21:25:32 +01:00
50c8e8be50 fix: use 'nixGL' for kitty when available 2026-03-11 21:25:32 +01:00
1eecdb8103 feat: add 'tmux' to 'shell' module 2026-03-11 21:25:32 +01:00
bf40f85b39 refactor: extract 'dotsPath' for 'dots' path 2026-03-11 21:25:32 +01:00
6b1b09f9a6 refactor: centralize kitty config 2026-03-11 21:25:32 +01:00
c25d42759c fix: remove 'edit_editor_config' alias 2026-03-11 21:25:32 +01:00
30fb73fec0 refactor: modularize 'nvim' for home manager hosts 2026-03-11 21:25:32 +01:00
c0885dc6ca feat: set up colmena with hetzner stuff 2026-03-11 21:25:32 +01:00
934cbff81d feat: configure auto suspend 2026-03-11 21:25:32 +01:00
8e8250ed56 feat: set up opencode (with automated API key) 2026-03-11 21:25:32 +01:00
03eac376d2 feat: add 'hcloud' module 2026-03-11 21:25:32 +01:00
7181356f5e chore: update Nix 'work' host 2026-03-11 21:25:32 +01:00
7fcd6eac8e chore: update lockfile 2026-03-11 21:25:32 +01:00
f7b4aa257f refactor: modularize 'nvim' for home manager hosts 2026-03-11 21:25:32 +01:00
254b3d255f feat: use shell module on work host 2026-03-11 21:25:32 +01:00
5ffb87f458 feat: modularize (and extend) kitty config 2026-03-11 21:25:32 +01:00
5368461675 feat: add 'hcloud' module 2026-03-11 21:25:32 +01:00
abe101d58e fix: add 'hetzner' module 2026-03-11 21:25:32 +01:00
1137705b20 chore: update lockfile 2026-03-11 21:25:32 +01:00
bda86e86ea feat: automate optimising store, garbage collection and upgrades 2026-03-11 21:25:32 +01:00
628681bc58 refactor(nixfmt): format 2026-03-11 21:25:32 +01:00
33033aa6e7 chore: add 'andromache' ssh public keys 2026-03-11 21:25:32 +01:00
7334018e6f refactor: simplify hosts files 2026-03-11 21:25:32 +01:00
f74803cd88 fix: remove xdg config 2026-03-11 21:25:32 +01:00
d0ee271e7b feat: replace 'sddm' with 'ly' 2026-03-11 21:25:32 +01:00
66f36cf71c feat: automate SSH config ('known_hosts', 'authorized_keys' ...) 2026-03-11 21:25:32 +01:00
fbdcf51e6c chore(nixfmt): format 2026-03-11 21:25:32 +01:00
c71e232fe7 fix: merge 'astyanax' services configuration 2026-03-11 21:25:32 +01:00
aed1aa2ad9 fix: disable 'throttled' service 2026-03-11 21:25:31 +01:00
6a0538c8b8 fix: improve niri desktop 2026-03-11 21:25:31 +01:00
1fcbc2fd83 fix: add anki to 'astyanax' host 2026-03-11 21:25:31 +01:00
6a0fa7a02d fix: move kitty tab bar to bottom 2026-03-11 21:25:31 +01:00
07223be230 fix: update font configuration 2026-03-11 21:25:31 +01:00
de944a017c chore: update lockfile 2026-03-11 21:25:31 +01:00
26e9a0e0c9 fix: disable 'nixos-hardware' module for astyanax (caused boot to hang on 'loading module i915') 2026-03-11 21:25:31 +01:00
c2f9a321a2 feat(home): add shell module 2026-03-11 21:25:31 +01:00
bad0979caf fix(anki): make sops optional for standalone home-manager 2026-03-11 21:25:31 +01:00
85628b1924 feat(home): migrate bash config to shell module 2026-03-11 21:25:31 +01:00
aae87a78ad feat(nixos): pass inputs to home-manager via extraSpecialArgs 2026-03-11 21:25:31 +01:00
81905c0287 chore(git): add .claude/ to gitignore 2026-03-11 21:25:31 +01:00
c26ce95e57 fix: make taskwarrior available on both NixOS and standalone home-manager 2026-03-11 21:25:31 +01:00
b7601bf665 chore: update NixOS 2026-03-11 21:25:31 +01:00
a2d90bbc00 fix: remove descriptions from 'browser' module 2026-03-11 21:25:31 +01:00
2fef58e066 fix: resolve nvim treesitter errors 2026-03-11 21:25:31 +01:00
bf4d5229a9 fix: add 'stylelint' to neovim flake 2026-03-11 21:25:31 +01:00
b13bba26d5 refactor(browser): create single browser module 2026-03-11 21:25:31 +01:00
e01f37321e chore: update Nix 'work' host 2026-03-11 21:25:31 +01:00
91b8358331 chore: update lockfile 2026-03-11 21:25:31 +01:00
ffe0d2a3ec feat(nvim): add typescript-language-server to runtime dependencies 2026-03-11 21:25:31 +01:00
613cd70f49 fix(nvim): ensure codecompanion config structure exists before mcphub extension loads 2026-03-11 21:25:31 +01:00
e7f675cea4 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>
2026-03-11 21:25:22 +01:00
3c56092131 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>
2026-03-11 21:25:22 +01:00
bcd78baf09 feat: set up 'claude-code.nvim' plugin 2026-03-11 21:25:22 +01:00
2d3b8070d7 chore: add TODO for unique 'networking.hostId' 2026-03-11 21:25:22 +01:00
bbe528ebce 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>
2026-03-11 21:25:22 +01:00
06fe355250 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>
2026-03-11 21:25:22 +01:00
767cc4c512 fix: format rust using 'rustfmt' 2026-03-11 21:25:22 +01:00
7dab619256 refactor: decouple 'andromache' home config from 'astyanax' 2026-03-11 21:25:22 +01:00
926a2def67 chore: update neovim flake (and main flake) 2026-03-11 21:25:22 +01:00
aa70174040 refactor: import shikane 'desktop/niri' instead of directly 2026-03-11 21:25:22 +01:00
6600b2325d feat: add plain 'mako' service for notifications 2026-03-11 21:25:22 +01:00
447ccd705e feat: declare anki config 2026-03-11 21:25:22 +01:00
6b56dfa595 fix: migrate 'r5rs' script to neovim 2026-03-11 21:25:22 +01:00
5fda65e0a5 fix: ignore directories that contain '.nobackup' in 'save-home' 2026-03-11 21:25:22 +01:00
de818cf4e8 chore: format using 'black' 2026-03-11 21:25:22 +01:00
b786abbed6 chore: clean up 'astyanax' packages 2026-03-11 21:25:22 +01:00
0de28843a3 feat: add 'fail2ban' to 'hecuba' host 2026-03-11 21:25:22 +01:00
a06a87802b refactor: use environment variable for zettelkasten path 2026-03-11 21:25:22 +01:00
54338e7498 feat: add 'rustfmt' for rust formatting 2026-03-11 21:25:22 +01:00
b15ec5d6ae chore: relock flake 2026-03-11 21:25:22 +01:00
58787c5917 feat: add 'figet.nvim' to 'nvim' flake 2026-03-11 21:25:22 +01:00
ec7975936f test(nvim): try out 'm_taskwarrior_d.nvim' plugin 2026-03-11 21:25:22 +01:00
3b87ac54a6 fix: resolve 'nix flake check' errors 2026-03-11 21:25:22 +01:00
76b01e120c feat: use 'rustaceanvim' instead for rust development 2026-03-11 21:25:22 +01:00
675692e3f3 feat: add 'wl-clipboard' to niri desktop 2026-03-11 21:25:22 +01:00
6fa4b9d72e fix: work around throttled error 2026-03-11 21:25:22 +01:00
542ebb3ee3 fix: declare graphics config for 'astyanax' host 2026-03-11 21:25:22 +01:00
4eee3de44a fix: resolve treesitter errors on NixOS 2026-03-11 21:25:22 +01:00
32a65d912a chore: ignore breaking changes warning for 'codecompanion.nvim' 2026-03-11 21:25:22 +01:00
d755464eb0 enable 'shikane' on 'astyanax' (and add 'wdisplays') 2026-03-11 21:25:22 +01:00
da462b6717 feat(nvim): set up rust lsp config 2026-03-11 21:25:22 +01:00
5c40f08146 refactor: enable firewall explicitely for 'hecuba' host 2026-03-11 21:25:22 +01:00
401b25b9a0 fix: remove common '.nix' suffix 2026-03-11 21:25:22 +01:00
3ed5ff019d fix: update waybar to match polybar config (for the most part) 2026-03-11 21:25:22 +01:00
62e62b8e20 refactor: move 'wlsunset' package into home manager module 2026-03-11 21:25:22 +01:00
Hektor Misplon
9e9c2b5349 chore: update 'nvim' flake 2026-03-11 21:25:22 +01:00
Hektor Misplon
28e24c284e fix: don't autoinstall treesitter grammars when using 'nixCats' 2026-03-11 21:25:22 +01:00
709f754697 fix: declare 'fuzzel' config and add it to 'niri' desktop 2026-03-11 21:25:22 +01:00
17627f5074 feat: track (currently unused) k3s module 2026-03-11 21:25:22 +01:00
2e2e52aa78 refactor: use 'default.nix' for all modules 2026-03-11 21:25:22 +01:00
591bd25a3d fix: declare 'waybar' config and add it to 'niri' desktop 2026-03-11 21:25:22 +01:00
03793989a5 fix: declare niri config 2026-03-11 21:25:22 +01:00
e69024f921 fix: try 'writeShellApplication' for 'astyanax' WOL script 2026-03-11 21:25:22 +01:00
f664d4b46a fix: declare 'andromache' 'eno1' interface MAC address 2026-03-11 21:25:22 +01:00
84d9ac50a6 feat: add 'hecuba' host config 2026-03-11 21:25:22 +01:00
7ccbbb418b fix: further harden 'hardened-openssh' module 2026-03-11 21:25:22 +01:00
3c294d2194 fix: replace 'gnome' desktop with 'niri' 2026-03-11 21:25:22 +01:00
82a4f44a19 fix: declare KeePassXC browser integration 2026-03-11 21:25:22 +01:00
6677b1e14b chore(pkgs): add 'signal-desktop' package 2026-03-11 21:25:22 +01:00
8315866dd7 fix: disable kitty tab shortcut for now 2026-03-11 21:25:22 +01:00
b4cac89e95 update bluetooth config 2026-03-11 21:25:22 +01:00
54bdee7e8f refactor: move bootloader into 'modules/boot' 2026-03-11 21:25:22 +01:00
11381a1ff9 refactor: move 'disko' modules into 'modules/disko' 2026-03-11 21:25:22 +01:00
e97dcbfcc5 resolve NixOS build warnings 2026-03-11 21:25:22 +01:00
243 changed files with 5351 additions and 1913 deletions

1
.envrc Normal file
View File

@@ -0,0 +1 @@
use flake

7
.gitignore vendored
View File

@@ -1,3 +1,7 @@
#
.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
@@ -5,4 +9,5 @@ result-*
nixos-efi-vars.fd nixos-efi-vars.fd
home/hosts/work/packages.local.nix .direnv/
.pre-commit-config.yaml

7
.mcp.json Normal file
View File

@@ -0,0 +1,7 @@
{
"mcpServers": {
"nixos": {
"command": "mcp-nixos"
}
}
}

View File

@@ -1,15 +1,27 @@
# NixOS flake # ❄️ NixOS flake
## Set up virtual machine ([`disko`](https://github.com/nix-community/disko/blob/master/docs/interactive-vm.md)) ## hosts
1. Build the virtual machine ### NixOS
```
nixos-rebuild switch --flake .#<hostname>
```
### home manager
```
home-manager switch --flake .#work
```
### virtual machines
``` ```
nix build -L '.#nixosConfigurations.vm.config.system.build.vmWithDisko' nix build -L '.#nixosConfigurations.vm.config.system.build.vmWithDisko'
```
2. Run the virtual machine
```
./result/bin/disko-vm ./result/bin/disko-vm
``` ```
## docs
* [deploy using colmena](./deploy/README.md)
* [SD installer images](./images/README.md)

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)

34
deploy/colmena.nix Normal file
View File

@@ -0,0 +1,34 @@
{
self,
inputs,
}:
let
inherit (inputs.nixpkgs) lib;
utils = import ../utils { inherit lib; };
hostDirNames = utils.dirNames ../hosts;
mkNode = hostname: meta: {
imports = [ ../hosts/${hostname} ];
deployment = {
inherit (meta.deployment) targetHost targetUser tags;
buildOnTarget = builtins.any (t: t != "local" && t != "arm") meta.deployment.tags;
};
};
nodes = lib.genAttrs hostDirNames (hostname: mkNode hostname (utils.hostMeta ../hosts/${hostname}));
in
inputs.colmena.lib.makeHive (
{
meta = {
nixpkgs = import inputs.nixpkgs { localSystem = "x86_64-linux"; };
specialArgs = {
inherit inputs;
outputs = self;
dotsPath = ../dots;
myUtils = utils;
};
};
}
// nodes
)

View File

@@ -27,8 +27,6 @@ alias ipa="ip -brief address"
alias ipl="ip -brief link" alias ipl="ip -brief link"
alias ipr="ip route" alias ipr="ip route"
alias clip="xclip -sel clip"
alias df="df -kTh" alias df="df -kTh"
alias fzfpac="pacman -Slq | fzf -m --preview 'pacman -Si {1}' | xargs -ro sudo pacman -S" alias fzfpac="pacman -Slq | fzf -m --preview 'pacman -Si {1}' | xargs -ro sudo pacman -S"
alias path='echo -e ${PATH//:/\\n}' # Pretty print path variables alias path='echo -e ${PATH//:/\\n}' # Pretty print path variables

View File

@@ -103,13 +103,6 @@ if [[ -z "${SSH_CONNECTION}" ]]; then
fi fi
# }}} # }}}
# pnpm
export PNPM_HOME="/home/h/.local/share/pnpm"
case ":$PATH:" in
*":$PNPM_HOME:"*) ;;
*) export PATH="$PNPM_HOME:$PATH" ;;
esac
# pnpm end
# Codi # Codi
# Usage: codi [filetype] [filename] # Usage: codi [filetype] [filename]

View File

@@ -4,16 +4,4 @@
# Set NeoVim as default editor # Set NeoVim as default editor
export EDITOR=nvim export EDITOR=nvim
export SUDO_EDITOR="$EDITOR" export SUDO_EDITOR="$EDITOR"
export SYSTEMD_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
}

32
dots/.bin/bak Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# back up a file by copying it to a new file with a .bak extension
# reference: https://askubuntu.com/questions/962489/is-there-any-way-to-create-backup-copy-of-a-file-without-type-its-name-twice
usage() {
echo "Usage: bak [-t|--timestamp] <file to back up>"
exit 1
}
timestamp=false
while [[ $# -gt 0 ]]; do
case $1 in
-t|--timestamp)
timestamp=true
shift
;;
*)
break
;;
esac
done
[ $# -eq 1 ] || usage
if $timestamp; then
date="$(date +%Y-%m-%d_%H-%M-%S)"
cp -vpn "$1"{,."$date".bak}
else
cp -vpn "$1"{,.bak}
fi

View File

@@ -1,221 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
readonly ALLOWED_MAIN_BRANCHES=("main" "master" "develop")
readonly BRANCH_TYPES=(
"feat For new features"
"hotfix For urgent fixes"
"fix For fixes"
"release For preparing releases"
"chore For non-code tasks"
)
error() {
echo "Error: $1" >&2
exit 1
}
warn() {
echo "Warning: $1" >&2
}
check_dependencies() {
local missing=()
for cmd in git fzf; do
if ! command -v "$cmd" &> /dev/null; then
missing+=("$cmd")
fi
done
if [[ ${#missing[@]} -gt 0 ]]; then
error "Missing required commands: ${missing[*]}"
fi
}
check_git_repo() {
if ! git rev-parse --git-dir &> /dev/null; then
error "Not in a git repository"
fi
}
check_current_branch() {
local current_branch
current_branch=$(git branch --show-current)
local is_main_branch=false
for branch in "${ALLOWED_MAIN_BRANCHES[@]}"; do
if [[ "$current_branch" == "$branch" ]]; then
is_main_branch=true
break
fi
done
if [[ "$is_main_branch" == false ]]; then
warn "Not branching from a main branch (current: $current_branch)"
read -rp "Continue anyway? [y/N] " response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
exit 0
fi
fi
}
get_user_email() {
local email
email=$(git config --get user.email 2>/dev/null)
if [[ -z "$email" ]]; then
error "Git user email not configured. Run: git config user.email 'your@email.com'"
fi
echo "$email"
}
select_branch_type() {
local selected
selected=$(printf '%s\n' "${BRANCH_TYPES[@]}" | \
fzf --prompt="Select branch type: " \
--height=40% \
--border \
--info=inline) || error "Branch type selection cancelled"
echo "${selected%% *}"
}
select_jira_ticket() {
local email=$1
if ! command -v jira &> /dev/null; then
warn "Jira CLI not found. Proceeding without ticket ID."
return 0
fi
echo "Fetching Jira tickets for $email..." >&2
local jira_data
jira_data=$(jira issue list --assignee="$email" --order-by=priority --plain --no-headers 2>/dev/null) || {
warn "Could not fetch Jira tickets. Proceeding without ticket ID."
return 0
}
if [[ -z "$jira_data" ]]; then
warn "No Jira tickets found. Proceeding without ticket ID."
return 0
fi
echo "$jira_data" >&2
echo "" >&2
local formatted_tickets
formatted_tickets=$(echo "$jira_data" | awk '{
ticket_id = $2
$1 = $2 = ""
description = $0
gsub(/^[ \t]+/, "", description)
if (length(description) > 60) {
description = substr(description, 1, 57) "..."
}
print ticket_id " - " description
}')
if [[ -z "$formatted_tickets" ]]; then
warn "No tickets to display. Proceeding without ticket ID."
return 0
fi
local selected_ticket
selected_ticket=$(echo -e "SKIP - Create branch without ticket ID\n$formatted_tickets" | \
fzf --prompt="Select Jira ticket (or skip): " \
--height=40% \
--border \
--info=inline) || error "Ticket selection cancelled"
if [[ "$selected_ticket" != "SKIP"* ]]; then
echo "${selected_ticket%% -*}"
fi
}
get_branch_description() {
local ticket_id=$1
local editor="${EDITOR:-vi}"
local tmpfile
tmpfile=$(mktemp)
trap "rm -f '$tmpfile'" EXIT
if [[ -n "$ticket_id" ]]; then
cat > "$tmpfile" << EOF
# Selected ticket: $ticket_id
# Enter your branch description below in kebab-case (e.g., my-description):
# The ticket ID will be automatically included in the branch name.
# Lines starting with # will be ignored.
EOF
else
cat > "$tmpfile" << 'EOF'
# Enter your branch description below in kebab-case (e.g., my-description):
# Lines starting with # will be ignored.
EOF
fi
"$editor" "$tmpfile" < /dev/tty > /dev/tty
local desc
desc=$(grep -v '^#' "$tmpfile" | tr -d '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
echo "$desc"
}
validate_description() {
local desc=$1
if [[ -z "$desc" ]]; then
error "No description provided"
fi
if [[ ! "$desc" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then
error "Invalid branch description format.\nUse lowercase letters, numbers, and hyphens only.\nNo trailing or consecutive hyphens allowed.\nExample: my-feature-description"
fi
}
create_branch() {
local type=$1
local ticket_id=$2
local desc=$3
local branch
if [[ -n "$ticket_id" ]]; then
branch="$type/$ticket_id-$desc"
else
branch="$type/$desc"
fi
if git show-ref --verify --quiet "refs/heads/$branch"; then
error "Branch '$branch' already exists"
fi
echo ""
echo "Creating branch: $branch"
git checkout -b "$branch"
}
main() {
check_dependencies
check_git_repo
check_current_branch
local email
email=$(get_user_email)
local type
type=$(select_branch_type)
echo "About to call select_jira_ticket" >&2
local ticket_id=""
ticket_id=$(select_jira_ticket "$email")
local desc
desc=$(get_branch_description "$ticket_id")
validate_description "$desc"
create_branch "$type" "$ticket_id" "$desc"
}
main "$@"

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

@@ -1,25 +0,0 @@
#!/usr/bin/env bash
# Back up my $HOME folder to OneDrive using `restic`.
#
# Adds extra flags needed for using `rclone` with sharepoint WebDav I.e. add
# `--ignore-size --ignore-checksum --update` to the default `rclone.args`.
#
# Select directory in repo using -r rclone:<repo>:<directory>
#
# Runs `backup` command on $HOME and ignore what is listed in `.resticexclude`
#
# ```/etc/restic-env
# export B2_ACCOUNT_ID=
# export B2_ACCOUNT_KEY=
# ```
#
# `restic -r b2:desktop-arch init`
source /etc/restic-env
restic -r "$RESTIC_REPOSITORY:$HOSTNAME" backup \
--tag "hektor" \
--one-file-system \
--files-from="$HOME/.resticinclude" \
--exclude-file="$HOME/.resticexclude" \
--verbose=3

View File

@@ -1,4 +0,0 @@
#!/usr/bin/env bash
cd "$ZK_PATH" || echo "No zettelkasten directory found"
git a . && git commit -m "Update" && git push

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env bash #!/usr/bin/env bash
[ -f "/tmp/pomo" ] && cat /tmp/pomo || echo "" [ -f "/home/h/.local/share/pomo" ] && cat /home/h/.local/share/pomo || echo ""

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,20 +0,0 @@
#!/bin/bash
if [ ! -d ~/.zk ]; then
echo "[zk] Setting up zettelkasten"
gh repo clone zk ~/.zk
else
echo "[zk] Zettelkasten already set up."
fi
read -p "Would you like open your zettelkasten? [y/N] " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
if [ -x "$(command -v zk)" ]; then
zk
else
echo "Error: 'zk' command not found or not executable"
exit 1
fi
fi

View File

@@ -1,5 +0,0 @@
#!/usr/bin/env bash
# Tiny Vim update helper
nvim +PlugUpgrade +PlugUpdate +CocUpdate

View File

@@ -1,33 +0,0 @@
#!/usr/bin/env bash
if [ "$TERM_PROGRAM" = tmux ]; then
cd ~/.zk && $EDITOR "$(cat ~/.zk/current-zettel.txt)"
else
echo 'Not in tmux'
echo 'Choose an option:'
echo '1. Open in tmux'
echo '2. Open in current terminal'
read -r -p 'Enter your choice: ' choice
case $choice in
1)
# Check if a tmux session is running with a window named zk
if tmux list-windows -F '#{window_name}' | grep -q zk; then
# Attach to the session containing the 'zk' window
session="$(tmux list-windows -F '#{window_name} #{session_name}' | grep zk | head -n 1 | awk '{ print $2 }')"
tmux attach -t "$session"
else
# Create session with a window named 'zk' and start nvim
tmux new-session -s zk -n zk -d
tmux send-keys -t zk:zk "cd ~/.zk && $EDITOR \"\$(cat ~/.zk/current-zettel.txt)\"" Enter
tmux attach -t zk
fi
;;
2)
cd ~/.zk && $EDITOR "$(cat ~/.zk/current-zettel.txt)"
;;
*)
echo 'Not opening Zettelkasten'
exit 1
;;
esac
fi

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
@@ -163,5 +163,4 @@ map cmd+q
#: }}} #: }}}
include ./themes/zenwritten_dark.conf
include ./nvim.conf include ./nvim.conf

View File

@@ -1,49 +0,0 @@
# This file is auto-generated by shipwright.nvim
# vim:ft=kitty
## name: zenwritten_dark
## author: Michael Chris Lopez
## license: MIT
## upstream: https://github.com/mcchrish/zenbones.nvim/raw/main/extras/kitty/zenwritten_dark.conf
## blurb: A zenbones variant with zero hue and saturation.
foreground #BBBBBB
background #191919
selection_foreground #BBBBBB
selection_background #404040
# Cursor colors
cursor #C9C9C9
cursor_text_color #191919
# URL underline color when hovering with mouse
# kitty window border colors
# OS Window titlebar colors
# Tab bar colors
active_tab_foreground #BBBBBB
active_tab_background #65435E
inactive_tab_foreground #BBBBBB
inactive_tab_background #303030
# Colors for marks (marked text in the terminal)
# The basic 16 colors
# black
color0 #191919
color8 #3D3839
# red
color1 #DE6E7C
color9 #E8838F
# green
color2 #819B69
color10 #8BAE68
# yellow
color3 #B77E64
color11 #D68C67
# blue
color4 #6099C0
color12 #61ABDA
# magenta
color5 #B279A7
color13 #CF86C1
# cyan
color6 #66A5AD
color14 #65B8C1
# white
color7 #BBBBBB
color15 #8E8E8E
# You can set the remaining 240 colors as color16 to color255.

View File

@@ -1,49 +0,0 @@
# This file is auto-generated by shipwright.nvim
# vim:ft=kitty
## name: zenwritten_light
## author: Michael Chris Lopez
## license: MIT
## upstream: https://github.com/mcchrish/zenbones.nvim/raw/main/extras/kitty/zenwritten_light.conf
## blurb: A zenbones variant with zero hue and saturation.
foreground #353535
background #EEEEEE
selection_foreground #353535
selection_background #D7D7D7
# Cursor colors
cursor #353535
cursor_text_color #EEEEEE
# URL underline color when hovering with mouse
# kitty window border colors
# OS Window titlebar colors
# Tab bar colors
active_tab_foreground #353535
active_tab_background #DEB9D6
inactive_tab_foreground #353535
inactive_tab_background #CFCFCF
# Colors for marks (marked text in the terminal)
# The basic 16 colors
# black
color0 #EEEEEE
color8 #C6C3C3
# red
color1 #A8334C
color9 #94253E
# green
color2 #4F6C31
color10 #3F5A22
# yellow
color3 #944927
color11 #803D1C
# blue
color4 #286486
color12 #1D5573
# magenta
color5 #88507D
color13 #7B3B70
# cyan
color6 #3B8992
color14 #2B747C
# white
color7 #353535
color15 #5C5C5C
# You can set the remaining 240 colors as color16 to color255.

View File

@@ -1,5 +1,6 @@
default_keybindings = false default_keybindings = false
flip_status_indicators = true flip_status_indicators = true
library_tabs = ["tracks", "albums", "artists", "playlists", "browse"] # remove podcasts tab
[keybindings] [keybindings]
"Enter" = "play" "Enter" = "play"
@@ -24,11 +25,10 @@ flip_status_indicators = true
"c" = "clear" "c" = "clear"
"=" = "volup 1" "=" = "volup 1"
"-" = "voldown 1" "-" = "voldown 1"
"/" = "focus search"
"Q" = "focus queue"
"L" = "focus library"
"1" = "focus queue" "1" = "focus queue"
"2" = "focus library" "2" = "focus search"
"3" = "focus library"
"4" = "focus cover"
"h" = "move left 1" "h" = "move left 1"
"j" = "move down 1" "j" = "move down 1"
"k" = "move up 1" "k" = "move up 1"
@@ -41,26 +41,5 @@ flip_status_indicators = true
"Y" = "share selected" "Y" = "share selected"
"U" = "update" "U" = "update"
[theme]
primary="#aaaaaa"
secondary="#555555"
background="1a1a1a"
title="#cccccc"
title_secondary="#aaaaaa"
playing="#ffffff"
playing_bg="1a1a1a"
playing_selected="#ffffff"
highlight="#cccccc"
highlight_bg="#333333"
error="#ffffff"
error_bg="#333333"
statusbar="#cccccc"
statusbar_bg="#1a1a1a"
statusbar_progress="#cccccc"
statusbar_progress_bg="#1a1a1a"
cmdline="#cccccc"
cmdline_bg="#1a1a1a"
search_match="#ffffff"
backend="pipe" backend="pipe"
notify="false" notify="false"

View File

@@ -1,3 +0,0 @@
username = 'hektor.misplon@gmail.com'
auth_type = 0
auth_data = 'KDEzMzc9PXRydTMpPzo='

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,23 @@
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 {}
cc_config.interactions.chat.variables = cc_config.interactions.chat.variables 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

@@ -0,0 +1,35 @@
local hydra_repl = "hydra-repl"
if not vim.fn.executable(hydra_repl) then
return
end
local function send(lines)
vim.system({ hydra_repl, table.concat(lines, "\n") })
end
local function get_paragraph(buf)
local start_ = vim.fn.search("^$", "bnW")
local end_ = vim.fn.search("^$", "nW") - 1
if end_ < vim.api.nvim_win_get_cursor(0)[1] then
end_ = vim.api.nvim_buf_line_count(buf)
end
return vim.api.nvim_buf_get_lines(buf, start_, end_, false)
end
local function get_selection(buf)
return vim.api.nvim_buf_get_lines(buf, vim.fn.line("'<") - 1, vim.fn.line("'>"), false)
end
vim.api.nvim_create_autocmd("FileType", {
pattern = "javascript",
callback = function(e)
if vim.fn.fnamemodify(vim.api.nvim_buf_get_name(e.buf), ":e") ~= "hydra" then
return
end
local buf = e.buf
vim.keymap.set("n", "<CR>", function() send(get_paragraph(buf)) end, { buffer = buf, desc = "hydra: send block" })
vim.keymap.set("v", "<CR>", function() send(get_selection(buf)) end, { buffer = buf, desc = "hydra: send selection" })
end,
})

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,10 +61,32 @@ 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',
},
},
},
},
openscad_ls = {},
pyright = {}, pyright = {},
-- tsserver = {},
svelte = { svelte = {
plugin = { plugin = {
svelte = { svelte = {
@@ -76,7 +95,6 @@ local servers = {
}, },
}, },
tailwindcss = {}, tailwindcss = {},
-- vtsls = {},
ts_ls = {}, ts_ls = {},
-- vtsls = { -- vtsls = {
-- maxTsServerMemory = 16384, -- maxTsServerMemory = 16384,

View File

@@ -1,23 +1,5 @@
local ls = require("luasnip") local ls = require("luasnip")
local s = ls.snippet
local sn = ls.snippet_node
local t = ls.text_node
local i = ls.insert_node
local f = ls.function_node
local c = ls.choice_node
local d = ls.dynamic_node
local r = ls.restore_node
local l = require("luasnip.extras").lambda
local rep = require("luasnip.extras").rep
local p = require("luasnip.extras").partial
local m = require("luasnip.extras").match
local n = require("luasnip.extras").nonempty
local dl = require("luasnip.extras").dynamic_lambda
local fmt = require("luasnip.extras.fmt").fmt
local fmta = require("luasnip.extras.fmt").fmta
local conds = require("luasnip.extras.expand_conditions")
ls.config.set_config({ ls.config.set_config({
history = true, history = true,
update_events = "TextChanged,TextChangedI", update_events = "TextChanged,TextChangedI",
@@ -27,287 +9,5 @@ ls.config.set_config({
store_selection_keys = "<Tab>", store_selection_keys = "<Tab>",
}) })
local function copy(args)
return args[1]
end
local function bash(_, _, command)
local file = io.popen(command, "r")
local res = {}
if file then
for line in file:lines() do
table.insert(res, line)
end
end
return res
end
local date_input = function(args, snip, old_state, date_format)
print(args, snip, old_state)
return sn(nil, i(1, os.date(date_format or "%Y-%m-%d")))
end
-- -- FIXME: EXAMPLE
-- ls.add_snippets("all", {
-- -- arg1: trigger `fn`,
-- -- arg2: nodes to insert into buffer on expansion.
-- s("fn", {
-- t("//Parameters: "), -- Text.
-- f(copy, 2), -- 1: function, 2: placeholders to copy text from
-- t({ "", "function " }), -- placeholder/insert.
-- i(1),
-- t("("), -- placeholder with initial text.
-- i(2, "int foo"), -- linebreak
-- t({ ") {", "\t" }), -- last placeholder, snippet exit point
-- i(0),
-- t({ "", "}" }),
-- }),
-- s("class", {
-- -- Choice: Switch between two different Nodes, first parameter is its position, second a list of nodes.
-- c(1, {
-- t("public "),
-- t("private "),
-- }),
-- t("class "),
-- i(2),
-- t(" "),
-- c(3, {
-- t("{"),
-- -- sn: Nested Snippet. Instead of a trigger, it has a position, just like insert-nodes. !!! These don't expect a 0-node!!!!
-- -- Inside Choices, Nodes don't need a position as the choice node is the one being jumped to.
-- sn(nil, {
-- t("extends "),
-- -- restoreNode: stores and restores nodes.
-- -- pass position, store-key and nodes.
-- r(1, "other_class", i(1)),
-- t(" {"),
-- }),
-- sn(nil, {
-- t("implements "),
-- -- no need to define the nodes for a given key a second time.
-- r(1, "other_class"),
-- t(" {"),
-- }),
-- }),
-- t({ "", "\t" }),
-- i(0),
-- t({ "", "}" }),
-- }),
-- -- Alternative printf-like notation for defining snippets. It uses format
-- -- string with placeholders similar to the ones used with Python's .format().
-- s(
-- "fmt1",
-- fmt("To {title} {} {}.", {
-- i(2, "Name"),
-- i(3, "Surname"),
-- title = c(1, { t("Mr."), t("Ms.") }),
-- })
-- ),
-- -- To escape delimiters use double them, e.g. `{}` -> `{{}}`.
-- -- Multi-line format strings by default have empty first/last line removed.
-- -- Indent common to all lines is also removed. Use the third `opts` argument
-- -- to control this behaviour.
-- s(
-- "fmt2",
-- fmt(
-- [[
-- foo({1}, {3}) {{
-- return {2} * {4}
-- }}
-- ]],
-- {
-- i(1, "x"),
-- rep(1),
-- i(2, "y"),
-- rep(2),
-- }
-- )
-- ),
-- -- Empty placeholders are numbered automatically starting from 1 or the last
-- -- value of a numbered placeholder. Named placeholders do not affect numbering.
-- s(
-- "fmt3",
-- fmt("{} {a} {} {1} {}", {
-- t("1"),
-- t("2"),
-- a = t("A"),
-- })
-- ),
-- -- The delimiters can be changed from the default `{}` to something else.
-- s("fmt4", fmt("foo() { return []; }", i(1, "x"), { delimiters = "[]" })),
-- -- `fmta` is a convenient wrapper that uses `<>` instead of `{}`.
-- s("fmt5", fmta("foo() { return <>; }", i(1, "x"))),
-- -- By default all args must be used. Use strict=false to disable the check
-- s(
-- "fmt6",
-- fmt("use {} only", { t("this"), t("not this") }, { strict = false })
-- ),
-- -- Use a dynamic_node to interpolate the output of a
-- -- function (see date_input above) into the initial
-- -- value of an insert_node.
-- s("novel", {
-- t("It was a dark and stormy night on "),
-- d(1, date_input, {}, { user_args = { "%A, %B %d of %Y" } }),
-- t(" and the clocks were striking thirteen."),
-- }),
-- -- Parsing snippets: First parameter: Snippet-Trigger, Second: Snippet body.
-- -- Placeholders are parsed into choices with 1. the placeholder text(as a snippet) and 2. an empty string.
-- -- This means they are not SELECTed like in other editors/Snippet engines.
-- ls.parser.parse_snippet(
-- "lspsyn",
-- "Wow! This ${1:Stuff} really ${2:works. ${3:Well, a bit.}}"
-- ),
-- -- When wordTrig is set to false, snippets may also expand inside other words.
-- ls.parser.parse_snippet(
-- { trig = "te", wordTrig = false },
-- "${1:cond} ? ${2:true} : ${3:false}"
-- ),
-- -- When regTrig is set, trig is treated like a pattern, this snippet will expand after any number.
-- ls.parser.parse_snippet({ trig = "%d", regTrig = true }, "A Number!!"),
-- -- Using the condition, it's possible to allow expansion only in specific cases.
-- s("cond", {
-- t("will only expand in c-style comments"),
-- }, {
-- condition = function(line_to_cursor, matched_trigger, captures)
-- -- optional whitespace followed by //
-- return line_to_cursor:match("%s*//")
-- end,
-- }),
-- -- there's some built-in conditions in "luasnip.extras.expand_conditions".
-- s("cond2", {
-- t("will only expand at the beginning of the line"),
-- }, {
-- condition = conds.line_begin,
-- }),
-- -- The last entry of args passed to the user-function is the surrounding snippet.
-- s(
-- { trig = "a%d", regTrig = true },
-- f(function(_, snip)
-- return "Triggered with " .. snip.trigger .. "."
-- end, {})
-- ),
-- -- It's possible to use capture-groups inside regex-triggers.
-- s(
-- { trig = "b(%d)", regTrig = true },
-- f(function(_, snip)
-- return "Captured Text: " .. snip.captures[1] .. "."
-- end, {})
-- ),
-- s({ trig = "c(%d+)", regTrig = true }, {
-- t("will only expand for even numbers"),
-- }, {
-- condition = function(line_to_cursor, matched_trigger, captures)
-- return tonumber(captures[1]) % 2 == 0
-- end,
-- }),
-- -- Use a function to execute any shell command and print its text.
-- s("bash", f(bash, {}, "ls")),
-- -- Short version for applying String transformations using function nodes.
-- s("transform", {
-- i(1, "initial text"),
-- t({ "", "" }),
-- -- lambda nodes accept an l._1,2,3,4,5, which in turn accept any string transformations.
-- -- This list will be applied in order to the first node given in the second argument.
-- l(l._1:match("[^i]*$"):gsub("i", "o"):gsub(" ", "_"):upper(), 1),
-- }),
-- s("transform2", {
-- i(1, "initial text"),
-- t("::"),
-- i(2, "replacement for e"),
-- t({ "", "" }),
-- -- Lambdas can also apply transforms USING the text of other nodes:
-- l(l._1:gsub("e", l._2), { 1, 2 }),
-- }),
-- s({ trig = "trafo(%d+)", regTrig = true }, {
-- -- env-variables and captures can also be used:
-- l(l.CAPTURE1:gsub("1", l.TM_FILENAME), {}),
-- }),
-- -- Set store_selection_keys = "<Tab>" (for example) in your
-- -- luasnip.config.setup() call to populate
-- -- TM_SELECTED_TEXT/SELECT_RAW/SELECT_DEDENT.
-- -- In this case: select a URL, hit Tab, then expand this snippet.
-- s("link_url", {
-- t('<a href="'),
-- f(function(_, snip)
-- -- TM_SELECTED_TEXT is a table to account for multiline-selections.
-- -- In this case only the first line is inserted.
-- return snip.env.TM_SELECTED_TEXT[1] or {}
-- end, {}),
-- t('">'),
-- i(1),
-- t("</a>"),
-- i(0),
-- }),
-- -- Shorthand for repeating the text in a given node.
-- s("repeat", { i(1, "text"), t({ "", "" }), rep(1) }),
-- -- Directly insert the ouput from a function evaluated at runtime.
-- s("part", p(os.date, "%Y")),
-- -- use matchNodes (`m(argnode, condition, then, else)`) to insert text
-- -- based on a pattern/function/lambda-evaluation.
-- -- It's basically a shortcut for simple functionNodes:
-- s("mat", {
-- i(1, { "sample_text" }),
-- t(": "),
-- m(1, "%d", "contains a number", "no number :("),
-- }),
-- -- The `then`-text defaults to the first capture group/the entire
-- -- match if there are none.
-- s("mat2", {
-- i(1, { "sample_text" }),
-- t(": "),
-- m(1, "[abc][abc][abc]"),
-- }),
-- -- It is even possible to apply gsubs' or other transformations
-- -- before matching.
-- s("mat3", {
-- i(1, { "sample_text" }),
-- t(": "),
-- m(
-- 1,
-- l._1:gsub("[123]", ""):match("%d"),
-- "contains a number that isn't 1, 2 or 3!"
-- ),
-- }),
-- -- `match` also accepts a function in place of the condition, which in
-- -- turn accepts the usual functionNode-args.
-- -- The condition is considered true if the function returns any
-- -- non-nil/false-value.
-- -- If that value is a string, it is used as the `if`-text if no if is explicitly given.
-- s("mat4", {
-- i(1, { "sample_text" }),
-- t(": "),
-- m(1, function(args)
-- -- args is a table of multiline-strings (as usual).
-- return (#args[1][1] % 2 == 0 and args[1]) or nil
-- end),
-- }),
-- -- The nonempty-node inserts text depending on whether the arg-node is
-- -- empty.
-- s("nempty", {
-- i(1, "sample_text"),
-- n(1, "i(1) is not empty!"),
-- }),
-- -- dynamic lambdas work exactly like regular lambdas, except that they
-- -- don't return a textNode, but a dynamicNode containing one insertNode.
-- -- This makes it easier to dynamically set preset-text for insertNodes.
-- s("dl1", {
-- i(1, "sample_text"),
-- t({ ":", "" }),
-- dl(2, l._1, 1),
-- }),
-- -- Obviously, it's also possible to apply transformations, just like lambdas.
-- s("dl2", {
-- i(1, "sample_text"),
-- i(2, "sample_text_2"),
-- t({ "", "" }),
-- dl(3, l._1:gsub("\n", " linebreak ") .. l._2, { 1, 2 }),
-- }),
-- }, {
-- key = "all",
-- })
require("luasnip.loaders.from_lua").lazy_load({ paths = { "~/.config/nvim/snips" } }) require("luasnip.loaders.from_lua").lazy_load({ paths = { "~/.config/nvim/snips" } })
require("luasnip.loaders.from_vscode").lazy_load({ paths = { "~/.config/Code - Insiders/User/snippets" } }) require("luasnip.loaders.from_vscode").lazy_load({ paths = { "~/.config/Code - Insiders/User/snippets" } })

View File

@@ -1,3 +1 @@
vim.opt.termguicolors = true
require("nvim-highlight-colors").setup({}) require("nvim-highlight-colors").setup({})

View File

@@ -28,9 +28,6 @@ require("lint").linters_by_ft = {
yaml = { "yamllint" }, yaml = { "yamllint" },
} }
-- TODO: Wouldn't it be possible / nice to only try to load the linters when they are
-- actually needed?
vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave" }, { vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave" }, {
callback = function() callback = function()
require("lint").try_lint() require("lint").try_lint()

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,16 +1,28 @@
vim.cmd([[ vim.g.tidal_default_config = { socket_name = "default", target_pane = "tidal:1.1" }
" Tidalcycles (sclang and vim-tidal) vim.g.tidal_no_mappings = 1
let g:tidal_default_config = {"socket_name": "default", "target_pane": "tidal:1.1"}
let g:tidal_no_mappings = 1
au FileType tidal nm <buffer> <leader>ep <Plug>TidalParagraphSend vim.api.nvim_create_autocmd("FileType", {
au FileType tidal nm <buffer> <leader>ee <Plug>TidalLineSend pattern = "tidal",
au FileType tidal nnoremap <buffer> <leader>h :TidalHush<cr> callback = function(e)
au FileType tidal com! -nargs=1 S :TidalSilence <args> local buf = e.buf
au FileType tidal com! -nargs=1 P :TidalPlay <args> vim.keymap.set("n", "<leader>ep", "<Plug>TidalParagraphSend", { buffer = buf, desc = "Tidal: send paragraph" })
au FileType tidal com! -nargs=0 H :TidalHush vim.keymap.set("n", "<leader>ee", "<Plug>TidalLineSend", { buffer = buf, desc = "Tidal: send line" })
vim.keymap.set("n", "<leader>h", ":TidalHush<cr>", { buffer = buf, desc = "Tidal: hush" })
vim.api.nvim_buf_create_user_command(buf, "S", "TidalSilence <args>", { nargs = 1 })
vim.api.nvim_buf_create_user_command(buf, "P", "TidalPlay <args>", { nargs = 1 })
vim.api.nvim_buf_create_user_command(buf, "H", "TidalHush", { nargs = 0 })
end,
})
" SuperCollider -- SuperCollider
au BufEnter,BufWinEnter,BufNewFile,BufRead *.sc,*.scd se filetype=supercollider vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter", "BufNewFile", "BufRead" }, {
au Filetype supercollider packadd scvim pattern = { "*.sc", "*.scd" },
]]) callback = function()
vim.bo.filetype = "supercollider"
end,
})
vim.api.nvim_create_autocmd("FileType", {
pattern = "supercollider",
command = "packadd scvim",
})

View File

@@ -1,6 +1,8 @@
require("zk.utils")
vim.cmd([[ vim.cmd([[
" Change local buffer to directory of current file after the plugin has loaded " Change local buffer to directory of current file after the plugin has loaded
autocmd VimEnter * lcd %:p:h execute 'autocmd BufEnter' g:zk_path . '/*.md' 'silent lcd %:p:h'
" " Override wiki index mapping to also cd into the wiki " " Override wiki index mapping to also cd into the wiki
nm <leader>ww <plug>(wiki-index) nm <leader>ww <plug>(wiki-index)
@@ -11,11 +13,16 @@ nm <leader>ww <plug>(wiki-index)
" nm <leader>s <plug>(wiki-link-follow-split) " nm <leader>s <plug>(wiki-link-follow-split)
" nm <leader>v <plug>(wiki-link-follow-vsplit) " nm <leader>v <plug>(wiki-link-follow-vsplit)
autocmd BufEnter *.md if expand('%:t') =~ '_' | echo 'hierarchical relation' | endif function! ZKContextualEcho()
autocmd BufEnter *.md if expand('%:t') =~ '--' | echo 'relation' | endif let l:name = expand('%:t')
autocmd BufEnter *.md if expand('%:t') =~ '<>' | echo 'dichotomy' | endif if l:name =~ '_' | echo 'hierarchical relation'
autocmd BufEnter *.md if expand('%:t') =~ 'my-' | echo 'personal file' | endif elseif l:name =~ '--' | echo 'relation'
autocmd BufEnter *.md if expand('%:t') =~ 'project_' | echo 'project file' | endif elseif l:name =~ '<>' | echo 'dichotomy'
elseif l:name =~ 'my-' | echo 'personal file'
elseif l:name =~ 'project_' | echo 'project file'
endif
endfunction
execute 'autocmd BufEnter' g:zk_path . '/*.md' 'call ZKContextualEcho()'
" Only load wiki.vim for zk directory " Only load wiki.vim for zk directory
let g:wiki_index_name='index' let g:wiki_index_name='index'
@@ -76,7 +83,7 @@ let g:wiki_templates = [
" "
let g:wiki_filetypes=['md'] let g:wiki_filetypes=['md']
let g:wiki_root='~/.zk' let g:wiki_root=g:zk_path
let g:wiki_global_load=0 let g:wiki_global_load=0
let g:wiki_link_creation = { let g:wiki_link_creation = {
\ 'md': { \ 'md': {

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": 1777273601,
"narHash": "sha256-KbOeWIF52SV53BOeETGO2C5ewaV2Ex9iaXH7G72gOr8=", "narHash": "sha256-xBUa8Tl9V7IXI+VmLEuDc81La/EhoSn1C3EVSnJ3cfU=",
"owner": "BirdeeHub", "owner": "BirdeeHub",
"repo": "nixCats-nvim", "repo": "nixCats-nvim",
"rev": "c81551ed87db2aefab30a12cf7425ff94dc0ad64", "rev": "f69ea013e328841a7def7037ed59788a76be8816",
"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": 1777270315,
"narHash": "sha256-yKB4G6cKsQsWN7M6rZGk6gkJPDNPIzT05y4qzRyCDlI=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "6f374686605df381de8541c072038472a5ea2e2d", "rev": "6368eda62c9775c38ef7f714b2555a741c20c72d",
"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": 1773934114,
"narHash": "sha256-W9NRa84l5Cs62OsDeqb+LMxk8oYjhVBCB3o3UmE9a0I=", "narHash": "sha256-8trqFsA7nTKSdtkiAL0Sa9bXjh5ONtAqN7XNE/B8ukM=",
"owner": "qvalentin", "owner": "qvalentin",
"repo": "helm-ls.nvim", "repo": "helm-ls.nvim",
"rev": "d6f3a8d4ad59b4f54cd734267dfb5411679ea608", "rev": "20df43509b02a3ce3c6b3eee254d6e2bffa9a370",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -82,11 +122,11 @@
"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 +170,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,10 +185,10 @@
}, },
"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-mcphub-nvim": "plugins-mcphub-nvim", "plugins-mcphub-nvim": "plugins-mcphub-nvim",
"plugins-nvimkit-nvim": "plugins-nvimkit-nvim", "plugins-nvimkit-nvim": "plugins-nvimkit-nvim",

View File

@@ -2,15 +2,16 @@
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 = {
url = "github:polarmutex/beancount.nvim"; url = "github:polarmutex/beancount.nvim";
flake = false; flake = false;
@@ -36,7 +37,6 @@
outputs = outputs =
{ {
self,
nixpkgs, nixpkgs,
nixCats, nixCats,
... ...
@@ -45,10 +45,38 @@
inherit (nixCats) utils; inherit (nixCats) utils;
luaPath = ./.; luaPath = ./.;
forEachSystem = utils.eachSystem nixpkgs.lib.platforms.all; forEachSystem = utils.eachSystem nixpkgs.lib.platforms.all;
extra_pkg_config = { }; extra_pkg_config = {
allowUnfreePredicate =
pkg:
builtins.elem (nixpkgs.lib.getName pkg) [
"vim-sandwich"
"jupytext.nvim"
"eyeliner.nvim"
"context_filetype.vim"
"editorconfig-vim"
"unicode.vim"
"quarto-nvim"
"vim-openscad"
"lsp_lines.nvim"
"nvim-highlight-colors"
"nvim-lint"
];
};
dependencyOverlays = [ mkDependencyOverlays = system: [
(utils.standardPluginOverlay inputs) (utils.standardPluginOverlay inputs)
(_final: _prev: {
mcp-hub = inputs.mcp-hub.packages.${system}.default;
})
(_: prev: {
luajitPackages = prev.luajitPackages.overrideScope (
_: lprev: {
neotest = lprev.neotest.overrideAttrs (_: {
doCheck = false;
});
}
);
})
]; ];
categoryDefinitions = categoryDefinitions =
@@ -59,21 +87,40 @@
{ {
lspsAndRuntimeDeps = with pkgs; { lspsAndRuntimeDeps = with pkgs; {
general = [ general = [
nodejs_24
black black
clang clang
clang-tools clang-tools
curl # → plenary-nvim, mcp-hub
delta
emmet-language-server
eslint_d
fd
gawk gawk
gdtoolkit_4 gdtoolkit_4
hadolint
helm-ls
isort isort
tree-sitter lua-language-server
ormolu mcp-hub
nodePackages.prettier
nixd nixd
nixfmt nixfmt
prettier
typescript-language-server
ormolu
prettierd prettierd
rust-analyzer
rustfmt
shellcheck-minimal shellcheck-minimal
stylelint
stylua stylua
tree-sitter
tailwindcss-language-server
typescript-language-server
vscode-langservers-extracted vscode-langservers-extracted
vtsls
yaml-language-server
yamllint
]; ];
}; };
@@ -123,7 +170,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 +189,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
]; ];
}; };
@@ -160,9 +210,7 @@
}; };
packageDefinitions = { packageDefinitions = {
nvim = nvim = _: {
{ ... }:
{
settings = { settings = {
suffix-path = true; suffix-path = true;
suffix-LD = true; suffix-LD = true;
@@ -180,6 +228,7 @@
forEachSystem ( forEachSystem (
system: system:
let let
dependencyOverlays = mkDependencyOverlays system;
nixCatsBuilder = utils.baseBuilder luaPath { nixCatsBuilder = utils.baseBuilder luaPath {
inherit inherit
nixpkgs nixpkgs
@@ -199,7 +248,7 @@
name = defaultPackageName; name = defaultPackageName;
packages = [ defaultPackage ]; packages = [ defaultPackage ];
inputsFrom = [ ]; inputsFrom = [ ];
shellHook = ''''; shellHook = "";
}; };
}; };
@@ -211,31 +260,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,15 +1,12 @@
local json_newline = function() local json_newline = function()
local line = vim.api.nvim_get_current_line() local line = vim.api.nvim_get_current_line()
if line == "" then if line == "" then
print("line is empty")
return "o" return "o"
elseif string.byte(line, -1) == string.byte(",") then elseif string.byte(line, -1) == string.byte(",") then
return "o" return "o"
elseif string.byte(line, -1) == string.byte("{") then elseif string.byte(line, -1) == string.byte("{") then
print("line ends with '{'")
return "o" return "o"
elseif string.byte(line, -1) == string.byte("}") then elseif string.byte(line, -1) == string.byte("}") then
print("line ends with '}'")
return "o" return "o"
else else
return "A,<CR>" return "A,<CR>"

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

@@ -26,5 +26,4 @@ set lcs=trail:·,tab:→\ ,nbsp:␣ " Whitespace rendering
set ar " Autoread set ar " Autoread
set spellsuggest+=5 " Limit spell suggestions set spellsuggest+=5 " Limit spell suggestions
set wildignore+=*/node_modules/*,*/tmp/*,*.so,*.swp,*.zip set wildignore+=*/node_modules/*,*/tmp/*,*.so,*.swp,*.zip
" set thesaurus+=./thesaurus/mthesaur.txt " FIXME
]]) ]])

View File

@@ -9,5 +9,6 @@ vim.filetype.add({
["%.env.*"] = "dotenv", ["%.env.*"] = "dotenv",
["%.pl$"] = "prolog", ["%.pl$"] = "prolog",
[".*.containerfile.*"] = "dockerfile", [".*.containerfile.*"] = "dockerfile",
["%.hydra$"] = "javascript",
}, },
}) })

View File

@@ -1,60 +1,57 @@
vim.cmd([[ vim.g.mapleader = " "
" Leader keys vim.g.maplocalleader = ";"
let mapleader = " "
let maplocalleader = ";"
" Splits & navigation
nm s <c-w> " Split horizontal
nm ss :sp<CR><c-w>w| " Split horizontal
nm sv :vs<CR><c-w>w| " Split vertical
nm sw <c-w>w| " Navigate splits
nm sh <c-w>h| "
nm sj <c-w>j| "
nm sk <c-w>k| "
nm sl <c-w>l| "
nn sH <c-w>8<| " Resize splits
nn sJ <c-w>8-| "
nn sK <c-w>8+| "
nn sL <c-w>8>| "
nn s= <c-w>=| " Equalize splits
" Open
nn sb :Lex<cr>| " File tree
nn <leader><leader> :noh<cr> |"
nn <leader>t :term<cr>| " Open terminal
" Remaps
ino <nowait> jj <esc>| " Normal now
nn <left> <nop>| " Hard mode
nn <down> <nop>| " "
nn <up> <nop>| " "
nn <right> <nop>| " "
ino <left> <nop>| " "
ino <down> <nop>| " "
ino <up> <nop>| " "
ino <right> <nop>| " "
" Search
nn <c-_> :noh<cr>| " map 'ctrl + /'
" Line numbers
nn <leader>n :set nu! rnu!<cr>
" Vim configuration
nn <leader>ec :vs $MYVIMRC<cr>
nn <leader>so :so %<cr>
]])
local set = vim.keymap.set local set = vim.keymap.set
set("n", "<leader>cx", "<cmd>!chmod +x %<CR>", { silent = true, desc = "Run `chmod +x` on current file" }) -- splits & navigation
set("n", "yp", "<cmd>let @+ = expand('%r')<CR>:p<CR>", { silent = true, desc = "Yank path" }) set("n", "s", "<c-w>", { desc = "window prefix" })
set("n", "ss", ":sp<CR><c-w>w", { desc = "split horizontal" })
set("n", "sv", ":vs<CR><c-w>w", { desc = "split vertical" })
set("n", "sw", "<c-w>w", { desc = "navigate splits" })
set("n", "sh", "<c-w>h", { desc = "focus left split" })
set("n", "sj", "<c-w>j", { desc = "focus below split" })
set("n", "sk", "<c-w>k", { desc = "focus above split" })
set("n", "sl", "<c-w>l", { desc = "focus right split" })
set("n", "sH", "<c-w>8<", { desc = "shrink split left" })
set("n", "sJ", "<c-w>8-", { desc = "shrink split down" })
set("n", "sK", "<c-w>8+", { desc = "grow split up" })
set("n", "sL", "<c-w>8>", { desc = "grow split right" })
set("n", "s=", "<c-w>=", { desc = "equalize splits" })
-- Remap native NeoVim comment keymaps -- open
set({ "n", "x" }, "<leader>c", "gc", { remap = true, desc = "Toggle comment" }) set("n", "sb", ":Lex<cr>", { desc = "file tree" })
set("n", "<leader>cc", "gcc", { remap = true, desc = "Toggle comment line" }) set("n", "<leader><leader>", ":noh<cr>", { desc = "clear highlights" })
set("o", "<leader>c", "gc", { remap = true, desc = "Comment textobject" }) set("n", "<leader>t", ":term<cr>", { desc = "open terminal" })
-- Move lines -- remaps
set("v", "K", ": '<,'>move '<-2<cr>gv") set("i", "jj", "<esc>", { nowait = true, desc = "exit insert mode" })
set("v", "J", ": '<,'>move '>+1<cr>gv") set("n", "<left>", "<nop>")
set("n", "<down>", "<nop>")
set("n", "<up>", "<nop>")
set("n", "<right>", "<nop>")
set("i", "<left>", "<nop>")
set("i", "<down>", "<nop>")
set("i", "<up>", "<nop>")
set("i", "<right>", "<nop>")
-- search
set("n", "<c-_>", ":noh<cr>", { desc = "clear search highlight" })
-- line numbers
set("n", "<leader>n", ":set nu! rnu!<cr>", { desc = "toggle line numbers" })
-- vim configuration
set("n", "<leader>ec", ":vs $MYVIMRC<cr>", { desc = "edit vimrc" })
set("n", "<leader>so", ":so %<cr>", { desc = "source current file" })
set("n", "<leader>cx", "<cmd>!chmod +x %<CR>", { silent = true, desc = "run `chmod +x` on current file" })
set("n", "yp", "<cmd>let @+ = expand('%r')<CR>:p<CR>", { silent = true, desc = "yank path" })
-- remap native NeoVim comment keymaps
set({ "n", "x" }, "<leader>c", "gc", { remap = true, desc = "toggle comment" })
set("n", "<leader>cc", "gcc", { remap = true, desc = "toggle comment line" })
set("o", "<leader>c", "gc", { remap = true, desc = "comment textobject" })
-- move lines
set("v", "K", ": '<,'>move '<-2<cr>gv", { desc = "move selection up" })
set("v", "J", ": '<,'>move '>+1<cr>gv", { desc = "move selection down" })

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

@@ -2,10 +2,10 @@ local autocmd = vim.api.nvim_create_autocmd
autocmd("BufNewFile", { autocmd("BufNewFile", {
pattern = "shell.nix", pattern = "shell.nix",
command = "0r ~/.config/nvim/skeletons/shell.nix", command = "0r ~/.config/nvim/skeletons/shell.nix.skeleton",
}) })
autocmd("BufNewFile", { autocmd("BufNewFile", {
pattern = "flake.nix", pattern = "flake.nix",
command = "0r ~/.config/nvim/skeletons/flake.nix", command = "0r ~/.config/nvim/skeletons/flake.nix.skeleton",
}) })

View File

@@ -13,13 +13,19 @@ local function get_markdown_files(base)
return items return items
end end
function source:get_keyword_pattern()
return "[%w%./%-]*"
end
function source:complete(params, callback) function source:complete(params, callback)
local cursor_before_line = params.context.cursor_before_line local cursor_before_line = params.context.cursor_before_line
local cursor_after_line = params.context.cursor_after_line or "" local cursor_after_line = params.context.cursor_after_line or ""
local trigger = cursor_before_line:match("%[[^%]]*%]%(([^)]*)$") if not cursor_before_line:match("%[[^%]]*%]%(") then
callback({})
return
end
if trigger ~= nil then
local items = get_markdown_files(".") local items = get_markdown_files(".")
local next_char = cursor_after_line:sub(1, 1) local next_char = cursor_after_line:sub(1, 1)
@@ -32,9 +38,6 @@ function source:complete(params, callback)
end end
callback(items) callback(items)
else
callback({})
end
end end
function source:get_trigger_characters() function source:get_trigger_characters()

View File

@@ -1,9 +1,10 @@
require("zk.cmp") require("zk.cmp")
require("zk.utils")
vim.cmd([[ vim.cmd([[
let s:zk_preview_enabled = 0 let s:zk_preview_enabled = 0
let s:live_server_job = -1 let s:live_server_job = -1
au BufEnter /home/h/.zk/*.md silent exe '!echo "%" > /home/h/.zk/current-zettel.txt' execute 'au BufEnter' g:zk_path . '/*.md' 'silent exe "!echo %" ">" g:zk_path . "/current-zettel.txt"'
function! ToggleZKPreview() function! ToggleZKPreview()
if s:zk_preview_enabled == 1 if s:zk_preview_enabled == 1
let s:zk_preview_enabled = 0 let s:zk_preview_enabled = 0
@@ -11,10 +12,10 @@ function! ToggleZKPreview()
au! ZKPreview au! ZKPreview
else else
let s:zk_preview_enabled = 1 let s:zk_preview_enabled = 1
let s:live_server_job = jobstart('live-server --watch=/home/h/.zk/current-zettel-content.html --open=current-zettel-content.html --port=8080') let s:live_server_job = jobstart('live-server --watch=' . g:zk_path . '/current-zettel-content.html --open=current-zettel-content.html --port=8080')
augroup ZKPreview augroup ZKPreview
au BufEnter /home/h/.zk/*.md silent exe '!cat "%:r.html" > /home/h/.zk/current-zettel-content.html' execute 'au BufEnter' g:zk_path . '/*.md' 'silent exe "!cat %:r.html" ">" g:zk_path . "/current-zettel-content.html"'
au BufWritePost /home/h/.zk/*.md silent exe '!make && cat "%:r.html" > /home/h/.zk/current-zettel-content.html' execute 'au BufWritePost' g:zk_path . '/*.md' 'silent exe "!make && cat %:r.html" ">" g:zk_path . "/current-zettel-content.html"'
augroup END augroup END
endif endif
endfunction endfunction

View File

@@ -0,0 +1,2 @@
vim.g.zk_path = os.getenv("ZK_PATH") or (os.getenv("HOME") .. "/.zk")
return vim.g.zk_path

View File

@@ -17,7 +17,7 @@ local LOCALHOST_IP = "127.0.0.1"
return { return {
s({ trig = "fn", desc = "Filename" }, { f(TM_FILENAME_BASE) }), s({ trig = "fn", desc = "Filename" }, { f(TM_FILENAME_BASE) }),
s({ trig = "fne", dscr = "Filename (+extension)" }, { f(TM_FILENAME) }), s({ trig = "fne", desc = "Filename (+extension)" }, { f(TM_FILENAME) }),
s({ trig = "hm" }, { t(NAME) }), s({ trig = "hm" }, { t(NAME) }),
s({ trig = "loho" }, { t(LOCALHOST) }), s({ trig = "loho" }, { t(LOCALHOST) }),
s({ trig = "lohoi" }, { t(LOCALHOST_IP) }), s({ trig = "lohoi" }, { t(LOCALHOST_IP) }),

View File

@@ -5,112 +5,112 @@ local i = ls.insert_node
return { return {
-- Flex -- Flex
s({ trig = "b1", dscr = "Add 'border: 1px <color>;'" }, { s({ trig = "b1", desc = "Add 'border: 1px <color>;'" }, {
t("border: 1px solid "), t("border: 1px solid "),
i(1), i(1),
t(";"), t(";"),
i(0), i(0),
}), }),
s({ trig = "dfl", dscr = "Add 'display: flex;'" }, { s({ trig = "dfl", desc = "Add 'display: flex;'" }, {
t("display: flex;"), t("display: flex;"),
i(0), i(0),
}), }),
s({ trig = "flr", dscr = "Add 'flex-direction: row;'" }, { s({ trig = "flr", desc = "Add 'flex-direction: row;'" }, {
t("flex-direction: row;"), t("flex-direction: row;"),
i(0), i(0),
}), }),
s({ trig = "flc", dscr = "Add 'flex-direction: column;'" }, { s({ trig = "flc", desc = "Add 'flex-direction: column;'" }, {
t("flex-direction: column;"), t("flex-direction: column;"),
i(0), i(0),
}), }),
s({ trig = "flw", dscr = "Add 'flex-wrap: wrap;'" }, { s({ trig = "flw", desc = "Add 'flex-wrap: wrap;'" }, {
t("flex-wrap: wrap;"), t("flex-wrap: wrap;"),
i(0), i(0),
}), }),
s({ trig = "dfc", dscr = "Add 'flex-direction: column;'" }, { s({ trig = "dfc", desc = "Add 'flex-direction: column;'" }, {
t("display: flex;"), t("display: flex;"),
t("flex-direction: column;"), t("flex-direction: column;"),
i(0), i(0),
}), }),
-- Grid -- Grid
s({ trig = "dg", dscr = "Add 'display: grid;'" }, { s({ trig = "dg", desc = "Add 'display: grid;'" }, {
t("display: grid;"), t("display: grid;"),
i(0), i(0),
}), }),
-- Block -- Block
s({ trig = "db", dscr = "Add 'display: block;'" }, { s({ trig = "db", desc = "Add 'display: block;'" }, {
t("display: block;"), t("display: block;"),
i(0), i(0),
}), }),
-- None -- None
s({ trig = "dn", dscr = "Add 'display: none;'" }, { s({ trig = "dn", desc = "Add 'display: none;'" }, {
t("display: none;"), t("display: none;"),
i(0), i(0),
}), }),
-- CSS Variables -- CSS Variables
s({ trig = "v", dscr = "Add CSS variable" }, { s({ trig = "v", desc = "Add CSS variable" }, {
t("var(--"), t("var(--"),
i(1), i(1),
t(")"), t(")"),
i(0), i(0),
}), }),
-- Margin -- Margin
s({ trig = "m", dscr = "Add 'margin: ;'" }, { s({ trig = "m", desc = "Add 'margin: ;'" }, {
t("margin: "), t("margin: "),
i(1), i(1),
t(";"), t(";"),
i(0), i(0),
}), }),
s({ trig = "mt", dscr = "Add 'margin-top: ;'" }, { s({ trig = "mt", desc = "Add 'margin-top: ;'" }, {
t("margin-top: "), t("margin-top: "),
i(1), i(1),
t(";"), t(";"),
i(0), i(0),
}), }),
s({ trig = "mr", dscr = "Add 'margin-right: ;'" }, { s({ trig = "mr", desc = "Add 'margin-right: ;'" }, {
t("margin-right: "), t("margin-right: "),
i(1), i(1),
t(";"), t(";"),
i(0), i(0),
}), }),
s({ trig = "mb", dscr = "Add 'margin-bottom: ;'" }, { s({ trig = "mb", desc = "Add 'margin-bottom: ;'" }, {
t("margin-bottom: "), t("margin-bottom: "),
i(1), i(1),
t(";"), t(";"),
i(0), i(0),
}), }),
s({ trig = "ml", dscr = "Add 'margin-left: ;'" }, { s({ trig = "ml", desc = "Add 'margin-left: ;'" }, {
t("margin-left: "), t("margin-left: "),
i(1), i(1),
t(";"), t(";"),
i(0), i(0),
}), }),
-- Padding -- Padding
s({ trig = "p", dscr = "Add 'padding: ;'" }, { s({ trig = "p", desc = "Add 'padding: ;'" }, {
t("padding: "), t("padding: "),
i(1), i(1),
t(";"), t(";"),
i(0), i(0),
}), }),
s({ trig = "pt", dscr = "Add 'padding-top: ;'" }, { s({ trig = "pt", desc = "Add 'padding-top: ;'" }, {
t("padding-top: "), t("padding-top: "),
i(1), i(1),
t(";"), t(";"),
i(0), i(0),
}), }),
s({ trig = "pr", dscr = "Add 'padding-right: ;'" }, { s({ trig = "pr", desc = "Add 'padding-right: ;'" }, {
t("padding-right: "), t("padding-right: "),
i(1), i(1),
t(";"), t(";"),
i(0), i(0),
}), }),
s({ trig = "pb", dscr = "Add 'padding-bottom: ;'" }, { s({ trig = "pb", desc = "Add 'padding-bottom: ;'" }, {
t("padding-bottom: "), t("padding-bottom: "),
i(1), i(1),
t(";"), t(";"),
i(0), i(0),
}), }),
s({ trig = "pl", dscr = "Add 'padding-left: ;'" }, { s({ trig = "pl", desc = "Add 'padding-left: ;'" }, {
t("padding-left: "), t("padding-left: "),
i(1), i(1),
t(";"), t(";"),

View File

@@ -4,19 +4,19 @@ local t = ls.text_node
local i = ls.insert_node local i = ls.insert_node
return { return {
s({ trig = "clg", dscr = "console.log" }, { s({ trig = "clg", desc = "console.log" }, {
t("console.log("), t("console.log("),
i(1), i(1),
t(")"), t(")"),
i(0), i(0),
}), }),
s({ trig = "Js", dscr = "JSON.stringify" }, { s({ trig = "Js", desc = "JSON.stringify" }, {
t("JSON.stringify("), t("JSON.stringify("),
i(1), i(1),
t(")"), t(")"),
i(0), i(0),
}), }),
s({ trig = "Jsf", dscr = "JSON.stringify (formatted)" }, { s({ trig = "Jsf", desc = "JSON.stringify (formatted)" }, {
t("JSON.stringify("), t("JSON.stringify("),
i(1), i(1),
t(", 0, 2)"), t(", 0, 2)"),

View File

@@ -915,21 +915,21 @@ end
return { return {
s( s(
{ trig = "^h", regTrig = true, dscr = "Markdown header" }, { trig = "^h", regTrig = true, desc = "Markdown header" },
fmta("# <><>", { fmta("# <><>", {
d(1, get_visual), d(1, get_visual),
i(0), i(0),
}) })
), ),
s( s(
{ trig = "^sec", regTrig = true, dscr = "Markdown header" }, { trig = "^sec", regTrig = true, desc = "Markdown header" },
fmta("## <><>", { fmta("## <><>", {
d(1, get_visual), d(1, get_visual),
i(0), i(0),
}) })
), ),
s( s(
{ trig = "^ssec", regTrig = true, dscr = "Markdown header" }, { trig = "^ssec", regTrig = true, desc = "Markdown header" },
fmta("### <><>", { fmta("### <><>", {
d(1, get_visual), d(1, get_visual),
i(0), i(0),

View File

@@ -1,11 +1,5 @@
local cmd = vim.cmd
local map = vim.keymap.set local map = vim.keymap.set
cmd([[
source ~/.vim/init/base.vim
source ~/.vim/init/mappings.vim
]])
require("keymaps") require("keymaps")
map({ "n", "v" }, "<leader>p", '<cmd>call VSCodeNotify("workbench.action.quickOpen")<cr>') map({ "n", "v" }, "<leader>p", '<cmd>call VSCodeNotify("workbench.action.quickOpen")<cr>')

View File

@@ -1 +0,0 @@
set -g status-style bg=default

View File

@@ -1 +0,0 @@
set -g status-style bg=blue,fg=black;

View File

@@ -1,22 +0,0 @@
# This file is based on the one provided by shipwright.nvim
set -g @FG '#dddddd'
set -g @BG '#111111'
set -g status-left ' #[fg=#{@FG},bold]#{s/root//:client_key_table} '
set -g status-right '#[fg=#{@FG},bold] [#S]#[fg=#{@FG},bold] [%d/%m] #[fg=#{@FG},bold][%I:%M%p] '
set -g status-style fg='#{@FG}',bg='#{@BG}'
set -g window-status-current-style fg='#{@FG}',bg='#{@BG}',bold
set -g pane-border-style fg='#{@FG}'
set -g pane-active-border-style fg='#{@FG}'
set -g message-style fg='#{@FG}',bg='#{@FG}'
set -g display-panes-active-colour '#{@FG}'
set -g display-panes-colour '#{@FG}'
set -g clock-mode-colour '#{@FG}'
set -g mode-style fg='#{@FG}',bg='#{@FG}'

View File

@@ -1,22 +0,0 @@
# This file is based on the one provided by shipwright.nvim
set -g @FG '#111111'
set -g @BG '#dddddd'
set -g status-left ' #[fg=#{@FG},bold]#{s/root//:client_key_table} '
set -g status-right '#[fg=#{@FG},bold] [#S]#[fg=#{@FG},bold] [%d/%m] #[fg=#{@FG},bold][%I:%M%p] '
set -g status-style fg='#{@FG}',bg='#{@BG}'
set -g window-status-current-style fg='#{@FG}',bg='#{@BG}',bold
set -g pane-border-style fg='#{@FG}'
set -g pane-active-border-style fg='#{@FG}'
set -g message-style fg='#{@FG}',bg='#{@FG}'
set -g display-panes-active-colour '#{@FG}'
set -g display-panes-colour '#{@FG}'
set -g clock-mode-colour '#{@FG}'
set -g mode-style fg='#{@FG}',bg='#{@FG}'

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
@@ -56,22 +68,11 @@ set -g status-left '#h '
set -g status-right '#(uptime | cut -f 4-5 -d " " | cut -f 1 -d ",") %a %l:%M:%S %p %Y-%m-%d' set -g status-right '#(uptime | cut -f 4-5 -d " " | cut -f 1 -d ",") %a %l:%M:%S %p %Y-%m-%d'
%endif %endif
# theming
%if "#{==:#{host},desktop-arch}"
set -g default-terminal "tmux-256color" set -g default-terminal "tmux-256color"
setw -g window-status-style fg=colour244,bg=default
setw -g window-status-current-style fg=colour232,bg=default,bold
set -g message-style fg=colour232,bg=default
setw -g clock-mode-colour colour235
set -g status-style bg=default
set -g pane-border-style fg=#cccccc
set -g pane-active-border-style fg=#555555
set -g message-style bg=#cccccc,fg=#000000
%endif
set-hook -g after-new-session 'if -F "#{==:#{session_name},ssh}" "source ${XDG_CONFIG_HOME}/tmux/hooks/tmux.ssh.conf" "source ${XDG_CONFIG_HOME}/tmux/hooks/tmux.regular.conf"'
# Vi copypaste mode # Vi copypaste mode
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

View File

@@ -1 +0,0 @@
set -g status-style bg=default

View File

@@ -93,3 +93,6 @@
[includeIf "gitdir:~/work/"] [includeIf "gitdir:~/work/"]
path = ~/.gitconfig.work path = ~/.gitconfig.work
[includeIf "gitdir:~/nix-dev-shells/"]
path = ~/.gitconfig.work

3
dots/.gitignore vendored
View File

@@ -84,6 +84,9 @@ dkms.conf
# Dotenv # Dotenv
.env .env
.envrc
.direnv/
.pre-commit-config.yaml
# Prevent module files from being ignored (e.g. NestJS) # Prevent module files from being ignored (e.g. NestJS)
!*.module* !*.module*

View File

@@ -1,44 +0,0 @@
# Restic ignore
# General
.trash
Trash
.cache
cache
Cache
CachedData
CachedExtension
CacheStorage
__pycache__
GPUCache
ShaderCache
build
.git
node_modules
venv
env
# Specifics
$HOME/.android
$HOME/.atom
$HOME/.build
$HOME/.cabal
$HOME/.cargo
$HOME/.conda
$HOME/.config/BraveSoftware/Brave-Browser/Default/Local Storage
$HOME/.config/BraveSoftware/Brave-Browser/Default/Local Extension Settings
$HOME/.config/nvm/versions
$HOME/.config/devcert
$HOME/.espressif
$HOME/.local/share/torbrowser
$HOME/.mozilla
$HOME/.nvm
$HOME/.npm
$HOME/.nuget
$HOME/.yarn
$HOME/.config/yarn
$HOME/doc/disk-images
$HOME/.stremio-server
$HOME/Games
!$HOME/Games/*/drive_c/users/h/AppData
!$HOME/Games/rhino

View File

@@ -1,3 +0,0 @@
/etc
/boot
/home

574
flake.lock generated
View File

@@ -1,5 +1,97 @@
{ {
"nodes": { "nodes": {
"base16": {
"inputs": {
"fromYaml": "fromYaml"
},
"locked": {
"lastModified": 1755819240,
"narHash": "sha256-qcMhnL7aGAuFuutH4rq9fvAhCpJWVHLcHVZLtPctPlo=",
"owner": "SenchoPens",
"repo": "base16.nix",
"rev": "75ed5e5e3fce37df22e49125181fa37899c3ccd6",
"type": "github"
},
"original": {
"owner": "SenchoPens",
"repo": "base16.nix",
"type": "github"
}
},
"base16-fish": {
"flake": false,
"locked": {
"lastModified": 1765809053,
"narHash": "sha256-XCUQLoLfBJ8saWms2HCIj4NEN+xNsWBlU1NrEPcQG4s=",
"owner": "tomyun",
"repo": "base16-fish",
"rev": "86cbea4dca62e08fb7fd83a70e96472f92574782",
"type": "github"
},
"original": {
"owner": "tomyun",
"repo": "base16-fish",
"rev": "86cbea4dca62e08fb7fd83a70e96472f92574782",
"type": "github"
}
},
"base16-helix": {
"flake": false,
"locked": {
"lastModified": 1776754714,
"narHash": "sha256-E3OAK27smtATTmX45uoTSRsVD+Y+ZiVVfgM/tjpbtYg=",
"owner": "tinted-theming",
"repo": "base16-helix",
"rev": "4d508123037e7851ad36ebf7d9c48b0e9e1eb581",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-helix",
"type": "github"
}
},
"base16-vim": {
"flake": false,
"locked": {
"lastModified": 1732806396,
"narHash": "sha256-e0bpPySdJf0F68Ndanwm+KWHgQiZ0s7liLhvJSWDNsA=",
"owner": "tinted-theming",
"repo": "base16-vim",
"rev": "577fe8125d74ff456cf942c733a85d769afe58b7",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-vim",
"rev": "577fe8125d74ff456cf942c733a85d769afe58b7",
"type": "github"
}
},
"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 +99,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 +121,11 @@
}, },
"locked": { "locked": {
"dir": "pkgs/firefox-addons", "dir": "pkgs/firefox-addons",
"lastModified": 1764561884, "lastModified": 1778040175,
"narHash": "sha256-vQ3iFPPhxsLqV3c5kgmYP53mVD6id6gsP0tN+oTmqok=", "narHash": "sha256-SSXJp3BMjO2LrW/VLjNdGGcjd3RFEyV4FemYA6OGrYw=",
"owner": "rycee", "owner": "rycee",
"repo": "nur-expressions", "repo": "nur-expressions",
"rev": "aba4621459aec251d90d6452e3495b58a8a5e185", "rev": "3bd76b0f41e65661866bddcac57ebe83aeadb581",
"type": "gitlab" "type": "gitlab"
}, },
"original": { "original": {
@@ -43,7 +135,113 @@
"type": "gitlab" "type": "gitlab"
} }
}, },
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1776136500,
"narHash": "sha256-r0gN2brVWA351zwMV0Flmlcd6SGMvYqFbvC3DfKFM8Y=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "0f8ba203d475587f477e7ae12661bd8459e225b7",
"type": "github"
},
"original": {
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"type": "github"
}
},
"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-compat_2": {
"flake": false,
"locked": {
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "NixOS",
"repo": "flake-compat",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github"
},
"original": {
"owner": "NixOS",
"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-parts_2": {
"inputs": {
"nixpkgs-lib": [
"stylix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1775087534,
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
"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"
}, },
@@ -61,6 +259,82 @@
"type": "github" "type": "github"
} }
}, },
"fromYaml": {
"flake": false,
"locked": {
"lastModified": 1731966426,
"narHash": "sha256-lq95WydhbUTWig/JpqiB7oViTcHFP8Lv41IGtayokA8=",
"owner": "SenchoPens",
"repo": "fromYaml",
"rev": "106af9e2f715e2d828df706c386a685698f3223b",
"type": "github"
},
"original": {
"owner": "SenchoPens",
"repo": "fromYaml",
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": "flake-compat_2",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1776796298,
"narHash": "sha256-PcRvlWayisPSjd0UcRQbhG8Oqw78AcPE6x872cPRHN8=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "3cfd774b0a530725a077e17354fbdb87ea1c4aad",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"git-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"gnome-shell": {
"flake": false,
"locked": {
"lastModified": 1767737596,
"narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=",
"owner": "GNOME",
"repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "github"
},
"original": {
"owner": "GNOME",
"repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "github"
}
},
"home-manager": { "home-manager": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -68,11 +342,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764544324, "lastModified": 1778009629,
"narHash": "sha256-GVBGjO7UsmzLrlOJV8NlKSxukHaHencrJqWkCA6FkqI=", "narHash": "sha256-nUoQtf4Zq7DRYJrfv904hjrxjAlWVP6a1pNNFKx3FCg=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "e4e25a8c310fa45f2a8339c7972dc43d2845a612", "rev": "00ed86e58bb6979a7921859fd1615d19382eac5c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -81,13 +355,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": 1776723456,
"narHash": "sha256-yxFxEKXFuXFyFIDZY1gla2OyuqcIE3uT8KDDgTmm3cE=", "narHash": "sha256-GBbbm05oXYqSZ2EgxQPsNpTKl16wNhvrlUxdmv0FbSU=",
"ref": "main", "ref": "main",
"rev": "b9c2ce32cc4c95d7ff01372faea2668407ef8d27", "rev": "135b681d24af6ee4508bbf7c657982d7be8743d4",
"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 +415,11 @@
}, },
"nixCats": { "nixCats": {
"locked": { "locked": {
"lastModified": 1764009888, "lastModified": 1777273601,
"narHash": "sha256-hJekfTiW1792txgRSM4LcHnz1lDSY87LYbsJEn2V378=", "narHash": "sha256-xBUa8Tl9V7IXI+VmLEuDc81La/EhoSn1C3EVSnJ3cfU=",
"owner": "BirdeeHub", "owner": "BirdeeHub",
"repo": "nixCats-nvim", "repo": "nixCats-nvim",
"rev": "16ac3281f322ea15d39843829e42a44d22da3715", "rev": "f69ea013e328841a7def7037ed59788a76be8816",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -116,7 +430,7 @@
}, },
"nixgl": { "nixgl": {
"inputs": { "inputs": {
"flake-utils": "flake-utils", "flake-utils": "flake-utils_2",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
] ]
@@ -137,11 +451,11 @@
}, },
"nixos-hardware": { "nixos-hardware": {
"locked": { "locked": {
"lastModified": 1764440730, "lastModified": 1777917524,
"narHash": "sha256-ZlJTNLUKQRANlLDomuRWLBCH5792x+6XUJ4YdFRjtO4=", "narHash": "sha256-k+LVe9YaO2BEPB9AaCtTtOMCeGi4dxDo6gt4Un3qoPY=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "9154f4569b6cdfd3c595851a6ba51bfaa472d9f3", "rev": "df7783100babf59001340a7a874ba3824e441ecb",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -153,11 +467,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1764517877, "lastModified": 1777954456,
"narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=", "narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2d293cbfa5a793b4c50d17c05ef9e385b90edf6c", "rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -167,14 +481,55 @@
"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"
}
},
"nur": {
"inputs": {
"flake-parts": [
"stylix",
"flake-parts"
],
"nixpkgs": [
"stylix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1777598946,
"narHash": "sha256-X239dAGaU1+gfDj8jKH8GzlqKMcxaVfXOio+uzBOkeE=",
"owner": "nix-community",
"repo": "NUR",
"rev": "5d55af01c0f86be583931fe99207fc56c14134b3",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "NUR",
"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-mcphub-nvim": "plugins-mcphub-nvim", "plugins-mcphub-nvim": "plugins-mcphub-nvim",
"plugins-nvimkit-nvim": "plugins-nvimkit-nvim", "plugins-nvimkit-nvim": "plugins-nvimkit-nvim",
@@ -207,30 +562,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": 1773934114,
"narHash": "sha256-W9NRa84l5Cs62OsDeqb+LMxk8oYjhVBCB3o3UmE9a0I=", "narHash": "sha256-8trqFsA7nTKSdtkiAL0Sa9bXjh5ONtAqN7XNE/B8ukM=",
"owner": "qvalentin", "owner": "qvalentin",
"repo": "helm-ls.nvim", "repo": "helm-ls.nvim",
"rev": "d6f3a8d4ad59b4f54cd734267dfb5411679ea608", "rev": "20df43509b02a3ce3c6b3eee254d6e2bffa9a370",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -242,11 +581,11 @@
"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 +629,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,15 +644,18 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"colmena": "colmena",
"disko": "disko", "disko": "disko",
"firefox-addons": "firefox-addons", "firefox-addons": "firefox-addons",
"git-hooks": "git-hooks",
"home-manager": "home-manager", "home-manager": "home-manager",
"nix-secrets": "nix-secrets", "nix-secrets": "nix-secrets",
"nixgl": "nixgl", "nixgl": "nixgl",
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"nvim": "nvim", "nvim": "nvim",
"sops-nix": "sops-nix" "sops-nix": "sops-nix",
"stylix": "stylix"
} }
}, },
"sops-nix": { "sops-nix": {
@@ -323,11 +665,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764483358, "lastModified": 1777944972,
"narHash": "sha256-EyyvCzXoHrbL467YSsQBTWWg4sR96MH1sPpKoSOelB4=", "narHash": "sha256-VfGRo1qTBKOe3s2gOv8LSoA6Fk19PvBlwQ1ECN0Evn8=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "5aca6ff67264321d47856a2ed183729271107c9c", "rev": "c591bf665727040c6cc5cb409079acb22dcce33c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -336,6 +678,55 @@
"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"
}
},
"stylix": {
"inputs": {
"base16": "base16",
"base16-fish": "base16-fish",
"base16-helix": "base16-helix",
"base16-vim": "base16-vim",
"firefox-gnome-theme": "firefox-gnome-theme",
"flake-parts": "flake-parts_2",
"gnome-shell": "gnome-shell",
"nixpkgs": [
"nixpkgs"
],
"nur": "nur",
"systems": "systems_2",
"tinted-kitty": "tinted-kitty",
"tinted-schemes": "tinted-schemes",
"tinted-tmux": "tinted-tmux",
"tinted-zed": "tinted-zed"
},
"locked": {
"lastModified": 1777835090,
"narHash": "sha256-VLH8zPweblCOvpnQXp4fVs7f6Q79YhXF5XFKlOrvIFk=",
"owner": "danth",
"repo": "stylix",
"rev": "7989a1054b01153212dede6005abfd1576b8328c",
"type": "github"
},
"original": {
"owner": "danth",
"repo": "stylix",
"type": "github"
}
},
"systems": { "systems": {
"locked": { "locked": {
"lastModified": 1681028828, "lastModified": 1681028828,
@@ -350,6 +741,85 @@
"repo": "default", "repo": "default",
"type": "github" "type": "github"
} }
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"tinted-kitty": {
"flake": false,
"locked": {
"lastModified": 1735730497,
"narHash": "sha256-4KtB+FiUzIeK/4aHCKce3V9HwRvYaxX+F1edUrfgzb8=",
"owner": "tinted-theming",
"repo": "tinted-kitty",
"rev": "de6f888497f2c6b2279361bfc790f164bfd0f3fa",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-kitty",
"type": "github"
}
},
"tinted-schemes": {
"flake": false,
"locked": {
"lastModified": 1777041405,
"narHash": "sha256-BAGZ7ObFV/9Z61OJZun7ifPyhkuHqNuW1QIhQ8LuzCo=",
"owner": "tinted-theming",
"repo": "schemes",
"rev": "5f868b3a338b6904c47f3833b9c411be641983a8",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "schemes",
"type": "github"
}
},
"tinted-tmux": {
"flake": false,
"locked": {
"lastModified": 1777169200,
"narHash": "sha256-h7dDbIzP5hDr9v97w9PL6jdAgXawmj6krcH+959rqpU=",
"owner": "tinted-theming",
"repo": "tinted-tmux",
"rev": "f798c2dce44ef815bb6b8f05a82135c7942d35ac",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-tmux",
"type": "github"
}
},
"tinted-zed": {
"flake": false,
"locked": {
"lastModified": 1777463218,
"narHash": "sha256-Bhkozqtq3BKLqWTlmKm8uAptfX4aRGI8QX3eEL54Vpc=",
"owner": "tinted-theming",
"repo": "base16-zed",
"rev": "5768d08ed2e7944a26a958868cdb073cb8856dae",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-zed",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

141
flake.nix
View File

@@ -3,9 +3,12 @@
nixpkgs = { nixpkgs = {
url = "github:nixos/nixpkgs/nixos-unstable"; url = "github:nixos/nixpkgs/nixos-unstable";
}; };
stylix = {
url = "github:danth/stylix";
inputs.nixpkgs.follows = "nixpkgs";
};
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,48 +38,134 @@
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";
};
git-hooks = {
url = "github:cachix/git-hooks.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = outputs =
{ {
self, self,
nixpkgs, nixpkgs,
nixos-hardware,
disko,
sops-nix,
nix-secrets,
home-manager, home-manager,
nixgl, nixgl,
firefox-addons, git-hooks,
nvim, ...
}@inputs: }@inputs:
let let
lib = inputs.nixpkgs.lib; inherit (self) outputs;
utils = import ./utils { inherit lib; }; inherit (inputs.nixpkgs) lib;
hostDirNames = utils.dirNames ./hosts; myUtils = import ./utils { inherit lib; };
hostDirNames = myUtils.dirNames ./hosts;
system = "x86_64-linux"; system = "x86_64-linux";
dotsPath = ./dots;
gitHooks = import ./git-hooks.nix {
inherit nixpkgs git-hooks system;
src = ./.;
};
in
{
nixosConfigurations =
(lib.genAttrs hostDirNames (
host:
nixpkgs.lib.nixosSystem {
modules = [
./hosts/${host}
{
nixpkgs.hostPlatform = (myUtils.hostMeta ./hosts/${host}).system;
host.name = host;
}
];
specialArgs = {
inherit
inputs
outputs
dotsPath
myUtils
;
};
}
))
// {
sd-image-orange-pi-aarch64 = nixpkgs.lib.nixosSystem {
modules = [
"${nixpkgs}/nixos/modules/installer/sd-card/sd-image-aarch64.nix"
./images/sd-image-orange-pi-aarch64.nix
{
nixpkgs.buildPlatform = "x86_64-linux";
nixpkgs.hostPlatform = "aarch64-linux";
}
];
specialArgs = {
inherit
inputs
outputs
dotsPath
myUtils
;
};
};
sd-image-raspberry-pi-aarch64 = nixpkgs.lib.nixosSystem {
modules = [
"${nixpkgs}/nixos/modules/installer/sd-card/sd-image-aarch64.nix"
./images/sd-image-raspberry-pi-aarch64.nix
{
nixpkgs.buildPlatform = "x86_64-linux";
nixpkgs.hostPlatform = "aarch64-linux";
}
];
specialArgs = {
inherit
inputs
outputs
dotsPath
myUtils
;
};
};
};
homeConfigurations = {
work = home-manager.lib.homeManagerConfiguration {
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system; inherit system;
overlays = [ nixgl.overlay ]; overlays = [ nixgl.overlay ];
}; };
in
{
nix.nixPath = [
"nixpkgs=${inputs.nixpkgs}"
]; # <https://github.com/nix-community/nixd/blob/main/nixd/docs/configuration.md>
nixosConfigurations = lib.genAttrs hostDirNames (
host:
nixpkgs.lib.nixosSystem {
modules = [ ./hosts/${host} ];
specialArgs = { inherit inputs; };
}
);
homeConfigurations = {
work = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [ ./home/hosts/work ]; modules = [ ./home/hosts/work ];
extraSpecialArgs = { inherit inputs; }; extraSpecialArgs = {
inherit
inputs
outputs
dotsPath
myUtils
;
}; };
}; };
}; };
apps.${system}.colmena = inputs.colmena.apps.${system}.default;
colmenaHive = import ./deploy/colmena.nix {
inherit
self
inputs
;
};
checks.${system} = gitHooks.checks;
formatter.${system} = gitHooks.formatter;
devShells.${system} = gitHooks.devShells;
legacyPackages.${system} = {
sd-image-orange-pi-aarch64 =
self.nixosConfigurations.sd-image-orange-pi-aarch64.config.system.build.sdImage;
sd-image-raspberry-pi-aarch64 =
self.nixosConfigurations.sd-image-raspberry-pi-aarch64.config.system.build.sdImage;
};
};
} }

47
git-hooks.nix Normal file
View File

@@ -0,0 +1,47 @@
{
nixpkgs,
git-hooks,
system,
src,
}:
let
pkgs = nixpkgs.legacyPackages.${system};
pre-commit-check = git-hooks.lib.${system}.run {
inherit src;
hooks = {
nixfmt = {
enable = true;
package = pkgs.nixfmt;
};
statix.enable = true;
deadnix.enable = true;
};
};
in
{
checks = {
inherit pre-commit-check;
};
formatter =
let
inherit (pre-commit-check) config;
inherit (config) package configFile;
script = ''
${pkgs.lib.getExe package} run --all-files --config ${configFile}
'';
in
pkgs.writeShellScriptBin "pre-commit-run" script;
devShells = {
default =
let
inherit (pre-commit-check) shellHook enabledPackages;
in
pkgs.mkShell {
inherit shellHook;
buildInputs = enabledPackages;
};
};
}

View File

@@ -1,6 +1,5 @@
{ {
lib, lib,
inputs,
config, config,
pkgs, pkgs,
... ...
@@ -8,12 +7,63 @@
{ {
imports = [ imports = [
(import ../astyanax { ../../modules
inherit inputs; ../../modules/3d
inherit config; ../../modules/ai-tools
inherit pkgs; ../../modules/anki
}) ../../modules/audio
../../modules/browser
../../modules/cloud
../../modules/comms
../../modules/desktop/niri
../../modules/devenv
../../modules/direnv
../../modules/git
../../modules/k8s/k9s.nix
../../modules/keepassxc
../../modules/music
../../modules/nvim
../../modules/pandoc
../../modules/photography
../../modules/secrets
../../modules/shell
../../modules/ssh
../../modules/taskwarrior
../../modules/terminal
../../modules/zk
../../modules/torrenting
]; ];
programs.taskwarrior.config.recurrence = lib.mkForce "on"; home = {
stateVersion = "25.05";
inherit (config.host) username;
homeDirectory = "/home/${config.host.username}";
};
xdg.userDirs.createDirectories = false;
xdg.userDirs.download = "${config.home.homeDirectory}/dl";
modules."3d" = {
printing.enable = true;
modeling.enable = true;
};
ai-tools = {
claude-code.enable = true;
opencode.enable = true;
};
browser.primary = "librewolf";
cloud.hetzner.enable = true;
comms.signal.enable = true;
git.github.enable = true;
shell.bash.aliases.lang-js = true;
shell.bash.addBinToPath = true;
torrenting.enable = true;
zk.enable = true;
programs = {
home-manager.enable = true;
taskwarrior.config.recurrence = lib.mkForce "on";
};
home.packages = import ../packages.nix { inherit pkgs; };
} }

View File

@@ -1,77 +1,65 @@
{ {
inputs,
config, config,
pkgs, pkgs,
... ...
}: }:
let
username = "h";
in
{ {
imports = [ imports = [
../../modules/dconf.nix # TODO: Only enable when on Gnome? ../../modules
../../modules/git.nix ../../modules/3d
../../modules/k9s.nix ../../modules/ai-tools
(import ../../modules/taskwarrior.nix { ../../modules/anki
inherit config; ../../modules/audio
inherit pkgs; ../../modules/browser
}) ../../modules/cloud
../../modules/comms
../../modules/desktop/niri
../../modules/devenv
../../modules/direnv
../../modules/git
../../modules/k8s/k9s.nix
../../modules/keepassxc
../../modules/music
../../modules/nfc
../../modules/nvim
../../modules/pandoc
../../modules/secrets
../../modules/shell
../../modules/ssh
../../modules/taskwarrior
../../modules/terminal
]; ];
home.stateVersion = "25.05"; home = {
home.username = username; stateVersion = "25.05";
home.homeDirectory = "/home/${username}"; inherit (config.host) username;
homeDirectory = "/home/${config.host.username}";
};
xdg.userDirs.createDirectories = false; xdg.userDirs = {
xdg.userDirs.download = "${config.home.homeDirectory}/dl"; enable = false;
createDirectories = false;
};
modules."3d".printing.enable = true;
ai-tools = {
claude-code.enable = true;
opencode.enable = true;
};
browser.primary = "librewolf";
cloud.hetzner.enable = true;
comms.signal.enable = true;
git.github.enable = true;
shell.bash.aliases.lang-js = true;
shell.bash.addBinToPath = 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
]

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

@@ -0,0 +1,22 @@
{ pkgs, ... }:
with pkgs;
[
bat
entr
feh
fzf
htop
jq
nmap
nvimpager
parallel
pass
ripgrep
silver-searcher
sops
tldr
tree
unzip
wget
]

View File

@@ -5,40 +5,95 @@
... ...
}: }:
let
username = "hektor";
in
{ {
imports = [ imports = [
../../modules/dconf.nix inputs.sops-nix.homeManagerModules.sops
../../modules/git.nix ../../modules
../../modules/k9s.nix ../../modules/ai-tools
../../modules/anki
../../modules/browser
../../modules/bruno
../../modules/cloud
../../modules/comms
../../modules/database
../../modules/dconf
../../modules/desktop/niri
../../modules/devenv
../../modules/direnv
../../modules/docker
../../modules/git
../../modules/go
../../modules/infra
../../modules/k8s
../../modules/k8s/k9s.nix
../../modules/keepassxc
../../modules/music
../../modules/nodejs
../../modules/nvim
../../modules/pandoc
../../modules/secrets
../../modules/shell
../../modules/stylix
../../modules/taskwarrior
../../modules/ticketing
../../modules/terminal
../../modules/vscode
]; ];
sops.age.keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
home.stateVersion = "25.05"; xdg = {
home.username = username; systemDirs.config = [ "/etc/xdg" ];
home.homeDirectory = "/home/${username}"; userDirs = {
createDirectories = false;
download = "${config.home.homeDirectory}/dl";
};
};
home = {
stateVersion = "25.05";
username = "hektor";
homeDirectory = "/home/${config.home.username}";
};
targets.genericLinux.nixGL = { targets.genericLinux.nixGL = {
packages = inputs.nixgl.packages; inherit (inputs.nixgl) packages;
defaultWrapper = "mesa"; defaultWrapper = "mesa";
}; };
programs = { browser.primary = "firefox";
# editorconfig.enable = true; browser.secondary = "chromium";
firefox = import ../../modules/firefox.nix { cloud.azure.enable = true;
inherit inputs; comms.signal.enable = true;
inherit pkgs; comms.teams.enable = true;
inherit config; ai-tools = {
claude-code.enable = true;
tirith.enable = true;
opencode.enable = true;
}; };
database = {
mssql.enable = true;
postgresql.enable = true;
redis.enable = true;
};
git.github.enable = true;
git.gitlab.enable = true;
secrets.vault.enable = true;
programs = {
gh.enable = true; gh.enable = true;
keepassxc = import ../../modules/keepassxc.nix;
kubecolor.enable = true; kubecolor.enable = true;
}; };
home.packages = import ./packages.nix { home.packages =
import ./packages.nix {
inherit inputs;
inherit config;
inherit pkgs;
}
++ import ../packages.nix {
inherit inputs; inherit inputs;
inherit config; inherit config;
inherit pkgs; inherit pkgs;

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,32 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.modules."3d";
in
{
options.modules."3d" = {
printing.enable = lib.mkEnableOption "3D printing tools";
modeling.enable = lib.mkEnableOption "3D modeling tools";
};
config = lib.mkMerge [
(lib.mkIf cfg.printing.enable {
home.packages = with pkgs; [
bambu-studio
orca-slicer
];
})
(lib.mkIf cfg.modeling.enable {
home.packages = with pkgs; [
blender
openscad-lsp
openscad-unstable
];
})
];
}

View File

@@ -0,0 +1,60 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.ai-tools.claude-code;
rtk-version = "0.18.1";
in
{
options.ai-tools.claude-code.enable = lib.mkEnableOption "claude code with rtk and ccline";
config = lib.mkIf cfg.enable {
programs.claude-code.enable = true;
home.packages = with pkgs; [
(stdenv.mkDerivation {
name = "ccline";
src = fetchurl {
url = "https://github.com/Haleclipse/CCometixLine/releases/download/v1.0.8/ccline-linux-x64.tar.gz";
hash = "sha256-Joe3Dd6uSMGi66QT6xr2oY/Tz8rA5RuKa6ckBVJIzI0=";
};
unpackPhase = "tar xzf $src";
installPhase = ''
mkdir -p $out/bin
cp ccline $out/bin/
chmod +x $out/bin/ccline
'';
meta = {
description = "CCometixLine Linux x64 CLI (Claude Code statusline)";
homepage = "https://github.com/Haleclipse/CCometixLine";
license = lib.licenses.mit;
platforms = [ "x86_64-linux" ];
};
})
(stdenv.mkDerivation {
name = "rtk-${rtk-version}";
version = rtk-version;
src = fetchurl {
url = "https://github.com/rtk-ai/rtk/releases/download/v${rtk-version}/rtk-x86_64-unknown-linux-gnu.tar.gz";
hash = "sha256-XoTia5K8b00OzcKYCufwx8ApkAS31DxUCpGSU0jFs2Q=";
};
unpackPhase = "tar xzf $src";
installPhase = ''
mkdir -p $out/bin
cp rtk $out/bin/
chmod +x $out/bin/rtk
'';
meta = {
description = "RTK - AI coding tool enhancer";
homepage = "https://www.rtk-ai.app";
license = lib.licenses.mit;
platforms = [ "x86_64-linux" ];
};
})
mcp-nixos
];
};
}

View File

@@ -0,0 +1,8 @@
{
imports = [
./claude-code.nix
./opencode.nix
./skills.nix
./tirith.nix
];
}

View File

@@ -0,0 +1,40 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.ai-tools.opencode;
in
{
options.ai-tools.opencode = {
enable = lib.mkEnableOption "opencode";
};
config = lib.mkIf cfg.enable {
home.packages = [ pkgs.opencode ];
home.file.".config/opencode/opencode.json".text = builtins.toJSON {
"$schema" = "https://opencode.ai/config.json";
permission = {
external_directory = {
"/run/secrets/" = "deny";
"~/.config/sops/age/keys.txt" = "deny";
"~/.ssh/id_rsa" = "deny";
"~/.ssh/id_ed25519" = "deny";
"~/.ssh/id_ecdsa" = "deny";
"~/.ssh/id_dsa" = "deny";
"/etc/ssh/ssh_host_rsa_key" = "deny";
"/etc/ssh/ssh_host_ed25519_key" = "deny";
"/etc/ssh/ssh_host_ecdsa_key" = "deny";
"/etc/ssh/ssh_host_dsa_key" = "deny";
};
command = {
sops = "deny";
};
};
plugin = [ "@mohak34/opencode-notifier@latest" ];
};
};
}

View File

@@ -0,0 +1,49 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.ai-tools.claude-code;
skillType = lib.types.submodule {
options = {
owner = lib.mkOption { type = lib.types.str; };
repo = lib.mkOption { type = lib.types.str; };
rev = lib.mkOption { type = lib.types.str; };
hash = lib.mkOption { type = lib.types.str; };
skill = lib.mkOption { type = lib.types.str; };
};
};
fetchSkill =
skill:
let
src = pkgs.fetchFromGitHub {
inherit (skill)
owner
repo
rev
hash
;
};
in
{
name = ".claude/skills/${skill.skill}";
value = {
source = "${src}/${skill.skill}";
recursive = true;
};
};
in
{
options.ai-tools.claude-code.skills = lib.mkOption {
type = lib.types.listOf skillType;
default = [ ];
};
config = lib.mkIf cfg.enable {
home.file = builtins.listToAttrs (map fetchSkill cfg.skills);
};
}

View File

@@ -0,0 +1,190 @@
#!/usr/bin/env python3
"""Claude Code PreToolUse hook — runs tirith check on Bash tool calls.
Reads JSON from stdin (Claude Code hook protocol), extracts the command,
and delegates to `tirith check --json` for security analysis.
Exit codes:
0 — hook completed successfully (decision in stdout JSON)
Non-zero — hook error (fail-closed by default; set TIRITH_FAIL_OPEN=1 for fail-open)
Output (stdout, only for deny):
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "..."
}
}
Environment:
TIRITH_BIN — path to tirith binary (default: "tirith")
TIRITH_HOOK_WARN_ACTION — "deny" (default) or "allow"
"""
import json
import os
import shutil
import subprocess
import sys
def get(data, *keys):
"""Return the first matching key from data (supports dual-case fields)."""
for k in keys:
if k in data:
return data[k]
return None
def deny(reason):
"""Print a deny decision using hookSpecificOutput and exit 0."""
print(
json.dumps(
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": reason,
}
}
)
)
sys.exit(0)
def fail_action():
"""Return the fail action: deny (default, fail-closed) or allow (fail-open via env)."""
return "allow" if os.environ.get("TIRITH_FAIL_OPEN") == "1" else "deny"
def fail_closed(reason):
"""Deny or allow based on TIRITH_FAIL_OPEN, for error/missing-binary paths."""
action = fail_action()
if action == "deny":
deny(reason)
else:
sys.exit(0)
def main():
try:
raw = sys.stdin.read()
if not raw.strip():
# Empty input — cannot determine command, fail-closed
fail_closed("tirith: empty hook input — blocked for safety")
return
data = json.loads(raw)
except (json.JSONDecodeError, OSError):
fail_closed("tirith: failed to parse hook input — blocked for safety")
return
if not isinstance(data, dict):
fail_closed("tirith: invalid hook input format — blocked for safety")
return
# Dual-case field extraction (camelCase and snake_case)
event = get(data, "hook_event_name", "hookEventName")
tool = get(data, "tool_name", "toolName")
tool_input = get(data, "tool_input", "toolInput") or {}
# Only intercept PreToolUse + Bash
if event != "PreToolUse" or tool != "Bash":
sys.exit(0)
if not isinstance(tool_input, dict):
fail_closed("tirith: invalid tool_input format — blocked for safety")
return
command = tool_input.get("command")
if not isinstance(command, str) or not command.strip():
fail_closed("tirith: no command found in hook input — blocked for safety")
return
# Locate tirith binary
tirith_bin = os.environ.get("TIRITH_BIN") or shutil.which("tirith") or "tirith"
try:
result = subprocess.run(
[
tirith_bin,
"check",
"--json",
"--non-interactive",
"--shell",
"posix",
"--",
command,
],
capture_output=True,
text=True,
timeout=10,
)
except FileNotFoundError:
fail_closed(f"tirith: {tirith_bin} not found — install tirith or set TIRITH_FAIL_OPEN=1")
return
except subprocess.TimeoutExpired:
fail_closed("tirith: check timed out — blocked for safety")
return
except OSError as e:
fail_closed(f"tirith: OS error running check — {e}")
return
# Unexpected exit code — fail-closed
if result.returncode not in (0, 1, 2):
fail_closed(f"tirith: unexpected exit code {result.returncode} — blocked for safety")
return
if result.returncode != 0 and not result.stdout.strip():
fail_closed("tirith: check returned non-zero with no output — blocked for safety")
return
# Exit 0 = clean, allow
if result.returncode == 0:
sys.exit(0)
# Exit 2 = warn — check TIRITH_HOOK_WARN_ACTION
if result.returncode == 2:
warn_action = os.environ.get("TIRITH_HOOK_WARN_ACTION", "deny").lower()
if warn_action == "allow":
sys.exit(0)
# Exit 1 = block, Exit 2 + deny = block
# Build reason from tirith JSON output
reason = "Tirith security check failed"
if result.stdout.strip():
try:
verdict = json.loads(result.stdout)
findings = verdict.get("findings", [])
if findings:
parts = []
for f in findings:
title = f.get("title", f.get("rule_id", "unknown"))
severity = f.get("severity", "")
parts.append(f"[{severity}] {title}" if severity else title)
reason = "Tirith: " + "; ".join(parts)
except json.JSONDecodeError:
reason = result.stdout.strip()[:500]
deny(reason)
if __name__ == "__main__":
try:
main()
except Exception:
# Fail-closed on unexpected errors (respects TIRITH_FAIL_OPEN)
if os.environ.get("TIRITH_FAIL_OPEN") == "1":
sys.exit(0)
# Deny — print structured output so Claude Code shows a message
print(
json.dumps(
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "tirith: unexpected hook error — blocked for safety",
}
}
)
)
sys.exit(0)

View File

@@ -0,0 +1,30 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.ai-tools.tirith;
in
{
options.ai-tools.tirith = {
enable = lib.mkEnableOption "tirith shell security guard";
};
config = lib.mkMerge [
(lib.mkIf cfg.enable {
home.packages = [ pkgs.tirith ];
})
(lib.mkIf (cfg.enable && config.ai-tools.claude-code.enable) {
home.file.".claude/hooks/tirith-check.py" = {
source = ./tirith-check.py;
executable = true;
};
home.activation.tirith-claude-code = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
${pkgs.tirith}/bin/tirith setup claude-code --with-mcp --scope user --force 2>/dev/null || true
'';
})
];
}

View File

@@ -1,6 +0,0 @@
{
enable = true;
# sync = {
# username = config.sops.secrets."email/personal".path;
# };
}

View File

@@ -0,0 +1,41 @@
{
config,
lib,
pkgs,
myUtils,
osConfig ? null,
inputs ? null,
...
}:
let
sops = myUtils.sopsAvailability config osConfig;
standalone = osConfig == null;
in
lib.optionalAttrs standalone {
sops.secrets = myUtils.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" null {
anki = [
"sync-user"
"sync-key"
];
};
}
// {
warnings = lib.optional (
!sops.available && config.programs.anki.enable
) "anki is enabled but sops secrets are not available. anki sync will not be configured.";
programs.anki = {
enable = true;
package = config.nixgl.wrap pkgs.anki;
addons = with pkgs.ankiAddons; [
anki-connect
puppy-reinforcement
review-heatmap
];
profiles."User 1".sync = lib.mkIf sops.available {
usernameFile = "${sops.secrets."anki/sync-user".path}";
keyFile = "${sops.secrets."anki/sync-key".path}";
};
};
}

View File

@@ -0,0 +1,7 @@
{ osConfig, pkgs, ... }:
{
home.packages = with pkgs; [ pulsemixer ];
services.mpris-proxy.enable = osConfig.hardware.bluetooth.enable or false;
}

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,33 @@
{ config, 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;
};
};
config.home.sessionVariables.BROWSER = config.browser.primary;
imports = [
./firefox.nix
./librewolf.nix
./chromium.nix
];
}

View File

@@ -1,23 +1,34 @@
{ inputs, pkgs, ... }: {
config,
inputs,
lib,
pkgs,
...
}:
let
bookmarks = import ./bookmarks.nix;
in
{ {
enable = true; nativeMessagingHosts =
nativeMessagingHosts = with pkgs; [ with pkgs;
[
tridactyl-native tridactyl-native
]; ]
policies = { ++ lib.optionals config.programs.keepassxc.enable [ keepassxc ];
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}; [ force = true;
packages = with inputs.firefox-addons.packages.${pkgs.stdenv.hostPlatform.system}; [
duckduckgo-privacy-essentials duckduckgo-privacy-essentials
firefox-color
istilldontcareaboutcookies istilldontcareaboutcookies
libredirect libredirect
keepassxc-browser keepassxc-browser
@@ -33,23 +44,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 +52,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,23 @@
{
config,
lib,
inputs,
pkgs,
...
}:
{
config = lib.mkIf (config.browser.primary == "firefox" || config.browser.secondary == "firefox") {
programs.firefox = {
enable = true;
}
// (import ./firefox-base.nix {
inherit
config
inputs
lib
pkgs
;
});
};
}

View File

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

View File

@@ -0,0 +1,7 @@
{ config, pkgs, ... }:
{
config = {
home.packages = [ (config.nixgl.wrap (config.wrapApp pkgs.bruno "--no-sandbox")) ];
};
}

View File

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

View File

@@ -0,0 +1,12 @@
{
config,
lib,
pkgs,
...
}:
{
config = lib.mkIf config.cloud.azure.enable {
home.packages = with pkgs; [ azure-cli ];
};
}

View File

@@ -0,0 +1,17 @@
{ lib, ... }:
{
options.cloud = {
azure = {
enable = lib.mkEnableOption "azure CLI";
};
hetzner = {
enable = lib.mkEnableOption "hetzner CLI";
};
};
imports = [
./azure.nix
./hetzner.nix
];
}

View File

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

View File

@@ -0,0 +1,17 @@
{ lib, ... }:
{
options.comms = {
signal = {
enable = lib.mkEnableOption "signal";
};
teams = {
enable = lib.mkEnableOption "teams";
};
};
imports = [
./signal.nix
./teams.nix
];
}

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