Files
sydnix/modules/home/users/crumb/emacs.nix
2025-04-16 16:53:43 -06:00

152 lines
4.9 KiB
Nix
Executable File

{ config, lib, pkgs, inputs, ... }@args:
let cfg = config.sydnix.users.crumb.emacs;
in {
options.sydnix.users.crumb.emacs.enable =
lib.mkEnableOption ''Emacs, à la crumb'';
config = lib.mkIf cfg.enable
(let
emacsBasePackage = pkgs'.emacs-unstable-pgtk;
# Hard-coded path. }:\
emacsConfigDir =
"/persist/dots/modules/home/users/${config.home.username}/emacs";
# Create a new instance of nixpkgs with emacs-overlay applied. This is a
# little unorthodox, but we do it
# 1. for the sake of organisation — For pure aesthetics and a clean
# codebase, I want everything Emacs to stay in this file;
# 2. and, there's simply no need to leak emacs-overlay's packages into the
# global nixpkgs instance when nothing else is using it!
pkgs' = import inputs.nixpkgs {
system = args.system;
overlays = [ inputs.emacs-overlay.overlays.emacs ];
};
emacsDataDir = "${config.xdg.dataHome}/emacs";
emacsCacheDir = "${emacsDataDir}/cache";
straightBaseDir = "${emacsDataDir}/straight";
fontPackages = [
pkgs.julia-mono
pkgs.nerd-fonts.victor-mono
pkgs.ibm-plex
];
my-aspell = pkgs.aspellWithDicts
(dicts: with dicts; [
en en-computers en-science
]);
my-tex = pkgs.texlive.combine {
inherit (pkgs.texlive)
scheme-basic # Set of common packages.
fontspec
dvisvgm dvipng wrapfig # For Org-mode previews/export.
amsmath # Essential for mathematics.
ulem hyperref
capt-of
pgf # Includes TikZ.
tikz-cd # Commutative diagrams w/ TikZ.
metafont
;
};
my-emacs =
let ewp = (pkgs.emacsPackagesFor emacsBasePackage).emacsWithPackages
(epkgs: with epkgs; [
jinx
pdf-tools
treesit-grammars.with-all-grammars
]);
in pkgs.symlinkJoin {
name = "sydmacs";
paths = [ ewp ];
nativeBuildInputs = [ pkgs.makeWrapper ];
buildInputs = [
pkgs.git # Dependency of Straight.el.
my-aspell
pkgs.direnv
pkgs.ghostscript # For TeX.
];
postBuild = ''
find "$out/bin" -name emacs -or -name "emacs-*" \
| while IFS= read -r emacs; do
echo "emacs: $emacs"
wrapProgram "$emacs" \
--add-flags "--init-directory \"${emacsConfigDir}\"" \
--set EMACS_STRAIGHT_BASE_DIR "${straightBaseDir}" \
--set EMACS_CACHE_DIR "${emacsCacheDir}" \
--set EMACS_DATA_DIR "${emacsDataDir}" \
--prefix PATH : "${pkgs.git}/bin" \
--prefix PATH : "${my-aspell}/bin" \
--prefix PATH : "${pkgs.direnv}/bin" \
--prefix PATH : "${my-tex}/bin" \
--prefix PATH : "${pkgs.unzip}/bin" \
--set ASPELL_CONF "dict-dir ${my-aspell}/lib/aspell"
done
'';
meta = emacsBasePackage.meta;
version = emacsBasePackage.version;
};
emacsclient-or-emacs = pkgs.writeShellScriptBin "emacsclient-or-emacs" ''
emacsclient --alternate-editor=${config.programs.emacs.finalPackage}/bin/emacs "$@"
'';
in {
programs.emacs = {
enable = true;
package = my-emacs;
};
sydnix.impermanence.cache.directories =
# Impermanence expects the path to be relative to ~.
map (lib.removePrefix config.home.homeDirectory) [
straightBaseDir
emacsCacheDir
emacsDataDir
];
# Set emacsclient as the default editor for the time being.
home.sessionVariables =
let e = "${emacsclient-or-emacs}/bin/emacsclient-or-emacs";
in {
"EDITOR" = e;
"VISUAL" = e;
};
home.file =
let default =
lib.removePrefix "${config.home.homeDirectory}/"
"${straightBaseDir}/straight/versions/default.el";
in {
${default}.source =
config.lib.file.mkOutOfStoreSymlink
"${emacsConfigDir}/straight-lockfile.el";
};
home.packages = [
emacsclient-or-emacs
] ++ fontPackages;
# There's probably a better place to put this, but the current setup demands
# Fontconfig for Emacs to find my fonts.
fonts.fontconfig.enable = true;
# TODO: Make sure this is using the right package for Emacs...
services.emacs = {
enable = true;
# Generate a desktop entry for emacsclient.
client.enable = true;
};
# We do this ourselves.
stylix.targets.emacs.enable = false;
home.shellAliases = {
e = "emacsclient-or-emacs";
ec = "emacsclient";
em = "emacs";
};
});
}