1# Emacs {#sec-emacs} 2 3## Configuring Emacs {#sec-emacs-config} 4 5The Emacs package comes with some extra helpers to make it easier to configure. `emacs.pkgs.withPackages` allows you to manage packages from ELPA. This means that you will not have to install that packages from within Emacs. For instance, if you wanted to use `company` `counsel`, `flycheck`, `ivy`, `magit`, `projectile`, and `use-package` you could use this as a `~/.config/nixpkgs/config.nix` override: 6 7```nix 8{ 9 packageOverrides = pkgs: with pkgs; { 10 myEmacs = emacs.pkgs.withPackages (epkgs: (with epkgs.melpaStablePackages; [ 11 company 12 counsel 13 flycheck 14 ivy 15 magit 16 projectile 17 use-package 18 ])); 19 }; 20} 21``` 22 23You can install it like any other packages via `nix-env -iA myEmacs`. However, this will only install those packages. It will not `configure` them for us. To do this, we need to provide a configuration file. Luckily, it is possible to do this from within Nix! By modifying the above example, we can make Emacs load a custom config file. The key is to create a package that provides a `default.el` file in `/share/emacs/site-start/`. Emacs knows to load this file automatically when it starts. 24 25```nix 26{ 27 packageOverrides = pkgs: with pkgs; rec { 28 myEmacsConfig = writeText "default.el" '' 29 (eval-when-compile 30 (require 'use-package)) 31 32 ;; load some packages 33 34 (use-package company 35 :bind ("<C-tab>" . company-complete) 36 :diminish company-mode 37 :commands (company-mode global-company-mode) 38 :defer 1 39 :config 40 (global-company-mode)) 41 42 (use-package counsel 43 :commands (counsel-descbinds) 44 :bind (([remap execute-extended-command] . counsel-M-x) 45 ("C-x C-f" . counsel-find-file) 46 ("C-c g" . counsel-git) 47 ("C-c j" . counsel-git-grep) 48 ("C-c k" . counsel-ag) 49 ("C-x l" . counsel-locate) 50 ("M-y" . counsel-yank-pop))) 51 52 (use-package flycheck 53 :defer 2 54 :config (global-flycheck-mode)) 55 56 (use-package ivy 57 :defer 1 58 :bind (("C-c C-r" . ivy-resume) 59 ("C-x C-b" . ivy-switch-buffer) 60 :map ivy-minibuffer-map 61 ("C-j" . ivy-call)) 62 :diminish ivy-mode 63 :commands ivy-mode 64 :config 65 (ivy-mode 1)) 66 67 (use-package magit 68 :defer 69 :if (executable-find "git") 70 :bind (("C-x g" . magit-status) 71 ("C-x G" . magit-dispatch-popup)) 72 :init 73 (setq magit-completing-read-function 'ivy-completing-read)) 74 75 (use-package projectile 76 :commands projectile-mode 77 :bind-keymap ("C-c p" . projectile-command-map) 78 :defer 5 79 :config 80 (projectile-global-mode)) 81 ''; 82 83 myEmacs = emacs.pkgs.withPackages (epkgs: (with epkgs.melpaStablePackages; [ 84 (runCommand "default.el" {} '' 85 mkdir -p $out/share/emacs/site-lisp 86 cp ${myEmacsConfig} $out/share/emacs/site-lisp/default.el 87 '') 88 company 89 counsel 90 flycheck 91 ivy 92 magit 93 projectile 94 use-package 95 ])); 96 }; 97} 98``` 99 100This provides a fairly full Emacs start file. It will load in addition to the user's personal config. You can always disable it by passing `-q` to the Emacs command. 101 102Sometimes `emacs.pkgs.withPackages` is not enough, as this package set has some priorities imposed on packages (with the lowest priority assigned to GNU-devel ELPA, and the highest for packages manually defined in `pkgs/applications/editors/emacs/elisp-packages/manual-packages`). But you can't control these priorities when some package is installed as a dependency. You can override it on a per-package-basis, providing all the required dependencies manually, but it's tedious and there is always a possibility that an unwanted dependency will sneak in through some other package. To completely override such a package, you can use `overrideScope`. 103 104```nix 105let 106 overrides = self: super: rec { 107 haskell-mode = self.melpaPackages.haskell-mode; 108 # ... 109 }; 110in 111((emacsPackagesFor emacs).overrideScope overrides).withPackages 112 (p: with p; [ 113 # here both these package will use haskell-mode of our own choice 114 ghc-mod 115 dante 116 ]) 117``` 118}