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:::