{ 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. ''; 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 = '' # 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}\"" \ ${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; }); }