{ pkgs, config, lib, ... }: with lib; let cfg = config.eboskma.programs.emacs; tangleEmacsConfig = initFile: pkgs.runCommand "tangled-emacs-${initFile}" { } '' cp ${./config.org} ./config.org ${cfg.package}/bin/emacs --batch --quick --load org ./config.org --funcall org-babel-tangle cp ${initFile} $out ''; tree-sitter-hare = pkgs.tree-sitter.buildGrammar { language = "tree-sitter-hare"; version = "unstable-2023-12-31"; src = pkgs.fetchFromSourcehut { owner = "~ecs"; repo = "tree-sitter-hare"; rev = "9408bb8fd6c110307f7c92fa834eb5dbd92e36d8"; sha256 = "iqaj+7Ax5zfXGXsJw5pesTlTeah2X4Li4LpInDSUTcU="; }; }; hare-mode = pkgs.emacsPackages.trivialBuild { pname = "hare-mode"; version = "unstable-2022-04-27"; src = pkgs.fetchFromSourcehut { owner = "~bbuccianti"; repo = "hare-mode"; rev = "bb7b2faccb5939b0c8d4ffa6a6e28a0d2bc93dd6"; sha256 = "SOnsNDWKL077AgTdpd9zZPhiyv8d/snllzTy53qlco8="; }; }; tree-sitter-qml = pkgs.tree-sitter.buildGrammar { language = "tree-sitter-qmljs"; version = "unstable-2024-02-02"; src = pkgs.fetchFromGitHub { owner = "yuja"; repo = "tree-sitter-qmljs"; rev = "9fa49ff3315987f715ce5666ff979a7742fa8a98"; sha256 = "q20gLVLs0LpqRpgo/qNRDfExbWXhICWZjM1ux4+AT6M="; }; }; emacsWithPackages = pkgs.emacsWithPackagesFromUsePackage { config = let tangledOrgConfig = tangleEmacsConfig "init.el"; in builtins.readFile tangledOrgConfig; defaultInitFile = true; package = cfg.package; alwaysEnsure = true; alwaysTangle = true; extraEmacsPackages = epkgs: with epkgs; [ hare-mode vterm (treesit-grammars.with-grammars ( p: with p; [ tree-sitter-bash tree-sitter-c tree-sitter-c-sharp tree-sitter-css tree-sitter-cmake tree-sitter-comment tree-sitter-commonlisp tree-sitter-cpp tree-sitter-css tree-sitter-cuda tree-sitter-devicetree tree-sitter-dockerfile tree-sitter-dot tree-sitter-eex tree-sitter-elisp tree-sitter-elixir tree-sitter-embedded-template tree-sitter-erlang tree-sitter-fish tree-sitter-glsl tree-sitter-go tree-sitter-gomod tree-sitter-gowork tree-sitter-graphql tree-sitter-hare tree-sitter-haskell tree-sitter-hcl tree-sitter-heex tree-sitter-html tree-sitter-http tree-sitter-javascript tree-sitter-jsdoc tree-sitter-json tree-sitter-latex tree-sitter-llvm tree-sitter-lua tree-sitter-make tree-sitter-markdown tree-sitter-markdown-inline tree-sitter-nix tree-sitter-nu tree-sitter-pioasm tree-sitter-python tree-sitter-qml tree-sitter-query tree-sitter-regex tree-sitter-rst tree-sitter-ruby tree-sitter-rust tree-sitter-scheme tree-sitter-scss tree-sitter-sql tree-sitter-surface tree-sitter-svelte tree-sitter-toml tree-sitter-tsx tree-sitter-typescript tree-sitter-verilog tree-sitter-yaml tree-sitter-zig ] )) emacsql emacsql-sqlite ]; }; orgProtocolDesktop = pkgs.makeDesktopItem { name = "org-protocol"; desktopName = "Emacs Org Protocol Handler"; icon = "emacs"; categories = [ "Development" "TextEditor" ]; keywords = [ "org-protocol" ]; type = "Application"; exec = "${emacsWithPackages}/bin/emacsclient -- %u"; terminal = false; mimeTypes = [ "x-scheme-handler/org-protocol" ]; startupWMClass = "Emacs"; }; in { options.eboskma.programs.emacs = { enable = mkEnableOption "activate emacs"; package = mkPackageOption pkgs "emacs" { }; daemon = mkOption { description = "Whether to enable emacs daemon"; type = types.bool; default = true; example = false; }; }; config = mkIf cfg.enable { programs.emacs = { enable = true; package = emacsWithPackages; }; services.emacs = mkIf cfg.daemon { enable = true; package = emacsWithPackages; client.enable = true; socketActivation.enable = true; defaultEditor = true; }; home.file."emacs.d/early-init.el".source = tangleEmacsConfig "early-init.el"; home.packages = with pkgs; [ (texlive.combine { inherit (texlive) scheme-small wrapfig ulem capt-of ; }) orgProtocolDesktop nodePackages.bash-language-server aspell lldb (nil.overrideAttrs (_: { doCheck = false; })) nixpkgs-fmt python3 ] ++ (with aspellDicts; [ en en-computers en-science fy nl ]); }; }