└── readme.org /readme.org: -------------------------------------------------------------------------------- 1 | #+TITLE: DIY reproducible Emacs 2 | 3 | * Introduction 4 | 5 | Clone this repository, open this file in Emacs, and follow the instructions to 6 | build yourself a reproducible Emacs configuration in 15 minutes! 7 | 8 | /Hint: You can try this in Docker using/ 9 | #+begin_src sh 10 | docker run -it nixos/nix nix-shell -p emacs-nox git 11 | #+end_src 12 | /After the container has started you can clone this repository and open this file in Emacs./ 13 | 14 | * How Emacs is configured? 15 | 16 | Usually we configure Emacs by modifying a file located at =~/.emacs.d/init.el=. 17 | Here, instead of directly modifying =~/.emacs.d/init.el=, we "tangle" this 18 | document which means that all code is extracted and written to 19 | =~/.emacs.d/init.el=. 20 | 21 | This document is tangled by opening it in Emacs, moving the point over the 22 | following block and pressing =C-c C-c=: 23 | #+begin_src elisp :results silent 24 | (org-babel-tangle) 25 | #+end_src 26 | Alternatively, you can write =M-x org-babel-tangle= or use the 27 | default shortcut =C-c C-v t=. 28 | Tangling can also be done directly from the shell by running 29 | #+begin_src sh 30 | emacs --eval '(org-mode 1) (org-babel-tangle-file "readme.org")' --kill 31 | #+end_src 32 | 33 | Restarting Emacs (=M-x kill-emacs= & =emacs=) will now enable the new 34 | configuration. 35 | 36 | * Package management 37 | 38 | After you restarted Emacs, you might've noticed that it took longer than usual. 39 | That's because several packages were installed by the package manager 40 | straight.el. We use straight.el to achieve reproducibility. In fact, you can 41 | transfer this file to a new computer and obtain an equivalent setup. 42 | 43 | The package manager is enabled in =init.el= via the following commands: 44 | #+begin_src elisp :mkdirp yes :tangle ~/.emacs.d/init.el 45 | (setq straight-use-package-by-default t) 46 | (setq straight-vc-git-default-clone-depth 1) 47 | (defvar bootstrap-version) 48 | (let* ((straight-repo-dir 49 | (expand-file-name "straight/repos" user-emacs-directory)) 50 | (bootstrap-file 51 | (concat straight-repo-dir "/straight.el/bootstrap.el")) 52 | (bootstrap-version 5)) 53 | (unless (file-exists-p bootstrap-file) 54 | (shell-command 55 | (concat 56 | "mkdir -p " straight-repo-dir " && " 57 | "git -C " straight-repo-dir " clone " 58 | "https://github.com/raxod502/straight.el.git && " 59 | "git -C " straight-repo-dir " checkout 2d407bc"))) 60 | (load bootstrap-file nil 'nomessage)) 61 | (straight-use-package 'use-package) 62 | #+end_src 63 | 64 | Notice how this installs straight.el using Git if it doesn't exist under 65 | =~/.emacs.d=. 66 | 67 | /Hint: If you want to upgrade straight.el, you can use a different commit ID 68 | above./ 69 | 70 | * Adding packages 71 | 72 | Before adding new packages to =init.el=, you might want to try them out at 73 | first. In straight.el, there is a convenient interactive command =M-x 74 | straight-use-package= which asks for a package name to install. 75 | Removing any temporary packages is done by restarting Emacs. 76 | 77 | A package can be installed permanently by adding it to the following block: 78 | #+begin_src elisp :mkdirp yes :tangle ~/.emacs.d/init.el 79 | ;; install and enable ivy 80 | (use-package ivy 81 | :commands ivy-mode 82 | :init (ivy-mode 1)) 83 | 84 | ;; install Magit and bind it to 85 | (use-package magit 86 | :bind (("C-x g" . magit-status))) 87 | #+end_src 88 | Each =use-package= call will correspond to a package, e.g., the first call will 89 | install =ivy= (and its dependencies) and run the command =(ivy-mode 1)= during 90 | initialization. 91 | 92 | * Fixing package versions 93 | 94 | Finally, to get a reproducible setup, you need to fix the package versions. 95 | After starting Emacs, you can run =M-x straight-freeze-versions= to write the 96 | file =~/.emacs.d/straight/versions/default.el=. Copy its contents to the 97 | following block to fix the package and dependency versions: 98 | #+begin_src elisp :mkdirp yes :tangle ~/.emacs.d/straight/versions/default.el 99 | (("dash.el" . "0517ab1ed18fd3af3c6131ca9e3a6e915036f809") 100 | ("emacs-async" . "14f48de586b0977e3470f053b810d77b07ea427a") 101 | ("emacsmirror-mirror" . "73d68771488284cceb42f70fda551e0a516cb249") 102 | ("gnu-elpa-mirror" . "fcb3cf5ba5f16885f7851885c954222aee6f03ab") 103 | ("magit" . "3c4259e3e090d8575a6bcf80ad53a393bb16b05f") 104 | ("melpa" . "3b8b731674a5c5d4f83d998258a5d4c9aabb2048") 105 | ("straight.el" . "2d407bccd9378f1d5218f8ba2ae85c6be73fbaf1") 106 | ("swiper" . "d2891aab7b816aebf21ebd01ce33933a6ac6244f") 107 | ("transient" . "4a2b7fdf75c6940b5b311d930ea26f7e85a08cd4") 108 | ("use-package" . "caa92f1d64fc25480551757d854b4b49981dfa6b") 109 | ("with-editor" . "6735180e73e787b79535c245b162249b70dbf841")) 110 | :beta 111 | #+end_src 112 | The above block gets tangled to =~/.emacs.d/straight/versions/default.el=. 113 | 114 | /Hint: If you want to update packages, you can use/ =straight-pull-package=, =straight-rebuild-package=, 115 | /and then redo the steps above./ 116 | --------------------------------------------------------------------------------