Compare commits

..

8 commits

Author SHA1 Message Date
42377ca489
feat: Update direnv to use most up-to-date version 2026-11-13 16:20:23 -06:00
c158f65263
cleanup (desktop): remove redundent syncthing declaration 2026-10-31 12:37:58 -05:00
11ecc1dde9
feat! (desktop): Remove unused zlink aliases
These aliases were workarounds for the Zed module, which would hard-link
the `settings.json` file from the Nix store, and not allow Zed to edit
the file. Now the settings seem to be soft-applied, allowing state to
accumulate, but also making experimenting much easier. Unlinking and
relinking the Zed settings file is redundent now, so remove.
2026-10-31 12:37:12 -05:00
f4b715bc2f
feat! (desktop): Remove unused "code" alias 2026-10-31 12:35:23 -05:00
e8fa43575d
cleanup: Remove beocat host 2026-10-31 12:28:18 -05:00
301f8c3e25
fix (flake): Remove unused inputs from agenix 2026-10-31 12:27:32 -05:00
3d115a271f
fix (plasma): Firefox PiP window rules 2026-10-31 11:57:01 -05:00
321981c212
wip: Add medical/American hunspell dict 2026-10-31 11:56:27 -05:00
9 changed files with 122 additions and 119 deletions

View file

@ -12,8 +12,6 @@
url = "github:ryantm/agenix"; url = "github:ryantm/agenix";
inputs = { inputs = {
nixpkgs.follows = "nixpkgs"; nixpkgs.follows = "nixpkgs";
darwin.follows = "nix-darwin";
home-manager.follows = "home-manager";
}; };
}; };
home-manager = { home-manager = {
@ -181,8 +179,6 @@
"millironx@bosephus" = mkHomeConfiguration { hostname = "bosephus"; }; "millironx@bosephus" = mkHomeConfiguration { hostname = "bosephus"; };
"tchristensen@beocat" = mkHomeConfiguration { hostname = "beocat"; };
"millironx@odyssey" = mkHomeConfiguration { "millironx@odyssey" = mkHomeConfiguration {
hostname = "odyssey"; hostname = "odyssey";
desktop = true; desktop = true;

View file

@ -1,8 +0,0 @@
{ config, lib, pkgs, pkgs-unstable, ... }: {
home = {
username = "tchristensen";
homeDirectory = "/homes/tchristensen";
};
programs = { };
services = { };
}

View file

@ -1,4 +1,4 @@
{ config, lib, pkgs, pkgs-unstable, ... }: { { pkgs, custom-pkgs, ... }: {
imports = [ imports = [
./../modules/defaults.nix ./../modules/defaults.nix
@ -15,21 +15,27 @@
(pkgs.writeShellScriptBin "get-current-wifi" '' (pkgs.writeShellScriptBin "get-current-wifi" ''
ipconfig getsummary $(networksetup -listallhardwareports | awk '/Hardware Port: Wi-Fi/{getline; print $2}') | awk -F ' SSID : ' '/ SSID : / {print $2}' ipconfig getsummary $(networksetup -listallhardwareports | awk '/Hardware Port: Wi-Fi/{getline; print $2}') | awk -F ' SSID : ' '/ SSID : / {print $2}'
'') '')
(pkgs.writeScriptBin "secure-finger" (pkgs.writeScriptBin "secure-finger" (
(builtins.readFile ./../bin/find_processes_using_secure_input.py)) builtins.readFile ./../bin/find_processes_using_secure_input.py
))
]; ];
sessionVariables = { sessionVariables = {
JULIA_NUM_THREADS = "$(sysctl -n hw.logicalcpu)"; JULIA_NUM_THREADS = "$(sysctl -n hw.logicalcpu)";
# This is a workaround because it appears that launchd sets the socket # This is a workaround because it appears that launchd sets the socket
# and the home-manager module won't set the socket if it's already set # and the home-manager module won't set the socket if it's already set
# This line seems to break on Linux, but is needed on MacOS # This line seems to break on Linux, but is needed on MacOS
SSH_AUTH_SOCK = SSH_AUTH_SOCK = "$(${pkgs.gnupg}/bin/gpgconf --list-dirs agent-ssh-socket)";
"$(${pkgs.gnupg}/bin/gpgconf --list-dirs agent-ssh-socket)";
}; };
shellAliases = { shellAliases = {
nproc = "sysctl -n hw.logicalcpu"; nproc = "sysctl -n hw.logicalcpu";
tailscale = "/Applications/Tailscale.app/Contents/MacOS/Tailscale"; tailscale = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
}; };
file = {
"Library/Spelling/en_US-medical.dic".source =
"${custom-pkgs.hunspell-en-med-glut}/share/hunspell/en_US-medical.dic";
"Library/Spelling/en_US-medical.aff".source =
"${custom-pkgs.hunspell-en-med-glut}/share/hunspell/en_US-medical.aff";
};
}; };
programs = { programs = {
bash = { bash = {
@ -51,5 +57,11 @@
''; '';
}; };
}; };
services = { gpg-agent = { pinentry = { package = pkgs.pinentry_mac; }; }; }; services = {
gpg-agent = {
pinentry = {
package = pkgs.pinentry_mac;
};
};
};
} }

View file

@ -1,6 +1,5 @@
{ {
pkgs, pkgs,
lib,
custom-pkgs, custom-pkgs,
... ...
}: }:
@ -37,39 +36,9 @@
woodpecker-cli woodpecker-cli
(texlive.combine { inherit (texlive) scheme-basic latex-bin latexmk; }) (texlive.combine { inherit (texlive) scheme-basic latex-bin latexmk; })
custom-pkgs.ark custom-pkgs.ark
custom-pkgs.hunspell-en-med custom-pkgs.hunspell-en-med-glut
custom-pkgs.jlfmt custom-pkgs.jlfmt
custom-pkgs.runic custom-pkgs.runic
]; ];
shellAliases = {
code = "codium";
zunlink = ''
readlink ~/.config/zed/settings.json > ~/.config/zed/hm-settings-location &&
rm ~/.config/zed/settings.json &&
cp $(< ~/.config/zed/hm-settings-location) ~/.config/zed/settings.json &&
chmod u+w ~/.config/zed/settings.json
'';
zrelink = ''
rm -f ~/.config/zed/settings.json &&
ln -s $(< ~/.config/zed/hm-settings-location) ~/.config/zed/settings.json
'';
};
};
services = {
syncthing.enable = true;
};
# Symlink the merged en_MED Hunspell dictionary into the user dictionary
# directory that Qt/Sonnet (and macOS native spellcheck) scan at startup.
home.file = lib.mkIf pkgs.stdenv.isDarwin {
"Library/Spelling/en_MED.dic".source = "${custom-pkgs.hunspell-en-med}/share/hunspell/en_MED.dic";
"Library/Spelling/en_MED.aff".source = "${custom-pkgs.hunspell-en-med}/share/hunspell/en_MED.aff";
};
# On Linux, Qt/Sonnet resolves QStandardPaths::GenericDataLocation + "/hunspell"
# which maps to ~/.local/share/hunspell (managed via xdg.dataFile).
xdg.dataFile = lib.mkIf pkgs.stdenv.isLinux {
"hunspell/en_MED.dic".source = "${custom-pkgs.hunspell-en-med}/share/hunspell/en_MED.dic";
"hunspell/en_MED.aff".source = "${custom-pkgs.hunspell-en-med}/share/hunspell/en_MED.aff";
}; };
} }

View file

@ -1,13 +1,24 @@
{ config, pkgs, custom-pkgs, ... }: {
config,
pkgs,
custom-pkgs,
...
}:
let let
home-manager-repo = "${config.xdg.configHome}/home-manager"; home-manager-repo = "${config.xdg.configHome}/home-manager";
mkOutOfStoreSymlink = config.lib.file.mkOutOfStoreSymlink; mkOutOfStoreSymlink = config.lib.file.mkOutOfStoreSymlink;
in { in
{
imports = [ ./../programs/plasma.nix ]; imports = [ ./../programs/plasma.nix ];
home = { home = {
packages = with pkgs; [ sqlitebrowser custom-pkgs.sc4pac ]; packages = with pkgs; [
sessionVariables = { ZED_WINDOW_DECORATIONS = "server"; }; sqlitebrowser
custom-pkgs.sc4pac
];
sessionVariables = {
ZED_WINDOW_DECORATIONS = "server";
};
}; };
services = { services = {
gpg-agent = { gpg-agent = {
@ -20,22 +31,22 @@ in {
}; };
xdg = { xdg = {
configFile = { configFile = {
"plasma-workspace/env/ZED_WINDOW_DECORATIONS.sh".text = "plasma-workspace/env/ZED_WINDOW_DECORATIONS.sh".text = "export ZED_WINDOW_DECORATIONS=server";
"export ZED_WINDOW_DECORATIONS=server";
"onedrive/config".text = '' "onedrive/config".text = ''
force_session_upload = "true" force_session_upload = "true"
delay_inotify_processing = "true" delay_inotify_processing = "true"
''; '';
}; };
dataFile = { dataFile = {
"hunspell/en_US-medical.dic".source =
"${custom-pkgs.hunspell-en-med-glut}/share/hunspell/en_US-medical.dic";
"hunspell/en_US-medical.aff".source =
"${custom-pkgs.hunspell-en-med-glut}/share/hunspell/en_US-medical.aff";
"kio/servicemenus/kate.desktop".source = ./../dotfiles/kate.desktop; "kio/servicemenus/kate.desktop".source = ./../dotfiles/kate.desktop;
"kio/servicemenus/vlc.desktop".source = ./../dotfiles/vlc.desktop; "kio/servicemenus/vlc.desktop".source = ./../dotfiles/vlc.desktop;
"kio/servicemenus/word-to-pdf.desktop".source = "kio/servicemenus/word-to-pdf.desktop".source = ./../dotfiles/word-to-pdf.desktop;
./../dotfiles/word-to-pdf.desktop; "kio/servicemenus/powerpoint-to-pdf.desktop".source = ./../dotfiles/powerpoint-to-pdf.desktop;
"kio/servicemenus/powerpoint-to-pdf.desktop".source = "user-places.xbel".source = mkOutOfStoreSymlink "${home-manager-repo}/dotfiles/user-places.xbel";
./../dotfiles/powerpoint-to-pdf.desktop;
"user-places.xbel".source =
mkOutOfStoreSymlink "${home-manager-repo}/dotfiles/user-places.xbel";
}; };
}; };
} }

View file

@ -2,7 +2,7 @@
with pkgs; with pkgs;
{ {
ark = callPackage ./ark.nix { }; ark = callPackage ./ark.nix { };
hunspell-en-med = callPackage ./hunspell-en-med.nix { }; hunspell-en-med-glut = callPackage ./hunspell-en-med-glut.nix { };
jlfmt = callPackage ./jlfmt.nix { }; jlfmt = callPackage ./jlfmt.nix { };
runic = callPackage ./runic.nix { }; runic = callPackage ./runic.nix { };
sc4pac = callPackage ./sc4pac.nix { }; sc4pac = callPackage ./sc4pac.nix { };

View file

@ -1,25 +1,19 @@
{ pkgs, lib }: { pkgs, lib }:
let let
# Hunspell dictionary of English medical terms by glutanimate. pname = "hunspell-en-med-glut";
# Merges OpenMedSpel (R. Robinson) and MTH-Med-Spel-Chek (Rajasekharan N.), version = "0.0.20140410";
# covering ~90,000 terms (anatomy, pharmacology, DSM-IV, ICD-9, etc.). src = pkgs.fetchFromGitHub {
# Note: word list is current to April 2014; GPL-3.0 licensed. owner = "glutanimate";
# Source: https://github.com/glutanimate/hunspell-en-med-glut repo = pname;
medDic = pkgs.fetchurl { rev = version;
url = "https://raw.githubusercontent.com/glutanimate/hunspell-en-med-glut/master/en_med_glut.dic"; sha256 = "sha256-7KzZ+4UToWMYFXxIRwQTxT4PwyVsBwLAF07Tlnk8eY8=";
# Run `nix build` once with this placeholder to get the real hash from the
# error message, then replace it here.
hash = "sha256-voNMOdaB3QED0Lut3KujWXhr0Sa+sdDAi27ZMoVJDBs=";
}; };
in in
pkgs.stdenv.mkDerivation { pkgs.stdenv.mkDerivation {
pname = "hunspell-en-med"; inherit pname;
# Date of last upstream commit to the dictionary file inherit version;
version = "2017-01-04"; inherit src;
dontUnpack = true;
installPhase = '' installPhase = ''
runHook preInstall runHook preInstall
@ -29,24 +23,25 @@ pkgs.stdenv.mkDerivation {
# de-duplicate, then prepend the new count to form a valid .dic file. # de-duplicate, then prepend the new count to form a valid .dic file.
{ {
tail -n +2 "${pkgs.hunspellDicts.en_US}/share/hunspell/en_US.dic" tail -n +2 "${pkgs.hunspellDicts.en_US}/share/hunspell/en_US.dic"
tail -n +2 ${medDic} tail -n +18 $src/en_med_glut.dic
} | sort -u > words.txt } | sort -u > words.txt
count=$(wc -l < words.txt) count=$(wc -l < words.txt)
{ printf '%s\n' "$count"; cat words.txt; } > $out/share/hunspell/en_MED.dic { printf '%s\n' "$count"; cat words.txt; } > $out/share/hunspell/en_US-medical.dic
# Reuse en_US affix rules; the medical word list carries no morphology. # Reuse en_US affix rules; the medical word list carries no morphology.
cp "${pkgs.hunspellDicts.en_US}/share/hunspell/en_US.aff" $out/share/hunspell/en_MED.aff cp "${pkgs.hunspellDicts.en_US}/share/hunspell/en_US.aff" $out/share/hunspell/en_US-medical.aff
runHook postInstall runHook postInstall
''; '';
meta = { meta = {
description = "Merged US English + medical terms Hunspell dictionary (en_MED)"; description = "Merged US English + medical terms Hunspell dictionary (en_US-medical)";
longDescription = '' longDescription = ''
Combines the standard en_US Hunspell dictionary with the glutanimate Combines the standard en_US Hunspell dictionary with the glutanimate
medical terms word list (hunspell-en-med-glut), giving a single medical terms word list (hunspell-en-med-glut), giving a single
en_MED dictionary that covers everyday English and ~90,000 medical terms. en_US-medical dictionary that covers everyday English and ~90,000 medical
terms.
''; '';
homepage = "https://github.com/glutanimate/hunspell-en-med-glut"; homepage = "https://github.com/glutanimate/hunspell-en-med-glut";
license = lib.licenses.gpl3; license = lib.licenses.gpl3;

View file

@ -1,6 +1,7 @@
{ ... }: { { pkgs-unstable, ... }: {
programs.direnv = { programs.direnv = {
enable = true; enable = true;
package = pkgs-unstable.direnv;
enableBashIntegration = true; enableBashIntegration = true;
enableZshIntegration = true; enableZshIntegration = true;
}; };

View file

@ -1,11 +1,16 @@
{ config, ... }: { { config, ... }: {
imports = [ ./konsole.nix ./yakuake.nix ]; imports = [
./konsole.nix
./yakuake.nix
];
programs.plasma = { programs.plasma = {
enable = true; enable = true;
overrideConfig = true; overrideConfig = true;
shortcuts = { yakuake.toggle-window-state = "Ctrl+`"; }; shortcuts = {
yakuake.toggle-window-state = "Ctrl+`";
};
configFile = { configFile = {
dolphinrc = { dolphinrc = {
DetailsMode.PreviewSize = 16; DetailsMode.PreviewSize = 16;
@ -22,8 +27,7 @@
"Places Icons Auto-resize" = false; "Places Icons Auto-resize" = false;
"Places Icons Static Size" = 22; "Places Icons Static Size" = 22;
}; };
PreviewSettings.Plugins = PreviewSettings.Plugins = "audiothumbnail,avif,blenderthumbnail,comicbookthumbnail,cursorthumbnail,djvuthumbnail,ebookthumbnail,exrthumbnail,directorythumbnail,fontthumbnail,imagethumbnail,jpegthumbnail,jxl,kraorathumbnail,windowsexethumbnail,windowsimagethumbnail,mobithumbnail,opendocumentthumbnail,gsthumbnail,rawthumbnail,svgthumbnail,gdk-pixbuf-thumbnailer,ffmpegthumbs,gsf-office";
"audiothumbnail,avif,blenderthumbnail,comicbookthumbnail,cursorthumbnail,djvuthumbnail,ebookthumbnail,exrthumbnail,directorythumbnail,fontthumbnail,imagethumbnail,jpegthumbnail,jxl,kraorathumbnail,windowsexethumbnail,windowsimagethumbnail,mobithumbnail,opendocumentthumbnail,gsthumbnail,rawthumbnail,svgthumbnail,gdk-pixbuf-thumbnailer,ffmpegthumbs,gsf-office";
}; };
# Store GPG passphrase # Store GPG passphrase
@ -34,19 +38,27 @@
}; };
# Disable hot corner # Disable hot corner
kwinrc = { Effect-overview.BorderActivate = 9; }; kwinrc = {
Effect-overview.BorderActivate = 9;
}; };
input.mice = [{ };
input.mice = [
{
enable = true; enable = true;
name = "Logitech M705"; name = "Logitech M705";
vendorId = "046d"; vendorId = "046d";
productId = "406d"; productId = "406d";
naturalScroll = true; naturalScroll = true;
}]; }
];
kwin = { kwin = {
cornerBarrier = false; cornerBarrier = false;
titlebarButtons = { titlebarButtons = {
left = [ "close" "minimize" "maximize" ]; left = [
"close"
"minimize"
"maximize"
];
right = [ "help" ]; right = [ "help" ];
}; };
virtualDesktops = { virtualDesktops = {
@ -66,7 +78,11 @@
hiding = "normalpanel"; hiding = "normalpanel";
screen = 0; screen = 0;
widgets = [ widgets = [
{ kickoff = { icon = "fedora-logo-icon"; }; } {
kickoff = {
icon = "fedora-logo-icon";
};
}
"org.kde.plasma.marginsseparator" "org.kde.plasma.marginsseparator"
"org.kde.plasma.windowlist" "org.kde.plasma.windowlist"
"org.kde.plasma.appmenu" "org.kde.plasma.appmenu"
@ -76,8 +92,7 @@
config = { config = {
Appearance.chartFace = "org.kde.ksysguard.barchart"; Appearance.chartFace = "org.kde.ksysguard.barchart";
Sensors.highPrioritySensorIds = "[${ Sensors.highPrioritySensorIds = "[${
builtins.concatStringsSep "," (builtins.genList builtins.concatStringsSep "," (builtins.genList (i: ''"cpu/cpu${builtins.toString i}/usage"'') 32)
(i: ''"cpu/cpu${builtins.toString i}/usage"'') 32)
}]"; }]";
}; };
} }
@ -89,8 +104,7 @@
name = "org.kde.plasma.systemmonitor.net"; name = "org.kde.plasma.systemmonitor.net";
config = { config = {
Appearance.chartFace = "org.kde.ksysguard.horizontalbars"; Appearance.chartFace = "org.kde.ksysguard.horizontalbars";
Sensors.highPrioritySensorIds = Sensors.highPrioritySensorIds = ''[ "network/all/download","network/all/upload" ]'';
''[ "network/all/download","network/all/upload" ]'';
# These are the values needed to make the network indicator # These are the values needed to make the network indicator
# actually useful, but it appears that plasma-manager doesn't # actually useful, but it appears that plasma-manager doesn't
# support nesting this deep yet. Disable for now. # support nesting this deep yet. Disable for now.
@ -157,7 +171,10 @@
opacity = "adaptive"; opacity = "adaptive";
hiding = "normalpanel"; hiding = "normalpanel";
screen = 1; screen = 1;
widgets = [ "org.kde.plasma.windowlist" "org.kde.plasma.appmenu" ]; widgets = [
"org.kde.plasma.windowlist"
"org.kde.plasma.appmenu"
];
} }
##### Bottom: Virtual desktop pager | Full-name taskbar w/o pins ##### ##### Bottom: Virtual desktop pager | Full-name taskbar w/o pins #####
{ {
@ -181,26 +198,36 @@
} }
]; ];
powerdevil.AC.autoSuspend.action = "nothing"; powerdevil.AC.autoSuspend.action = "nothing";
window-rules = [{ window-rules = [
{
description = "Firefox picture-in-picture"; description = "Firefox picture-in-picture";
match = { match = {
window-class = { # Window class intentionally omitted ("Unimportant") — matching on
value = "org.mozilla.firefox"; # class alone causes the rule to silently fail on Wayland.
title = {
value = "Picture-in-Picture";
type = "exact"; type = "exact";
}; };
window-types = [ "normal" ];
}; };
apply = { apply = {
above = true; above = {
aboverule = 2; value = true;
apply = "force";
}; };
}]; skiptaskbar = {
value = true;
apply = "force";
};
};
}
];
workspace = { workspace = {
lookAndFeel = "org.kde.breezedark.desktop"; lookAndFeel = "org.kde.breezedark.desktop";
wallpaperFillMode = "preserveAspectCrop"; wallpaperFillMode = "preserveAspectCrop";
wallpaperSlideShow = { wallpaperSlideShow = {
interval = 86400; interval = 86400;
path = path = "${config.home.homeDirectory}/Nextcloud/Pictures/Desktop backgrounds/";
"${config.home.homeDirectory}/Nextcloud/Pictures/Desktop backgrounds/";
}; };
}; };
}; };