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

let
  inherit (pkgs) stdenv;

  editorScript = pkgs.writeScriptBin "edit" ''
    #!${pkgs.runtimeShell}
    if [ -z "$1" ]; then
      exec ${config.programs.emacs.finalPackage}/bin/emacsclient --create-frame --alternate-editor ${config.programs.emacs.finalPackage}/bin/emacs
    else
      exec ${config.programs.emacs.finalPackage}/bin/emacsclient --alternate-editor ${config.programs.emacs.finalPackage}/bin/emacs --create-frame "$@"
    fi
  '';
  desktopApplicationFile = pkgs.writeTextFile {
    name = "emacsclient.desktop";
    destination = "/share/applications/emacsclient.desktop";
    text = ''
      [Desktop Entry]
      Name=Emacsclient
      GenericName=Text Editor
      Comment=Edit text
      MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
      Exec=${editorScript}/bin/edit %F
      Icon=emacs
      Type=Application
      Terminal=false
      Categories=Development;TextEditor;
      StartupWMClass=Emacs
      Keywords=Text;Editor;
    '';
  };
in
{
  imports = [
    ../modules/eshell.nix
  ];
  nixpkgs.overlays = [
    (import (builtins.fetchTarball {
      url = https://github.com/nix-community/emacs-overlay/archive/master.tar.gz;
    }))
  ];

  programs.emacs = {
    enable = true;
    package = lib.mkDefault pkgs.unstable.emacs;
    eshell = {
      aliases = {
        pk = "eshell-up-pk $1";
        up = "eshell-up $1";

        ec = "find-file $1";

        l = "ls $*";
        la = "ls -A $*";
        ll = "ls -lh $*";
        lla = "ls -lhA $*";

        https = "http --default-scheme https $*";

        ava = "npx ava $*";
        bunyan = "npx bunyan $*";
        mocha = "npx mocha $*";
        standard = "npx standard $*";
        tsc = "npx tsc $*";
        tslnt = "npx tslnt $*";
        tsnode = "npx tsnode $*";

        kx = "kubectx $*";
        kns = "kubens $*";

        cdg = "cd (projectile-project-root)";
      };
    };
    extraPackages = epkgs: (with epkgs; [
      ace-link
      all-the-icons
      almost-mono-themes
      add-node-modules-path
      ag
      all-the-icons
      amx
      auto-async-byte-compile
      avy
      bash-completion
      caddyfile-mode
      cider
      clojure-mode
      company
      company-web
      company-tabnine
      consult
      consult-eglot
      counsel
      counsel-projectile
      crux
      docker-compose-mode
      dockerfile-mode
      dired-git-info
      editorconfig
      eglot
      eldoc-box
      emmet-mode
      esh-autosuggest
      esh-buf-stack
      esh-help
      eshell-fringe-status
      eshell-toggle
      eshell-up
      evil
      evil-anzu
      evil-collection
      evil-commentary
      evil-embrace
      evil-ledger
      evil-matchit
      evil-mu4e
      evil-numbers
      evil-org
      evil-quickscope
      evil-space
      evil-surround
      eyebrowse
      feature-mode
      format-all
      flycheck
      general
      git-gutter-fringe
      git-messenger
      git-modes
      git-timemachine
      gitlab-ci-mode
      gitlab-ci-mode-flycheck
      go-mode
      goto-chg
      haskell-mode
      helpful
      ivy-hydra
      janet-mode
      jinja2-mode
      js2-mode
      json-mode
      k8s-mode
      kubel
      kubel-evil
      ledger-mode
      magit
      markdown-mode
      modus-themes
      doom-modeline
      nginx-mode
      nix-mode
      nix-update
      org-journal
      paredit
      php-mode
      posframe
      projectile
      projectile-ripgrep
      quickrun
      racket-mode
      rainbow-mode
      rainbow-delimiters
      restclient
      ripgrep
      rjsx-mode
      rustic
      scss-mode
      spacemacs-theme
      swiper
      tide
      toml-mode
      tree-sitter
      tree-sitter-langs
      tree-sitter-indent
      typescript-mode
      undo-tree
      use-package
      web-mode
      wgrep-ag
      ws-butler
      which-key
      yaml-mode
      yasnippet
    ] ++ lib.optionals (!stdenv.isDarwin) [
      pkgs.mu
    ]);
  };
  home.packages = [
    editorScript
  ];
  home.sessionVariables = {
    EDITOR = "${editorScript}/bin/edit";
  };
  xdg.configFile."emacs/early-init.el" = {
    source = ../emacs/early-init.el;
    onChange = ''
      ${config.programs.emacs.finalPackage}/bin/emacs -Q -batch -f batch-byte-compile .config/emacs/early-init.el
      '';
  };
  xdg.configFile."emacs/init.el" = {
    source = ../emacs/init.el;
    onChange = ''
      ${config.programs.emacs.finalPackage}/bin/emacs -Q -batch -f batch-byte-compile .config/emacs/init.el
      ${config.programs.emacs.finalPackage}/bin/emacs -Q -batch -l package -f package-quickstart-refresh
    '';
  };

  home.file.".local/share/applications/emacsclient.desktop" = lib.mkIf stdenv.isLinux {
    source = desktopApplicationFile;
  };
}