Idle cache 30 min -> 1 h, absolute cap 2 h -> 8 h. Both `lib.mkDefault` so an
inventory can set `services.gpg-agent.defaultCacheTtl` without `mkForce`.
State the reason for nixvim over LazyVim/NvChad — lazy.nvim fetches and updates
plugins at runtime, putting the editor outside the flake — along with what that
costs in ergonomics, and that borrowing a distro's keymaps and defaults into
this file remains open.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015D4NsszUG7hy9ghKZ4nfhm
`:bdelete` closes the window when no other listed buffer is left for it to
show, so closing the last file with neo-tree open left a full-width tree.
Point the window at another listed buffer, or a fresh empty one, before
deleting. `confirm` matches `<leader>Q`, prompting instead of failing on a
modified buffer.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015D4NsszUG7hy9ghKZ4nfhm
`:qa` fails with E37 when any buffer is modified, leaving the quit dead-ended.
`:confirm qa` asks Save/Discard/Cancel per modified buffer, which neither
strands the user nor writes unintended edits the way `:wqa` would.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015D4NsszUG7hy9ghKZ4nfhm
nvim detects `.mustache` but ships no syntax for it, leaving Moodle templates
as plain text. `vim-mustache-handlebars` supplies syntax, indent and ftdetect,
covering the constructs the Handlebars tree-sitter grammar rejects: bare
sections, `{{{unescaped}}}`, partials and `{{< parent }}` inheritance.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015D4NsszUG7hy9ghKZ4nfhm
blink.cmp uses the `enter` preset with `completion.list.selection.preselect =
false`, so an item is taken only once selected with `<Down>`/`<C-n>` and `<CR>`
otherwise inserts a newline. `<C-y>` stays bound as vim's own confirm key.
`<Esc>` and `<C-e>` both run `cancel` rather than the preset's `hide`: hiding
leaves the auto_insert preview in the buffer without the `additionalTextEdits`
and snippet expansion a real accept applies, and builtin ins-completion `<C-e>`
likewise restores the typed text.
`shiftwidth`/`tabstop` are 4, matching PHP's PSR-12. PHP's `indentkeys` carry
`*<Return>`, which reindents the just-finished line on every newline; at width 2
that silently re-indented 4-space files.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015D4NsszUG7hy9ghKZ4nfhm
`pkill -x waybar` matched only comm `waybar`, but the home-manager
wrapper launches the bar with comm `.waybar-wrapped` (arg[0] still
`waybar`), so the kill missed and left a stale bar drawing on the old
geometry after an unplug. Match both comms via an anchored ERE in both
the `monitor-hotplug` handler and `swapMonitors`.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A real DP/HDMI unplug makes Hyprland tear down the layer-shell surfaces on
the surviving monitor and not recreate them, so waybar and the wallpaper
vanish there. A SIGUSR2 reload rereads waybar's config but does not
recreate a bar that was already destroyed, so it left the laptop bar gone.
Kill and restart waybar instead — a fresh process enumerates the current
outputs and draws a bar on each — and add a settle delay before re-pushing
the wallpaper so it lands on the settled geometry. Verified against a real
DP-1 unplug: the LVDS-1 bar and wallpaper survive.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hyprland drops the layer-shell surfaces on the remaining output when a
monitor is removed and does not recreate them, so waybar and the awww
wallpaper vanish on unplug. The socket2 watcher only reacted to
`monitoradded`, which masked it — reconnecting re-fired the add and
restored both. Handle `monitorremoved` too, and on either event re-push
the wallpaper and reload waybar (SIGUSR2 rebuilds its per-output bars).
Renamed `wallpaper-hotplug` to `monitor-hotplug` since it now does both.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The postgresql client is installed from the private inventory, not this
baseline, so its dotfile config belongs there too. Drops `PSQLRC` and the
`psql/rc` history file; wget/readline stay (their tools are ubiquitous).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
the baseline hard-coded a german layout, leaking a personal value into a
module meant to be region-neutral. ship `mkDefault "us"` like `console.keyMap`
so a consumer overrides it from their inventory.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
replace the floating `Ctrl-\` toggle (unergonomic on a German layout) with
`<leader>th`/`<leader>tv` for horizontal/vertical splits; `<C-w>` in the
terminal leaves to normal mode in one chord.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New `modules/printing-scanning.nix` exposes `local.printing.*` and `local.scanning.*` (CUPS drivers, SANE with a Canon BJNP `bjnpHosts` escape hatch, shared Avahi mDNS), all off by default so a consumer opts in and a server gets none of it. Imported from `modules/nixos.nix`.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The public baseline hard-coded a German keymap and Europe/Berlin time
zone — personal values a consumer would have to override. Default them to
region-agnostic values instead (`us` keymap, `UTC`, `en_US` locale), all
`mkDefault`, so a private inventory sets the real regional values on top
without needing `mkForce`.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New `nixvim` flake input (release branch, follows nixpkgs) drives the whole
editor from `modules/nvim.nix`, wired into `homeModules.default`. Minimal LSP
baseline (`nixd`, `bashls`) exposed as `local.nvim.lspServers`; blink-cmp,
Telescope, neo-tree, lualine, treesitter, colorizer, gitsigns, toggleterm, and a
catppuccin theme. which-key groups plus `<leader>?`/`<leader>sk` give an
in-editor keybind cheatsheet; per-directory session persistence with
`sessionoptions` + a `PersistenceSavePre` neo-tree close for clean layouts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`$mod CTRL o` reflows the two connected monitors adjacent in reversed
order (gap-free regardless of differing widths) and re-inits the
layer-shell clients, which Hyprland doesn't reliably re-notify on a
runtime output move: waybar rebuilds on SIGUSR2, wallpaper is re-pushed.
`monitor` default becomes `mkDefault` so a host can pin its own layout.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
awww-daemon paints only the outputs present when `awww img` last ran and does
not repaint a monitor connected later, so it comes up on the daemon's black
fill — which a transparent foot then shows instead of the wallpaper. Add
`wallpaper-hotplug`: it watches Hyprland's event socket and re-runs `setbg`
(which pushes to all outputs) on each `monitoradded`.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New `local.hyprland.workspaceRules` option binds workspaces to monitor
connectors so each has a home screen; a consumer sets it from its own host
config (empty by default). Soft binding — an absent monitor's workspaces fall
back to an active one, so a laptop-only session still works.
`$mod+o` / `$mod SHIFT+o` focus and move the current workspace to the other
monitor. When rules are set, an `exec-once` nudges a single-monitor session to
workspace 1 rather than a support monitor's high default.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Center a `hyprland/window` title module and move the clock/date to the far
right of the bar. Give the clock a month-calendar tooltip with One Dark
Pango styling (yellow header, purple weekdays, blue underlined today, dim
ISO week-number gutter), 3-per-row year view via right-click.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Template hard-set `en_US.UTF-8`, so a consumer setting `i18n.defaultLocale`
in the private inventory hit a conflicting-definition eval error. Wrap the
template default in `lib.mkDefault` per the overrides-are-options contract.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ship `mc.ext.ini` as the `local.mc.extIni` option (like `local.mc.menu`):
Enter browses archives in-place as before and delegates every other type to
`xdg-open`. Add public `mime.nix` with `xdg.mimeApps` defaults (pdf ->
zathura, images -> imv, audio/video -> mpv, office -> libreoffice) -- public
because those handlers are; personal browser/mail defaults stay private.
Also document, at the Hyprland swallow config, how swallowing differs from an
app opening fullscreen/maximized (LibreOffice restores its own maximized state
and looks swallowed but isn't).
Shutdown stalls are hard to debug because journald is torn down mid-way,
so late hangs never reach the journal. `modules/shutdown-debug.nix`
exposes `local.shutdownDebug.*`: verbose systemd logging routed to kmsg
(recoverable from pstore after a forced power-off), an opt-in tty9 debug
shell, and a shortened `DefaultTimeoutStopSec` preset (system + user) so
a hung unit is killed and logged in seconds instead of spinning at 90s.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Style the `hyprland/workspaces` buttons so the focused workspace is
distinguishable when several are occupied: white text, darker
background, blue underline; urgent workspaces turn red.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- `$mod+h`/`l` used dwindle's `splitratio`, a no-op in the master layout;
switch to `mfact` so they actually resize the master area.
- `$mod+f` ran `fullscreen 1` (maximize, bar/gaps kept); swap so `$mod+f` is
true fullscreen and `$mod SHIFT+f` maximizes.
- add `$mod+space` `swapwithmaster` (dwm-style zoom).
- the `XF86MonBrightness` binds called `brightnessctl`, which was never
installed; add the package. It writes via the active logind session.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A viewer opened from a foot shell (zathura/imv, incl. from mc) now hides
the terminal and takes its place, restoring it on close. Requires
standalone foot: server/client mode shares one process across all
windows, so PID-based swallow cannot tell them apart. `$mod+Return` runs
`foot`, not `footclient`, and the `foot --server` exec-once is dropped.
Expose the user menu as a `types.lines` option instead of a baked source
file. The shipped menu is a `mkBefore` definition (not a `default`, which a
consumer definition would drop), so `local.mc.menu = "…"` appends entries
after the baseline and `lib.mkForce "…"` replaces it wholesale.
`ini` stays a baked source file: it is section/key=value, so append-to-extend
risks duplicate keys — not a safe override path.
Public baseline module: installs `mc` plus `ouch` (backs the F2 pack/unpack
entries, archive format inferred from the extension), and ships `ini`, `menu`,
and a generated `panels.ini` into `$XDG_CONFIG_HOME/mc`.
`local.mc.otherDir` exposes the other-panel start dir as an option defaulting
to `config.home.homeDirectory`, so the one personal value isn't baked in. The
F2 user menu is trimmed to the entries that match this config (imv/zathura/mpv
openers, ouch pack/unpack, man view); the stock rcp/uudecode/news/latex cruft
is dropped. `auto_save_setup=false` keeps mc from rewriting the read-only store
symlinks on exit.
Move librewolf out of the bare package list into its own module declaring
`local.librewolf.package` (default pkgs.librewolf), mirroring texlive. Lets a
consumer swap the wrapped package — extraPolicies/extraPrefs — to share
extensions and an about:config baseline across profiles without editing the
module.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
texlive scheme is the `local.texlive.package` option (default scheme-medium)
so consumers can swap schemes without editing the module; TEXMF* vars keep
its cache/config out of $HOME. pandoc PDF defaults to xelatex — pdflatex
fails on combining Unicode (e.g. U+0308 in decomposed ä).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
awww starts after the compositor, so hyprland painted its bundled
splash until the real wallpaper landed. Disable it via `misc`.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The agent, not the client, collects the FIDO PIN when signing with an
agent-held verify-required `sk-ssh-ed25519` key. Its systemd user service
started with a minimal env lacking `SSH_ASKPASS`, so those signatures failed
as "incorrect passphrase supplied to decrypt private key". Set `SSH_ASKPASS`
and `SSH_ASKPASS_REQUIRE=force` on the unit so the agent can pop pinentry.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gnome-keyring 50 dropped its ssh component and gpg's ssh support is off,
so there was no agent at all — SSH_AUTH_SOCK unset, `ssh-add` failed.
Keys stay added-on-demand (`AddKeysToAgent = "no"` in the inventory).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
QT_QPA_PLATFORMTHEME=gtk3 (what makes Qt apps read Adwaita-dark) reaches
the systemd-user env — so gpg-agent's signing pinentry is dark — but not
Hyprland's children, so the shell-spawned ssh askpass pinentry launched
without it and came up light. Export it in the compositor env so every
session child inherits it. Keeps pinentry-qt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fuzzel ignores the portal color-scheme, so set its palette explicitly to
match waybar. Hide non-launcher `.desktop` entries (foot variants, mpv/
umpv, zathura, nvim) via `noDisplay` shadows. Replace the per-action
app-list power entries with a `$mod+Backspace` `fuzzel --dmenu` power
menu (Log Out / Reboot / Shut Down), colored Papirus icons.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Qt apps (keepassxc, pinentry-qt) rendered light while the GTK side was
Adwaita-dark. keepassxc's `auto` theme reads dark/light only from the
xdg-desktop-portal `color-scheme` value, which the gtk portal serves from
dconf `org/gnome/desktop/interface/color-scheme` — unset, so it reported
"no preference" and fell back to light. Set it to `prefer-dark`.
Also route Qt through the `gtk3` platform theme (`libqgtk3` ships in
qtbase, unlike an external `adwaita-qt` style plugin which nixpkgs' baked
`QT_PLUGIN_PATH` makes unreachable), and set the GTK prefer-dark flag.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bare Print grabs the whole screen to a timestamped PNG under
~/Pictures/Screenshots; $mod selects a region (slurp), SHIFT sends to the
clipboard instead. A mako toast confirms each capture. Adds grim/slurp and
enables xdg.userDirs for the Pictures target.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>