Every Nixy solution I could find or conceive had too many points spread across these various facets: - Flimsy (emacsWithPackagesFromUsePackage) - Inelegant (builtins.exec, manual listings) - Inflexible (emacsWithPackagesFromUsePackage) - Otherwise unergonomic (everything }:D) Straight.el is sufficiently declarative, flexible, and Nix-friendly without blindly bowing down to the imperialist NixOS user. Now, Convenience and ergonomics shan't be forsaken for the dogma that is total Nixation.
368 lines
9.9 KiB
Org Mode
Executable File
368 lines
9.9 KiB
Org Mode
Executable File
:PROPERTIES:
|
||
:ID: 26ecd52b-1c5c-46b8-8eb9-fe827a753f0a
|
||
:ROAM_ALIASES: sydnix
|
||
:END:
|
||
#+title: Guix-rebound 2
|
||
#+tags: nix
|
||
|
||
Current name of ~guix-rebound~ ought to be changed. This is a rewrite from scratch. }:3
|
||
|
||
A second try at NixOS, now that I have a better idea of what I'm doing. The effort is largely inspired by my darling Faye's glorious ~wishsys~.
|
||
|
||
* Inbox
|
||
|
||
* Conventions
|
||
|
||
** User configuration
|
||
|
||
In order of descending preference, user programs should be configured by...
|
||
|
||
1. Wrappers, with config files optionally living somewhere under =/persist/dots=.
|
||
2. home-manager's modules.
|
||
3. ~home.file~ and similar.
|
||
4. Mutable symlinks using ~home.file~ and ~mkOutOfStoreSymlink~.
|
||
|
||
** Repo structure
|
||
|
||
*** =hosts/=
|
||
|
||
Each directory =hosts/«HOST»= is expected to configure a single specific device, where =«HOST»= is the device's exact hostname. Said directory =«HOST»= should have at least the following structure:
|
||
|
||
#+begin_example
|
||
hosts
|
||
└── «HOST»
|
||
├── configuration.nix
|
||
└── system.nix
|
||
#+end_example
|
||
|
||
Where =configuration.nix= is the main entry point imported by the top-level flake, and =system.nix= evaluates to a string corresponding to the =system= option to be used.
|
||
|
||
*** =users/=
|
||
|
||
Similarly to the =hosts= directory, each subdirectory =users/«USER»= is assumed to have some structure, and that =«USER»= is the precise username desired.
|
||
|
||
#+begin_example
|
||
users
|
||
└── «USER»
|
||
└── default.nix
|
||
#+end_example
|
||
|
||
Where =default.nix= returns an attrset of form
|
||
|
||
#+begin_src nix
|
||
{
|
||
# The NixOS option `users.users.«USER»` will be set to result of
|
||
# `systemConfiguration`.
|
||
systemConfiguration = { config, pkgs, lib, ... }: {
|
||
# isNormalUser = true;
|
||
# extraGroups = [ "wheel" ];
|
||
# ...
|
||
};
|
||
|
||
# Home-manager configuration
|
||
homeConfiguration = { config, pkgs, lib, ... }: {
|
||
# home.packages = [ pkgs.hello ];
|
||
# ...
|
||
};
|
||
}
|
||
#+end_src
|
||
|
||
** Impermanence and persistence
|
||
|
||
I use impermanence to wipe most of my filesystem on boot.
|
||
|
||
*** Boot process
|
||
|
||
What follows is an overview of [[file:modules/nixos/impermanence/rollback.nix][modules/nixos/impermanence/rollback.nix]].
|
||
|
||
On boot, ...
|
||
|
||
- The existing subvolume root filesystem will be moved to a 'death row' directory, where it will live for about three days before deletion. Precisely, =«btrfs-filesystem»/«root-subvolume»= is moved to =«btrfs-filesystem»/old-roots/«timestamp»=. The brief grace period allows for easy recovery in the (very common) case where files are unintentionally deleted due to the user's silly human negligence.
|
||
|
||
- A new, blank subvolume is created in place of the previous. Precisely, the subvolume =«btrfs-filesystem»/«root-subvolume»= is created.
|
||
|
||
- Any subvolumes under =«btrfs-filesystem»/old-roots= older than three days are deleted.
|
||
|
||
*** The =/persist= directory
|
||
|
||
- =/persist/root= :: Persistent files to be linked into the real root, =/=. These are managed by Impermanence.
|
||
|
||
- =/persist/home/«user»= :: Persistent files to be linked into the analogous location under the real home, =/home/«user»=. These are managed by Impermanence.
|
||
|
||
- =/persist/vault/«user»= :: Persistent files belonging to specific users. This differs from the persistent home directories in that files are not necessarily linked anywhere.
|
||
|
||
* ~sydnix-cli~
|
||
|
||
sydnix-cli is a command-line utility written in Clojure wrapping various sydnix-related scripts.
|
||
|
||
* Tasks
|
||
|
||
** Begin setting up doomless Emacs
|
||
|
||
*** DONE Daemon
|
||
CLOSED: [2025-01-03 Fri 20:00]
|
||
|
||
*** DONE Mutable config
|
||
CLOSED: [2025-01-03 Fri 20:01]
|
||
|
||
Path is currently hardcoded to =/persist/dots/users/crumb/programs/emacs=. An immutable file (created by home-manager's =programs.emacs.extraConfig=) loads =init.el= from the hardcoded path.
|
||
|
||
*** DONE Packages via Nixpkgs
|
||
CLOSED: [2025-01-03 Fri 20:40]
|
||
|
||
*** TODO =map!= macro
|
||
|
||
*** TODO Module system?
|
||
|
||
** Emacs config
|
||
|
||
*** [#A] One-off environment changes without direnv
|
||
|
||
I would like the ability to ergonomically e.g. add HLS to my current environment without setting up an entire project. Perhaps something like "create new workspace under a nix-shell invocation" could work?
|
||
|
||
*** minibuffer
|
||
|
||
**** DONE jk to escape
|
||
CLOSED: [2024-11-20 Wed 12:11]
|
||
|
||
**** DONE history navigation in insert mode w/ [[kbd:][C-j]] / [[kbd:][C-k]]
|
||
CLOSED: [2024-11-20 Wed 12:11]
|
||
|
||
**** [[kbd:][RET]] to send whilst in normal mode
|
||
|
||
*** dired
|
||
|
||
**** DONE use [[kbd:][/]] to live narrow
|
||
CLOSED: [2024-11-14 Thu 04:46]
|
||
|
||
*** set up JuliaMono for use with ipa: links
|
||
|
||
*** text-mode
|
||
|
||
**** grammar
|
||
|
||
**** spellcheck and dictionaries
|
||
|
||
**** org-mode
|
||
|
||
***** init.org for beorg
|
||
|
||
***** IPA links
|
||
|
||
***** capture templates
|
||
|
||
****** journal entry
|
||
|
||
****** todo
|
||
|
||
***** fancy headline stars
|
||
|
||
***** DONE better colour for inline code
|
||
CLOSED: [2024-11-21 Thu 09:04]
|
||
|
||
**** DONE variable pitch
|
||
CLOSED: [2024-11-30 Sat 19:06]
|
||
|
||
*** form and element text objects à la vim-sexp
|
||
|
||
*** customise the eshell prompt
|
||
|
||
*** jump to prev/next hole in haskell
|
||
|
||
*** make a bind for inserting hrules
|
||
|
||
*** KILL set up emms
|
||
CLOSED: [2024-12-11 Wed 13:46]
|
||
|
||
- BLOCKER: [[*download my music library][download my music library]]
|
||
|
||
it kinda sucks. }:\
|
||
|
||
*** set up JuliaMono for use with IPA glyphs
|
||
|
||
*** KILL literate config
|
||
CLOSED: [2024-12-27 Fri 19:35]
|
||
|
||
Just kind of a pain in the ass. }:)
|
||
|
||
*** evil-cp fixes
|
||
|
||
**** [[kbd:][(]] / [[kbd:][)]]
|
||
|
||
When [[kbd:][)]] is hit whilst the cursor is at ~↓1~, it should move to the matching
|
||
bracket, ~↓2~, *not* the right bracket of the ~save-excursion~ call.
|
||
#+begin_src elisp
|
||
(save-excursion
|
||
;; ↓1 ↓2
|
||
(re-search-forward))
|
||
#+end_src
|
||
|
||
**** element text objects
|
||
|
||
*** automatically close compilation buffer
|
||
|
||
*** fix =[e= / =]e=
|
||
|
||
*** unmap =TAB= in normal mode
|
||
|
||
*** eshell trail à la M-x calc
|
||
|
||
#+begin_quote
|
||
I really like how you re-examined shells and terminals. I hadn't thought of how
|
||
they're kinda unrelated. What I then don't understand is why eshell stuck to
|
||
the paradigm of interleaving input and output. It's a relic left over from
|
||
terminals. ie:
|
||
>>> input
|
||
[tonnes of output]
|
||
>>> input
|
||
[tonnes of output]
|
||
to me it seems the input should be entered in the minibuffer (or some separate
|
||
frame/window) and the outputs should be in a separate window/frame with separate
|
||
read-only buffers.
|
||
#+end_quote
|
||
[[https://www.reddit.com/r/emacs/comments/6y3q4k/comment/dml16vq/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button][source]]
|
||
|
||
** TODO Securely store credentials for glab/gh CLIs
|
||
|
||
** TODO Dotfiles
|
||
|
||
- [[https://rgoulter.com/blog/posts/programming/2022-02-20-using-home-manager-to-manage-symlinks-to-dotfiles.html][link]]
|
||
- [[https://www.bekk.christmas/post/2021/16/dotfiles-with-nix-and-home-manager][link]]
|
||
|
||
*** TODO Emacs
|
||
|
||
*** TODO Bash
|
||
|
||
**** TODO =shopt -s histverify=
|
||
|
||
Don’t execute expanded result immediately.
|
||
|
||
*** DONE (neo)vim
|
||
CLOSED: [2024-12-29 Sun 17:53]
|
||
|
||
*** TODO readline
|
||
|
||
** DONE disko
|
||
CLOSED: [2024-12-28 Sat 18:13]
|
||
|
||
** IDEA refactor disko configs to be more reusable
|
||
|
||
** IDEA replace uses of gpg with age
|
||
|
||
I don't know anything about either.
|
||
|
||
** TODO password store 4 firefox
|
||
|
||
** DONE password store w/ age
|
||
CLOSED: [2024-12-29 Sun 02:34]
|
||
|
||
https://github.com/FiloSottile/passage
|
||
|
||
** TODO Automatically sync password store
|
||
|
||
** DONE secrets
|
||
CLOSED: [2024-12-29 Sun 01:41]
|
||
|
||
** DONE git config
|
||
CLOSED: [2024-12-30 Mon 17:01]
|
||
|
||
** TODO niri
|
||
|
||
Or Qtile
|
||
|
||
** TODO qtile
|
||
|
||
Or Niri
|
||
|
||
** TODO Convenient way to wrap programs
|
||
|
||
[[https://github.com/viperML/wrapper-manager][wrapper-manager]] looks like it will be really annoying to integrate into my config without a NixOS/HM module.
|
||
|
||
** TODO tf2.nix
|
||
|
||
- declaratively configure tf2
|
||
- tf2Packages?
|
||
- mastercomfig integration?
|
||
- define aliases / bindings from nix?
|
||
|
||
** TODO mpd
|
||
|
||
*** TODO mpdscribble
|
||
|
||
** TODO syncthing
|
||
|
||
** HOLD impermanence
|
||
|
||
** DONE ~sydnix.defaults~ module
|
||
CLOSED: [2024-12-31 Tue 01:05]
|
||
|
||
** DONE Split up ~flake.nix~ into a file per output
|
||
CLOSED: [2024-12-31 Tue 01:04]
|
||
|
||
** TODO default package sets
|
||
|
||
Some examples of what I mean:
|
||
|
||
- ~defaultPackages.essential = true~ to install ~neovim~ and ~git~;
|
||
- ~defaultPackages.development = true~ for ~jj~ and Emacs.
|
||
- ~defaultPackages.desktop = true~ for ~cantata~, ~obs~, ~vlc~, ~vesktop~, ~soulseek~;
|
||
|
||
Naturally, one would expect some way to say "all these, except this and that."
|
||
|
||
** TODO Set envvars
|
||
|
||
*** =$EDITOR=
|
||
|
||
See [[id:5b4ee1e4-fad7-4783-8e98-301b41579a63][~choose-editor~]].
|
||
|
||
** System maintenance scripts
|
||
|
||
It might be a good idea to namespace these as subcommands of a single binary.
|
||
|
||
*** TODO ~nix-clean~
|
||
|
||
Collect garbage, clean up boot entries, delete old generations...
|
||
|
||
https://discourse.nixos.org/t/what-to-do-with-a-full-boot-partition/2049
|
||
|
||
*** TODO ~choose-editor~
|
||
:PROPERTIES:
|
||
:ID: 5b4ee1e4-fad7-4783-8e98-301b41579a63
|
||
:END:
|
||
|
||
- If the Emacs daemon is running...
|
||
- ...then run ~emacsclient~.
|
||
- ...otherwise, prompt the user to choose between Emacs and Vim
|
||
- If Emacs: run ~emacs~.
|
||
- If Vim: In order, try ~nvim~, ~vim~, then ~vi~.
|
||
- If neither are available, use ~nix run nixpkgs#nvim~
|
||
- If this fails, try ~nano~.
|
||
|
||
- Support ~--pager~
|
||
|
||
*** TODO =rage-edit=
|
||
|
||
*** TODO ~forget-host HOST~
|
||
|
||
Remove a given host from =~/.ssh/known_hosts=. Something like =sed -i -e '/192.168.122.54/d' .ssh/known_hosts=.
|
||
|
||
*** TODO =lets-temp [NAME]=
|
||
|
||
Create a new tempdir called ~[NAME]~, and cd into it.
|
||
|
||
* References
|
||
|
||
Following is a subset of the many places I've learnt from.
|
||
|
||
- My darling dearest Faye's =wishsys= }:D
|
||
- [[https://github.com/rasendubi/dotfiles][rasendubi/dotfiles]]
|
||
- [[https://git.mangoiv.com/mangoiv/dotfiles][mangoiv/dotfiles]]
|
||
- [[https://github.com/hlissner/dotfiles/][hlissner/dotfiles]]
|
||
- [[https://github.com/Shawn8901/nix-configuration/tree/af71d51998a6772a300f842795b947e27202fa73][Shawn8901/nix-configuration]]
|
||
- [cite:@christensen2020erase]
|
||
- [cite:@ayats2024dropping]
|
||
- [cite:@zaynetdinov2024you]
|
||
- [[https://prelude.emacsredux.com/en/stable/][Emacs Prelude]]
|
||
- [[https://github.com/doomemacs/doomemacs][Doom Emacs]]
|
||
- [[https://cce.whatthefuck.computer/cce][Ryan Rix's Complete Computing Environment]]
|