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