Doom-Emacs is a Emacs framework, Emacs is a huge software with multiple packages and ways to do everything, doom-emacs try to make that a little bit easier for most new users offering a simpler way to install and manage most important packages and configs, under the hood it's a lot of elisp code that install most useful Emacs packages, manage packages state, improves performance with multiple tweaks and offer all of that in a easy opt-in/out way to final users via modules.
Doom uses under the hood the evil-mode
package, which is a package that tries to bring Vim's commands and motion to Emacs, so knowing vim helps a lot how to use Doom emacs, although you don't need to understand vim to start using it.
- Emacs 27.1+ (Mac users:
brew install emacs-plus@28 --with-native-comp
), more details here. - ripgrep (for faster project search) (Mac users:
brew install ripgrep
). - fd (Mac users:
brew install fd
)
After emacs properly installed, install doom-emacs following the official instructions, after that, make sure you run doom sync
and doom doctor
and they don't return any errors (warnings are OK).
TLTR:
git clone --depth 1 https://github.com/hlissner/doom-emacs ~/.emacs.d
~/.emacs.d/bin/doom install
All doom-emacs configurations are inside ~/.doom.d
folder:
.doom.d/init.el
: This is what doom reads when starting, it contains all the modules it should enable, every change requires adoom sync
..doom.d/packages.el
: All extra packages you want that should be installed that are not available via a module ininit.el
. every change requires adoom sync
..doom.d/config.el
: Your custom configuration for anything you want to change on your Emacs.
You can create any extra files for bindings, or functions and on config.el
load it, for example: (load! "+bindings")
for a .doom.d/+bindings.el
file.
Tip: most changes on config.el
don't need to restart emacs, a simple , e e
should eval that config, even so if that doesn't work, you will need to restart emacs or , r r
Tip: Use SPC f p
to open .doom.d
files in doom-emacs.
Enable lsp
module under :tools
section in your ~/.doom.d/init.el
.
Enable (treemacs +lsp)
module under :ui
section in your ~/.doom.d/init.el
.
Add base config which include some good defaults:
config.el
(setq read-process-output-max (* 1024 1024)
doom-localleader-key "," ;; easier than <SPC m>
;; doom-font (font-spec :family "JetBrainsMono Nerd Font Mono" :size 18) ;; Make sure to use a font you have installed
;; doom-theme 'doom-dracula
projectile-project-search-path '("~/YOUR_PROJECTS_BASE_PATH") ;; Change this to your base path for projects
projectile-enable-caching nil)
(add-to-list 'default-frame-alist '(fullscreen . maximized))
(use-package! lsp-mode
:commands lsp
:config
(setq lsp-semantic-tokens-enable t)
(add-hook 'lsp-after-apply-edits-hook (lambda (&rest _) (save-buffer)))) ;; save buffers after renaming
Enable clojure
module with +lsp
flag under :lang
section: (clojure +lsp)
in your ~/.doom.d/init.el
.
Main packages that this module will install:
- cider: Support for Clojure REPL on Emacs.
- lsp-mode: Make Emacs more IDEish, adding multiple features using static analysis.
Make sure to install clojure-lsp via Emacs when prompted or following instructions.
Doom has lots of default keybindings, and has the feature of showing a popup with the available keybindigns when you press the first one, try pressing one time SPC
, after a little bit, doom should show all keybindings you can access and its key, this helps finding a keybinding even not knowing the proper keybinding.
Doom keybindings could be global ones or specific by current buffer major modes (Clojure, Dart, etc), the global ones usually start with SPC
, for example SPC p a
which will call projectile-add-known-project
, while keybindings for the current buffer/mode will start with the localleader key, ,
, for example , t t
to run the current Clojure test with cider.
Note: Some commands have multiple keybindings, this guide will try to present some of them.
SPC f p
Access your doom's config files
-
Project
SPC SPC
Find file in projectSPC p a
Add a folder as a known projectSPC p p
Change to a known projectSPC s p
Search on whole project -
Buffer/Window
SPC f f
Find or create a new fileSPC f s
Save bufferSPC <
Switch to recent bufferSPC b k
Kill current bufferSPC w c
Close current windowSPC w v
Split verticalSPC w s
Split horizontalSPC w h
Go to left windowSPC w j
Go to bottom windowSPC w k
Go to top windowSPC w l
Go to right window/
+ type to search on buffer (Usen
andN
to next/prev) -
LSP
SPC c d
Find symbol definitionSPC c D
Find symbol referencesSPC c o
Organize importsSPC c a
List/Execute code actionSPC c f
Format buffer or regionSPC c r
Safe rename symbol in project
, '
Connect to REPL (jack in), check this workaround for Mac users not being able to use '
.
, r l
Load buffer into REPL
, r c
Clean REPL
, r q
Disconnect REPL
, r b
Show REPL window
, e e
Eval current expression
, e d
Eval current defun
, t t
Run current test
, t n
Run ns tests
, t a
Run last test
Add following to enable paredit and create keybindings
config.el
(use-package! paredit
:hook ((clojure-mode . paredit-mode)
(emacs-lisp-mode . paredit-mode)))
;; Fell free to move this to a bindings file you load from config.el
(after! paredit
(define-key paredit-mode-map (kbd "C-<left>") nil)
(define-key paredit-mode-map (kbd "C-<right>") nil)
(map! :nvi
:desc "Forward barf"
"M-<left>" #'paredit-forward-barf-sexp
:desc "Forward slurp"
"M-<right>" #'paredit-forward-slurp-sexp
:desc "Backward slurp"
"M-S-<left>" #'paredit-backward-slurp-sexp
:desc "Backward barf"
"M-S-<right>" #'paredit-backward-barf-sexp
:desc "Backward"
"C-c <left>" #'paredit-backward
:desc "Forward"
"C-c <right>" #'paredit-forward))
When you open a project for the first time, lsp-mode will prompt asking what is the project root, usually, it guesses correctly and you just need to input i
. Make sure you answer that and not skip otherwise LSP won't work properly, if you miss it, you can SPC :
lsp
and it should ask it again, or SPC :
lsp-workspace-folders-remove
to remove a wrong project root.
Doom shows the current REPL state of Clojure at the modeline on the right, with a terminal/shell icon, each color represents a state:
- Gray: REPL is not connected
- Yellow: REPL connected but not evaluated
- Green: REPL in sync.
Usually your workflow will be something like, open a project, connect to the repl with , '
and after connected load the file + deps with , r l
. You can easily clean the REPL state with , r c
and eval things with , e d
or , e e
, running tests with , t t
.
If you lose your REPL, you can , r b
to show on the window or , r q
to quit if any.
-
SPC h d d
toggle debug mode showing stacktraces of errors. -
Reach #emacs slack channel.
Feel free to link your doom emacs config =)
This section adds some information for people that want to understand a little bit better about Emacs, totally optional to read.
A buffer is an interface between Emacs and a file or process. It doesn’t have to be visible on the screen. You can (and sometimes will) have hundreds of buffers open in Emacs, but you’ll probably only have windows open to one or two at a time. Buffers hold text and each one has a unique name.
A window is a view onto a buffer. It allows you, the user, to see what’s going on inside that buffer. If the buffer is associated with a file, you’ll see the text of the file. If the buffer is associated with a process, such as a shell, you’ll see some representation of that process. You can split the current frame, which leaves you looking at two windows.
A frame in Emacs is what you would call a window in most other contexts. They’re just windows in the normal sense of the word—you can drag them around the screen or close them with the X
button or do whatever you do with windows. In the command line version of Emacs, you only ever have one frame. However, with the GUI (graphical) version you can open multiple frames.
minibuffer is the small rectangle on the bottom of your Emacs, it shows lots of information of the current executed command, it's important to pay attention on that when executing some command, usually the feedback or error is shown there. (It's clickable too which will open the *messages*
buffer)
modeline is the rectangle right above the minibuffer, it can be totally customizable, usually contains the file name, line/row info and some information about LSP/REPL state on the right.