diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/editors/emacs.xml')
-rw-r--r-- | nixpkgs/nixos/modules/services/editors/emacs.xml | 587 |
1 files changed, 587 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/editors/emacs.xml b/nixpkgs/nixos/modules/services/editors/emacs.xml new file mode 100644 index 000000000000..1ac53c818a7f --- /dev/null +++ b/nixpkgs/nixos/modules/services/editors/emacs.xml @@ -0,0 +1,587 @@ +<chapter xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="module-services-emacs"> + <title>Emacs</title> +<!-- + Documentation contributors: + Damien Cassou @DamienCassou + Thomas Tuegel @ttuegel + Rodney Lorrimar @rvl + --> + <para> + <link xlink:href="https://www.gnu.org/software/emacs/">Emacs</link> is an + extensible, customizable, self-documenting real-time display editor — and + more. At its core is an interpreter for Emacs Lisp, a dialect of the Lisp + programming language with extensions to support text editing. + </para> + <para> + Emacs runs within a graphical desktop environment using the X Window System, + but works equally well on a text terminal. Under + <productname>macOS</productname>, a "Mac port" edition is available, which + uses Apple's native GUI frameworks. + </para> + <para> + <productname>Nixpkgs</productname> provides a superior environment for + running <application>Emacs</application>. It's simple to create custom builds + by overriding the default packages. Chaotic collections of Emacs Lisp code + and extensions can be brought under control using declarative package + management. <productname>NixOS</productname> even provides a + <command>systemd</command> user service for automatically starting the Emacs + daemon. + </para> + <section xml:id="module-services-emacs-installing"> + <title>Installing <application>Emacs</application></title> + + <para> + Emacs can be installed in the normal way for Nix (see + <xref linkend="sec-package-management" />). In addition, a NixOS + <emphasis>service</emphasis> can be enabled. + </para> + + <section xml:id="module-services-emacs-releases"> + <title>The Different Releases of Emacs</title> + + <para> + <productname>Nixpkgs</productname> defines several basic Emacs packages. + The following are attributes belonging to the <varname>pkgs</varname> set: + <variablelist> + <varlistentry> + <term> + <varname>emacs</varname> + </term> + <term> + <varname>emacs25</varname> + </term> + <listitem> + <para> + The latest stable version of Emacs 25 using the + <link + xlink:href="http://www.gtk.org">GTK+ 2</link> + widget toolkit. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <varname>emacs25-nox</varname> + </term> + <listitem> + <para> + Emacs 25 built without any dependency on X11 libraries. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <varname>emacsMacport</varname> + </term> + <term> + <varname>emacs25Macport</varname> + </term> + <listitem> + <para> + Emacs 25 with the "Mac port" patches, providing a more native look and + feel under macOS. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + + <para> + If those aren't suitable, then the following imitation Emacs editors are + also available in Nixpkgs: + <link xlink:href="https://www.gnu.org/software/zile/">Zile</link>, + <link xlink:href="http://homepage.boetes.org/software/mg/">mg</link>, + <link xlink:href="http://yi-editor.github.io/">Yi</link>. + </para> + </section> + + <section xml:id="module-services-emacs-adding-packages"> + <title>Adding Packages to Emacs</title> + + <para> + Emacs includes an entire ecosystem of functionality beyond text editing, + including a project planner, mail and news reader, debugger interface, + calendar, and more. + </para> + + <para> + Most extensions are gotten with the Emacs packaging system + (<filename>package.el</filename>) from + <link + xlink:href="https://elpa.gnu.org/">Emacs Lisp Package Archive + (<acronym>ELPA</acronym>)</link>, + <link xlink:href="https://melpa.org/"><acronym>MELPA</acronym></link>, + <link xlink:href="https://stable.melpa.org/">MELPA Stable</link>, and + <link xlink:href="http://orgmode.org/elpa.html">Org ELPA</link>. Nixpkgs is + regularly updated to mirror all these archives. + </para> + + <para> + Under NixOS, you can continue to use + <function>package-list-packages</function> and + <function>package-install</function> to install packages. You can also + declare the set of Emacs packages you need using the derivations from + Nixpkgs. The rest of this section discusses declarative installation of + Emacs packages through nixpkgs. + </para> + + <note> + <para> + This documentation describes the new Emacs packages framework in NixOS + 16.03 (<varname>emacsPackagesNg</varname>) which should not be confused + with the previous and deprecated framework + (<varname>emacs24Packages</varname>). + </para> + </note> + + <para> + The first step to declare the list of packages you want in your Emacs + installation is to create a dedicated derivation. This can be done in a + dedicated <filename>emacs.nix</filename> file such as: + <example xml:id="ex-emacsNix"> + <title>Nix expression to build Emacs with packages (<filename>emacs.nix</filename>)</title> +<programlisting language="nix"> +/* +This is a nix expression to build Emacs and some Emacs packages I like +from source on any distribution where Nix is installed. This will install +all the dependencies from the nixpkgs repository and build the binary files +without interfering with the host distribution. + +To build the project, type the following from the current directory: + +$ nix-build emacs.nix + +To run the newly compiled executable: + +$ ./result/bin/emacs +*/ +{ pkgs ? import <nixpkgs> {} }: <co xml:id="ex-emacsNix-1" /> + +let + myEmacs = pkgs.emacs; <co xml:id="ex-emacsNix-2" /> + emacsWithPackages = (pkgs.emacsPackagesNgGen myEmacs).emacsWithPackages; <co xml:id="ex-emacsNix-3" /> +in + emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [ <co xml:id="ex-emacsNix-4" /> + magit # ; Integrate git <C-x g> + zerodark-theme # ; Nicolas' theme + ]) ++ (with epkgs.melpaPackages; [ <co xml:id="ex-emacsNix-5" /> + undo-tree # ; <C-x u> to show the undo tree + zoom-frm # ; increase/decrease font size for all buffers %lt;C-x C-+> + ]) ++ (with epkgs.elpaPackages; [ <co xml:id="ex-emacsNix-6" /> + auctex # ; LaTeX mode + beacon # ; highlight my cursor when scrolling + nameless # ; hide current package name everywhere in elisp code + ]) ++ [ + pkgs.notmuch # From main packages set <co xml:id="ex-emacsNix-7" /> + ]) +</programlisting> + </example> + <calloutlist> + <callout arearefs="ex-emacsNix-1"> + <para> + The first non-comment line in this file (<literal>{ pkgs ? ... + }</literal>) indicates that the whole file represents a function. + </para> + </callout> + <callout arearefs="ex-emacsNix-2"> + <para> + The <varname>let</varname> expression below defines a + <varname>myEmacs</varname> binding pointing to the current stable + version of Emacs. This binding is here to separate the choice of the + Emacs binary from the specification of the required packages. + </para> + </callout> + <callout arearefs="ex-emacsNix-3"> + <para> + This generates an <varname>emacsWithPackages</varname> function. It + takes a single argument: a function from a package set to a list of + packages (the packages that will be available in Emacs). + </para> + </callout> + <callout arearefs="ex-emacsNix-4"> + <para> + The rest of the file specifies the list of packages to install. In the + example, two packages (<varname>magit</varname> and + <varname>zerodark-theme</varname>) are taken from MELPA stable. + </para> + </callout> + <callout arearefs="ex-emacsNix-5"> + <para> + Two packages (<varname>undo-tree</varname> and + <varname>zoom-frm</varname>) are taken from MELPA. + </para> + </callout> + <callout arearefs="ex-emacsNix-6"> + <para> + Three packages are taken from GNU ELPA. + </para> + </callout> + <callout arearefs="ex-emacsNix-7"> + <para> + <varname>notmuch</varname> is taken from a nixpkgs derivation which + contains an Emacs mode. + </para> + </callout> + </calloutlist> + </para> + + <para> + The result of this configuration will be an <command>emacs</command> + command which launches Emacs with all of your chosen packages in the + <varname>load-path</varname>. + </para> + + <para> + You can check that it works by executing this in a terminal: +<screen> +$ nix-build emacs.nix +$ ./result/bin/emacs -q +</screen> + and then typing <literal>M-x package-initialize</literal>. Check that you + can use all the packages you want in this Emacs instance. For example, try + switching to the zerodark theme through <literal>M-x load-theme <RET> + zerodark <RET> y</literal>. + </para> + + <tip> + <para> + A few popular extensions worth checking out are: auctex, company, + edit-server, flycheck, helm, iedit, magit, multiple-cursors, projectile, + and yasnippet. + </para> + </tip> + + <para> + The list of available packages in the various ELPA repositories can be seen + with the following commands: + <example xml:id="module-services-emacs-querying-packages"> + <title>Querying Emacs packages</title> +<programlisting><![CDATA[ +nix-env -f "<nixpkgs>" -qaP -A emacsPackagesNg.elpaPackages +nix-env -f "<nixpkgs>" -qaP -A emacsPackagesNg.melpaPackages +nix-env -f "<nixpkgs>" -qaP -A emacsPackagesNg.melpaStablePackages +nix-env -f "<nixpkgs>" -qaP -A emacsPackagesNg.orgPackages +]]></programlisting> + </example> + </para> + + <para> + If you are on NixOS, you can install this particular Emacs for all users by + adding it to the list of system packages (see + <xref linkend="sec-declarative-package-mgmt" />). Simply modify your file + <filename>configuration.nix</filename> to make it contain: + <example xml:id="module-services-emacs-configuration-nix"> + <title>Custom Emacs in <filename>configuration.nix</filename></title> +<programlisting><![CDATA[ +{ + environment.systemPackages = [ + # [...] + (import /path/to/emacs.nix { inherit pkgs; }) + ]; +} +]]></programlisting> + </example> + </para> + + <para> + In this case, the next <command>nixos-rebuild switch</command> will take + care of adding your <command>emacs</command> to the <varname>PATH</varname> + environment variable (see <xref linkend="sec-changing-config" />). + </para> + +<!-- fixme: i think the following is better done with config.nix +https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides +--> + + <para> + If you are not on NixOS or want to install this particular Emacs only for + yourself, you can do so by adding it to your + <filename>~/.config/nixpkgs/config.nix</filename> (see + <link xlink:href="http://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides">Nixpkgs + manual</link>): + <example xml:id="module-services-emacs-config-nix"> + <title>Custom Emacs in <filename>~/.config/nixpkgs/config.nix</filename></title> +<programlisting><![CDATA[ +{ + packageOverrides = super: let self = super.pkgs; in { + myemacs = import /path/to/emacs.nix { pkgs = self; }; + }; +} +]]></programlisting> + </example> + </para> + + <para> + In this case, the next <literal>nix-env -f '<nixpkgs>' -iA + myemacs</literal> will take care of adding your emacs to the + <varname>PATH</varname> environment variable. + </para> + </section> + + <section xml:id="module-services-emacs-advanced"> + <title>Advanced Emacs Configuration</title> + + <para> + If you want, you can tweak the Emacs package itself from your + <filename>emacs.nix</filename>. For example, if you want to have a + GTK+3-based Emacs instead of the default GTK+2-based binary and remove the + automatically generated <filename>emacs.desktop</filename> (useful is you + only use <command>emacsclient</command>), you can change your file + <filename>emacs.nix</filename> in this way: + </para> + + <example xml:id="ex-emacsGtk3Nix"> + <title>Custom Emacs build</title> +<programlisting><![CDATA[ +{ pkgs ? import <nixpkgs> {} }: +let + myEmacs = (pkgs.emacs.override { + # Use gtk3 instead of the default gtk2 + withGTK3 = true; + withGTK2 = false; + }).overrideAttrs (attrs: { + # I don't want emacs.desktop file because I only use + # emacsclient. + postInstall = (attrs.postInstall or "") + '' + rm $out/share/applications/emacs.desktop + ''; + }); +in [...] +]]></programlisting> + </example> + + <para> + After building this file as shown in <xref linkend="ex-emacsNix" />, you + will get an GTK3-based Emacs binary pre-loaded with your favorite packages. + </para> + </section> + </section> + <section xml:id="module-services-emacs-running"> + <title>Running Emacs as a Service</title> + + <para> + <productname>NixOS</productname> provides an optional + <command>systemd</command> service which launches + <link xlink:href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html"> + Emacs daemon </link> with the user's login session. + </para> + + <para> + <emphasis>Source:</emphasis> + <filename>modules/services/editors/emacs.nix</filename> + </para> + + <section xml:id="module-services-emacs-enabling"> + <title>Enabling the Service</title> + + <para> + To install and enable the <command>systemd</command> user service for Emacs + daemon, add the following to your <filename>configuration.nix</filename>: +<programlisting> +<xref linkend="opt-services.emacs.enable"/> = true; +<xref linkend="opt-services.emacs.package"/> = import /home/cassou/.emacs.d { pkgs = pkgs; }; +</programlisting> + </para> + + <para> + The <varname>services.emacs.package</varname> option allows a custom + derivation to be used, for example, one created by + <function>emacsWithPackages</function>. + </para> + + <para> + Ensure that the Emacs server is enabled for your user's Emacs + configuration, either by customizing the <varname>server-mode</varname> + variable, or by adding <literal>(server-start)</literal> to + <filename>~/.emacs.d/init.el</filename>. + </para> + + <para> + To start the daemon, execute the following: +<screen> +$ nixos-rebuild switch # to activate the new configuration.nix +$ systemctl --user daemon-reload # to force systemd reload +$ systemctl --user start emacs.service # to start the Emacs daemon +</screen> + The server should now be ready to serve Emacs clients. + </para> + </section> + + <section xml:id="module-services-emacs-starting-client"> + <title>Starting the client</title> + + <para> + Ensure that the emacs server is enabled, either by customizing the + <varname>server-mode</varname> variable, or by adding + <literal>(server-start)</literal> to <filename>~/.emacs</filename>. + </para> + + <para> + To connect to the emacs daemon, run one of the following: +<programlisting><![CDATA[ +emacsclient FILENAME +emacsclient --create-frame # opens a new frame (window) +emacsclient --create-frame --tty # opens a new frame on the current terminal +]]></programlisting> + </para> + </section> + + <section xml:id="module-services-emacs-editor-variable"> + <title>Configuring the <varname>EDITOR</varname> variable</title> + +<!--<title><command>emacsclient</command> as the Default Editor</title>--> + + <para> + If <xref linkend="opt-services.emacs.defaultEditor"/> is + <literal>true</literal>, the <varname>EDITOR</varname> variable will be set + to a wrapper script which launches <command>emacsclient</command>. + </para> + + <para> + Any setting of <varname>EDITOR</varname> in the shell config files will + override <varname>services.emacs.defaultEditor</varname>. To make sure + <varname>EDITOR</varname> refers to the Emacs wrapper script, remove any + existing <varname>EDITOR</varname> assignment from + <filename>.profile</filename>, <filename>.bashrc</filename>, + <filename>.zshenv</filename> or any other shell config file. + </para> + + <para> + If you have formed certain bad habits when editing files, these can be + corrected with a shell alias to the wrapper script: +<programlisting>alias vi=$EDITOR</programlisting> + </para> + </section> + + <section xml:id="module-services-emacs-per-user"> + <title>Per-User Enabling of the Service</title> + + <para> + In general, <command>systemd</command> user services are globally enabled + by symlinks in <filename>/etc/systemd/user</filename>. In the case where + Emacs daemon is not wanted for all users, it is possible to install the + service but not globally enable it: +<programlisting> +<xref linkend="opt-services.emacs.enable"/> = false; +<xref linkend="opt-services.emacs.install"/> = true; +</programlisting> + </para> + + <para> + To enable the <command>systemd</command> user service for just the + currently logged in user, run: +<programlisting>systemctl --user enable emacs</programlisting> + This will add the symlink + <filename>~/.config/systemd/user/emacs.service</filename>. + </para> + </section> + </section> + <section xml:id="module-services-emacs-configuring"> + <title>Configuring Emacs</title> + + <para> + The Emacs init file should be changed to load the extension packages at + startup: + <example xml:id="module-services-emacs-package-initialisation"> + <title>Package initialization in <filename>.emacs</filename></title> +<programlisting><![CDATA[ +(require 'package) + +;; optional. makes unpure packages archives unavailable +(setq package-archives nil) + +(setq package-enable-at-startup nil) +(package-initialize) +]]></programlisting> + </example> + </para> + + <para> + After the declarative emacs package configuration has been tested, + previously downloaded packages can be cleaned up by removing + <filename>~/.emacs.d/elpa</filename> (do make a backup first, in case you + forgot a package). + </para> + +<!-- + todo: is it worth documenting customizations for + server-switch-hook, server-done-hook? + --> + + <section xml:id="module-services-emacs-major-mode"> + <title>A Major Mode for Nix Expressions</title> + + <para> + Of interest may be <varname>melpaPackages.nix-mode</varname>, which + provides syntax highlighting for the Nix language. This is particularly + convenient if you regularly edit Nix files. + </para> + </section> + + <section xml:id="module-services-emacs-man-pages"> + <title>Accessing man pages</title> + + <para> + You can use <function>woman</function> to get completion of all available + man pages. For example, type <literal>M-x woman <RET> nixos-rebuild + <RET>.</literal> + </para> + </section> + + <section xml:id="sec-emacs-docbook-xml"> + <title>Editing DocBook 5 XML Documents</title> + + <para> + Emacs includes + <link + xlink:href="https://www.gnu.org/software/emacs/manual/html_node/nxml-mode/Introduction.html">nXML</link>, + a major-mode for validating and editing XML documents. When editing DocBook + 5.0 documents, such as <link linkend="book-nixos-manual">this one</link>, + nXML needs to be configured with the relevant schema, which is not + included. + </para> + + <para> + To install the DocBook 5.0 schemas, either add + <varname>pkgs.docbook5</varname> to + <xref linkend="opt-environment.systemPackages"/> + (<link + linkend="sec-declarative-package-mgmt">NixOS</link>), or run + <literal>nix-env -i pkgs.docbook5</literal> + (<link linkend="sec-ad-hoc-packages">Nix</link>). + </para> + + <para> + Then customize the variable <varname>rng-schema-locating-files</varname> to + include <filename>~/.emacs.d/schemas.xml</filename> and put the following + text into that file: + <example xml:id="ex-emacs-docbook-xml"> + <title>nXML Schema Configuration (<filename>~/.emacs.d/schemas.xml</filename>)</title> +<programlisting language="xml"><![CDATA[ +<?xml version="1.0"?> +<!-- + To let emacs find this file, evaluate: + (add-to-list 'rng-schema-locating-files "~/.emacs.d/schemas.xml") +--> +<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0"> + <!-- + Use this variation if pkgs.docbook5 is added to environment.systemPackages + --> + <namespace ns="http://docbook.org/ns/docbook" + uri="/run/current-system/sw/share/xml/docbook-5.0/rng/docbookxi.rnc"/> + <!-- + Use this variation if installing schema with "nix-env -iA pkgs.docbook5". + <namespace ns="http://docbook.org/ns/docbook" + uri="../.nix-profile/share/xml/docbook-5.0/rng/docbookxi.rnc"/> + --> +</locatingRules> +]]></programlisting> + </example> + </para> + </section> + </section> +</chapter> |