{emacsPackage ? null}: {
  config,
  lib,
  pkgs,
  ...
}: let
  myAspell = pkgs.aspellWithDicts (d: [
    d.en
    d.en-science
    d.en-computers
  ]);
  emacsPackage' =
    if emacsPackage == null
    then pkgs.emacs29-pgtk
    else emacsPackage;
in {
  home.packages = with pkgs; [
    # For markdown rendering
    python312Packages.grip
    # For graph generation
    graphviz
    sqlite
    plantuml
    # For latex editing
    texlive.combined.scheme-medium
    # For notifications
    libnotify
    # For spelling
    myAspell
    # For nix
    nil
    manix
    nix-doc
    # For email
    mu
    meson
    pkg-config
    glib
    # Ripgrep for projectile
    ripgrep
    fd
    # Desktop file for org-protocol
    (makeDesktopItem {
      name = "org-protocol";
      exec = "emacsclient %u";
      comment = "Org protocol";
      desktopName = "org-protocol";
      type = "Application";
      mimeTypes = ["x-scheme-handler/org-protocol"];
    })
    # For format output
    # wkhtmltopdf
  ];
  programs.emacs = {
    enable = true;
    package = emacsPackage';
    extraPackages = epkgs:
      with pkgs; [
        epkgs.mu4e
        epkgs.vterm
        epkgs.pdf-tools
        epkgs.emacsql
        epkgs.emacsql-sqlite
        (tree-sitter.withPlugins (
          grammars:
            with grammars; [
              tree-sitter-nix
              tree-sitter-rust
              tree-sitter-toml
            ]
        ))
      ];
  };
  services.emacs = {
    enable = true;
    client.enable = true;
  };
}