Files
.dotfiles/home/jashton.nix
T

275 lines
7.7 KiB
Nix

{ config, lib, pkgs, inputs, ... }:
let
# Compile your custom wvkbd build
custom_wvkbd = pkgs.wvkbd.overrideAttrs (oldAttrs: {
# Pin the package version to the exact commit from your flake input
src = inputs.wvkbd-src;
version = "custom-git";
# Choose your preferred layout layout (e.g., mobintl, standard, cyrillic)
makeFlags = (oldAttrs.makeFlags or []) ++ [ "LAYOUT=mobintl" ];
# Optional: Swap out the layout with your own config.h file if you have one
preBuild = ''
cp ${./programs/layout.custom.h} layout.mobintl.h
cp ${./programs/config.custom.h} config.mobintl.h
cp ${./programs/keymap.custom.h} keymap.mobintl.h
'';
});
in
{
imports = [
./programs
./desktop
];
home.username = "jashton";
home.homeDirectory = "/home/jashton";
home.file.".zshrc".text = ''
# Zsh is configured globally at the NixOS system level.
# This file exists solely to prevent the zsh-newuser-install prompt.
'';
home.sessionVariables = {
EDITOR = "nvim";
NIXOS_OZONE_WL = "1"; # Forces Electron/Chromium apps to use Wayland natively
GTK_IM_MODULE = "wayland"; # Forces GTK apps to use Wayland text-input protocols
QT_IM_MODULE = "wayland"; # Forces Qt apps to use Wayland text-input protocols
TEXT_INPUT_PRESENT = "1"; # Explicitly signals virtual keyboard capability to the shell
JAVA_HOME = "{pkgs.jdk21}";
};
home.packages = with pkgs; [
antigravity
asciinema
claude-code
discord
eclipses.eclipse-java
ffmpeg
gemini-cli
kicad
libreoffice
librewolf
opencode
pdftk
picom
prismlauncher
scrot
signal-desktop
spotify
thunderbird
tor
tor-browser
vlc
wtype
xwayland-satellite
yt-dlp
zathura
custom_wvkbd
(pkgs.writeShellScriptBin "jroot" ''
d="$PWD"
while [ "$d" != "/" ]; do
if [ -f "$d/.classpath" ]; then printf '%s\n' "$d"; exit 0; fi
d="$(dirname "$d")"
done
echo "jroot: no .classpath found at or above $PWD" >&2
exit 1
'')
(pkgs.writeShellScriptBin "jbuild" ''
set -euo pipefail
# Assign first: `cd "$(jroot)"` would swallow a jroot failure, because
# `cd ""` is a successful no-op and set -e never sees the error.
ROOT="$(jroot)"
cd "$ROOT"
mkdir -p bin
SOURCES="$(mktemp)"
trap 'rm -f "$SOURCES"' EXIT
find . -path ./bin -prune -o -name '.*' -prune -o -name '*.java' -print > "$SOURCES"
if [ ! -s "$SOURCES" ]; then
echo "jbuild: no .java files found under $ROOT" >&2
exit 1
fi
# bin is deliberately NOT on the compile classpath: every source is passed
# explicitly, so a stale .class from a deleted file would silently satisfy
# references that ought to fail.
javac -g --release 21 -encoding UTF-8 -d bin -cp "lib/*" @"$SOURCES"
'')
(pkgs.writeShellScriptBin "jclean" ''
set -euo pipefail
ROOT="$(jroot)"
rm -rf "$ROOT/bin"
echo "cleaned $ROOT/bin"
'')
(pkgs.writeShellScriptBin "jrun" ''
set -euo pipefail
if [ $# -lt 1 ]; then
echo "usage: jrun <package.MainClass> [args...]" >&2
exit 1
fi
ROOT="$(jroot)"
jbuild
cd "$ROOT"
MAIN="$1"; shift
exec java -cp "bin:lib/*" "$MAIN" "$@"
'')
(pkgs.writeShellScriptBin "jtest" ''
set -euo pipefail
# sort -V so 1.10.2 beats 1.9.0; plain tail -n1 sorts those the wrong way.
JUNIT="$(ls -1 "$HOME"/dev/jars/junit-platform-console-standalone-*.jar 2>/dev/null | sort -V | tail -n1 || true)"
if [ -z "$JUNIT" ]; then
echo "jtest: no junit-platform-console-standalone jar in ~/dev/jars" >&2
exit 1
fi
ROOT="$(jroot)"
jbuild
cd "$ROOT"
if [ $# -eq 0 ]; then
exec java -jar "$JUNIT" execute --class-path "bin:lib/*" --scan-class-path --details=tree
fi
ARGS=""
for pkg in "$@"; do
ARGS="$ARGS --select-package $pkg"
done
exec java -jar "$JUNIT" execute --class-path "bin:lib/*" $ARGS --details=tree
'')
(pkgs.writeShellScriptBin "fkill" ''
set -eu
if [ $# -lt 1 ]; then
echo "usage: fkill <process-name>" >&2
echo "eg. fkill firefox" >&2
exit 1
fi
PROGRAM="$1"
if ! pgrep -x -- "$PROGRAM" >/dev/null 2>&1; then
echo "fkill: no process named '$PROGRAM'" >&2
exit 1
fi
pgrep -a -x -- "$PROGRAM"
printf 'Kill these? [y/N] '
read -r reply
case "$reply" in
[yY]*) pkill -x -- "$PROGRAM" ;;
*) echo "aborted" ;;
esac
'')
(pkgs.writeShellScriptBin "find-open-port" ''
set -u
if [ $# -lt 1 ]; then
echo "Please provide an application name, project directory, or other identifier."
echo ' Usage: find-open-port $HOME/dev/some-project'
echo " Usage: find-open-port some-app"
exit 1
fi
APP_NAME="$1"
REGISTRY_FILE="$HOME/.dotfiles/ports.registry"
MIN_PORT=8000
MAX_PORT=8999
MAX_RETRIES=50
mkdir -p "$(dirname "$REGISTRY_FILE")"
if [ -f "$REGISTRY_FILE" ] && grep -q "^$APP_NAME : " "$REGISTRY_FILE"; then
echo "Already registered:"
grep "^$APP_NAME : " "$REGISTRY_FILE"
exit 0
fi
echo "Searching for available port between $MIN_PORT and $MAX_PORT for $APP_NAME..."
for ((i=1; i<=MAX_RETRIES; i++)); do
RANDOM_PORT=$(shuf -i $MIN_PORT-$MAX_PORT -n 1)
if ! ss -tuln | grep -E -q ":$RANDOM_PORT\b"; then
if [ -f "$REGISTRY_FILE" ] && grep -q "\b$RANDOM_PORT\b" "$REGISTRY_FILE"; then
continue
fi
echo "$APP_NAME : $RANDOM_PORT" >> "$REGISTRY_FILE"
echo -e "\nSuccessfully wrote '$APP_NAME : $RANDOM_PORT' to $REGISTRY_FILE"
exit 0
fi
done
echo -e "\nError: Could not find an open port between $MIN_PORT and $MAX_PORT after $MAX_RETRIES attempts."
exit 1
'')
];
home.activation = {
# 1. Create the persistent directories
createWorkspaceDirs = lib.hm.dag.entryAfter ["writeBoundary"] ''
$DRY_RUN_CMD mkdir -p $HOME/dev
$DRY_RUN_CMD mkdir -p $HOME/downloads
$DRY_RUN_CMD mkdir -p $HOME/life
$DRY_RUN_CMD mkdir -p $HOME/media/pics
$DRY_RUN_CMD mkdir -p $HOME/media/videos
$DRY_RUN_CMD mkdir -p $HOME/school
'';
};
systemd.user.services.lan-mouse = {
Unit = {
Description = "Lan Mouse Daemon";
After = [ "graphical-session.target" ];
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
# The --daemon flag ensures it runs silently in the background without opening the GUI
ExecStart = "${pkgs.lan-mouse}/bin/lan-mouse --daemon";
Restart = "on-failure";
RestartSec = "5";
};
};
programs.ssh = {
enable = true;
enableDefaultConfig = false;
settings = {
"*" = {
forwardAgent = false;
addKeysToAgent = "no";
compression = false;
serverAliveInterval = 0;
serverAliveCountMax = 3;
hashKnownHosts = false;
userKnownHostsFile = "~/.ssh/known_hosts";
controlMaster = "no";
controlPath = "~/.ssh/master-%r@%n:%p";
controlPersist = "no";
};
"heliotrope" = {
hostname = "100.77.235.110";
};
"lavender" = {
hostname = "100.99.189.49";
};
"violet" = {
hostname = "100.101.100.84";
};
"lilac" = {
hostname = "100.82.51.88";
};
};
};
home.stateVersion = "26.05"; # DO NOT CHANGE
}