Compare commits

...

78 Commits

Author SHA1 Message Date
2928c14adb Generate static mac-portable config 2026-05-14 16:40:54 +02:00
35e92af403 Create static build of mac-portable config 2026-05-14 14:36:47 +00:00
6e1631d77b Describe layout 2026-05-14 15:38:40 +02:00
ac28afc5eb Update signing key 2026-05-14 15:22:08 +02:00
ac3712aec5 Correct path to test legacy presence 2026-05-14 15:20:23 +02:00
a453390013 Clarify "migrated" .zshrc 2026-05-14 15:19:41 +02:00
00049f5255 Make homeDirectory setting a default
Some hosts may have different home path
2026-05-14 15:17:23 +02:00
6f260619a7 Add git signingkey and name/email to personal file 2026-05-14 14:38:06 +02:00
031eab1b27 Clarify FIDO2 key limitations 2026-05-14 14:04:34 +02:00
231a769de5 Update fw_nix to pick up new cache paths 2026-05-13 20:53:04 +00:00
6df6976cd2 nix flake update 2026-05-11 19:14:38 +00:00
9f5e9b00e8 Enable mosh on linux-headless 2026-05-11 19:10:04 +00:00
7b85d3b585 Give gemini esphome 2026-05-11 19:09:52 +00:00
ce75ee4024 Show timezone next to timestamp in tmux 2026-05-08 15:41:02 +00:00
94800586f6 Add MIT license 2026-05-04 09:27:04 +00:00
efbcd546f9 TODO for better integration between zsh and iTerm2 2026-05-03 16:20:53 +02:00
f75a9f1ccb Finish migrating to tmux
fix environment variable being reset to most recent value in new panels
2026-05-01 19:49:21 +00:00
e38f96eedb Move linux-lxc away from linux-headless
Not every linux-headless is LXC; e.g. venus
2026-04-30 13:12:34 +02:00
d7be1664ae nix flake update 2026-04-29 20:48:39 +00:00
24055ddfe7 Extract linux bits into a new module 2026-04-29 22:44:15 +02:00
7bde25ebec Avoid affinity warnings for ag 2026-04-29 19:57:14 +00:00
930d951625 Migrate from GNU screen to tmux 2026-04-29 19:56:58 +00:00
4261c3e605 Add safe key 2026-04-29 17:13:05 +00:00
612ffea3ad Note on application setting 2026-04-29 19:12:32 +02:00
5ef6f5e636 Reformat settings.json (again...) 2026-04-29 17:53:42 +02:00
84f4a855cf Swap for FIDO2 keys 2026-04-29 15:31:08 +00:00
757602449b Definitively switch PIV->FIDO2 for SSH
And move Security section from home/home
2026-04-29 17:14:24 +02:00
090889f324 Move to iTerm2
Mostly for tmux integration
2026-04-29 17:12:08 +02:00
20af840d34 Update vim plugin name 2026-04-29 17:11:34 +02:00
7c4a46bd53 Allow reverse SSH via regular trusted keys 2026-04-29 17:10:49 +02:00
2bf2f60bde Use sudo with darwin-rebuild, too 2026-04-28 21:07:53 +02:00
dbc6551b0c Allow diff 2026-04-28 17:47:21 +00:00
e733c3d86d Migrate to Secretive fully 2026-04-28 16:30:48 +02:00
57144414f1 Support darwin and HM in local nix-deploy 2026-04-28 07:19:31 +00:00
a7c1cc3bd7 Keep sshfs on deimos also during logout 2026-04-28 06:24:55 +00:00
8e6f9a3fde Fix Gemini policy config for new syntax 2026-04-28 06:24:37 +00:00
fb274bb6f1 Fix colorcolumn 2026-04-20 15:49:59 +00:00
3111ac4dce Use a standard color scheme and move ftplugin 2026-04-20 15:28:51 +00:00
5212277efe Allow a couple more commands for gemini 2026-04-20 14:51:37 +00:00
4d9399290c Migrate vim plugins to nixos modules 2026-04-20 14:51:12 +00:00
87569883a3 Allow nix flake check 2026-04-16 09:28:22 +02:00
eeadf2c382 nix flake update 2026-04-16 09:26:57 +02:00
c8689d21e8 Allow nix-hash 2026-04-16 07:26:17 +00:00
4a614e1c66 Add nix to the list of available jailed packages
This will allow agent to run python/esphome/etc without
attempting to download and install them
2026-04-13 16:38:46 +00:00
d521f95a67 Prefer gemini3 models 2026-04-05 20:10:10 +00:00
3da7b843fb Do not install systemwide gemini-cli 2026-04-05 20:09:46 +00:00
6d4d4393ed nix flake update for newest packages 2026-04-05 20:02:52 +00:00
eeded33577 Move stow under home-manager activation 2026-04-05 17:41:18 +00:00
dee90c84a7 Allow gemini a few more commands 2026-04-05 17:38:47 +00:00
7b0c69ec60 Workaround for broken nix-deploy 2026-04-03 20:04:47 +00:00
9d3cca1395 Add procps for pgrep 2026-04-03 19:57:09 +00:00
e69dd65d53 bubblewrap gemini-cli 2026-04-03 19:52:41 +00:00
5115a41917 Remove freeradius mount (config moved to nix) 2026-04-03 06:28:57 +00:00
bfaa50ea8f Enable zsh on-host to populate /etc/zshrc with nix 2026-04-03 06:23:16 +00:00
c8ddc04c40 Implement "impermanence" for LXC 2026-04-03 06:20:42 +00:00
979c1aa080 Add jail to flake.nix
Inspired by
https://dev.to/andersonjoseph/how-i-run-llm-agents-in-a-secure-nix-sandbox-1899
2026-04-01 11:45:38 +00:00
28ffd61581 Remove unused config from host (set in home.nix) 2026-04-01 11:44:26 +00:00
727aa4fb02 nix flake update fw_nix
Update local nix cache paths
2026-03-29 17:53:19 +00:00
0e9885920b Update fw_nix for htop fix 2026-03-29 17:43:01 +02:00
df3ce1c299 nix flake update fw_nix
This should get us local git server public keys.
2026-03-29 16:34:50 +02:00
8c375d0a99 Use secretive agent for SSH 2026-03-29 13:48:58 +02:00
58fb358955 Split configuration into reusable modules 2026-03-29 11:50:03 +02:00
5a8f0aa4df Extract primaryUser into module args 2026-03-29 09:41:38 +02:00
2b6a9f52b9 Split mac-portable module out 2026-03-29 09:36:29 +02:00
5637b6188f Upgrade flake with pre-commit hooks and devShell 2026-03-28 23:18:52 +01:00
20913e8a21 Refactor brew installation and add system options 2026-03-28 23:06:50 +01:00
2aec0d341d Fix git config override 2026-03-28 22:54:01 +01:00
a0e97dd1f5 Initial nix-darwin config for mars 2026-03-28 20:33:58 +01:00
bca195af38 Fix build broken by legacy channel.nix logic 2026-03-28 17:52:29 +00:00
fc70e3437b nix flake update fw_nix 2026-03-28 17:33:35 +00:00
2c92686d78 Iterate on host/user split 2026-03-28 18:04:55 +01:00
2bde3e4732 Move configs into individual modules 2026-03-28 16:27:22 +00:00
8155416fcd Fix systemd user umount problems 2026-03-28 15:14:54 +00:00
2303e201db Auto-mount freeradius and haremote 2026-03-28 14:45:32 +00:00
7416a1cedc Add config for deimos 2026-03-27 21:48:25 +00:00
921afda0cc One more nix command for allowlist 2026-03-27 21:48:09 +00:00
be34170875 Set preferredEditor in Gemini 2026-03-27 20:26:57 +00:00
974b98b6b2 Add coding policy 2026-03-27 20:26:55 +00:00
57 changed files with 2098 additions and 491 deletions

1
.envrc Normal file
View File

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

8
.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
# direnv cache
/.direnv
# "nix build" default output link
result
# nix pre-commit autogenerated by devShell
/.pre-commit-config.yaml

39
.gitmodules vendored
View File

@@ -1,39 +0,0 @@
[submodule "legacy/.vim/bundle/ctrlp.vim"]
path = legacy/.vim/bundle/ctrlp.vim
url = https://github.com/kien/ctrlp.vim
[submodule "legacy/.vim/bundle/vim-startify"]
path = legacy/.vim/bundle/vim-startify
url = https://github.com/mhinz/vim-startify
[submodule "legacy/.vim/bundle/nerdcommenter"]
path = legacy/.vim/bundle/nerdcommenter
url = https://github.com/scrooloose/nerdcommenter
[submodule "legacy/.vim/bundle/vim-showmarks"]
path = legacy/.vim/bundle/vim-showmarks
url = https://github.com/jacquesbh/vim-showmarks
[submodule "legacy/.vim/bundle/vim-coffee-script"]
path = legacy/.vim/bundle/vim-coffee-script
url = https://github.com/kchmck/vim-coffee-script
[submodule "legacy/.vim/bundle/nginx.vim"]
path = legacy/.vim/bundle/nginx.vim
url = https://github.com/vim-scripts/nginx.vim
[submodule "legacy/.vim/bundle/supertab"]
path = legacy/.vim/bundle/supertab
url = https://github.com/ervandew/supertab
[submodule "legacy/.vim/bundle/vim-pathogen"]
path = legacy/.vim/bundle/vim-pathogen
url = https://github.com/tpope/vim-pathogen.git
[submodule "legacy/.vim/bundle/vim-sensible"]
path = legacy/.vim/bundle/vim-sensible
url = https://github.com/tpope/vim-sensible.git
[submodule "legacy/.vim/bundle/auto-pairs"]
path = legacy/.vim/bundle/auto-pairs
url = https://github.com/jiangmiao/auto-pairs
[submodule "legacy/.vim/bundle/vim-javascript"]
path = legacy/.vim/bundle/vim-javascript
url = https://github.com/pangloss/vim-javascript.git
[submodule "legacy/.vim/bundle/vim-lastplace"]
path = legacy/.vim/bundle/vim-lastplace
url = https://github.com/farmergreg/vim-lastplace.git
[submodule "legacy/.vim/bundle/dart-vim-plugin"]
path = legacy/.vim/bundle/dart-vim-plugin
url = https://github.com/dart-lang/dart-vim-plugin.git

7
LICENSE.txt Normal file
View File

@@ -0,0 +1,7 @@
Copyright (c) 2026 dotdoom
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

155
README.md
View File

@@ -1,17 +1,20 @@
# User and machine configs
## Installation
Step 1.
```
cd
git clone git@github.com:dotdoom/dotfiles.git
cd dotfiles
git submodule update --init
```
Step 2 - stow.
Step 2 - if Nix is not an option.
```
stow migrated
stow legacy
stow exported/{machine}
```
Step 2 - Nix.
@@ -22,6 +25,148 @@ nix run \
home-manager/master -- \
switch \
--extra-experimental-features 'nix-command flakes' \
--flake .#linux-headless
stow legacy
--flake .#artem@deimos
```
## Layout
- `assets`: files which are assets for home-manager
- `legacy`: files to be placed under `$HOME` which are still under stow
- `hosts/*/{darwin,nixos,home}.nix`: personal machine nix configs
- `modules/{darwin,nixos,home}/*.nix`: exported nix configs
- `exported`: for those poor souls who can not run nix, a pre-built collection
of files for `$HOME`, best effort
## Security
Risks taken (disclaimer):
- hardware attestation (this documentation and some code lists almost precisely
the hardware I use, and the way I use it)
- privacy (committing public keys technically allows verifying which servers I
have access to).
### SSH client
- `.ssh/id_XXXXX`
Static keys (stored in bitwarden). These have to be passphrase-protected when
stored on a disk; use `ssh-keygen -p -f .ssh/id_XXXXX`.
The use of these keys is expected to be low, but SSH may always fall back to
it, in which case you have to remember and type the passphrase. Use
`ssh-add -D` to remove unencrypted identity from memory afterwards. Saving a
passphrase in keychain is possible, but using Security Enclave is recommended
instead.
- Apple Security Enclave
This is the most used but also most ephemeral key, because it's bound to a
machine. It's provided by Secretive app acting as an SSH agent and the private
key is stored in Apple Security Enclave on a MacBook, requiring a fingerprint
touch on SSH.
- Yubikey
Yubikey PIV can be used as Smart Card, requiring a daemon and PGP
infrastructure. It's useful when a root entity is signing certificates from
multiple Yubikey owners, i.e. in large enterprise.
Another obstacle is that we already use Secretive as our SSH agent, and it
doesn't mux well with Yubikey agent, see `mac-portable.nix` for details.
Instead of PIV, we use FIDO2 slots on Yubikey to generate resident (i.e.
stored solely on Yubikey itself) SSH keys using modern OpenSSH client built-in
FIDO2 support. This doesn't need an agent or a background daemon. The lack of
agent however means that these keys can not be forwarded to remote host for
further SSH, Git signing or push.
To generate a new key:
```
ssh-keygen -t ed25519-sk -O resident -O verify-required
# Omit "-O verify-required" to skip PIN; only if key is physically safe.
# Add "-O no-touch-required" to skip touch.
```
To restore "private key" files (remove `_rk` and drop them into `.ssh`):
```
ssh-keygen -K
```
To list or delete FIDO2 (and WebAuthn) credentials:
```
ykman fido credentials list
ykman fido credentials delete abcdef123
```
### SSH from VM
For trusted VMs, ssh-agent forwarding is configured in `.ssh/config.d/local`:
```
Host deimos
ForwardAgent yes
```
### Commit signing
Use SSH keys (from Apple SE and Yubikey) to sign commits. Make sure to generate
a different set of keys for signing than the one you use for authentication, to
decouple authentication from authorization and reduce key leakage blast radius.
Add `-O application=ssh:git-signature` to mark the key for signing (personal
convention).
### AGE encryption
All files are encrypted using some sort of hardware. Using an on-disk key alone
is not sufficient.
Each of the AGE plugins generates and subsequently during decryption uses a
(usually not sensitive) identity, which contains metadata about how to access
the specific cryptography on underlying hardware. Use the plugin directly to
initialize the hardware:
- `age-plugin-se keygen --access-control any-biometry-or-passcode`
- `age-plugin-yubikey --generate`
The identities which can be used to decrypt the secrets for editing (i.e.
Yubikey PIV, Apple SE) are concatenated into a single file:
- MacOS: `~/Library/Application Support/sops/age/keys.txt`
- Linux: `~/.config/sops/age/keys.txt`
which is not secret. You can only decrypt the data on the device where Yubikey
is plugged into, or one that has Apple SE or a TPM.
For Yubikey, you can also retrieve the identity using `age-plugin-yubikey -i`,
feeding the output directly into the identities file. To manage a Yubikey:
```
# Disable unused features
$ ykman config nfc --disable OTP
$ ykman config usb --disable OTP
# Check what's already there; slot 9A can be used by `O=yubikey-agent`; we don't
# rely on that key at the moment, see SSH above
$ ykman piv info
# To delete a key (age-plugin-yubikey uses 82 for slot 1, 83 for slot 2 etc).
$ ykman piv certificates delete 82
# Fully reset (initialize).
$ ykman piv reset
# See Bitwarden for keys
$ ykman piv access change-pin
$ ykman piv access change-puk
```
### Remote decryption
There's an ephemeral SSH server configured in `.ssh/ephemeral_sshd` which will
listen on localhost. If you port-forward it to remote machine, it can be
configured to run certain binaries (age plugins) through a reverse SSH
connection, which enables the use of local hardware to decrypt remote secrets.

View File

@@ -41,13 +41,8 @@ set switchbuf+=usetab " Switch to existing tab; open a new tab for the new buf
let mapleader=","
filetype off
runtime bundle/vim-pathogen/autoload/pathogen.vim
execute pathogen#infect()
set background=dark
colorscheme mydark
colorscheme torte
" Configure plugins.
@@ -71,22 +66,24 @@ let dart_format_on_save = 1
set viminfo='10,\"100,:100,n~/.viminfo
" Line width limit hint.
set colorcolumn=81
augroup EditorWidth
" colorcolumn breaks copy from terminal, so we use this instead.
au!
au BufEnter * highlight OverLength ctermbg=darkred
au BufEnter * match OverLength /\%81v./
au BufEnter *.go match OverLength /\%101v./
au BufEnter *.java match OverLength /\%101v./
au BufEnter *.data match OverLength /$$/
au BufEnter .vimrc match OverLength /$$/
au BufEnter *.go setlocal colorcolumn=101
au BufEnter *.java setlocal colorcolumn=101
au BufEnter *.data setlocal colorcolumn=0
au BufEnter .vimrc setlocal colorcolumn=0
augroup END
" Custom filetypes.
au BufNewFile,BufRead *.pi setf python
augroup FileTypeSettings
au!
au FileType groovy,java setlocal shiftwidth=4 expandtab
au FileType javascript,json,python,ruby setlocal shiftwidth=2 expandtab
augroup END
filetype indent off
" Automatically insert the current comment leader after hitting <Enter> in Insert mode.

View File

@@ -8,9 +8,9 @@ export PATH="${HOME}/bin:${PATH}"
# Since we exec right afterwards, there's no point in setting this shell up.
if [[ -o login ]]; then
[ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ] && \
[ -z "$STY" ] && \
which screen 2>/dev/null && \
exec screen -URR
[ -z "$TMUX" ] && \
command -v tmux >/dev/null && \
exec tmux new -A -D -s main
fi
HISTFILE=~/.zsh_history
@@ -62,7 +62,7 @@ alias grep='grep --line-buffered --color=auto'
alias ipt='iptables -nvL --line-numbers'
alias ip6t='ip6tables -nvL --line-numbers'
alias tcpdump='tcpdump -l'
alias ag='ag -C 2 --pager="$PAGER" --smart-case'
alias ag='ag -C 2 --noaffinity --pager="$PAGER" --smart-case'
alias mysql='mysql --select_limit=1000'
alias logcat='adb logcat -v "color printable usec year zone" -T 10'
alias readelf='readelf -W'
@@ -85,29 +85,47 @@ size: %{size_download}\n"'
# nix-deploy nas # deploy nas
# nix-deploy test secondary # deploy secondary but do not add to boot
nix-deploy() {
ACTION=switch
if [ $# -gt 1 ]; then
ACTION=$1
local action=switch target config cmd r_flake
if (( $# == 0 )); then
# Local deployment.
if [[ "$OSTYPE" == darwin* ]]; then
cmd=darwin-rebuild
r_flake="darwin#darwin-rebuild"
else
cmd=nixos-rebuild
r_flake="nixpkgs#nixos-rebuild"
fi
local run_cmd=($cmd)
command -v "$cmd" >/dev/null 2>&1 || run_cmd=(nix run "$r_flake" --)
sudo "${run_cmd[@]}" switch --flake . |& nom
# home-manager switch if exists.
local hm_conf="$(whoami)@$(hostname -s)"
if [[ "$(nix eval --json ".#homeConfigurations" --apply "x: x ? \"$hm_conf\"" 2>/dev/null)" == "true" ]]; then
local hm_run=(home-manager)
command -v home-manager >/dev/null 2>&1 || hm_run=(nix run "home-manager#home-manager" --)
"${hm_run[@]}" switch --flake .
fi
return
fi
# Remote deployment (always NixOS).
if (( $# == 1 )); then
target=$1
shift
fi
if which nixos-rebuild &>/dev/null; then
COMMAND=(nixos-rebuild)
else
COMMAND=(nix run nixpkgs#nixos-rebuild --)
fi
if [ $# -gt 0 ]; then
TARGET_HOST=$1 # user@host.domain
TARGET_WITH_DOMAIN=${TARGET_HOST#*@} # host.domain
TARGET=${TARGET_WITH_DOMAIN%%.*} # host
shift
"${COMMAND[@]}" "${ACTION?}" \
--flake ".#${TARGET?}" \
--target-host "${TARGET_HOST?}" \
--sudo \
"$@" |& nom
else
sudo "${COMMAND[@]}" switch --flake . |& nom
action=$1
target=$2
shift 2
fi
config=${${target#*@}%%.*}
cmd=(nixos-rebuild)
command -v nixos-rebuild >/dev/null 2>&1 || cmd=(nix run "nixpkgs#nixos-rebuild" --)
"${cmd[@]}" "$action" --flake ".#$config" --target-host "$target" --sudo "$@" |& nom
}
myip() {

7
bin/export-home-config Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
CONFIG=$1
OUT_DIR="exported/$CONFIG"
STORE_PATH=$(nix build .#homeConfigurations."$CONFIG".activationPackage --extra-experimental-features 'nix-command flakes' --no-link --print-out-paths)
mkdir -p "$OUT_DIR"
cp -rL "$STORE_PATH/home-files/." "$OUT_DIR/"

View File

@@ -0,0 +1,3 @@
[global]
hide_env_diff = true
warn_timeout = "30s"

View File

@@ -0,0 +1,603 @@
# -*- mode: sh -*-
# shellcheck shell=bash
# begin prologue inserted by resholve
NIX_DIRENV_FALLBACK_NIX=${NIX_DIRENV_FALLBACK_NIX:-/nix/store/bym3ycma17qshv526xjbdn2iayn6q7kr-nix-2.34.7/bin/nix}
# end prologue inserted by resholve
NIX_DIRENV_VERSION=3.1.1
# min required versions
BASH_MIN_VERSION=4.4
DIRENV_MIN_VERSION=2.21.3
_NIX_DIRENV_LOG_PREFIX="nix-direnv: "
_nix_direnv_info() {
log_status "${_NIX_DIRENV_LOG_PREFIX}$*"
}
_nix_direnv_warning() {
local msg=$*
local color_normal=""
local color_warning=""
if [[ -t 2 ]]; then
color_normal="\e[m"
color_warning="\e[33m"
fi
printf "%b" "$color_warning"
log_status "${_NIX_DIRENV_LOG_PREFIX}${msg}"
printf "%b" "$color_normal"
}
_nix_direnv_error() { log_error "${_NIX_DIRENV_LOG_PREFIX}$*"; }
_nix_direnv_nix=""
_nix() {
${_nix_direnv_nix} --no-warn-dirty --extra-experimental-features "nix-command flakes" "$@"
}
_require_version() {
local cmd=$1 raw_version=$2 version=${2%%[^0-9.]*} required=$3
if ! printf "%s\n" "$required" "$version" | LC_ALL=C /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/sort -c -V 2>/dev/null; then
_nix_direnv_error \
"minimum required $(/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/basename "$cmd") version is $required (installed: $raw_version)"
return 1
fi
}
_require_cmd_version() {
local cmd=$1 required=$2 version
if ! has "$cmd"; then
_nix_direnv_error "command not found: $cmd"
return 1
fi
version=$($cmd --version)
[[ $version =~ ([0-9]+\.[0-9]+(\.[0-9]+)?) ]]
_require_version "$cmd" "${BASH_REMATCH[1]}" "$required"
}
_nix_direnv_preflight() {
if [[ -z $direnv ]]; then
# shellcheck disable=2016
_nix_direnv_error '$direnv environment variable was not defined. Was this script run inside direnv?'
return 1
fi
# check command min versions
if [[ -z ${NIX_DIRENV_SKIP_VERSION_CHECK:-} ]]; then
# bash check uses $BASH_VERSION with _require_version instead of
# _require_cmd_version because _require_cmd_version uses =~ operator which would be
# a syntax error on bash < 3
if ! _require_version bash "$BASH_VERSION" "$BASH_MIN_VERSION" ||
# direnv stdlib defines $direnv
! _require_cmd_version "$direnv" "$DIRENV_MIN_VERSION"; then
return 1
fi
fi
if command -v nix >/dev/null 2>&1; then
_nix_direnv_nix=$(command -v nix)
elif [[ -n ${NIX_DIRENV_FALLBACK_NIX:-} ]]; then
_nix_direnv_nix="${NIX_DIRENV_FALLBACK_NIX}"
else
_nix_direnv_error "Could not find Nix binary, please add Nix to PATH or set NIX_DIRENV_FALLBACK_NIX"
return 1
fi
local layout_dir
layout_dir=$(direnv_layout_dir)
if [[ ! -d "$layout_dir/bin" ]]; then
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/mkdir -p "$layout_dir/bin"
fi
# N.B. This script relies on variable expansion in *this* shell.
# (i.e. The written out file will have the variables expanded)
# If the source path changes, the script becomes broken.
# Because direnv_layout_dir is user controlled,
# we can't assume to be able to reverse it to get the source dir
# So there's little to be done about this.
# Remove first to handle case where file is owned by a different user
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -f "${layout_dir}/bin/nix-direnv-reload"
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/cat >"${layout_dir}/bin/nix-direnv-reload" <<-EOF
#!/usr/bin/env bash
set -e
if [[ ! -d "$PWD" ]]; then
echo "Cannot find source directory; Did you move it?"
echo "(Looking for "$PWD")"
echo 'Cannot force reload with this script - use "direnv reload" manually and then try again'
exit 1
fi
# rebuild the cache forcefully
_nix_direnv_force_reload=1 direnv exec "$PWD" true
# Update the mtime for .envrc.
# This will cause direnv to reload again - but without re-building.
touch "$PWD/.envrc"
# Also update the timestamp of whatever profile_rc we have.
# This makes sure that we know we are up to date.
touch -r "$PWD/.envrc" "${layout_dir}"/*.rc
EOF
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/chmod +x "${layout_dir}/bin/nix-direnv-reload"
PATH_add "${layout_dir}/bin"
}
# Usage: nix_direnv_version <version_at_least>
#
# Checks that the nix-direnv version is at least as old as <version_at_least>.
nix_direnv_version() {
_require_version nix-direnv $NIX_DIRENV_VERSION "$1"
}
_nix_export_or_unset() {
local key=$1 value=$2
if [[ $value == __UNSET__ ]]; then
unset "$key"
else
export "$key=$value"
fi
}
_nix_import_env() {
local profile_rc=$1
local -A values_to_restore=(
["NIX_BUILD_TOP"]=${NIX_BUILD_TOP:-__UNSET__}
["TMP"]=${TMP:-__UNSET__}
["TMPDIR"]=${TMPDIR:-__UNSET__}
["TEMP"]=${TEMP:-__UNSET__}
["TEMPDIR"]=${TEMPDIR:-__UNSET__}
["terminfo"]=${terminfo:-__UNSET__}
)
local old_xdg_data_dirs=${XDG_DATA_DIRS:-}
# On the first run in manual mode, the profile_rc does not exist.
if [[ ! -e $profile_rc ]]; then
return
fi
eval "$(<"$profile_rc")"
# `nix print-dev-env` will create a temporary directory and use it as TMPDIR
# We cannot rely on this directory being available at all times,
# as it may be garbage collected.
# Instead - just remove it immediately.
# Use recursive & force as it may not be empty.
if [[ -n ${NIX_BUILD_TOP+x} && $NIX_BUILD_TOP == */nix-shell.* && -d $NIX_BUILD_TOP ]]; then
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -rf "$NIX_BUILD_TOP"
fi
for key in "${!values_to_restore[@]}"; do
_nix_export_or_unset "$key" "${values_to_restore[${key}]}"
done
local new_xdg_data_dirs=${XDG_DATA_DIRS:-}
export XDG_DATA_DIRS=
local IFS=:
for dir in $new_xdg_data_dirs${old_xdg_data_dirs:+:}$old_xdg_data_dirs; do
dir="${dir%/}" # remove trailing slashes
if [[ :$XDG_DATA_DIRS: == *:$dir:* ]]; then
continue # already present, skip
fi
XDG_DATA_DIRS="$XDG_DATA_DIRS${XDG_DATA_DIRS:+:}$dir"
done
}
_nix_add_gcroot() {
local storepath=$1
local symlink=$2
_nix build --out-link "$symlink" "$storepath"
}
_nix_refresh_gcroots() {
# Use touch to update all symlinks' timestamps to prevent nh
# from garbage collecting the frequently used direnv environment.
local layout_dir
layout_dir=$(direnv_layout_dir)
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/touch -h "${layout_dir}"/flake-profile-* "${layout_dir}"/flake-inputs/* "${layout_dir}"/nix-profile-*
}
_nix_clean_old_gcroots() {
local layout_dir=$1
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -rf "$layout_dir/flake-inputs/"
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -f "$layout_dir"/{nix,flake}-profile*
}
_nix_argsum_suffix() {
local out checksum
if [ -n "$1" ]; then
if has sha1sum; then
out=$(/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/sha1sum <<<"$1")
elif has shasum; then
out=$(shasum <<<"$1")
else
# degrade gracefully both tools are not present
return
fi
read -r checksum _ <<<"$out"
echo "-$checksum"
fi
}
nix_direnv_watch_file() {
# shellcheck disable=2016
log_error '`nix_direnv_watch_file` is deprecated - use `watch_file`'
watch_file "$@"
}
_nix_direnv_watches() {
local -n _watches=$1
if [[ -z ${DIRENV_WATCHES-} ]]; then
return
fi
while IFS= read -r line; do
local regex='"[Pp]ath": "(.+)"$'
if [[ $line =~ $regex ]]; then
local path="${BASH_REMATCH[1]}"
if [[ $path == "${XDG_DATA_HOME:-${HOME:-/var/empty}/.local/share}/direnv/allow/"* ]]; then
continue
fi
# expand new lines and other json escapes
# shellcheck disable=2059
path=$(printf "$path")
_watches+=("$path")
fi
done < <($direnv show_dump "${DIRENV_WATCHES}")
}
: "${_nix_direnv_manual_reload:=0}"
nix_direnv_manual_reload() {
_nix_direnv_manual_reload=1
}
: "${_nix_direnv_allow_fallback:=1}"
nix_direnv_disallow_fallback() {
_nix_direnv_info "Fallback disallowed"
_nix_direnv_allow_fallback=0
}
_nix_direnv_warn_manual_reload() {
if [[ -e $1 ]]; then
_nix_direnv_warning 'cache is out of date. use "nix-direnv-reload" to reload'
else
_nix_direnv_warning 'cache does not exist. use "nix-direnv-reload" to create it'
fi
}
use_flake() {
if ! _nix_direnv_preflight; then
return 1
fi
flake_expr="${1:-.}"
flake_uri="${flake_expr%#*}"
flake_dir=${flake_uri#"path:"}
if [[ $flake_expr == -* ]]; then
local message="the first argument must be a flake expression"
if [[ -n ${2:-} ]]; then
_nix_direnv_error "$message"
return 1
else
_nix_direnv_error "$message. did you mean 'use flake . $1'?"
return 1
fi
fi
local files_to_watch
files_to_watch=("$HOME/.direnvrc" "$HOME/.config/direnv/direnvrc")
if [[ -d $flake_dir ]]; then
files_to_watch+=("$flake_dir/flake.nix" "$flake_dir/flake.lock" "$flake_dir/devshell.toml")
fi
watch_file "${files_to_watch[@]}"
local layout_dir profile
layout_dir=$(direnv_layout_dir)
profile="${layout_dir}/flake-profile$(_nix_argsum_suffix "$flake_expr")"
local profile_rc="${profile}.rc"
local flake_inputs="${layout_dir}/flake-inputs/"
local watches
_nix_direnv_watches watches
local profile_missing=0
if [[ ! -e $profile ]]; then
_nix_direnv_info "cache invalidated: profile ($profile) does not exist"
profile_missing=1
fi
local profile_rc_missing=0
if [[ ! -e $profile_rc ]]; then
_nix_direnv_info "cache invalidated: profile_rc ($profile_rc) does not exist"
profile_rc_missing=1
fi
local file_nt_profilerc=0
local file=
local newer_files
for file in "${watches[@]}"; do
if [[ $file -nt $profile_rc ]]; then
newer_files+=("$file")
file_nt_profilerc=1
fi
done
if [[ $file_nt_profilerc -eq 1 ]]; then
_nix_direnv_info "cache invalidated: files newer than cache:"
echo -n "$_NIX_DIRENV_LOG_PREFIX" >/dev/stderr
printf "%s\n" "${newer_files[@]}" >/dev/stderr
fi
if [[ $profile_missing -eq 1 || $profile_rc_missing -eq 1 || $file_nt_profilerc -eq 1 ]]; then
if [[ $_nix_direnv_manual_reload -eq 1 && -z ${_nix_direnv_force_reload-} ]]; then
_nix_direnv_warn_manual_reload "$profile_rc"
else
local tmp_profile_rc
local tmp_profile="${layout_dir}/flake-tmp-profile.$$"
if tmp_profile_rc=$(_nix print-dev-env --profile "$tmp_profile" "$@"); then
# If we've gotten here, the user's current devShell is valid and we should cache it
_nix_clean_old_gcroots "$layout_dir"
# We need to update our cache
echo "$tmp_profile_rc" >"$profile_rc"
_nix_add_gcroot "$tmp_profile" "$profile"
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -f "$tmp_profile" "$tmp_profile"*
# also add garbage collection root for source
local flake_input_paths
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/mkdir -p "$flake_inputs"
flake_input_paths=$(_nix flake archive \
--json --no-write-lock-file \
-- "$flake_uri")
while [[ $flake_input_paths =~ /nix/store/[^\"]+ ]]; do
local store_path="${BASH_REMATCH[0]}"
_nix_add_gcroot "${store_path}" "${flake_inputs}/${store_path##*/}"
flake_input_paths="${flake_input_paths/${store_path}/}"
done
_nix_direnv_info "Renewed cache"
else
# The user's current flake failed to evaluate,
# but there is already a prior profile_rc,
# which is probably more useful than nothing.
# Fallback to use that (which means just leaving profile_rc alone!)
if [[ $_nix_direnv_allow_fallback -eq 1 ]]; then
_nix_direnv_warning "Evaluating current devShell failed. Falling back to previous environment!"
export NIX_DIRENV_DID_FALLBACK=1
else
return 1
fi
fi
fi
else
if [[ -e ${profile_rc} ]]; then
# Our cache is valid, use that
_nix_direnv_info "Using cached dev shell"
_nix_refresh_gcroots
else
# We don't have a profile_rc to use!
_nix_direnv_error "use_flake failed - Is your flake's devShell working?"
return 1
fi
fi
_nix_import_env "$profile_rc"
}
use_nix() {
if ! _nix_direnv_preflight; then
return 1
fi
local layout_dir path version
layout_dir=$(direnv_layout_dir)
if path=$(/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/realpath -e "$(_nix eval --impure --expr "<nixpkgs>" 2>/dev/null)"); then
if [[ -f "${path}/.version-suffix" ]]; then
version=$(<"${path}/.version-suffix")
elif [[ -f "${path}/.git/HEAD" ]]; then
local head
read -r head <"${path}/.git/HEAD"
local regex="ref: (.*)"
if [[ $head =~ $regex ]]; then
read -r version <"${path}/.git/${BASH_REMATCH[1]}"
else
version="$head"
fi
elif [[ -f "${path}/.version" && ${path} == "/nix/store/"* ]]; then
# borrow some bits from the store path
local version_prefix
read -r version_prefix < <(
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/cat "${path}/.version"
echo
)
version="${version_prefix}-${path:11:16}"
fi
fi
local profile
profile="${layout_dir}/nix-profile-${version:-unknown}$(_nix_argsum_suffix "$*")"
local profile_rc="${profile}.rc"
local in_packages=0
local attribute=
local packages=""
local extra_args=()
local nixfile=
if [[ -e "shell.nix" ]]; then
nixfile="./shell.nix"
elif [[ -e "default.nix" ]]; then
nixfile="./default.nix"
fi
while [[ $# -gt 0 ]]; do
i="$1"
shift
case $i in
-p | --packages)
in_packages=1
;;
--command | --run | --exclude)
# These commands are unsupported
# ignore them
shift
;;
--pure | -i | --keep)
# These commands are unsupported (but take no argument)
# ignore them
;;
--include | -I)
extra_args+=("$i" "${1:-}")
shift
;;
--attr | -A)
attribute="${1:-}"
shift
;;
--option | -o | --arg | --argstr)
extra_args+=("$i" "${1:-}" "${2:-}")
shift
shift
;;
-*)
# Other arguments are assumed to be of a single arg form
# (--foo=bar or -j4)
extra_args+=("$i")
;;
*)
if [[ $in_packages -eq 1 ]]; then
packages+=" $i"
else
nixfile=$i
fi
;;
esac
done
watch_file "$HOME/.direnvrc" "$HOME/.config/direnv/direnvrc" "shell.nix" "default.nix"
local watches
_nix_direnv_watches watches
local profile_missing=0
if [[ ! -e $profile ]]; then
_nix_direnv_info "cache invalidated: profile ($profile) does not exist"
profile_missing=1
fi
local profile_rc_missing=0
if [[ ! -e $profile_rc ]]; then
_nix_direnv_info "cache invalidated: profile_rc ($profile_rc) does not exist"
profile_rc_missing=1
fi
local file_nt_profilerc=0
local file=
local newer_files
for file in "${watches[@]}"; do
if [[ $file -nt $profile_rc ]]; then
newer_files+=("$file")
file_nt_profilerc=1
fi
done
if [[ $file_nt_profilerc -eq 1 ]]; then
_nix_direnv_info "cache invalidated: files newer than cache:"
echo -n "$_NIX_DIRENV_LOG_PREFIX" >/dev/stderr
printf "%s\n" "${newer_files[@]}" >/dev/stderr
fi
if [[ $profile_missing -eq 1 || $profile_rc_missing -eq 1 || $file_nt_profilerc -eq 1 ]]; then
if [[ $_nix_direnv_manual_reload -eq 1 && -z ${_nix_direnv_force_reload-} ]]; then
_nix_direnv_warn_manual_reload "$profile_rc"
else
local tmp_profile="${layout_dir}/nix-tmp-profile.$$"
local tmp_profile_rc
if [[ -n $packages ]]; then
extra_args+=("--expr" "with import <nixpkgs> {}; mkShell { buildInputs = [ $packages ]; }")
else
extra_args+=("--file" "$nixfile" --arg inNixShell true)
if [[ -n $attribute ]]; then
extra_args+=("$attribute")
fi
fi
# Some builtin nix tooling depends on this variable being set BEFORE their invocation to change their behavior
# (notably haskellPackages.developPackage returns an env if this is set)
# This allows us to more closely mimic nix-shell.
export IN_NIX_SHELL="impure"
if tmp_profile_rc=$(_nix \
print-dev-env \
--profile "$tmp_profile" \
--impure \
"${extra_args[@]}"); then
_nix_clean_old_gcroots "$layout_dir"
echo "$tmp_profile_rc" >"$profile_rc"
_nix_add_gcroot "$tmp_profile" "$profile"
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -f "$tmp_profile" "$tmp_profile"*
_nix_direnv_info "Renewed cache"
else
if [[ $_nix_direnv_allow_fallback -eq 1 ]]; then
_nix_direnv_warning "Evaluating current nix shell failed. Falling back to previous environment!"
export NIX_DIRENV_DID_FALLBACK=1
else
unset IN_NIX_SHELL
return 1
fi
fi
fi
else
if [[ -e ${profile_rc} ]]; then
_nix_direnv_info "Using cached dev shell"
_nix_refresh_gcroots
else
_nix_direnv_error "use_nix failed - Is your nix shell working?"
unset IN_NIX_SHELL
return 1
fi
fi
_nix_import_env "$profile_rc"
}
### resholve directives (auto-generated) ## format_version: 3
# resholve: fake builtin:PATH_add
# resholve: fake builtin:direnv_layout_dir
# resholve: fake builtin:has
# resholve: fake builtin:log_error
# resholve: fake builtin:log_status
# resholve: fake builtin:watch_file
# resholve: fake external:nix
# resholve: fake function:shasum
# resholve: keep $NIX_DIRENV_FALLBACK_NIX
# resholve: keep $_nix_direnv_nix
# resholve: keep $ambient_nix
# resholve: keep $cmd
# resholve: keep $direnv
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/basename
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/cat
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/chmod
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/mkdir
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/realpath
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/sha1sum
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/sort
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/touch

View File

@@ -0,0 +1,83 @@
set -g default-terminal "screen"
set -g base-index 0
setw -g pane-base-index 0
set -g status-keys vi
set -g mode-keys vi
bind -N "Select pane to the left of the active pane" h select-pane -L
bind -N "Select pane below the active pane" j select-pane -D
bind -N "Select pane above the active pane" k select-pane -U
bind -N "Select pane to the right of the active pane" l select-pane -R
bind -r -N "Resize the pane left by 5" \
H resize-pane -L 5
bind -r -N "Resize the pane down by 5" \
J resize-pane -D 5
bind -r -N "Resize the pane up by 5" \
K resize-pane -U 5
bind -r -N "Resize the pane right by 5" \
L resize-pane -R 5
# rebind main key: C-a
unbind C-b
set -g prefix C-a
bind -N "Send the prefix key through to the application" \
C-a send-prefix
set -g mouse on
set -g focus-events off
setw -g aggressive-resize off
setw -g clock-mode-style 12
set -s escape-time 0
set -g history-limit 10240
set-environment -g SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
set-option -g update-environment "DISPLAY SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION"
# Instead of flashing or beeping, blink the window in status.
set -g visual-bell off
set -g monitor-activity on
set -g bell-action none
set -g window-status-activity-style "fg=yellow,blink"
# Requires support from terminal (e.g. iTerm2).
set -s set-clipboard on
# For scrolling through logs.
bind y set-window-option synchronize-panes
# Panel configuration.
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
bind Enter resize-pane -Z
# Navigation.
bind -n M-Up new-window -c "#{pane_current_path}"
bind -n M-Down confirm-before -p "kill-window #W? (y/n)" kill-window
bind -n M-Left previous-window
bind -n M-Right next-window
# Status bar.
set -g status-interval 5
set -g status-position bottom
set -g status-style "bg=default,fg=white"
set -g status-left-length 20
set -g status-left "#[fg=green,bold]#H #[fg=white]| "
set -g status-right-length 60
set -g status-right "#[fg=cyan]%H:%M%Z %d.%m.%Y #[fg=white]| #[fg=yellow]Load: #(cut -d ' ' -f 1-3 /proc/loadavg)"
set -g status-justify left
set -g window-status-format "#[fg=white,dim]#I:#W#F"
set -g window-status-current-format "#[fg=white,bold,bg=blue] #I:#W#F "

View File

View File

@@ -0,0 +1,27 @@
# Environment variables
. "/nix/store/qvbn8gycz1r5r2n7ffx60258jwhsf9qs-hm-session-vars.sh/etc/profile.d/hm-session-vars.sh"
# Only source this once
if [[ -z "$__HM_ZSH_SESS_VARS_SOURCED" ]]; then
export __HM_ZSH_SESS_VARS_SOURCED=1
fi
[ -r ~/.zshenv_local ] && source ~/.zshenv_local || true
# Can't use ssh-agent-mux to mux Secretive and yubikey-agent:
# https://github.com/overhacked/ssh-agent-mux/issues/56
# export SSH_AUTH_SOCK=~/.ssh/ssh-agent-mux.sock
# Can't use Secretive to SSH using PIV from Yubikey:
# https://github.com/maxgoedjen/secretive/issues/330
#
# If PIV entry was generated by yubikey-agent, Secretive may not see it at
# all. Running 'ykman piv objects generate chuid' should fix that.
# https://github.com/maxgoedjen/secretive/issues/333
# See README.md "Security" section to learn how we create keys.
# Setting IdentityAgent in SSH config achieves a similar result, but doesn't
# work with commit signing.
export SSH_AUTH_SOCK=~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh

View File

@@ -0,0 +1,41 @@
typeset -U path cdpath fpath manpath
for profile in ${(z)NIX_PROFILES}; do
fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions)
done
HELPDIR="/nix/store/0vkfqzpklvs9nmx6439vqwvlzwryd60j-zsh-5.9/share/zsh/$ZSH_VERSION/help"
autoload -U compinit && compinit
# History options should be set in .zshrc and after oh-my-zsh sourcing.
# See https://github.com/nix-community/home-manager/issues/177.
HISTSIZE="10000"
SAVEHIST="10000"
HISTFILE="/Users/empty/.zsh_history"
mkdir -p "$(dirname "$HISTFILE")"
# Set shell options
set_opts=(
HIST_FCNTL_LOCK HIST_IGNORE_DUPS HIST_IGNORE_SPACE SHARE_HISTORY
NO_APPEND_HISTORY NO_EXTENDED_HISTORY NO_HIST_EXPIRE_DUPS_FIRST
NO_HIST_FIND_NO_DUPS NO_HIST_IGNORE_ALL_DUPS NO_HIST_SAVE_NO_DUPS
)
for opt in "${set_opts[@]}"; do
setopt "$opt"
done
unset opt set_opts
# Outside NixOS, we need to load this manually. Same on MacOS, if
# /etc/zshrc is reset to its default content (post-upgrade).
if [ -r /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh ]; then
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
fi
if [ -r ~/dotfiles/assets/.zshrc ]; then
# Hack for faster iterations
. ~/dotfiles/assets/.zshrc
else
. /nix/store/036d8d9k0wqwsg88azvzb8lb02hd22n2-.zshrc
fi
eval "$(/nix/store/wjg69ndjcayriaav4rqrfq93rqn8hsq4-direnv-2.37.1/bin/direnv hook zsh)"

View File

@@ -0,0 +1 @@
{"Profiles":[{"Columns":160,"Guid":"17DF2CCB-C7CD-4BCC-AC28-666DD6C8AF4A","Mouse Reporting":true,"Name":"Nix-Managed","Normal Font":"Menlo-Regular 13","Rows":45}]}

View File

@@ -0,0 +1 @@
/nix/store/f1p62r5lq4ilsj6kla8mmzfqj4q57x45-home-manager-fonts

262
flake.lock generated
View File

@@ -1,8 +1,77 @@
{
"nodes": {
"brew-src": {
"flake": false,
"locked": {
"lastModified": 1778146321,
"narHash": "sha256-HeBwuJmuBioZHyZqDOcf7W/xsMFupSD583v6I5Cl7a8=",
"owner": "Homebrew",
"repo": "brew",
"rev": "af835384ac574f76025adb38b292b04cecee1f1f",
"type": "github"
},
"original": {
"owner": "Homebrew",
"ref": "5.1.10",
"repo": "brew",
"type": "github"
}
},
"darwin": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1777780666,
"narHash": "sha256-8wURyQMdDkGUarSTKOGdCuFfYiwa3HbzwscUfn3STDE=",
"owner": "nix-darwin",
"repo": "nix-darwin",
"rev": "8c62fba0854ba15c8917aed18894dbccb48a3777",
"type": "github"
},
"original": {
"owner": "nix-darwin",
"repo": "nix-darwin",
"type": "github"
}
},
"flake-compat": {
"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-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-utils": {
"inputs": {
"systems": "systems"
"systems": "systems_3"
},
"locked": {
"lastModified": 1681202837,
@@ -18,6 +87,116 @@
"type": "github"
}
},
"fw_nix": {
"inputs": {
"git-hooks": "git-hooks",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1778705491,
"narHash": "sha256-LOZbixhLsv2QbUbqH+I06eRMAI7FBDDkGoMWH523OkE=",
"ref": "refs/heads/main",
"rev": "b6fb4221bd5f54bc427de84230e0c95952399c21",
"revCount": 25,
"type": "git",
"url": "https://github.com/futureware-tech/nix.git"
},
"original": {
"type": "git",
"url": "https://github.com/futureware-tech/nix.git"
}
},
"git-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"fw_nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1778507602,
"narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"git-hooks_2": {
"inputs": {
"flake-compat": "flake-compat_2",
"gitignore": "gitignore_2",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1778507602,
"narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"fw_nix",
"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"
}
},
"gitignore_2": {
"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"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -25,11 +204,11 @@
]
},
"locked": {
"lastModified": 1774007980,
"narHash": "sha256-FOnZjElEI8pqqCvB6K/1JRHTE8o4rer8driivTpq2uo=",
"lastModified": 1778503501,
"narHash": "sha256-08L/X4/do7nET4rzidJ76eV/1r+mB7DchVpdPypsghc=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "9670de2921812bc4e0452f6e3efd8c859696c183",
"rev": "85ba629c79449badf4338117c27f0ee92b4b9f1a",
"type": "github"
},
"original": {
@@ -38,13 +217,46 @@
"type": "github"
}
},
"jail-nix": {
"locked": {
"lastModified": 1772137954,
"narHash": "sha256-h4MGNbOo7L3RHi4uNFmsg5g17/DHXEfnv/xiG6BrNFQ=",
"owner": "~alexdavid",
"repo": "jail.nix",
"rev": "42b355c38ca63dab4904acc5c0d95f17954a8c9b",
"type": "sourcehut"
},
"original": {
"owner": "~alexdavid",
"repo": "jail.nix",
"type": "sourcehut"
}
},
"nix-homebrew": {
"inputs": {
"brew-src": "brew-src"
},
"locked": {
"lastModified": 1778332591,
"narHash": "sha256-ctJ3ADtugrnbMfMBobA645gCqXVIyHnsCNMkVaIuSiM=",
"owner": "zhaofengli",
"repo": "nix-homebrew",
"rev": "7d0038b5bb60568ec41f5f4ef5067cd221ca7c0d",
"type": "github"
},
"original": {
"owner": "zhaofengli",
"repo": "nix-homebrew",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1773821835,
"narHash": "sha256-TJ3lSQtW0E2JrznGVm8hOQGVpXjJyXY2guAxku2O9A4=",
"lastModified": 1777954456,
"narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "b40629efe5d6ec48dd1efba650c797ddbd39ace0",
"rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1",
"type": "github"
},
"original": {
@@ -56,8 +268,14 @@
},
"root": {
"inputs": {
"darwin": "darwin",
"fw_nix": "fw_nix",
"git-hooks": "git-hooks_2",
"home-manager": "home-manager",
"jail-nix": "jail-nix",
"nix-homebrew": "nix-homebrew",
"nixpkgs": "nixpkgs",
"systems": "systems_2",
"vscode-server": "vscode-server"
}
},
@@ -76,6 +294,36 @@
"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"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"vscode-server": {
"inputs": {
"flake-utils": "flake-utils",

191
flake.nix
View File

@@ -3,6 +3,7 @@
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
systems.url = "github:nix-systems/default";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
@@ -11,96 +12,146 @@
url = "github:nix-community/nixos-vscode-server";
inputs.nixpkgs.follows = "nixpkgs";
};
fw_nix = {
url = "git+https://github.com/futureware-tech/nix.git";
inputs.nixpkgs.follows = "nixpkgs";
};
darwin = {
url = "github:nix-darwin/nix-darwin";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-homebrew.url = "github:zhaofengli/nix-homebrew";
git-hooks = {
url = "github:cachix/git-hooks.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
jail-nix.url = "sourcehut:~alexdavid/jail.nix";
};
outputs =
{
self,
nixpkgs,
systems,
home-manager,
vscode-server,
}:
darwin,
...
}@inputs:
let
trustedSSHKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBxRBsFGa8OFbviYDGSAKLgfm/K2XUxvCo+31FW37yab artem"
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIPAtIXXHm58julnr7S0xzBTM1jN5JkKxOL4JpuWDOa2jAAAABHNzaDo= office-dock-usb-a"
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIHY1xx0huqV6Mcc2WngYDabITeNUbGamJ8//206MxxVTAAAABHNzaDo= keychain-usb-c"
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIHzY2eOz+JdaKOpIgZbF5FsZzQy0l8vPJjAQdTpBFGsoAAAABHNzaDo= safe"
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJg7zQ4H0LQeQcILZBwCzQ+MYKtCgKm7HPe9oFeoyprKZXAvpm+HDHtaYdU39JF9f+nvRztzXuMhgETAQMAQCkc= fingerprint@macbook"
];
eachSystem = nixpkgs.lib.genAttrs (import systems);
in
{
homeModules.main = {
imports = [ ./modules/home.nix ];
checks = eachSystem (system: {
pre-commit-check = inputs.git-hooks.lib.${system}.run (
{
src = ./.;
excludes = [ "^exported/" ];
hooks.export-mac-portable = {
enable = nixpkgs.lib.hasInfix "darwin" system;
name = "Build static mac-portable home directory files";
entry = "bin/export-home-config mac-portable && git add exported/mac-portable";
pass_filenames = false;
};
}
// inputs.fw_nix.lib.pre-commit
);
});
homeModules = {
mac-portable = import ./modules/home/mac-portable.nix;
linux-headless = import ./modules/home/linux-headless.nix;
};
darwinModules = {
mac-portable = import ./modules/darwin/mac-portable.nix;
};
nixosModules = {
linux-headless = import ./modules/nixos/linux-headless.nix;
linux-lxc = import ./modules/nixos/linux-lxc.nix;
};
homeConfigurations."linux-headless" = home-manager.lib.homeManagerConfiguration {
homeConfigurations."artem@deimos" = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-linux;
extraSpecialArgs.primaryUser = "artem";
modules = [
self.homeModules.main
vscode-server.homeModules.default
(
{ lib, ... }:
{
home.username = "artem";
home.homeDirectory = "/home/artem";
services.vscode-server.enable = true;
services.vscode-server.installPath = [
"$HOME/.vscode-server"
"$HOME/.antigravity-server"
];
}
)
self.homeModules.linux-headless
./hosts/deimos/home.nix
];
};
homeConfigurations."mac-portable" = home-manager.lib.homeManagerConfiguration {
homeConfigurations."artem@mars" = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-darwin;
extraSpecialArgs = {
primaryUser = "artem";
inherit trustedSSHKeys;
};
modules = [
self.homeModules.main
(
{ pkgs, ... }:
{
# TODO: consider
# https://nest.pijul.com/yonkeltron/macOS-nix-config:main/ZLDSMIXK5XFW6.EIAAA
home.username = "artem";
home.homeDirectory = "/Users/artem";
home.packages = with pkgs; [
secretive
vlc-bin
dosbox-staging # dosbox appears broken on darwin
# 1. Move config file to /usr/local/etc/wireguard/wg0.conf
# 2. sudo wg-quick up wg0
wireguard-tools
wireguard-go
antigravity
];
nixpkgs.config.allowUnfree = true;
programs.vscode.enable = true;
launchd.agents.keyboard-remap = {
# Remap top-left key (paragraph) to backquote and backslash like
# proper ISO keyboard does, and the key right to the LShift to
# Shift.
enable = true;
config = {
Label = "com.user.keyboard-remap";
ProgramArguments = [
"/usr/bin/hidutil"
"property"
"--set"
''
{"UserKeyMapping":
[
{"HIDKeyboardModifierMappingSrc":0x700000035, "HIDKeyboardModifierMappingDst":0x7000000e1},
{"HIDKeyboardModifierMappingSrc":0x700000064, "HIDKeyboardModifierMappingDst":0x700000035},
]
}''
];
RunAtLoad = true;
};
};
}
)
self.homeModules.mac-portable
./hosts/mars/home.nix
];
};
homeConfigurations.mac-portable = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-darwin;
extraSpecialArgs.primaryUser = "empty";
modules = [ self.homeModules.mac-portable ];
};
darwinConfigurations.mars = darwin.lib.darwinSystem {
system = "x86_64-darwin";
specialArgs.primaryUser = "artem";
modules = [
self.darwinModules.mac-portable
inputs.fw_nix.nixosModules.tools
inputs.fw_nix.nixosModules.nix-settings
inputs.fw_nix.nixosModules.futureware
inputs.nix-homebrew.darwinModules.nix-homebrew
./hosts/mars/darwin.nix
];
};
nixosConfigurations.deimos =
let
system = "x86_64-linux";
in
nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = {
inherit trustedSSHKeys;
inherit (inputs) jail-nix;
};
modules = [
self.nixosModules.linux-headless
self.nixosModules.linux-lxc
inputs.fw_nix.nixosModules.nix-gc
inputs.fw_nix.nixosModules.nix-settings
inputs.fw_nix.nixosModules.tools
inputs.fw_nix.nixosModules.sshd
inputs.fw_nix.nixosModules.futureware
./hosts/deimos/nixos.nix
];
};
devShells = eachSystem (
system:
let
pkgs = import nixpkgs { inherit system; };
inherit (self.checks.${system}.pre-commit-check) shellHook enabledPackages;
in
{
default = pkgs.mkShell {
packages = enabledPackages;
inherit shellHook;
};
}
);
};
}

33
hosts/deimos/home.nix Normal file
View File

@@ -0,0 +1,33 @@
_: {
home.homeDirectory = "/home/artem";
services.vscode-server.enable = true;
services.vscode-server.installPath = [
"$HOME/.vscode-server"
"$HOME/.antigravity-server"
];
systemd.user.mounts.home-artem-src-haremote = {
Unit = {
Description = "Mount ~/src/haremote";
After = [ "network-online.target" ];
Wants = [ "network-online.target" ];
};
Mount = {
What = "root@homeassistant.home.arpa:/homeassistant";
Where = "/home/artem/src/haremote";
Type = "fuse.sshfs";
Options = "reconnect,ServerAliveInterval=15,uid=1000,gid=1000,IdentityAgent=/home/artem/.ssh/ssh_auth_sock";
};
Install = {
WantedBy = [ "default.target" ];
};
};
programs.zsh.loginExtra = ''
if [ -n "$SSH_AUTH_SOCK" ]; then
mkdir -p ~/src/haremote
[ -z "$(ls -A ~/src/haremote 2>/dev/null)" ] && systemctl --user restart home-artem-src-haremote.mount
fi
'';
}

85
hosts/deimos/nixos.nix Normal file
View File

@@ -0,0 +1,85 @@
{
pkgs,
trustedSSHKeys,
jail-nix,
...
}:
let
jail = jail-nix.lib.init pkgs;
in
{
users.users.artem = {
uid = 1000;
isNormalUser = true;
extraGroups = [
"wheel"
"docker"
];
openssh.authorizedKeys.keys = trustedSSHKeys;
shell = pkgs.zsh;
linger = true; # Keep sshfs mounted even on logout.
};
virtualisation.docker.enable = true;
environment.systemPackages = with pkgs; [
# TODO: move below into hosts/deimos/home.nix
sshfs
nixd
home-assistant-cli
yt-dlp
# jailed-gemini --yolo
(jail "jailed-gemini" pkgs.gemini-cli (
with jail.combinators;
[
network
time-zone
no-new-session
mount-cwd
(readwrite (noescape "~/.gemini"))
# The above is a stow-controlled symlink to the following.
(readwrite (noescape "~/dotfiles/legacy/.gemini"))
(add-pkg-deps (
with pkgs;
[
bashInteractive
curl
wget
jq
git
which
ripgrep
gnugrep
gnused
gawkInteractive
ps
findutils
gzip
unzip
gnutar
diffutils
coreutils
procps
python3
esphome
nix
]
))
]
))
];
# For building RPi configs. Extra steps are handled by the host (nas).
# https://discuss.linuxcontainers.org/t/systemd-binfmt-service-is-masked/21566/4
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
networking = {
hostName = "deimos";
domain = "home.arpa";
};
}

5
hosts/mars/darwin.nix Normal file
View File

@@ -0,0 +1,5 @@
_: {
homebrew.casks = [
"bambu-studio"
];
}

52
hosts/mars/home.nix Normal file
View File

@@ -0,0 +1,52 @@
{
pkgs,
lib,
trustedSSHKeys,
...
}:
{
home.packages = with pkgs; [
dosbox-staging # dosbox appears broken on darwin
# 1. Move config file to /usr/local/etc/wireguard/wg0.conf
# 2. sudo wg-quick up wg0
wireguard-tools
wireguard-go
antigravity
];
home.activation.setupAuthorizedKeys = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
run install -m 0600 -D \
${pkgs.writeText "keys" (builtins.concatStringsSep "\n" trustedSSHKeys)} \
''${HOME?}/.ssh/ephemeral_sshd/authorized_keys
'';
# TODO: consider
# https://nest.pijul.com/yonkeltron/macOS-nix-config:main/ZLDSMIXK5XFW6.EIAAA
# and
# https://github.com/bgub/nix-macos-starter/tree/main
launchd.agents.keyboard-remap = {
# Remap top-left key (paragraph) to backquote and backslash like
# proper ISO keyboard does, and the key right to the LShift to
# Shift.
enable = true;
config = {
Label = "com.user.keyboard-remap";
ProgramArguments = [
"/usr/bin/hidutil"
"property"
"--set"
''
{"UserKeyMapping":
[
{"HIDKeyboardModifierMappingSrc":0x700000035, "HIDKeyboardModifierMappingDst":0x7000000e1},
{"HIDKeyboardModifierMappingSrc":0x700000064, "HIDKeyboardModifierMappingDst":0x700000035},
]
}''
];
RunAtLoad = true;
};
};
}

View File

@@ -9,7 +9,7 @@
"**/.svn": true,
"**/.vscode": true,
"**/*.g.dart": true,
"**/CVS": true
"**/CVS": true,
},
"files.autoSave": "onFocusChange",
"terminal.integrated.fontSize": 13,
@@ -24,7 +24,7 @@
// Disable [confusing] file icons in Explorer
"workbench.iconTheme": null,
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
"source.organizeImports": "explicit",
},
"debug.toolBarLocation": "docked",
"debug.openDebug": "openOnDebugBreak",
@@ -39,7 +39,7 @@
"Pluginfile": "ruby",
"Matchfile": "ruby",
"Gymfile": "ruby",
"Appfile": "ruby"
"Appfile": "ruby",
},
"git.decorations.enabled": false,
"git.detectSubmodules": false,
@@ -51,11 +51,11 @@
"workbench.colorTheme": "Default Dark+",
"[javascript]": {
"editor.formatOnSave": false
"editor.formatOnSave": false,
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"[dart]": {
@@ -66,16 +66,16 @@
"editor.tabCompletion": "onlySnippets",
// No suggestions when plugin does not provide them (comments, strings).
"editor.wordBasedSuggestions": "off"
"editor.wordBasedSuggestions": "off",
},
"search.exclude": {
"**/.flutter": true
"**/.flutter": true,
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"nix.enableLanguageServer": true,
"nix.serverPath": "nixd",
"[nix]": {
"editor.defaultFormatter": "jnoortheen.nix-ide"
"editor.defaultFormatter": "jnoortheen.nix-ide",
},
}

View File

@@ -0,0 +1,126 @@
[[rule]]
toolName = "run_shell_command"
commandPrefix = "pre-commit run --all-files"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "grep"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "cat"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "git add"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "git status"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "git show"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "git log"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "git diff"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "diff"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "mkdir"
decision = "allow"
priority = 100
[[rule]]
toolName = "write_file"
decision = "allow"
priority = 100
[[rule]]
toolName = "replace"
decision = "allow"
priority = 100
[[rule]]
toolName = "google_web_search"
decision = "allow"
priority = 100
[[rule]]
toolName = "glob"
decision = "allow"
priority = 100
[[rule]]
toolName = "grep_search"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "tail"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "xxd"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "ls"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "find"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "head"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "echo"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "sha256sum"
decision = "allow"
priority = 100

View File

@@ -6,6 +6,36 @@ priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "pre-commit run --all-files"
commandPrefix = "nix eval"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "nix derivation show"
decision = "allow"
priority = 100
[[rule]]
mcpName = "nix"
toolName = "*"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "nix-hash"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "nix-diff"
decision = "allow"
priority = 100
[[rule]]
toolName = "run_shell_command"
commandPrefix = "nix flake check"
decision = "allow"
priority = 100

View File

@@ -26,6 +26,10 @@
"warningAcknowledged": true,
"enabled": true,
"maxAge": "30d"
}
},
"preferredEditor": "vim"
},
"model": {
"name": "auto-gemini-3"
}
}
}

View File

@@ -33,12 +33,13 @@
autoSetupMerge = false
# Set up new branches in a way that "git pull" does a rebase by default.
autoSetupRebase = always
# Commit signing, currently using ssh@mars -- to be switched to sign@mars after 2026-05-15
[gpg]
format = ssh
[commit]
gpgsign = true
# Must always go last, to be able to override the settings above.
[include]
path = ~/.config/gitconfig_local
[user]
signingkey = key::ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNwSX/Ib6kNzgRKqWfcb3HsAQQo++Gt9KeXSvP6NDk6YQPjDsi+//IiBovgLjQ34El+x8l8y3aYhfIGlCyX7aOM= sign@mars
name = Artem Sheremet
email = dot.doom@gmail.com

View File

@@ -1,34 +0,0 @@
# http://aperiodic.net/screen/commands:start
# see accompanying file ~/.ssh/rc
setenv SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
# no screen blinking on bell
vbell off
startup_message off
# disable "New screen..." message
msgwait 0
defscrollback 10240
# hostname, timestamp, LA in status bar
caption always "%{+b}%H | %c %d.%m.%Y | Load: %l"
# colored window list
hardstatus alwayslastline "%-Lw%{= BW}%50>%n%f* %t%{-}%+Lw%<"
# Launch login shells
shell -${SHELL}
# 256color support
#termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'
term screen-256color
#defbce "on"
# beep on activity monitor alert (C-a M)
# ex.: 12:37 activity -> 7$ zsh
activity "%c activity -> %n%f %t^G"
# Alt Left/Right = switch windows
bindkey "^[[1;3D" prev
bindkey "^[[1;3C" next
bindkey "^[b" prev
bindkey "^[f" next
# Alt N = new window
bindkey "^[n" screen
shelltitle '% |zsh'

View File

@@ -1,2 +0,0 @@
setlocal shiftwidth=4
setlocal expandtab

View File

@@ -1,2 +0,0 @@
setlocal shiftwidth=4
setlocal expandtab

View File

@@ -1,2 +0,0 @@
setlocal shiftwidth=2
setlocal expandtab

View File

@@ -1,2 +0,0 @@
setlocal shiftwidth=2
setlocal expandtab

View File

@@ -1,2 +0,0 @@
setlocal shiftwidth=2
setlocal expandtab

View File

@@ -1,2 +0,0 @@
setlocal shiftwidth=2
setlocal expandtab

View File

@@ -1,61 +0,0 @@
" My Dark GUI Theme
set background=dark
highlight clear
if version > 580
hi clear
if exists("syntax_on")
syntax reset
endif
endif
let g:colors_name = "mydark"
hi Normal guifg=grey guibg=#000010 gui=none ctermfg=grey ctermbg=none cterm=none
hi Cursor guibg=#FF00FF gui=none ctermbg=magenta
hi Visual guifg=white guibg=#101099 gui=none ctermfg=white ctermbg=blue cterm=none
hi Comment guifg=#12AA12 gui=none ctermfg=darkgreen cterm=none
hi Constant guifg=red gui=none ctermfg=red cterm=none
hi String guifg=red gui=none ctermfg=red cterm=none
hi Character guifg=red gui=none ctermfg=red cterm=none
hi Number guifg=yellow gui=none ctermfg=yellow cterm=none
hi Boolean guifg=#FF8000 gui=none ctermfg=darkyellow cterm=none
hi Float guifg=yellow gui=none ctermfg=yellow cterm=none
hi Identifier guifg=grey gui=none ctermfg=grey cterm=none
hi Function guifg=grey gui=none ctermfg=grey cterm=none
hi Statement guifg=#FF8000 gui=none ctermfg=darkyellow cterm=none
hi Conditional guifg=#FF8000 gui=none ctermfg=darkyellow cterm=none
hi Repeat guifg=#FF8000 gui=none ctermfg=darkyellow cterm=none
hi Label guifg=#FF8000 gui=none ctermfg=darkyellow cterm=none
hi Operator guifg=#00FFFF gui=none ctermfg=cyan cterm=none
hi Keyword guifg=#FF8000 gui=none ctermfg=darkyellow cterm=none
hi Exception guifg=#FF8000 gui=none ctermfg=darkyellow cterm=none
hi PreProc guifg=#008080 gui=none ctermfg=darkcyan cterm=none
hi Include guifg=#008080 gui=none ctermfg=darkcyan cterm=none
hi Define guifg=#008080 gui=none ctermfg=darkcyan cterm=none
hi Macro guifg=#008080 gui=none ctermfg=darkcyan cterm=none
hi PreCondit guifg=#008080 gui=none ctermfg=darkcyan cterm=none
hi Type guifg=white gui=none ctermfg=white cterm=none
hi StorageClass guifg=#FF8000 gui=none ctermfg=darkyellow cterm=none
hi Structure guifg=#FF8000 gui=none ctermfg=darkyellow cterm=none
hi Typedef guifg=#FF8000 gui=none ctermfg=darkyellow cterm=none
hi Pmenu ctermfg=black ctermbg=blue cterm=none guifg=black guibg=darkblue
hi PmenuSel ctermfg=white ctermbg=blue cterm=none guifg=white guibg=darkblue gui=none
hi PmenuSbar ctermbg=cyan guibg=cyan
hi PmenuThumb ctermfg=white guifg=white
hi DiffAdd cterm=none ctermbg=darkgreen ctermfg=black
hi DiffChange cterm=none ctermbg=darkmagenta ctermfg=black
hi DiffText cterm=none ctermbg=cyan ctermfg=black
hi DiffDelete cterm=none ctermbg=darkred ctermfg=black
hi NearColLimit gui=none guibg=yellow guifg=darkblue cterm=none ctermbg=yellow ctermfg=darkblue cterm=none cterm=none cterm=none cterm=none
hi OverColLimit gui=none guibg=red guifg=darkblue cterm=none ctermbg=red ctermfg=darkblue
hi ExtraWhitespace guibg=red ctermbg=red
hi ColorColumn ctermbg=darkyellow

View File

@@ -1,145 +0,0 @@
" Vim syntax file
" Language: Flat Assembler (FASM)
" Maintainer: Ron Aaron <ron@ronware.org>
" Last Change: 2004 May 16
" Vim URL: http://www.vim.org/lang.html
" FASM Home: http://flatassembler.net/
" FASM Version: 1.52
if version < 600
syntax clear
elseif exists("b:current_syntax")
finish
endif
setlocal iskeyword=a-z,A-Z,48-57,.,_
setlocal isident=a-z,A-Z,48-57,.,_
syn case ignore
syn keyword fasmRegister ah al ax bh bl bp bx ch cl cr0 cr1 cr2 cr3 cr4 cr5 cr6
syn keyword fasmRegister cr7 cs cx dh di dl dr0 dr1 dr2 dr3 dr4 dr5 dr6 dr7 ds dx
syn keyword fasmRegister eax ebp ebx ecx edi edx es esi esp fs gs mm0 mm1 mm2 mm3
syn keyword fasmRegister mm4 mm5 mm6 mm7 si sp ss st st0 st1 st2 st3 st4 st5 st6
syn keyword fasmRegister st7 tr0 tr1 tr2 tr3 tr4 tr5 tr6 tr7 xmm0 xmm1 xmm2 xmm3
syn keyword fasmRegister xmm4 xmm5 xmm6 xmm7
syn keyword fasmAddressSizes byte dqword dword fword pword qword tword word
syn keyword fasmDataDirectives db dd df dp dq dt du dw file rb rd rf rp rq rt rw
syn keyword fasmInstr aaa aad aam aas adc add addpd addps addsd addss addsubpd
syn keyword fasmInstr addsubps and andnpd andnps andpd andps arpl bound bsf bsr
syn keyword fasmInstr bswap bt btc btr bts call cbw cdq clc cld clflush cli clts
syn keyword fasmInstr cmc cmova cmovae cmovb cmovbe cmovc cmove cmovg cmovge cmovl
syn keyword fasmInstr cmovle cmovna cmovnae cmovnb cmovnbe cmovnc cmovne cmovng
syn keyword fasmInstr cmovnge cmovnl cmovnle cmovno cmovnp cmovns cmovnz cmovo cmovp
syn keyword fasmInstr cmovpe cmovpo cmovs cmovz cmp cmpeqpd cmpeqps cmpeqsd cmpeqss
syn keyword fasmInstr cmplepd cmpleps cmplesd cmpless cmpltpd cmpltps cmpltsd cmpltss
syn keyword fasmInstr cmpneqpd cmpneqps cmpneqsd cmpneqss cmpnlepd cmpnleps cmpnlesd
syn keyword fasmInstr cmpnless cmpnltpd cmpnltps cmpnltsd cmpnltss cmpordpd cmpordps
syn keyword fasmInstr cmpordsd cmpordss cmppd cmpps cmps cmpsb cmpsd cmpss cmpsw
syn keyword fasmInstr cmpunordpd cmpunordps cmpunordsd cmpunordss cmpxchg cmpxchg8b
syn keyword fasmInstr comisd comiss cpuid cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps
syn keyword fasmInstr cvtpi2pd cvtpi2ps cvtps2dq cvtps2pd cvtps2pi cvtsd2si cvtsd2ss
syn keyword fasmInstr cvtsi2sd cvtsi2ss cvtss2sd cvtss2si cvttpd2dq cvttpd2pi cvttps2dq
syn keyword fasmInstr cvttps2pi cvttsd2si cvttss2si cwd cwde daa das data dec div
syn keyword fasmInstr divpd divps divsd divss else emms end enter extrn f2xm1 fabs
syn keyword fasmInstr fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb
syn keyword fasmInstr fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp
syn keyword fasmInstr fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree
syn keyword fasmInstr ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp
syn keyword fasmInstr finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv
syn keyword fasmInstr fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi
syn keyword fasmInstr fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem
syn keyword fasmInstr fprem1 fptan frndint frstor frstpm fsave fscale fsetpm fsin
syn keyword fasmInstr fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr
syn keyword fasmInstr fsubrp ftst fucom fucomi fucomip fucomp fucompp fwait fxam
syn keyword fasmInstr fxch fxrstor fxsave fxtract fyl2x fyl2xp1 haddpd haddps heap
syn keyword fasmInstr hlt hsubpd hsubps idiv if imul in inc ins insb insd insw int
syn keyword fasmInstr int3 into invd invlpg iret iretd iretw ja jae jb jbe jc jcxz
syn keyword fasmInstr je jecxz jg jge jl jle jmp jna jnae jnb jnbe jnc jne jng jnge
syn keyword fasmInstr jnl jnle jno jnp jns jnz jo jp jpe jpo js jz lahf lar lddqu
syn keyword fasmInstr ldmxcsr lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw
syn keyword fasmInstr load loadall286 loadall386 lock lods lodsb lodsd lodsw loop
syn keyword fasmInstr loopd loope looped loopew loopne loopned loopnew loopnz loopnzd
syn keyword fasmInstr loopnzw loopw loopz loopzd loopzw lsl lss ltr maskmovdqu maskmovq
syn keyword fasmInstr maxpd maxps maxsd maxss mfence minpd minps minsd minss monitor
syn keyword fasmInstr mov movapd movaps movd movddup movdq2q movdqa movdqu movhlps
syn keyword fasmInstr movhpd movhps movlhps movlpd movlps movmskpd movmskps movntdq
syn keyword fasmInstr movnti movntpd movntps movntq movq movq2dq movs movsb movsd
syn keyword fasmInstr movshdup movsldup movss movsw movsx movupd movups movzx mul
syn keyword fasmInstr mulpd mulps mulsd mulss mwait neg nop not or org orpd orps
syn keyword fasmInstr out outs outsb outsd outsw packssdw packsswb packuswb paddb
syn keyword fasmInstr paddd paddq paddsb paddsw paddusb paddusw paddw pand pandn
syn keyword fasmInstr pause pavgb pavgusb pavgw pcmpeqb pcmpeqd pcmpeqw pcmpgtb
syn keyword fasmInstr pcmpgtd pcmpgtw pextrw pf2id pf2iw pfacc pfadd pfcmpeq pfcmpge
syn keyword fasmInstr pfcmpgt pfmax pfmin pfmul pfnacc pfpnacc pfrcp pfrcpit1 pfrcpit2
syn keyword fasmInstr pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pi2fw pinsrw pmaddwd pmaxsw
syn keyword fasmInstr pmaxub pminsw pminub pmovmskb pmulhrw pmulhuw pmulhw pmullw
syn keyword fasmInstr pmuludq pop popa popad popaw popd popf popfd popfw popw por
syn keyword fasmInstr prefetch prefetchnta prefetcht0 prefetcht1 prefetcht2 prefetchw
syn keyword fasmInstr psadbw pshufd pshufhw pshuflw pshufw pslld pslldq psllq psllw
syn keyword fasmInstr psrad psraw psrld psrldq psrlq psrlw psubb psubd psubq psubsb
syn keyword fasmInstr psubsw psubusb psubusw psubw pswapd punpckhbw punpckhdq punpckhqdq
syn keyword fasmInstr punpckhwd punpcklbw punpckldq punpcklqdq punpcklwd push pusha
syn keyword fasmInstr pushad pushaw pushd pushf pushfd pushfw pushw pxor rcl rcpps
syn keyword fasmInstr rcpss rcr rdmsr rdpmc rdtsc rep repe repne repnz repz ret
syn keyword fasmInstr retd retf retfd retfw retn retnd retnw retw rol ror rsm rsqrtps
syn keyword fasmInstr rsqrtss sahf sal salc sar sbb scas scasb scasd scasw seta
syn keyword fasmInstr setae setalc setb setbe setc sete setg setge setl setle setna
syn keyword fasmInstr setnae setnb setnbe setnc setne setng setnge setnl setnle
syn keyword fasmInstr setno setnp setns setnz seto setp setpe setpo sets setz sfence
syn keyword fasmInstr sgdt shl shld shr shrd shufpd shufps sidt sldt smsw sqrtpd
syn keyword fasmInstr sqrtps sqrtsd sqrtss stc std sti stmxcsr store stos stosb
syn keyword fasmInstr stosd stosw str sub subpd subps subsd subss sysenter sysexit
syn keyword fasmInstr test ucomisd ucomiss ud2 unpckhpd unpckhps unpcklpd unpcklps
syn keyword fasmInstr verr verw wait wbinvd wrmsr xadd xchg xlat xlatb xor xorpd
syn keyword fasmPreprocess common equ fix forward include local macro purge restore
syn keyword fasmPreprocess reverse struc
syn keyword fasmDirective align binary code coff console discardable display dll
syn keyword fasmDirective elf entry executable export extern far fixups format gui
syn keyword fasmDirective import label ms mz native near notpageable pe public readable
syn keyword fasmDirective repeat resource section segment shareable stack times
syn keyword fasmDirective use16 use32 virtual wdm writeable
syn keyword fasmOperator as at defined eq eqtype from mod on ptr rva used
syn match fasmNumericOperator "[+-/*]"
syn match fasmLogicalOperator "[=|&~<>]\|<=\|>=\|<>"
" numbers
syn match fasmBinaryNumber "\<[01]\+b\>"
syn match fasmHexNumber "\<\d\x*h\>"
syn match fasmHexNumber "\<\(0x\|$\)\x*\>"
syn match fasmFPUNumber "\<\d\+\(\.\d*\)\=\(e[-+]\=\d*\)\=\>"
syn match fasmOctalNumber "\<\(0\o\+o\=\|\o\+o\)\>"
syn match fasmDecimalNumber "\<\(0\|[1-9]\d*\)\>"
syn region fasmComment start=";" end="$"
syn region fasmString start="\"" end="\"\|$"
syn region fasmString start="'" end="'\|$"
syn match fasmSymbol "[()|\[\]:]"
syn match fasmSpecial "[#?%$,]"
syn match fasmLabel "^\s*[^; \t]\+:"
hi def link fasmAddressSizes type
hi def link fasmNumericOperator fasmOperator
hi def link fasmLogicalOperator fasmOperator
hi def link fasmBinaryNumber fasmNumber
hi def link fasmHexNumber fasmNumber
hi def link fasmFPUNumber fasmNumber
hi def link fasmOctalNumber fasmNumber
hi def link fasmDecimalNumber fasmNumber
hi def link fasmSymbols fasmRegister
hi def link fasmPreprocess fasmDirective
" link to standard syn groups so the 'colorschemes' work:
hi def link fasmOperator operator
hi def link fasmComment comment
hi def link fasmDirective preproc
hi def link fasmRegister type
hi def link fasmNumber constant
hi def link fasmSymbol structure
hi def link fasmString String
hi def link fasmSpecial special
hi def link fasmInstr keyword
hi def link fasmLabel label
hi def link fasmPrefix preproc
let b:current_syntax = "fasm"
" vim: ts=8 sw=8 :

View File

@@ -0,0 +1,58 @@
{ pkgs, primaryUser, ... }:
{
nixpkgs.config.allowUnfree = true;
system.primaryUser = primaryUser;
users.users.${primaryUser} = {
home = "/Users/${primaryUser}";
shell = pkgs.zsh;
};
security.pam.services.sudo_local.touchIdAuth = true;
system = {
startup.chime = false;
defaults = {
loginwindow = {
GuestEnabled = false;
DisableConsoleAccess = true;
};
finder = {
AppleShowAllFiles = true; # hidden files
AppleShowAllExtensions = true; # file extensions
_FXShowPosixPathInTitle = true; # title bar full path
ShowPathbar = true; # breadcrumb nav at bottom
ShowStatusBar = true; # file count & disk space
};
NSGlobalDomain = {
NSAutomaticSpellingCorrectionEnabled = false;
NSAutomaticCapitalizationEnabled = false;
NSAutomaticPeriodSubstitutionEnabled = false;
NSAutomaticWindowAnimationsEnabled = false;
};
};
};
# Create /etc/zshrc that loads the nix-darwin environment.
programs.zsh.enable = true;
nix-homebrew = {
# Initial install of homebrew.
enable = true;
user = primaryUser;
autoMigrate = true;
};
homebrew = {
enable = true;
onActivation = {
cleanup = "zap";
autoUpdate = false;
upgrade = true;
};
};
system.stateVersion = 6; # Never change.
}

View File

@@ -1,51 +0,0 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
git
vim
stow
wget
];
programs.zsh = {
enable = true;
initContent = ''
# Outside NixOS, we need to load this manually. Same on MacOS, if
# /etc/zshrc is reset to its default content (post-upgrade).
if [ -r /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh ]; then
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
fi
if [ -r ~/dotfiles/migrated/.zshrc ]; then
. ~/dotfiles/migrated/.zshrc
else
# If no custom override is available, use the one bundled with flake.
. ${../migrated/.zshrc}
fi
'';
# At least have the following in .zshenv_local:
# export GIT_AUTHOR_NAME='Alfred Muster'
# export GIT_AUTHOR_EMAIL='test@example.com'
# export GIT_COMMITTER_NAME="${GIT_AUTHOR_NAME?}"
# export GIT_COMMITTER_EMAIL="${GIT_AUTHOR_EMAIL?}"
envExtra = ''
[ -r ~/.zshenv_local ] && source ~/.zshenv_local || true
'';
};
programs.home-manager.enable = true;
programs.direnv = {
enable = true;
enableZshIntegration = true;
nix-direnv.enable = true;
config.global = {
warn_timeout = "30s";
hide_env_diff = true;
};
};
home.stateVersion = "25.11"; # never modify
}

142
modules/home/common.nix Normal file
View File

@@ -0,0 +1,142 @@
{
pkgs,
lib,
primaryUser,
...
}:
{
home.username = primaryUser;
home.packages = with pkgs; [
stow
wget
gemini-cli
silver-searcher
yubikey-manager
];
home.activation.stowLegacy = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
if [ -d "$HOME/dotfiles/legacy" ]; then
run ${pkgs.stow}/bin/stow -d $HOME/dotfiles -t $HOME legacy
fi
'';
programs.zsh = {
enable = true;
initContent = ''
# Outside NixOS, we need to load this manually. Same on MacOS, if
# /etc/zshrc is reset to its default content (post-upgrade).
if [ -r /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh ]; then
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
fi
if [ -r ~/dotfiles/assets/.zshrc ]; then
# Hack for faster iterations
. ~/dotfiles/assets/.zshrc
else
. ${../../assets/.zshrc}
fi
'';
# At least have the following in .zshenv_local:
# export GIT_AUTHOR_NAME='Alfred Muster'
# export GIT_AUTHOR_EMAIL='test@example.com'
# export GIT_COMMITTER_NAME="${GIT_AUTHOR_NAME?}"
# export GIT_COMMITTER_EMAIL="${GIT_AUTHOR_EMAIL?}"
envExtra = ''
[ -r ~/.zshenv_local ] && source ~/.zshenv_local || true
'';
};
programs.vim = {
enable = true;
plugins = with pkgs.vimPlugins; [
auto-pairs
ctrlp-vim
dart-vim-plugin
nerdcommenter
nginx-vim
supertab
vim-javascript
vim-lastplace
vim-sensible
vim-startify
];
extraConfig = ''
if filereadable(expand("~/dotfiles/assets/.vimrc"))
# Hack for faster iterations
source ~/dotfiles/assets/.vimrc
else
source ${../../assets/.vimrc}
endif
'';
};
programs.home-manager.enable = true;
programs.direnv = {
enable = true;
enableZshIntegration = true;
nix-direnv.enable = true;
config.global = {
warn_timeout = "30s";
hide_env_diff = true;
};
};
programs.tmux = {
enable = true;
shortcut = "a"; # ^a
escapeTime = 0;
historyLimit = 10240;
# hjkl HJKL and mouse to switch between and resize panels.
mouse = true;
keyMode = "vi";
customPaneNavigationAndResize = true;
extraConfig = ''
set-environment -g SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
set-option -g update-environment "DISPLAY SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION"
# Instead of flashing or beeping, blink the window in status.
set -g visual-bell off
set -g monitor-activity on
set -g bell-action none
set -g window-status-activity-style "fg=yellow,blink"
# Requires support from terminal (e.g. iTerm2).
set -s set-clipboard on
# For scrolling through logs.
bind y set-window-option synchronize-panes
# Panel configuration.
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
bind Enter resize-pane -Z
# Navigation.
bind -n M-Up new-window -c "#{pane_current_path}"
bind -n M-Down confirm-before -p "kill-window #W? (y/n)" kill-window
bind -n M-Left previous-window
bind -n M-Right next-window
# Status bar.
set -g status-interval 5
set -g status-position bottom
set -g status-style "bg=default,fg=white"
set -g status-left-length 20
set -g status-left "#[fg=green,bold]#H #[fg=white]| "
set -g status-right-length 60
set -g status-right "#[fg=cyan]%H:%M%Z %d.%m.%Y #[fg=white]| #[fg=yellow]Load: #(cut -d ' ' -f 1-3 /proc/loadavg)"
set -g status-justify left
set -g window-status-format "#[fg=white,dim]#I:#W#F"
set -g window-status-current-format "#[fg=white,bold,bg=blue] #I:#W#F "
'';
};
home.stateVersion = "25.11"; # never modify
}

View File

@@ -0,0 +1,8 @@
{ lib, primaryUser, ... }:
{
imports = [
./common.nix
];
home.homeDirectory = lib.mkDefault "/home/${primaryUser}";
}

View File

@@ -0,0 +1,78 @@
{
pkgs,
lib,
primaryUser,
...
}:
{
imports = [
./common.nix
];
home.homeDirectory = lib.mkDefault "/Users/${primaryUser}";
home.packages = with pkgs; [
secretive
vlc-bin
# Faster and more feature-rich than Terminal.
# TODO: https://iterm2.com/shell_integration/zsh
iterm2
# Newer OpenSSH client to support FIDO2 keys.
openssh
libfido2
];
targets.darwin.defaults."com.googlecode.iterm2" = {
# $ defaults read ~/Library/Preferences/com.googlecode.iterm2.plist
# Allow tmux (and others) to use OSC 52 to set clipboard.
AllowClipboardAccess = true;
# Allow programs to clear scrollback.
PreventEscapeSequenceFromClearingHistory = false;
TripleClickSelectsFullWrappedLines = true;
WordChars = "/-._~";
PromptOnQuit = false;
};
home.file."Library/Application Support/iTerm2/DynamicProfiles/nix-profile.json".text =
builtins.toJSON
{
Profiles = [
{
Name = "Nix-Managed";
Guid = "17DF2CCB-C7CD-4BCC-AC28-666DD6C8AF4A";
"Normal Font" = "Menlo-Regular 13";
Columns = 160;
Rows = 45;
# For tmux selection and moving borders.
"Mouse Reporting" = true;
}
];
};
programs.zsh.envExtra = ''
# Can't use ssh-agent-mux to mux Secretive and yubikey-agent:
# https://github.com/overhacked/ssh-agent-mux/issues/56
# export SSH_AUTH_SOCK=~/.ssh/ssh-agent-mux.sock
# Can't use Secretive to SSH using PIV from Yubikey:
# https://github.com/maxgoedjen/secretive/issues/330
#
# If PIV entry was generated by yubikey-agent, Secretive may not see it at
# all. Running 'ykman piv objects generate chuid' should fix that.
# https://github.com/maxgoedjen/secretive/issues/333
# See README.md "Security" section to learn how we create keys.
# Setting IdentityAgent in SSH config achieves a similar result, but doesn't
# work with commit signing.
export SSH_AUTH_SOCK=~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh
'';
nixpkgs.config.allowUnfree = true;
programs.vscode.enable = true;
}

View File

@@ -0,0 +1,23 @@
{
pkgs,
...
}:
{
# Create /etc/zshrc that loads the nix-darwin environment.
programs.zsh.enable = true;
security.sudo.wheelNeedsPassword = false;
programs.mosh.enable = true;
documentation.man.enable = true;
environment.systemPackages = with pkgs; [
# https://unix.stackexchange.com/questions/651165/using-systemd-to-mount-remote-filesystems-in-user-bus
# Have to run the wrapper due to SUID.
(pkgs.writeShellScriptBin "umount.fuse.sshfs" ''
exec /run/wrappers/bin/fusermount -u "$1"
'')
];
system.stateVersion = "25.11"; # Never change this.
}

View File

@@ -0,0 +1,75 @@
{
modulesPath,
pkgs,
...
}:
{
imports = [
"${modulesPath}/virtualisation/lxc-container.nix"
];
# Disable legacy channel behavior that lxc-container brings in via installer/cd-dvd/channel.nix.
system.installer.channel.enable = false;
# Impermanence setup:
# 1. There's no initrd/stage 1 in LXC container; /sbin/init is invoked after
# LXC finishes setting up special and user-configured filesystems. Any
# options in boot.initrd, as well as neededForBoot fileSystems won't be
# respected.
# 2. Non-boot fileSystems (aka systemd) mount too late for systemd or nixos
# persistence to be instantiated, so we have to create this script below.
# 3. The expectation from host is to mount /home and /nix. Root filesystem
# will also be a disk, as that's Incus requirement; the host should clean
# it up periodically using: "incus rebuild --empty <vm>".
# 4. Since rootfs will be empty after rebuild, you have to point LXC at the
# current init (instead of /sbin/init), by adding to the "config:" section
# in "incus config edit <vm>":
# raw.lxc: lxc.init.cmd = /nix/var/nix/profiles/system/init
system.activationScripts.persistence = {
deps = [ "specialfs" ];
text = ''
persist() {
local item="$1"
local constructor="''${item%%:*}"
local target="''${item#*:}"
mkdir -p "$(dirname "$target")"
$constructor "$target"
if ! mountpoint -q "$target"; then
local source="/home/persistent/$target"
mkdir -p "$(dirname "$source")"
$constructor "$source"
mount --bind "$source" "$target"
fi
}
for item in \
"mkdir -p:/var/lib/nixos" \
"mkdir -p:/var/lib/systemd" \
"touch:/etc/machine-id" \
"touch:/etc/ssh/ssh_host_ed25519_key" \
; do
persist "$item"
done
chmod 0600 /etc/ssh/ssh_host_ed25519_key
# lxc-container.nix installBootloader/installInitScript will attempt to
# symlink /sbin/init, so we have to create the parent directory.
mkdir -p /sbin
'';
};
system.activationScripts.users.deps = [ "persistence" ];
# This is supposed to persist machine-id, but fails.
systemd.services.systemd-machine-id-commit.enable = false;
# unprivileged LXCs can't set net.ipv4.ping_group_range
security.wrappers.ping = {
owner = "root";
group = "root";
capabilities = "cap_net_raw+p";
source = "${pkgs.iputils.out}/bin/ping";
};
}