{ 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 ]; postBuild = let runtime-binaries = [ my-aspell pkgs.git # Dependency of Straight.el. pkgs.ghostscript # For TeX. my-tex pkgs.unzip # For jump-to-source. ]; in '' find "$out/bin" -name emacs -or -name "emacs-*" \ | while IFS= read -r emacs; do wrapProgram "$emacs" \ --add-flags "--init-directory \"${emacsConfigDir}\"" \ --set EMACS_STRAIGHT_BASE_DIR "${straightBaseDir}" \ --set EMACS_CACHE_DIR "${emacsCacheDir}" \ --set EMACS_DATA_DIR "${emacsDataDir}" \ --set ASPELL_CONF "dict-dir ${my-aspell}/lib/aspell" \ --prefix PATH : "${lib.makeBinPath runtime-binaries}" 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"; }; }); }