nixos/preload: init
[NixPkgs.git] / nixos / modules / services / editors / emacs.nix
blobfad4f39ff2104ced304c7b75770d15b2def52196
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
7   cfg = config.services.emacs;
9   editorScript = pkgs.writeScriptBin "emacseditor" ''
10     #!${pkgs.runtimeShell}
11     if [ -z "$1" ]; then
12       exec ${cfg.package}/bin/emacsclient --create-frame --alternate-editor ${cfg.package}/bin/emacs
13     else
14       exec ${cfg.package}/bin/emacsclient --alternate-editor ${cfg.package}/bin/emacs "$@"
15     fi
16   '';
18   desktopApplicationFile = pkgs.writeTextFile {
19     name = "emacsclient.desktop";
20     destination = "/share/applications/emacsclient.desktop";
21     text = ''
22       [Desktop Entry]
23       Name=Emacsclient
24       GenericName=Text Editor
25       Comment=Edit text
26       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++;
27       Exec=emacseditor %F
28       Icon=emacs
29       Type=Application
30       Terminal=false
31       Categories=Development;TextEditor;
32       StartupWMClass=Emacs
33       Keywords=Text;Editor;
34     '';
35   };
40   options.services.emacs = {
41     enable = mkOption {
42       type = types.bool;
43       default = false;
44       description = lib.mdDoc ''
45         Whether to enable a user service for the Emacs daemon. Use `emacsclient` to connect to the
46         daemon. If `true`, {var}`services.emacs.install` is
47         considered `true`, whatever its value.
48       '';
49     };
51     install = mkOption {
52       type = types.bool;
53       default = false;
54       description = lib.mdDoc ''
55         Whether to install a user service for the Emacs daemon. Once
56         the service is started, use emacsclient to connect to the
57         daemon.
59         The service must be manually started for each user with
60         "systemctl --user start emacs" or globally through
61         {var}`services.emacs.enable`.
62       '';
63     };
66     package = mkOption {
67       type = types.package;
68       default = pkgs.emacs;
69       defaultText = literalExpression "pkgs.emacs";
70       description = lib.mdDoc ''
71         emacs derivation to use.
72       '';
73     };
75     defaultEditor = mkOption {
76       type = types.bool;
77       default = false;
78       description = lib.mdDoc ''
79         When enabled, configures emacsclient to be the default editor
80         using the EDITOR environment variable.
81       '';
82     };
84     startWithGraphical = mkOption {
85       type = types.bool;
86       default = config.services.xserver.enable;
87       defaultText = literalExpression "config.services.xserver.enable";
88       description = lib.mdDoc ''
89         Start emacs with the graphical session instead of any session. Without this, emacs clients will not be able to create frames in the graphical session.
90       '';
91     };
92   };
94   config = mkIf (cfg.enable || cfg.install) {
95     systemd.user.services.emacs = {
96       description = "Emacs: the extensible, self-documenting text editor";
98       serviceConfig = {
99         Type = "forking";
100         ExecStart = "${pkgs.bash}/bin/bash -c 'source ${config.system.build.setEnvironment}; exec ${cfg.package}/bin/emacs --daemon'";
101         ExecStop = "${cfg.package}/bin/emacsclient --eval (kill-emacs)";
102         Restart = "always";
103       };
105       unitConfig = optionalAttrs cfg.startWithGraphical {
106         After = "graphical-session.target";
107       };
108     } // optionalAttrs cfg.enable {
109       wantedBy = if cfg.startWithGraphical then [ "graphical-session.target" ] else [ "default.target" ];
110     };
112     environment.systemPackages = [ cfg.package editorScript desktopApplicationFile ];
114     environment.variables.EDITOR = mkIf cfg.defaultEditor (mkOverride 900 "emacseditor");
115   };
117   meta.doc = ./emacs.md;