{
  config,
  lib,
  pkgs,
  ...
}:

let
  plainmacs = pkgs.writeShellScriptBin "plainmacs" ''
    INIT_SCRIPT=$(cat <<EOF
    (progn
      (setq make-backup-files nil auto-save-default nil create-lockfiles nil)
      (load-theme 'tango-dark t)
      (set-face-attribute 'default nil :background "black")
      ;; Bright yellow highlighting for selected region
      (set-face-attribute 'region nil :background "#ffff50" :foreground "black")
      ;; Bright green cursor to distinguish from yellow region
      (set-cursor-color "#ccff66")
      ;; Hightlight the current line
      (set-face-attribute 'line-number-current-line nil :foreground "white")
      ;; Set default font
      (set-face-attribute 'default nil :height 100 :width 'regular :weight 'regular :family "Cascadia Mono")
      ;; Set fallback font for unicode glyphs
      (when (display-graphic-p)
        (set-fontset-font "fontset-default" nil (font-spec :name "Noto Color Emoji")))
      (menu-bar-mode -1)
      (when (fboundp 'tool-bar-mode)
        (tool-bar-mode -1))
      (when (  fboundp 'scroll-bar-mode)
        (scroll-bar-mode -1))
      (pixel-scroll-precision-mode)
      (setq frame-resize-pixelwise t)
      )
    EOF
    )

    exec ${pkgs.emacs29-pgtk}/bin/emacs -q --eval "$INIT_SCRIPT" "''${@}"
  '';
  e_shorthand = pkgs.writeShellScriptBin "e" ''
    exec ${pkgs.emacs_full}/bin/emacs "''${@}"
  '';
in
{
  imports = [ ];

  config = lib.mkMerge [
    {
      environment.systemPackages = with pkgs; [
        plainmacs
        e_shorthand
        emacs_full
      ];

      nixpkgs.overlays = [
        (final: prev: {
          emacs_full = pkgs.symlinkJoin {
            name = "emacs_full";
            paths = [ pkgs.emacs29-pgtk ];
            buildInputs = [ pkgs.makeWrapper ];
            postBuild = ''
              wrapProgram $out/bin/emacs --prefix PATH : ${
                lib.makeBinPath [
                  (pkgs.aspellWithDicts (
                    dicts: with dicts; [
                      en
                      en-computers
                    ]
                  ))
                  pkgs.nixd # nix language server
                  pkgs.nixfmt-rfc-style # auto-formatting nix files through nixd
                  pkgs.clang # To compile tree-sitter grammars
                ]
              }
            '';
          };
        })
      ];

      home-manager.users.talexander =
        { pkgs, ... }:
        {
          home.file.".config/emacs" = {
            source = ./files/emacs;
            recursive = true;
          };
        };

      environment.persistence."/state" = lib.mkIf (!config.me.buildingIso) {
        hideMounts = true;
        users.talexander = {
          directories = [
            ".config/emacs/eln-cache" # Installed packages
            ".config/emacs/elpa" # Installed packages
            ".config/emacs/private" # For recentf
            ".config/emacs/tree-sitter" # Compiled tree-sitter grammars
          ];
          files = [
            ".config/emacs/history" # For savehist
            ".config/emacs/.last-package-update-day" # For use-package
          ];
        };
      };

      environment.variables.EDITOR = "${plainmacs}/bin/plainmacs";
    }
  ];
}