I love text editors as you can probably tell from my content. The text editor I use the most is emacs and I have been using DOOM for a little while now. Doom is simply someone else’s config which is made to be usable. This is the second most popular config for emacs the other being spacemacs. At the core Doom differs from spacemacs by lazy loading as much as possible and let the user have more control over how they do things. For someone like me who is obsessed with control this is perfect. I think spacemacs is a bit more userfriendly for someone who has never used emacs and does not want to hack on it and add elisp so generally I mention both to newer people. This is a basic guide aimed at 3 groups of users (emacs, vim and IDE/normal text editor people)
To get started all you have to do is go to the doom github and copy/paste a command. At the time of this writing the command is
# note that this requires you to backup or delete your .emacs.d
git clone https://github.com/hlissner/doom-emacs ~/.emacs.d
~/.emacs.d/bin/doom install
So in normal emacs you should already know that you can edit either ~/.emacs=
or ~/.emacs.d/init.el
. Because of the way doom works with lazy loading
everything it gives you another directory to put your config in. That directory
is ~/.doom.d
and contains 3 files by default. Because of the aspect of lazy
loading to update packages you have to run a shell command. Yes I know this
seems alien to many emacs users but the idea is that you shouldn’t be running
emacs when you update anyway. Note you only have to run these commands when you
change the packages that emacs is using. The command is located in
~/.emacs.d/bin
and the creator of doom suggests you just add it to your PATH.
This command takes one argument which is what you want it to do. The most common
one is doom refresh
or doom re
(both are the same just one is less typing).
This is your bread and butter and any time you want to add/delete packages you
should use this command. Another useful command is doom upgrade
and this one
actually updates all of your packages to the latest version AND upgrades doom to
the latest version. Finally we have the doom doctor
command. This one tells
you what (if anything) is wrong with doom or if your missing any external
programs.
# TLDR
export PATH="$PATH:$HOME/.emacs.d/bin"
doom refresh # installs any packages that are in config
doom upgrade # updates doom and any packages installed
doom doctor # Says what doom is missing to be perfect ie ripgrep
Now that we can update our packages we can start editing the config. The first
file to go over is the .doom.d/init.el
. Remember its in .doom.d not in
.emacs.d. This file runs before the config and is made to define exactly what
premade layers you are going to be using. Note that each layer has specific
options which you can toggle by putting it in parens and adding the option name
with a plus sign. Config.el is where you want to put the majority of your
config. This is the general purpose place where most of it is meant to go. Note
that doom provides many extra commands to make things easier for you and those
in and of itself make doom worth it. Packages.el is strictly for packages and
not for configuration even of those packages, put those in your config.el.
# TLDR
.doom.d
├── config.el # your user config
├── init.el # pre config, your layers
├── packages.el # your packages to install
There are many different commands that doom provides however keep in mind they are inspired by emacs and by vim commands.
Comming from emacs
Before I say anything note that doom lets you do default emacs keybindings all
you have to do is disable the evil package. We can use this as a example on how
to disable a package. Now that we got the basics of doom lets look at it from a
emacs perspective. If you come from vim or a IDE/basic text editor then skip
this section and go to the next one. I’m going to assume basic knowledge of
package installation and explain a little about how you can make doom how you
want it to be. In normal emacs you can litterally install packages 100 different
ways. Dooms approach on package management is imo the best approach. You just
don’t do it unless you have to. Also its configuration based so you don’t have
to worry about having to reinstall everything manually. In order to install a
package you either let doom handle it (assuming it has a layer associated with
it) or do it yourself. To let doom handle it all you have to do is uncomment the
packagename in your .doom.d/init.el
and then run doom refresh
.
Say we have this
;;; init.el
(doom!
...
evil ;; Just add a ; before evil then run doom refresh
...)
we can disable evil by doing
(doom!
...
;evil
...)
and running
doom refresh
Now to install your own package you can use the package.el file and the
def-package! macro. This pulls it from melpa however you can give it other options to pull
from git repos or other places. See the doom documentation for more about that. Once
you do this you would need to configure said package (unless you just want the
package and no configuration). To configure it, go to your config.el and add a
use-package!
or a after!
.
;;; package.el
(def-package! packagename)
;;; config.el
;; Note this is close to the use-package syntax but NOT the same
(use-package! packagename
:init (message "Before my package is loaded")
:config (message "After my package has been loaded"))
;; After! works like a eval-after-load but is not the same
(after! packagename
(message "My package has been loaded!!!"))
After that your package should be loaded! Note that when you do it this way things will become much faster because stuff is only loaded when you need it due to the nature of the macros.
The last really nice macro doom has is map!
which is close to the general
package. You can use a single map!
command to define multiple keybindings and
on any map you want. It uses a common lisp style optional value to define the
map and you can embed lists in it to define multiple maps in the same command.
You also can define a prefix key for all keys pressed. It also allows for
binding the leader key, a prefix with a specific map, after a feature(or
package) is loaded, and when a condition is met. See more at C-h f map!
.
(map! "C-c e" 'somefunc
(:map org-mode
"C-c e" 'org-edit-src)
(:leader
"`" 'do-something)
(:prefix ","
"," 'say-comma-comma)
(:when (stirng= system-name "rentoo")
"M-e" 'im-running-on-hostname-rentoo))
Doom offers this other functionality from vim called the leader key. This functions like a very clean C-x and C-c which doesn’t edit text but communicate with plugins, layers or other things. One example is the g key for git. This is enabled with the git layer and contains magit, and other git related keybinds.
Other then that most of the functionality is similar to emacs with a whole bunch of preconfigured plugins