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 those 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 = 10 pkgs: with pkgs; { 11 myEmacs = emacs.pkgs.withPackages ( 12 epkgs: 13 (with epkgs.melpaStablePackages; [ 14 company 15 counsel 16 flycheck 17 ivy 18 magit 19 projectile 20 use-package 21 ]) 22 ); 23 }; 24} 25``` 26 27You can install it like any other package 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. 28 29```nix 30{ 31 packageOverrides = pkgs: { 32 myEmacsConfig = pkgs.writeText "default.el" '' 33 (eval-when-compile 34 (require 'use-package)) 35 36 ;; load some packages 37 38 (use-package company 39 :bind ("<C-tab>" . company-complete) 40 :diminish company-mode 41 :commands (company-mode global-company-mode) 42 :defer 1 43 :config 44 (global-company-mode)) 45 46 (use-package counsel 47 :commands (counsel-descbinds) 48 :bind (([remap execute-extended-command] . counsel-M-x) 49 ("C-x C-f" . counsel-find-file) 50 ("C-c g" . counsel-git) 51 ("C-c j" . counsel-git-grep) 52 ("C-c k" . counsel-ag) 53 ("C-x l" . counsel-locate) 54 ("M-y" . counsel-yank-pop))) 55 56 (use-package flycheck 57 :defer 2 58 :config (global-flycheck-mode)) 59 60 (use-package ivy 61 :defer 1 62 :bind (("C-c C-r" . ivy-resume) 63 ("C-x C-b" . ivy-switch-buffer) 64 :map ivy-minibuffer-map 65 ("C-j" . ivy-call)) 66 :diminish ivy-mode 67 :commands ivy-mode 68 :config 69 (ivy-mode 1)) 70 71 (use-package magit 72 :defer 73 :if (executable-find "git") 74 :bind (("C-x g" . magit-status) 75 ("C-x G" . magit-dispatch-popup)) 76 :init 77 (setq magit-completing-read-function 'ivy-completing-read)) 78 79 (use-package projectile 80 :commands projectile-mode 81 :bind-keymap ("C-c p" . projectile-command-map) 82 :defer 5 83 :config 84 (projectile-global-mode)) 85 ''; 86 87 myEmacs = emacs.pkgs.withPackages ( 88 epkgs: 89 (with epkgs.melpaStablePackages; [ 90 (runCommand "default.el" { } '' 91 mkdir -p $out/share/emacs/site-lisp 92 cp ${myEmacsConfig} $out/share/emacs/site-lisp/default.el 93 '') 94 company 95 counsel 96 flycheck 97 ivy 98 magit 99 projectile 100 use-package 101 ]) 102 ); 103 }; 104} 105``` 106 107This 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. 108 109Sometimes `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`. 110 111```nix 112let 113 overrides = self: super: rec { 114 haskell-mode = self.melpaPackages.haskell-mode; 115 # ... 116 }; 117in 118((emacsPackagesFor emacs).overrideScope overrides).withPackages ( 119 p: with p; [ 120 # here both these package will use haskell-mode of our own choice 121 ghc-mod 122 dante 123 ] 124) 125``` 126}