Files
sydnix/modules/home/emacs.nix

150 lines
4.5 KiB
Nix

{ config, lib, pkgs, inputs, ... }@args:
let cfg = config.sydnix.emacs;
in {
options.sydnix.emacs = {
enable = lib.mkEnableOption "Emacs";
userDir = lib.mkOption {
description = ''
The path to the Emacs user directory.
'';
# Mutable config.
default = "/persist/dots/modules/home/users/msyds/emacs";
type = lib.types.path;
};
package = lib.mkPackageOption pkgs "emacs" {
default = [ "emacs-pgtk" ];
};
emacsPackages = lib.mkOption {
description = ''
Emacs packages to be installed. Used primarily for Elisp packages with
system dependencies.
'';
default = _epkgs: [];
type = lib.types.anything // {
merge =
_loc: defs: epkgs: lib.concatMap (f: f epkgs) (lib.getValues defs);
check = lib.isFunction;
};
};
fontPackages = lib.mkOption {
description = ''
Font packages to be made available to Emacs.
'';
type = lib.types.listOf lib.types.package;
default = [];
};
tex = {
enable = lib.mkEnableOption "TexLive";
extraTexPackages = lib.mkOption {
description = ''
TexLive package to be made available.
'';
default = {};
type = lib.types.attrsOf lib.types.package;
};
};
extraWrapProgramArgs = lib.mkOption {
description = ''
Extra arguments to pass to the final wrapProgram call.
'';
default = [];
type = lib.types.listOf lib.types.str;
apply = lib.escapeShellArgs;
};
};
config = lib.mkIf cfg.enable
(let
emacsDataDir = "${config.xdg.dataHome}/emacs";
emacsCacheDir = "${config.xdg.cacheHome}/emacs";
warnings =
if config.fonts.fontconfig.enable
then []
else [''This Emacs config will have font issues if
fonts.fontconfig.enable is not enabled.''];
essentialTexPackages = {
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.
quiver # Commutative diagrams w/ TikZ & q.uiver.app.
metafont
preview # For new-gen org-latex-preview.
mylatexformat # For new-gen org-latex-preview.
collection-fontsrecommended # Essential fonts.
etoolbox # For Org-mode exports.
;
};
my-texlive = pkgs.texlive.combine
(essentialTexPackages // cfg.tex.extraTexPackages);
sydmacs =
let ewp = (pkgs.emacsPackagesFor cfg.package).emacsWithPackages
cfg.emacsPackages;
in pkgs.symlinkJoin {
name = "sydmacs";
paths = [ ewp ];
nativeBuildInputs = [
pkgs.makeWrapper
];
postBuild =
let
runtime-binaries = [
pkgs.git # Dependency of Straight.el.
pkgs.ghostscript # For TeX.
my-texlive
pkgs.unzip # For jump-to-source.
];
in ''
# Read all emacs binaries into a Bash array.
readarray -d "" emacsen \
< <(find "$out/bin" \( -name emacs -or -name 'emacs-*' \) -print0)
for emacs in "''${emacsen[@]}"; do
wrapProgram "$emacs" \
--add-flags "--init-directory \"${cfg.userDir}\"" \
--prefix PATH : "${lib.makeBinPath runtime-binaries}" \
${cfg.extraWrapProgramArgs}
done
'';
meta = cfg.package.meta;
version = cfg.package.version;
};
in {
programs.emacs = {
enable = true;
package = sydmacs;
};
sydnix.impermanence.cache.directories = [
# Impermanence expects the path to be relative to ~.
(lib.removePrefix "${config.home.homeDirectory}/" emacsCacheDir)
];
sydnix.impermanence.directories = [
# Impermanence expects the path to be relative to ~.
(lib.removePrefix "${config.home.homeDirectory}/" emacsDataDir)
];
home.packages = cfg.fontPackages;
services.emacs = {
enable = true;
# Generate a desktop entry for emacsclient.
client.enable = true;
};
# We do this ourselves.
stylix.targets.emacs.enable = false;
});
}