1# Emacs {#module-services-emacs}
2
3<!--
4 Documentation contributors:
5 Damien Cassou @DamienCassou
6 Thomas Tuegel @ttuegel
7 Rodney Lorrimar @rvl
8 Adam Hoese @adisbladis
9 -->
10
11[Emacs](https://www.gnu.org/software/emacs/) is an
12extensible, customizable, self-documenting real-time display editor — and
13more. At its core is an interpreter for Emacs Lisp, a dialect of the Lisp
14programming language with extensions to support text editing.
15
16Emacs runs within a graphical desktop environment using the X Window System,
17but works equally well on a text terminal. Under
18macOS, a "Mac port" edition is available, which
19uses Apple's native GUI frameworks.
20
21Nixpkgs provides a superior environment for
22running Emacs. It's simple to create custom builds
23by overriding the default packages. Chaotic collections of Emacs Lisp code
24and extensions can be brought under control using declarative package
25management. NixOS even provides a
26{command}`systemd` user service for automatically starting the Emacs
27daemon.
28
29## Installing Emacs {#module-services-emacs-installing}
30
31Emacs can be installed in the normal way for Nix (see
32[](#sec-package-management)). In addition, a NixOS
33*service* can be enabled.
34
35### The Different Releases of Emacs {#module-services-emacs-releases}
36
37Nixpkgs defines several basic Emacs packages.
38The following are attributes belonging to the {var}`pkgs` set:
39
40 {var}`emacs`
41 : The latest stable version of Emacs using the [GTK 2](http://www.gtk.org)
42 widget toolkit.
43
44 {var}`emacs-nox`
45 : Emacs built without any dependency on X11 libraries.
46
47 {var}`emacsMacport`
48 : Emacs with the "Mac port" patches, providing a more native look and
49 feel under macOS.
50
51If those aren't suitable, then the following imitation Emacs editors are
52also available in Nixpkgs:
53[Zile](https://www.gnu.org/software/zile/),
54[mg](http://homepage.boetes.org/software/mg/),
55[Yi](http://yi-editor.github.io/),
56[jmacs](https://joe-editor.sourceforge.io/).
57
58### Adding Packages to Emacs {#module-services-emacs-adding-packages}
59
60Emacs includes an entire ecosystem of functionality beyond text editing,
61including a project planner, mail and news reader, debugger interface,
62calendar, and more.
63
64Most extensions are gotten with the Emacs packaging system
65({file}`package.el`) from
66[Emacs Lisp Package Archive (ELPA)](https://elpa.gnu.org/),
67[MELPA](https://melpa.org/),
68[MELPA Stable](https://stable.melpa.org/), and
69[Org ELPA](http://orgmode.org/elpa.html). Nixpkgs is
70regularly updated to mirror all these archives.
71
72Under NixOS, you can continue to use
73`package-list-packages` and
74`package-install` to install packages. You can also
75declare the set of Emacs packages you need using the derivations from
76Nixpkgs. The rest of this section discusses declarative installation of
77Emacs packages through nixpkgs.
78
79The first step to declare the list of packages you want in your Emacs
80installation is to create a dedicated derivation. This can be done in a
81dedicated {file}`emacs.nix` file such as:
82
83::: {.example #ex-emacsNix}
84### Nix expression to build Emacs with packages (`emacs.nix`)
85
86```nix
87/*
88This is a nix expression to build Emacs and some Emacs packages I like
89from source on any distribution where Nix is installed. This will install
90all the dependencies from the nixpkgs repository and build the binary files
91without interfering with the host distribution.
92
93To build the project, type the following from the current directory:
94
95$ nix-build emacs.nix
96
97To run the newly compiled executable:
98
99$ ./result/bin/emacs
100*/
101
102# The first non-comment line in this file indicates that
103# the whole file represents a function.
104{ pkgs ? import <nixpkgs> {} }:
105
106let
107 # The let expression below defines a myEmacs binding pointing to the
108 # current stable version of Emacs. This binding is here to separate
109 # the choice of the Emacs binary from the specification of the
110 # required packages.
111 myEmacs = pkgs.emacs;
112 # This generates an emacsWithPackages function. It takes a single
113 # argument: a function from a package set to a list of packages
114 # (the packages that will be available in Emacs).
115 emacsWithPackages = (pkgs.emacsPackagesFor myEmacs).emacsWithPackages;
116in
117 # The rest of the file specifies the list of packages to install. In the
118 # example, two packages (magit and zerodark-theme) are taken from
119 # MELPA stable.
120 emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
121 magit # ; Integrate git <C-x g>
122 zerodark-theme # ; Nicolas' theme
123 ])
124 # Two packages (undo-tree and zoom-frm) are taken from MELPA.
125 ++ (with epkgs.melpaPackages; [
126 undo-tree # ; <C-x u> to show the undo tree
127 zoom-frm # ; increase/decrease font size for all buffers %lt;C-x C-+>
128 ])
129 # Three packages are taken from GNU ELPA.
130 ++ (with epkgs.elpaPackages; [
131 auctex # ; LaTeX mode
132 beacon # ; highlight my cursor when scrolling
133 nameless # ; hide current package name everywhere in elisp code
134 ])
135 # notmuch is taken from a nixpkgs derivation which contains an Emacs mode.
136 ++ [
137 pkgs.notmuch # From main packages set
138 ])
139```
140:::
141
142The result of this configuration will be an {command}`emacs`
143command which launches Emacs with all of your chosen packages in the
144{var}`load-path`.
145
146You can check that it works by executing this in a terminal:
147```ShellSession
148$ nix-build emacs.nix
149$ ./result/bin/emacs -q
150```
151and then typing `M-x package-initialize`. Check that you
152can use all the packages you want in this Emacs instance. For example, try
153switching to the zerodark theme through `M-x load-theme <RET> zerodark <RET> y`.
154
155::: {.tip}
156A few popular extensions worth checking out are: auctex, company,
157edit-server, flycheck, helm, iedit, magit, multiple-cursors, projectile,
158and yasnippet.
159:::
160
161The list of available packages in the various ELPA repositories can be seen
162with the following commands:
163::: {.example #module-services-emacs-querying-packages}
164### Querying Emacs packages
165
166```
167nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.elpaPackages
168nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.melpaPackages
169nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.melpaStablePackages
170nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.orgPackages
171```
172:::
173
174If you are on NixOS, you can install this particular Emacs for all users by
175adding it to the list of system packages (see
176[](#sec-declarative-package-mgmt)). Simply modify your file
177{file}`configuration.nix` to make it contain:
178::: {.example #module-services-emacs-configuration-nix}
179### Custom Emacs in `configuration.nix`
180
181```
182{
183 environment.systemPackages = [
184 # [...]
185 (import /path/to/emacs.nix { inherit pkgs; })
186 ];
187}
188```
189:::
190
191In this case, the next {command}`nixos-rebuild switch` will take
192care of adding your {command}`emacs` to the {var}`PATH`
193environment variable (see [](#sec-changing-config)).
194
195<!-- fixme: i think the following is better done with config.nix
196https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides
197-->
198
199If you are not on NixOS or want to install this particular Emacs only for
200yourself, you can do so by adding it to your
201{file}`~/.config/nixpkgs/config.nix` (see
202[Nixpkgs manual](https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides)):
203::: {.example #module-services-emacs-config-nix}
204### Custom Emacs in `~/.config/nixpkgs/config.nix`
205
206```
207{
208 packageOverrides = super: let self = super.pkgs; in {
209 myemacs = import /path/to/emacs.nix { pkgs = self; };
210 };
211}
212```
213:::
214
215In this case, the next `nix-env -f '<nixpkgs>' -iA
216myemacs` will take care of adding your emacs to the
217{var}`PATH` environment variable.
218
219### Advanced Emacs Configuration {#module-services-emacs-advanced}
220
221If you want, you can tweak the Emacs package itself from your
222{file}`emacs.nix`. For example, if you want to have a
223GTK 3-based Emacs instead of the default GTK 2-based binary and remove the
224automatically generated {file}`emacs.desktop` (useful if you
225only use {command}`emacsclient`), you can change your file
226{file}`emacs.nix` in this way:
227
228::: {.example #ex-emacsGtk3Nix}
229### Custom Emacs build
230
231```
232{ pkgs ? import <nixpkgs> {} }:
233let
234 myEmacs = (pkgs.emacs.override {
235 # Use gtk3 instead of the default gtk2
236 withGTK3 = true;
237 withGTK2 = false;
238 }).overrideAttrs (attrs: {
239 # I don't want emacs.desktop file because I only use
240 # emacsclient.
241 postInstall = (attrs.postInstall or "") + ''
242 rm $out/share/applications/emacs.desktop
243 '';
244 });
245in [...]
246```
247:::
248
249After building this file as shown in [](#ex-emacsNix), you
250will get an GTK 3-based Emacs binary pre-loaded with your favorite packages.
251
252## Running Emacs as a Service {#module-services-emacs-running}
253
254NixOS provides an optional
255{command}`systemd` service which launches
256[Emacs daemon](https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html)
257with the user's login session.
258
259*Source:* {file}`modules/services/editors/emacs.nix`
260
261### Enabling the Service {#module-services-emacs-enabling}
262
263To install and enable the {command}`systemd` user service for Emacs
264daemon, add the following to your {file}`configuration.nix`:
265```
266services.emacs.enable = true;
267services.emacs.package = import /home/cassou/.emacs.d { pkgs = pkgs; };
268```
269
270The {var}`services.emacs.package` option allows a custom
271derivation to be used, for example, one created by
272`emacsWithPackages`.
273
274Ensure that the Emacs server is enabled for your user's Emacs
275configuration, either by customizing the {var}`server-mode`
276variable, or by adding `(server-start)` to
277{file}`~/.emacs.d/init.el`.
278
279To start the daemon, execute the following:
280```ShellSession
281$ nixos-rebuild switch # to activate the new configuration.nix
282$ systemctl --user daemon-reload # to force systemd reload
283$ systemctl --user start emacs.service # to start the Emacs daemon
284```
285The server should now be ready to serve Emacs clients.
286
287### Starting the client {#module-services-emacs-starting-client}
288
289Ensure that the emacs server is enabled, either by customizing the
290{var}`server-mode` variable, or by adding
291`(server-start)` to {file}`~/.emacs`.
292
293To connect to the emacs daemon, run one of the following:
294```
295emacsclient FILENAME
296emacsclient --create-frame # opens a new frame (window)
297emacsclient --create-frame --tty # opens a new frame on the current terminal
298```
299
300### Configuring the {var}`EDITOR` variable {#module-services-emacs-editor-variable}
301
302<!--<title>{command}`emacsclient` as the Default Editor</title>-->
303
304If [](#opt-services.emacs.defaultEditor) is
305`true`, the {var}`EDITOR` variable will be set
306to a wrapper script which launches {command}`emacsclient`.
307
308Any setting of {var}`EDITOR` in the shell config files will
309override {var}`services.emacs.defaultEditor`. To make sure
310{var}`EDITOR` refers to the Emacs wrapper script, remove any
311existing {var}`EDITOR` assignment from
312{file}`.profile`, {file}`.bashrc`,
313{file}`.zshenv` or any other shell config file.
314
315If you have formed certain bad habits when editing files, these can be
316corrected with a shell alias to the wrapper script:
317```
318alias vi=$EDITOR
319```
320
321### Per-User Enabling of the Service {#module-services-emacs-per-user}
322
323In general, {command}`systemd` user services are globally enabled
324by symlinks in {file}`/etc/systemd/user`. In the case where
325Emacs daemon is not wanted for all users, it is possible to install the
326service but not globally enable it:
327```
328services.emacs.enable = false;
329services.emacs.install = true;
330```
331
332To enable the {command}`systemd` user service for just the
333currently logged in user, run:
334```
335systemctl --user enable emacs
336```
337This will add the symlink
338{file}`~/.config/systemd/user/emacs.service`.
339
340## Configuring Emacs {#module-services-emacs-configuring}
341
342The Emacs init file should be changed to load the extension packages at
343startup:
344
345::: {.example #module-services-emacs-package-initialisation}
346### Package initialization in `.emacs`
347
348```
349(require 'package)
350
351;; optional. makes unpure packages archives unavailable
352(setq package-archives nil)
353
354(setq package-enable-at-startup nil)
355(package-initialize)
356```
357:::
358
359After the declarative emacs package configuration has been tested,
360previously downloaded packages can be cleaned up by removing
361{file}`~/.emacs.d/elpa` (do make a backup first, in case you
362forgot a package).
363
364<!--
365 todo: is it worth documenting customizations for
366 server-switch-hook, server-done-hook?
367 -->
368
369### A Major Mode for Nix Expressions {#module-services-emacs-major-mode}
370
371Of interest may be {var}`melpaPackages.nix-mode`, which
372provides syntax highlighting for the Nix language. This is particularly
373convenient if you regularly edit Nix files.
374
375### Accessing man pages {#module-services-emacs-man-pages}
376
377You can use `woman` to get completion of all available
378man pages. For example, type `M-x woman <RET> nixos-rebuild <RET>.`
379
380### Editing DocBook 5 XML Documents {#sec-emacs-docbook-xml}
381
382Emacs includes
383[nXML](https://www.gnu.org/software/emacs/manual/html_node/nxml-mode/Introduction.html),
384a major-mode for validating and editing XML documents. When editing DocBook
3855.0 documents, such as [this one](#book-nixos-manual),
386nXML needs to be configured with the relevant schema, which is not
387included.
388
389To install the DocBook 5.0 schemas, either add
390{var}`pkgs.docbook5` to [](#opt-environment.systemPackages)
391([NixOS](#sec-declarative-package-mgmt)), or run
392`nix-env -f '<nixpkgs>' -iA docbook5`
393([Nix](#sec-ad-hoc-packages)).
394
395Then customize the variable {var}`rng-schema-locating-files` to
396include {file}`~/.emacs.d/schemas.xml` and put the following
397text into that file:
398::: {.example #ex-emacs-docbook-xml}
399### nXML Schema Configuration (`~/.emacs.d/schemas.xml`)
400
401```xml
402<?xml version="1.0"?>
403<!--
404 To let emacs find this file, evaluate:
405 (add-to-list 'rng-schema-locating-files "~/.emacs.d/schemas.xml")
406-->
407<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
408 <!--
409 Use this variation if pkgs.docbook5 is added to environment.systemPackages
410 -->
411 <namespace ns="http://docbook.org/ns/docbook"
412 uri="/run/current-system/sw/share/xml/docbook-5.0/rng/docbookxi.rnc"/>
413 <!--
414 Use this variation if installing schema with "nix-env -iA pkgs.docbook5".
415 <namespace ns="http://docbook.org/ns/docbook"
416 uri="../.nix-profile/share/xml/docbook-5.0/rng/docbookxi.rnc"/>
417 -->
418</locatingRules>
419```
420:::