1187 lines
45 KiB
Org Mode
1187 lines
45 KiB
Org Mode
#+TITLE: Getting Started Guide
|
|
#+STARTUP: nofold
|
|
|
|
* Table of Contents :TOC_4:
|
|
- [[#install][Install]]
|
|
- [[#emacs--dependencies][Emacs & dependencies]]
|
|
- [[#on-linux][On Linux]]
|
|
- [[#arch-linux][Arch Linux:]]
|
|
- [[#ubuntu][Ubuntu:]]
|
|
- [[#nixos][NixOS]]
|
|
- [[#on-macos][On macOS]]
|
|
- [[#where-not-to-install-emacs-from][Where *not* to install Emacs from]]
|
|
- [[#on-windows][On Windows]]
|
|
- [[#chocolatey--scoop][chocolatey / scoop]]
|
|
- [[#wsl][WSL]]
|
|
- [[#wsl2][WSL2]]
|
|
- [[#doom-emacs][Doom Emacs]]
|
|
- [[#install-doom-manually][Install Doom Manually]]
|
|
- [[#install-doom-alongside-other-configs-with-chemacs][Install Doom alongside other configs (with Chemacs)]]
|
|
- [[#externalsystem-dependencies][External/system dependencies]]
|
|
- [[#update][Update]]
|
|
- [[#doom][Doom]]
|
|
- [[#plugins][Plugins]]
|
|
- [[#rollback][Rollback]]
|
|
- [[#customize][Customize]]
|
|
- [[#how-to-enable-or-disable-modules][How to enable or disable modules]]
|
|
- [[#package-management][Package management]]
|
|
- [[#installing-packages][Installing packages]]
|
|
- [[#installing-packages-from-external-sources][Installing packages from external sources]]
|
|
- [[#disabling-packages][Disabling packages]]
|
|
- [[#changing-a-built-in-recipe-for-a-package][Changing a built-in recipe for a package]]
|
|
- [[#usingloading-local-packages][Using/loading local packages]]
|
|
- [[#configuring-doom][Configuring Doom]]
|
|
- [[#configuring-packages][Configuring packages]]
|
|
- [[#reloading-your-config][Reloading your config]]
|
|
- [[#binding-keys][Binding keys]]
|
|
- [[#doomdir-file-structure][DOOMDIR file structure]]
|
|
- [[#writing-your-own-modules][Writing your own modules]]
|
|
- [[#structure-of-a-module][Structure of a module]]
|
|
- [[#initel][=init.el=]]
|
|
- [[#configel][=config.el=]]
|
|
- [[#packagesel][=packages.el=]]
|
|
- [[#autoloadel-or-autoloadel][=autoload/*.el= OR =autoload.el=]]
|
|
- [[#doctorel][=doctor.el=]]
|
|
- [[#additional-files][Additional files]]
|
|
- [[#load-order][Load order]]
|
|
- [[#module-flags][Module flags]]
|
|
- [[#testing-for-flags][Testing for flags]]
|
|
- [[#module-settings][Module settings]]
|
|
- [[#module-cookies][Module cookies]]
|
|
- [[#common-mistakes-when-configuring-doom-emacs][Common mistakes when configuring Doom Emacs]]
|
|
- [[#packages-are-eagerly-loaded][Packages are eagerly loaded]]
|
|
- [[#manual-package-management][Manual package management]]
|
|
- [[#using-org-babel-do-load-languages-to-load-your-babel-plugins][Using ~org-babel-do-load-languages~ to load your babel plugins]]
|
|
- [[#using-delete-trailing-whitespaces-or-whitespace-cleanup-to-manage-leftover-whitespace][Using ~delete-trailing-whitespaces~ or ~whitespace-cleanup~ to manage leftover whitespace]]
|
|
- [[#troubleshoot][Troubleshoot]]
|
|
- [[#ive-run-into-an-issue-where-do-i-start][I've run into an issue, where do I start?]]
|
|
- [[#looking-up-documentation-and-state-from-within-emacs][Looking up documentation and state from within Emacs]]
|
|
- [[#variables-functions-faces-etc][Variables, functions, faces, etc.]]
|
|
- [[#for-doom-modules-packages-autodefs-etc][For Doom Modules, packages, autodefs, etc.]]
|
|
- [[#how-to-extract-a-backtrace-from-an-error][How to extract a backtrace from an error]]
|
|
- [[#enabling-debug-on-error][Enabling ~debug-on-error~]]
|
|
- [[#a-backtrace-from-bindoom][A backtrace from ~bin/doom~]]
|
|
- [[#evaluating-elisp-on-the-fly][Evaluating Elisp on-the-fly]]
|
|
- [[#how-to-determine-the-origin-of-a-bug][How to determine the origin of a bug]]
|
|
- [[#testing-in-dooms-sandbox][Testing in Doom's sandbox]]
|
|
- [[#opening-the-sandbox][Opening the sandbox]]
|
|
- [[#launching-the-sandbox][Launching the sandbox]]
|
|
- [[#testing-packages-in-the-sandbox][Testing packages in the sandbox]]
|
|
- [[#bisecting-your-private-config][Bisecting your private config]]
|
|
- [[#bisecting-doom-emacs][Bisecting Doom Emacs]]
|
|
|
|
* Install
|
|
To embark on this grand Emacs adventure, you'll need a couple things installed,
|
|
including Emacs (shocking, I know), Doom Emacs, the plugins Doom depends on, and
|
|
any external tools /they/ depend on as well.
|
|
|
|
In summary, you'll be installing:
|
|
|
|
+ *git*
|
|
+ *Emacs 26.1+*
|
|
+ *ripgrep*
|
|
+ *all-the-icons fonts* -- unnecessary for exclusive use of terminal Emacs
|
|
|
|
And then some optional dependencies that you will likely want, as the will
|
|
optimize Doom's performance and stability.
|
|
|
|
+ [[https://github.com/sharkdp/fd][fd]]
|
|
+ *GNU ls* (BSD ls on macOS/BSD Linux has some limitations)
|
|
+ *clang* -- with which to compile certain external dependencies, like the
|
|
emacsqlite binary, irony server (requires clang), or vterm module
|
|
|
|
The following sections will cover how to install Emacs and these dependencies
|
|
across various operating systems.
|
|
|
|
#+BEGIN_QUOTE
|
|
If any of these install instructions are outdated, or your OS is missing, please
|
|
help us by [[https://github.com/hlissner/doom-emacs/issues/new][letting us know]] (or correcting it yourself; pull requests are
|
|
welcome).
|
|
#+END_QUOTE
|
|
|
|
** Emacs & dependencies
|
|
*** On Linux
|
|
Emacs should be available through your distribution's package manager.
|
|
Otherwise, it can be [[https://www.gnu.org/software/emacs/manual/html_node/efaq/Installing-Emacs.html][built from source]].
|
|
|
|
**** Arch Linux:
|
|
#+BEGIN_SRC bash
|
|
pacman -S git tar clang emacs ripgrep fd
|
|
#+END_SRC
|
|
|
|
Emacs 27 (HEAD) can be installed through [[https://aur.archlinux.org/packages/emacs-git/][emacs-git]], available on the AUR.
|
|
|
|
**** Ubuntu:
|
|
#+BEGIN_SRC bash
|
|
apt-get install git tar clang ripgrep fd-find
|
|
#+END_SRC
|
|
|
|
On Ubuntu 18.04, the latest version of Emacs available is 25.3 (and 24.3 on
|
|
Ubuntu 16 or 14). Therefore, we have a few extra steps to install 26.1+:
|
|
|
|
#+BEGIN_SRC bash
|
|
add-apt-repository ppa:kelleyk/emacs
|
|
apt-get update
|
|
apt-get install emacs26
|
|
#+END_SRC
|
|
|
|
**** NixOS
|
|
On NixOS Emacs 26.x can be installed via ~nix-env --install emacs~, or more
|
|
permanently by adding the following entry to ~etc/nixos/configuration.nix~:
|
|
|
|
#+BEGIN_SRC nix
|
|
environment.systemPackages = with pkgs; [
|
|
coreutils # basic GNU utilities
|
|
git
|
|
clang
|
|
emacs
|
|
ripgrep
|
|
fd
|
|
];
|
|
#+END_SRC
|
|
|
|
*** On macOS
|
|
Mac users several options to install Emacs, but only a few of them are
|
|
recommended for Doom Emacs (you'll need to [[http://brew.sh/][install Homebrew]] first). To start
|
|
with:
|
|
|
|
#+BEGIN_SRC bash
|
|
brew install git clang ripgrep fd coreutils
|
|
#+END_SRC
|
|
|
|
As for Emacs, there are several formulas to choose from. There are the best
|
|
options, in order from most to least recommended for Doom.
|
|
|
|
- [[https://github.com/d12frosted/homebrew-emacs-plus][emacs-plus]] (the safest option):
|
|
|
|
#+BEGIN_SRC bash
|
|
brew tap d12frosted/emacs-plus
|
|
brew install emacs-plus
|
|
ln -s /usr/local/opt/emacs-plus/Emacs.app /Applications/Emacs.app
|
|
#+END_SRC
|
|
|
|
- [[https://formulae.brew.sh/formula/emacs][emacs]] is another acceptable option.
|
|
|
|
#+BEGIN_SRC bash
|
|
brew install emacs
|
|
#+END_SRC
|
|
|
|
- [[https://bitbucket.org/mituharu/emacs-mac/overview][emacs-mac]] is also acceptable. It offers slightly better integration into
|
|
macOS, with native emojis and better childframe support. However, at the time
|
|
of writing, it [[https://github.com/railwaycat/homebrew-emacsmacport/issues/52][lacks multi-tty support]] (which impacts daemon usage). Use it if
|
|
you experience crashing or performance issues with emacs-plus.
|
|
|
|
#+BEGIN_SRC bash
|
|
brew tap railwaycat/emacsmacport
|
|
brew install emacs-mac
|
|
ln -s /usr/local/opt/emacs-mac/Emacs.app /Applications/Emacs.app
|
|
#+END_SRC
|
|
|
|
**** Where *not* to install Emacs from
|
|
These builds/forks have known compatibility issues with Doom and are likely to
|
|
cause you issues later on. Do not use them:
|
|
|
|
+ emacsformacosx.com
|
|
+ ~brew cask install emacs~ (installs from emacsformacosx.com)
|
|
+ AquaMacs
|
|
+ XEmacs
|
|
|
|
*** On Windows
|
|
*Support for Windows is immature,* so your mileage will vary. Some have reported
|
|
success with installing Doom via WSL, chocolatey on git-bash or cygwin.
|
|
|
|
#+BEGIN_QUOTE
|
|
If you manage to get Doom on Windows and found this wasn't enough, or could be
|
|
improved, please help us expand this section!
|
|
#+END_QUOTE
|
|
|
|
**** [[https://chocolatey.org/][chocolatey]] / scoop
|
|
Chocolatey is the simplest to get Doom up and running with:
|
|
|
|
#+BEGIN_SRC sh
|
|
choco install git llvm emacs ripgrep fd
|
|
#+END_SRC
|
|
|
|
#+begin_quote
|
|
You can also use [[https://scoop.sh/][scoop]] by simply replacing ~choco~ with ~scoop~ in the above
|
|
snippet to achieve the same result. This hasn't been tested, however.
|
|
#+end_quote
|
|
|
|
You will also need to [[https://mywindowshub.com/how-to-edit-system-environment-variables-for-a-user-in-windows-10/][add a ~HOME~ system variable]], pointing to
|
|
=C:\Users\USERNAME\=, otherwise Emacs will treat
|
|
=C:\Users\USERNAME\AppData\Roaming= is your ~HOME~, which causes issues.
|
|
|
|
It's also a good idea to add =C:\Users\USERNAME\.emacs.d\bin= to your ~PATH~.
|
|
|
|
**** TODO WSL
|
|
|
|
**** TODO WSL2
|
|
|
|
** Doom Emacs
|
|
The quickest way to get Doom up and running is:
|
|
|
|
#+BEGIN_SRC bash
|
|
git clone https://github.com/hlissner/doom-emacs ~/.emacs.d
|
|
~/.emacs.d/bin/doom install
|
|
#+END_SRC
|
|
|
|
=doom install= performs the following for you:
|
|
|
|
1. It creates your =DOOMDIR= at =~/.doom.d=, if it (or =~/.config/doom=) don't
|
|
already exist.
|
|
2. Copies =~/.emacs.d/init.example.el= to =$DOOMDIR/init.el=, which contains a
|
|
~doom!~ statement that controls what modules to enable and in what order they
|
|
are loaded.
|
|
3. Creates dummy config.el and packages.el files in ~$DOOMDIR~.
|
|
4. Optionally generates an envvar file (equivalent to using ~doom env~), which
|
|
stores your shell environment in an env file that Doom will load at startup.
|
|
*This is essential for macOS users!*
|
|
5. Installs all dependencies for enabled modules (specified by
|
|
=$DOOMDIR/init.el=),
|
|
6. And prompts to install the icon fonts required by the [[https://github.com/domtronn/all-the-icons.el][all-the-icons]] package.
|
|
|
|
#+BEGIN_QUOTE
|
|
You'll find a break down of ~doom install~ into shell commands in the next
|
|
section.
|
|
#+END_QUOTE
|
|
|
|
Consider the =~/.emacs.d/bin/doom= script your new best friend. It performs a
|
|
variety of essential functions to help you manage your Doom Emacs configuration,
|
|
not least of which is installing or updating it or its plugins. If nothing else,
|
|
get to know these four commands:
|
|
|
|
- ~doom refresh~: Ensures that Doom is in a proper state to be used (i.e. needed
|
|
packages are installed, orphaned packages are removed and necessary metadata
|
|
correctly generated).
|
|
- ~doom upgrade~: Updates Doom Emacs (if available) and its packages.
|
|
- ~doom env~: Generates an "envvar file", which scrapes your shell environment
|
|
into a file that is loaded by Doom Emacs at startup. This is especially
|
|
necessary for macOS users who open Emacs through an Emacs.app bundle.
|
|
- ~doom doctor~: If Doom misbehaves, the doc will diagnose common issues with
|
|
your installation and environment. If all else fails, you'll find help on
|
|
Doom's [[https://discord.gg/bcZ6P3y][Discord server]] and [[https://github.com/hlissner/doom-emacs/issues][issue tracker]].
|
|
|
|
Run ~doom help <COMMAND>~ for documentation on these commands, or ~doom help~
|
|
for an overview of what the =bin/doom= script is capable of.
|
|
|
|
#+begin_quote
|
|
I recommend you add =~/.emacs.d/bin= to your ~PATH~ so you can call =doom=
|
|
directly, from anywhere. You don't need to be CDed into =~/.emacs.d/bin= to use
|
|
it. A quick way to do so is to add this to your .bashrc or .zshrc file:
|
|
|
|
~export PATH="$HOME/.emacs.d/bin:$PATH"~
|
|
#+end_quote
|
|
|
|
*** Install Doom Manually
|
|
If you'd rather install Doom yourself, without the magic of =bin/doom install=,
|
|
here is its equivalent in bash shell commands:
|
|
|
|
#+BEGIN_SRC bash
|
|
git clone https://github.com/hlissner/doom-emacs ~/.emacs.d
|
|
|
|
# So we don't have to write ~/.emacs.d/bin/doom every time
|
|
export PATH="$HOME/.emacs.d/bin:$PATH"
|
|
|
|
# Create a directory for our private config
|
|
mkdir ~/.doom.d # or ~/.config/doom
|
|
|
|
# The init.example.el file contains an example doom! call, which tells Doom what
|
|
# modules to load and in what order.
|
|
cp ~/.emacs.d/init.example.el ~/.doom.d/init.el
|
|
|
|
# If your ISP or proxy doesn't allow you to install from
|
|
# raw.githubusercontent.com, then you'll have to install straight (our package
|
|
# manager) manually:
|
|
mkdir -p ~/.emacs.d/.local/straight/repos
|
|
git clone -b develop https://github.com/raxod502/straight.el ~/.emacs.d/.local/straight/repos/straight.el
|
|
|
|
# Edit ~/.doom.d/init.el and adjust the modules list to your liking before
|
|
# running this:
|
|
doom install
|
|
|
|
# If you know Emacs won't be launched from your shell environment (e.g. you're
|
|
# on macOS or use an app launcher that doesn't launch programs with the correct
|
|
# shell), then creating an envvar file is necessary to ensure Doom inherits your
|
|
# shell environment.
|
|
#
|
|
# If you don't know whether you need this or not, no harm in doing it anyway.
|
|
# `doom install` will prompt you to generate an envvar file. If you responded
|
|
# no, you can generate it later with the following command:
|
|
doom env
|
|
|
|
# Install the icon fonts Doom uses
|
|
emacs --batch -f all-the-icons-install-fonts
|
|
#+END_SRC
|
|
|
|
To understand the purpose of the =~/.doom.d= directory and =~/.doom.d/init.el=
|
|
file, see the [[#customize][Customize]] section further below.
|
|
|
|
*** Install Doom alongside other configs (with Chemacs)
|
|
[[https://github.com/plexus/chemacs][Chemacs]] is a bootloader for Emacs; it makes it easy to switch between multiple
|
|
Emacs configurations. Here is a quick guide for setting it up with Doom Emacs as
|
|
the default config.
|
|
|
|
1. First, install Doom somewhere:
|
|
|
|
#+BEGIN_SRC sh
|
|
git clone https://github.com/hlissner/doom-emacs ~/doom-emacs
|
|
~/doom-emacs/bin/doom install
|
|
#+END_SRC
|
|
|
|
2. Download [[https://raw.githubusercontent.com/plexus/chemacs/master/.emacs][the Chemacs' startup script]] to =~/.emacs=:
|
|
|
|
#+BEGIN_SRC bash
|
|
wget -O ~/.emacs https://raw.githubusercontent.com/plexus/chemacs/master/.emacs
|
|
#+END_SRC
|
|
|
|
#+begin_quote
|
|
*WARNING:* the =~/.emacs.d= directory must not exist for this to work.
|
|
#+end_quote
|
|
|
|
3. Create =~/.emacs-profiles.el= with a list of your Emacs profiles. This file
|
|
is structured like a =.dir-locals.el= file. Here is an example with Doom (as
|
|
the default), Spacemacs, and Prelude:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(("default" . ((user-emacs-directory . "~/doom-emacs")))
|
|
("spacemacs" . ((user-emacs-directory . "~/spacemacs")))
|
|
("prelude" . ((user-emacs-directory . "~/prelude"))))
|
|
#+END_SRC
|
|
|
|
To start Emacs with a specific config, use the =--with-profile= option:
|
|
|
|
#+BEGIN_SRC bash
|
|
emacs --with-profile spacemacs
|
|
#+END_SRC
|
|
|
|
If no profile is specified, the =default= profile is used.
|
|
|
|
** External/system dependencies
|
|
Your system, your rules. There are as many ways to set up a programming
|
|
environment as there are dislikes on Youtube Rewind 2018, so Doom entrusts this
|
|
task to you, dear user.
|
|
|
|
Doom is comprised of modules which provide most of its features, including
|
|
language support and integration with external tools. However, some of these
|
|
have external dependencies that you must install yourself. You'll find what
|
|
modules need what and how to install them in that module's README.org file. If
|
|
you find a module without a README file, helps us out by creating one for us!
|
|
|
|
~doom doctor~ will provide an overview of missing dependencies (only for the
|
|
modules you have enabled) by reporting which ones haven't been installed yet.
|
|
Once you know what's missing, have a look at the documentation for that module.
|
|
|
|
Use ~M-x doom/help-modules~ (bound to =SPC h d m=) to quickly jump to a module's
|
|
documentation from inside Doom. Otherwise, check out the [[file:index.org::*Module list][Module Index]].
|
|
|
|
* Update
|
|
Doom is an active project and many of its 300+ plugins are in active development
|
|
as well. It is wise to occasionally update them. The following section will go
|
|
over how to do so.
|
|
|
|
#+begin_quote
|
|
*Important: you may encounter errors after up/downgrading Emacs.* Emacs bytecode
|
|
is not forward compatible, so you must recompile or reinstall your plugins to
|
|
fix this, i.e.
|
|
|
|
+ ~doom build~, to rebuild all your installed plugins,
|
|
+ Or delete =~/.emacs.d/.local= then ~doom refresh~ to reinstall them
|
|
#+end_quote
|
|
|
|
** Doom
|
|
The =bin/doom= script provides a simple command for upgrading Doom (which will
|
|
also update your plugins):
|
|
|
|
#+BEGIN_SRC bash
|
|
doom upgrade # short version: doom up
|
|
#+END_SRC
|
|
|
|
If you want to update Doom manually, ~doom upgrade~ is equivalent to:
|
|
|
|
#+BEGIN_SRC bash
|
|
cd ~/.emacs.d
|
|
git pull # updates Doom
|
|
doom refresh # refreshes plugins & autoloads
|
|
doom update # updates installed plugins
|
|
#+END_SRC
|
|
|
|
To minimize issues while upgrading, avoid modifying Doom's source files. All
|
|
your customization should be kept in your =DOOMDIR= (typically, =~/.doom.d=).
|
|
Read the [[#customize][Customize]] section for more on configuring Doom.
|
|
|
|
** Plugins
|
|
To update /only/ your plugins (i.e. not Doom), run ~doom update~ (short version:
|
|
~doom u~).
|
|
|
|
** Rollback
|
|
The =bin/doom= script doesn't currently offer rollback support for Doom or its
|
|
plugins (yet).
|
|
|
|
* Customize
|
|
Your private configuration is located in =~/.doom.d=, by default (if
|
|
=~/.config.d/doom= exists, that will be used instead). This directory is
|
|
referred to as your ~$DOOMDIR~ or your "private module".
|
|
|
|
~doom install~ will create three files in your DOOMDIR to start you off:
|
|
|
|
+ init.el :: This is where you'll find your ~doom!~ block, which controls what
|
|
modules are enabled and in what order they are loaded. This is copied from
|
|
=~/.emacs.d/init.example.el=.
|
|
+ config.el :: This is where the bulk of your private configuration will go.
|
|
+ packages.el :: This is where you tell Doom what packages you want to install
|
|
and where from.
|
|
|
|
** How to enable or disable modules
|
|
Every private config starts with a ~doom!~ block, found in =$DOOMDIR/init.el=.
|
|
If you followed the Doom installation instructions and ran ~doom install~, this
|
|
file should exist and will contain one.
|
|
|
|
This block controls what modules are enabled and in what order they are loaded.
|
|
To enable a module, add it to this list. To disable it, either remove it or
|
|
comment it out (in Emacs Lisp, anything following a semicolon is ignored by the
|
|
Elisp interpreter; i.e. it's "commented out").
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;; To comment something out, you insert at least one semicolon before it. The
|
|
;; Emacs Lisp interpreter will ignore whatever follows.
|
|
(doom! :lang
|
|
python ; this module is not commented, therefore enabled
|
|
;;javascript ; this module is commented out, therefore disabled
|
|
;;lua ; this module is disabled
|
|
ruby ; this module is enabled
|
|
php) ; this module is enabled
|
|
#+END_SRC
|
|
|
|
Some modules have optional features that can be enabled by passing them flags
|
|
like so:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(doom! :completion
|
|
(company +auto)
|
|
:lang
|
|
(csharp +unity)
|
|
(org +attach +babel +capture +export +present +protocol)
|
|
(sh +fish))
|
|
#+END_SRC
|
|
|
|
Different modules support different flags. To see a quick list of what modules
|
|
support what flags in [[file:index.org::*Module list][the Module Index]].
|
|
|
|
*WARNING:* when changing your ~doom!~ block you *must* run =~/.emacs.d/bin/doom
|
|
refresh= and restart Emacs for the changes to take effect. This ensures the
|
|
needed packages are installed, orphaned packages are removed, and necessary
|
|
metadata for your Doom Emacs config has been generated.
|
|
|
|
** Package management
|
|
Doom's package manager is declarative. Your ~DOOMDIR~ is a module, and modules
|
|
may optionally possess a packages.el file, where you may declare what packages
|
|
you want to install (and where from) using the ~package!~ macro. It can be used
|
|
to:
|
|
|
|
1. Install packages (conditionally, even),
|
|
2. Disable packages (uninstalling them and disabling their configuration),
|
|
3. Or change where a package is installed from.
|
|
|
|
If a package is installed via ELPA and does not have a ~package!~ declaration,
|
|
Doom will assume the package is unwanted and uninstall it for you next time
|
|
~doom refresh~ is executed.
|
|
|
|
#+begin_quote
|
|
Remember to run ~doom refresh~ after modifying your packages, to ensure they are
|
|
installed and properly integrated into Doom.
|
|
#+end_quote
|
|
|
|
*** Installing packages
|
|
To install a package, add a ~package!~ declaration for it to
|
|
=DOOMDIR/packages.el=:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;; Install a package named "example" from ELPA or MELPA
|
|
(package! example)
|
|
|
|
;; Tell Doom to install it from a particular archive (e.g. elpa). By default, it
|
|
;; will search orgmode.org and melpa.org before searching elpa.gnu.org. See
|
|
;; `package-archives' to adjust this order (or to see what values :pin will
|
|
;; accept).
|
|
(package! example :pin "elpa")
|
|
|
|
;; Instruct Doom to install this package once, but never update it when you run
|
|
;; `doom update` or `doom upgrade`:
|
|
(package! example :freeze t)
|
|
|
|
;; Or tell Doom to not manage a particular package at all.
|
|
(package! example :ignore t)
|
|
#+END_SRC
|
|
|
|
~package!~ will return non-nil if the package isn't disabled and is cleared for
|
|
install. Use this fact to conditionally install other packages, e.g.
|
|
|
|
#+BEGIN_SRC elisp
|
|
(when (package! example)
|
|
(package! plugin-that-example-depends-on))
|
|
#+END_SRC
|
|
|
|
*** Installing packages from external sources
|
|
To install a package straight from an external source (like github, gitlab,
|
|
etc), you'll need to specify a [[https://github.com/raxod502/straight.el#the-recipe-format][MELPA-style straight recipe]]:
|
|
|
|
Here are a few examples:
|
|
|
|
#+BEGIN_SRC elisp
|
|
;; Install it directly from a github repository. For this to work, the package
|
|
;; must have an appropriate .el and must have at least a Package-Version
|
|
;; or Version line in its header.
|
|
(package! example :recipe (:host github :repo "username/my-example-fork"))
|
|
|
|
;; If the source files for a package are in a subdirectory in said repo, you'll
|
|
;; need to specify what files to pull in.
|
|
(package! example :recipe
|
|
(:host github
|
|
:repo "username/my-example-fork"
|
|
:files ("*.el" "src/lisp/*.el")))
|
|
|
|
;; To grab a particular commit:
|
|
(package! example :recipe
|
|
(:host gitlab
|
|
:repo "username/my-example-fork"
|
|
:branch "develop"))
|
|
|
|
;; If a package has a default recipe on MELPA or emacsmirror, you may omit
|
|
;; keywords and the recipe will inherit from their original.
|
|
(package! example :recipe (:branch "develop"))
|
|
|
|
;; If the repo pulls in many unneeded submodules, you can disable recursive cloning
|
|
(package! example :recipe (:nonrecursive t))
|
|
#+END_SRC
|
|
|
|
*** Disabling packages
|
|
The ~package!~ macro possesses a ~:disable~ property.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(package! irony :disable t)
|
|
(package! rtags :disable t)
|
|
#+END_SRC
|
|
|
|
Once a package is disabled, ~use-packages!~ and ~after!~ blocks for it will be
|
|
ignored, and the package will be removed the next time you run ~doom refresh~.
|
|
Use this to disable undesirable packages included with the built-in modules.
|
|
|
|
Alternatively, the ~disable-packages!~ macro exists for more concisely disabling
|
|
multiple packages:
|
|
|
|
#+BEGIN_SRC elisp
|
|
(disable-packages! irony rtags)
|
|
#+END_SRC
|
|
|
|
*** Changing a built-in recipe for a package
|
|
If a module installs package X, but you'd like to install it from somewhere else
|
|
(say, a superior fork or a fork with a bugfix), simple add a ~package!~
|
|
declaration for it in your =DOOMDIR/packages.el=. Your private declarations
|
|
always have precedence over modules (even your own modules).
|
|
|
|
#+BEGIN_SRC elisp
|
|
;; modules/editor/evil/packages.el
|
|
(package! evil) ; installs from MELPA
|
|
|
|
;; DOOMDIR/packages.el
|
|
(package! evil :recipe (:host github :repo "username/my-evil-fork"))
|
|
#+END_SRC
|
|
|
|
You will need to run ~doom refresh~ for this change to take effect.
|
|
|
|
*** TODO Using/loading local packages
|
|
|
|
** Configuring Doom
|
|
*** Configuring packages
|
|
If your configuration needs are simple, the ~use-package!~, ~after!~,
|
|
~add-hook!~ and ~setq-hook!~ emacros can help you reconfigure packages:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;;; ~/.doom.d/config.el (example)
|
|
(setq doom-font (font-spec :family "Fira Mono" :size 12))
|
|
|
|
;; Takes a feature symbol or a library name (string)
|
|
(after! evil
|
|
(setq evil-magic nil))
|
|
|
|
;; Takes a major-mode, a quoted hook function or a list of either
|
|
(add-hook! python-mode
|
|
(setq python-shell-interpreter "bpython"))
|
|
|
|
;; These are equivalent
|
|
(setq-hook! 'python-mode-hook python-indent-offset 2)
|
|
(setq-hook! python-mode python-indent-offset 2)
|
|
|
|
(use-package! hl-todo
|
|
;; if you omit :defer, :hook, :commands, or :after, then the package is loaded
|
|
;; immediately. By using :hook here, the `hl-todo` package won't be loaded
|
|
;; until prog-mode-hook is triggered (by activating a major mode derived from
|
|
;; it, e.g. python-mode)
|
|
:hook (prog-mode . hl-todo-mode)
|
|
:init
|
|
;; code here will run immediately
|
|
:config
|
|
;; code here will run after the package is loaded
|
|
(setq hl-todo-highlight-punctuation ":"))
|
|
#+END_SRC
|
|
|
|
For more flexibility, the ~use-package-hook!~ is another option, but should be
|
|
considered a last resort (because there is usually a better way). It allows you
|
|
to disable, append/prepend to and/or overwrite Doom's ~use-package!~ blocks.
|
|
These are powered by ~use-package~'s inject-hooks under the hood.
|
|
|
|
~use-package-hook!~ *must be used before that package's ~use-package!~ block*.
|
|
Therefore it must be used from your private init.el file.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;;; ~/.doom.d/init.el (example)
|
|
;; If a :pre-init / :pre-config hook returns nil, it overwrites that package's
|
|
;; original :init / :config block. Exploit this to overwrite Doom's config.
|
|
(use-package-hook! doom-themes
|
|
:pre-config
|
|
(setq doom-neotree-file-icons t)
|
|
nil)
|
|
|
|
;; ...otherwise, make sure they always return non-nil!
|
|
(use-package-hook! evil
|
|
:pre-init
|
|
(setq evil-magic nil)
|
|
t)
|
|
|
|
;; `use-package-hook' also has :post-init and :post-config hooks
|
|
#+END_SRC
|
|
|
|
*** Reloading your config
|
|
You may find it helpful to have your changes take effect immediately. For things
|
|
that don't require a complete restart of Doom Emacs (like changing your enabled
|
|
modules or installed packages), you can evaluate Emacs Lisp code on-the-fly.
|
|
|
|
+ Evil users can use the =gr= operator to evaluate a segment of code. The return
|
|
value is displayed in the minibuffer or in a popup (if the result is large
|
|
enough to warrant one).
|
|
|
|
=gr= works for most languages, but using it on Elisp is a special case; it's
|
|
executed within your current session of Emacs. You can use this to modify
|
|
Emacs' state on the fly.
|
|
+ Non-evil users can use =C-x C-e= to run ~eval-last-sexp~, as well as ~M-x
|
|
+eval/buffer-or-region~ (on =SPC c e=).
|
|
+ Another option is to open a scratch buffer with =SPC x=, change its major mode
|
|
(~M-x emacs-lisp-mode~), and use the above keys to evaluate your code.
|
|
+ An ielm REPL is available by pressing =SPC o r=
|
|
(~+eval/open-repl-other-window~).
|
|
+ There's also =M-:= or =SPC ;=, which invokes ~eval-expression~, which you can
|
|
use to run elisp code inline.
|
|
|
|
While all this is helpful for reconfiguring your running Emacs session, it can
|
|
also be helpful for debugging.
|
|
|
|
*** TODO Binding keys
|
|
+ define-key
|
|
+ global-set-key
|
|
+ map!
|
|
+ unmap!
|
|
+ define-key!
|
|
|
|
*** TODO DOOMDIR file structure
|
|
|
|
** Writing your own modules
|
|
Modules are made up of several files, all of which are optional. This is a
|
|
comprehensive list of what they are:
|
|
|
|
#+begin_example
|
|
modules/
|
|
category/
|
|
module/
|
|
test/*.el
|
|
autoload/*.el
|
|
autoload.el
|
|
init.el
|
|
config.el
|
|
packages.el
|
|
doctor.el
|
|
#+end_example
|
|
|
|
By default, doom looks for modules in two places: =.emacs.d/modules/= where doom's
|
|
own modules are located and =$DOOMDIR/modules/= where you can define your
|
|
own private modules.
|
|
*** Structure of a module
|
|
**** =init.el=
|
|
This file is loaded first, before anything else, but after Doom core is loaded.
|
|
|
|
Use this file to:
|
|
|
|
+ Configure Emacs or perform setup/teardown operations that must be set before
|
|
other modules are (or this module is) loaded. Tampering with ~load-path~, for
|
|
instance.
|
|
+ Reconfigure packages defined in Doom modules with ~use-package-hook!~ (as a
|
|
last resort, when ~after!~ and hooks aren't enough).
|
|
+ To change the behavior of ~bin/doom~.
|
|
|
|
Do *not* use this file to:
|
|
|
|
+ Configure packages with ~use-package!~ or ~after!~
|
|
+ Preform expensive or error-prone operations; these files are evaluated
|
|
whenever ~bin/doom~ is used.
|
|
|
|
**** =config.el=
|
|
This file is the heart of every module.
|
|
|
|
Code in this file should expect that dependencies (in =packages.el=) are
|
|
installed and available, but shouldn't make assumptions about what /modules/ are
|
|
activated (use ~featurep!~ for this).
|
|
|
|
Packages should be configured using ~after!~ or ~use-package!~.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;; from modules/completion/company/config.el
|
|
(use-package! company
|
|
:commands (company-mode global-company-mode company-complete
|
|
company-complete-common company-manual-begin company-grab-line)
|
|
:config
|
|
(setq company-idle-delay nil
|
|
company-tooltip-limit 10
|
|
company-dabbrev-downcase nil
|
|
company-dabbrev-ignore-case nil)
|
|
[...])
|
|
#+END_SRC
|
|
|
|
#+begin_quote
|
|
For anyone already familiar with ~use-package~, ~use-package!~ is merely a thin
|
|
wrapper around it. It supports all the same keywords and can be used in much the
|
|
same way.
|
|
#+end_quote
|
|
|
|
**** =packages.el=
|
|
This file is where package declarations belong. It's also a good place to look
|
|
if you want to see what packages a module manages (and where they are installed
|
|
from).
|
|
|
|
A =packages.el= file shouldn't contain complex logic. Mostly conditional
|
|
statements and ~package!~, ~disable-packages!~ or ~depend-on!~ calls. It
|
|
shouldn't produce side effects and should be deterministic. Because this file
|
|
gets evaluated in an environment isolated from your interactive session, code
|
|
within should make no assumptions about the current session.
|
|
|
|
The ~package!~ macro is the star of the show in =packages.el= files:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;; from modules/lang/org/packages.el
|
|
(package! org-bullets)
|
|
|
|
;; from modules/tools/rotate-text/packages.el
|
|
(package! rotate-text :recipe (:host github :repo "debug-ito/rotate-text.el"))
|
|
#+END_SRC
|
|
|
|
Its ~:recipe~ property accepts [[https://github.com/melpa/melpa#recipe-format][a MELPA recipe]], which provides a lot of control
|
|
over where to fetch a package, including specific commit, tags or branches:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(package! rotate-text
|
|
:recipe (:host github
|
|
:repo "debug-ito/rotate-text.el"
|
|
:commit "1a2b3c4d"))
|
|
#+END_SRC
|
|
|
|
You can also use this ~package!~ to disable other packages:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;; Uninstalls evil, keeps it uninstalled, and tells Doom to ignore any
|
|
;; use-package! and after! blocks for it
|
|
(package! evil :disable t)
|
|
|
|
;; disable-packages! can be used to disable multiple packages in one statement
|
|
(disable-packages! evil evil-snipe evil-escape)
|
|
#+END_SRC
|
|
|
|
**** =autoload/*.el= OR =autoload.el=
|
|
Functions marked with an autoload cookie (~;;;###autoload~) in these files will
|
|
be lazy loaded.
|
|
|
|
When you run ~bin/doom autoloads~, Doom scans these files to populate autoload file
|
|
in =~/.emacs.d/.local/autoloads.el=, which will tell Emacs where to find these
|
|
functions when they are called.
|
|
|
|
For example:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;; from modules/lang/org/autoload/org.el
|
|
;;;###autoload
|
|
(defun +org/toggle-checkbox ()
|
|
(interactive)
|
|
[...])
|
|
|
|
;; from modules/lang/org/autoload/evil.el
|
|
;;;###autoload (autoload '+org:attach "lang/org/autoload/evil" nil t)
|
|
(evil-define-command +org:attach (&optional uri)
|
|
(interactive "<a>")
|
|
[...])
|
|
#+END_SRC
|
|
|
|
**** =doctor.el=
|
|
This file is used by ~make doctor~, and should test for all that module's
|
|
dependencies. If it is missing one, it should use the ~warn!~, ~error!~ and
|
|
~explain!~ macros to inform the user why it's a problem and, ideally, a way to
|
|
fix it.
|
|
|
|
For example, the ~:lang cc~ module's doctor checks to see if the irony server is
|
|
installed:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;; from lang/cc/doctor.el
|
|
(require 'irony)
|
|
(unless (file-directory-p irony-server-install-prefix)
|
|
(warn! "Irony server isn't installed. Run M-x irony-install-server"))
|
|
#+END_SRC
|
|
|
|
**** Additional files
|
|
Sometimes, it is preferable that a module's config.el file be split up into
|
|
multiple files. The convention is to name these additional files with a leading
|
|
=+=, e.g. =modules/feature/version-control/+git.el=.
|
|
|
|
There is no syntactical or functional significance to this convention.
|
|
Directories do not have to follow this convention, nor do files within those
|
|
directories.
|
|
|
|
These additional files are *not* loaded automatically. You will need to use the
|
|
~load!~ macro to do so:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;; from modules/feature/version-control/config.el
|
|
(load! +git)
|
|
#+END_SRC
|
|
|
|
The ~load!~ macro will try to load a =+git.el= relative to the current file.
|
|
|
|
*** Load order
|
|
Module files are loaded in a precise order:
|
|
|
|
#+BEGIN_SRC sh
|
|
~/.emacs.d/early-init.el # in Emacs 27+ only
|
|
~/.emacs.d/init.el
|
|
$DOOMDIR/init.el
|
|
{~/.emacs.d,$DOOMDIR}/modules/*/*/init.el
|
|
{~/.emacs.d,$DOOMDIR}/modules/*/*/config.el
|
|
$DOOMDIR/config.el
|
|
#+END_SRC
|
|
|
|
*** Module flags
|
|
In the code examples of the previous section, you may have noticed something odd
|
|
about that haskell entry: ~(haskell +intero)~. ~+intero~ is a module flag. You
|
|
may specify these for any module that supports them. Unsupported flags are
|
|
ignored.
|
|
|
|
You can find out what flags a module supports by looking at its documentation (a
|
|
README.org in the module's directory; which can be jumped to quickly with ~M-x
|
|
doom/describe-module~).
|
|
|
|
For example, the haskell module supports the ~+intero~ and ~+dante~ flags, which
|
|
represent the two Haskell backends available to Emacs. You may choose one or the
|
|
other (or neither, or both) by specifying the appropriate flags in you ~doom!~
|
|
block:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(doom! :lang (haskell +dante))
|
|
#+END_SRC
|
|
|
|
You may specify as many flags are you like:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(doom! :lang (org +attach +babel +capture +export +present))
|
|
#+END_SRC
|
|
|
|
#+begin_quote
|
|
=+flagname= is simply a naming convention and has no syntactical or functional
|
|
significance.
|
|
#+end_quote
|
|
|
|
**** Testing for flags
|
|
Modules are free to interpret flags however they like. If you are writing your
|
|
own module(s), you can test for flags using the ~featurep! MODULE SUBMODULE
|
|
&optional FLAG~ macro:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(when (featurep! :lang haskell +dante)
|
|
[...])
|
|
#+END_SRC
|
|
|
|
The first two arguments if ~featurep!~ may be skipped if it is used from inside
|
|
a module. For example:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;; In modules/lang/haskell/config.el
|
|
(when (featurep! +dante) ; same as (featurep! :lang haskell +dante)
|
|
[...])
|
|
#+END_SRC
|
|
|
|
*** Module settings
|
|
Some modules expose settings that can be configured from other modules. Use ~M-x
|
|
doom/help-autdefs~ (=SPC h d a= or =C-h d a=) to see what is available and how
|
|
to use them.
|
|
|
|
An example would be the ~set-company-backend!~ function that the =:completion
|
|
company= module exposes. It lets you register company completion backends with
|
|
certain major modes. For instance:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(set-company-backend! 'python-mode '(company-anaconda))
|
|
#+END_SRC
|
|
|
|
You'll find what settings a module exposes in its documentation (remember to use
|
|
~M-x doom/help-modules~ on =SPC h d m= or =C-h d m=).
|
|
*** Module cookies
|
|
There is a special syntax available to module files called module cookies. Like
|
|
autoload cookies (~;;;###autoload~), module files may have ~;;;###if FORM~ at or
|
|
near the top of the file. FORM is read by ~doom refresh~ and ~doom compile~ to
|
|
determine whether or not to ignore this file.
|
|
|
|
If FORM returns nil, the file won't be scanned for autoloads nor will it be
|
|
byte-compiled. Use this to prevent errors that may occur if that file contains
|
|
(for example) calls to functions that won't exist if a certain feature isn't
|
|
available to that module, e.g.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;;;###if (featurep! +intero)
|
|
#+END_SRC
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;;;###if (not (featurep 'evil-mode))
|
|
#+END_SRC
|
|
|
|
Remember that these run in a limited, non-interactive sub-session, so do not
|
|
call anything that wouldn't be available in a Doom session without any modules
|
|
enabled.
|
|
** Common mistakes when configuring Doom Emacs
|
|
Having helped many users configure Doom, I've spotted a few recurring oversights
|
|
that I will list here, in the hopes that it will help you avoid the same
|
|
mistakes:
|
|
|
|
*** Packages are eagerly loaded
|
|
Using ~use-package!~ without a deferring keyword (one of: ~:defer :after
|
|
:commands :defer-incrementally :after-call~) will load the package immediately.
|
|
This can cause other packages to be pulled in and loaded, which will compromise
|
|
many of Doom's startup optimizations.
|
|
|
|
This is usually by accident. Choosing which keyword to use depends on the
|
|
needs of the package, so there is no simple answer to this.
|
|
|
|
*** Manual package management
|
|
A lot of Emacs documentation and help will contain advice to install packages
|
|
with package.el's API (e.g. ~package-install~) or with use-package's ~:ensure~
|
|
keyword). You are free to do this, if it is your preference, but otherwise, Doom
|
|
has its own package management system.
|
|
|
|
Migrating ~use-package~ code to Doom is usually a case of removing the ~:ensure~
|
|
keyword and adding a ~(package! PACKAGENAME)~ to =~/.doom.d/packages.el= (and
|
|
running ~doom refresh~ to sync your config).
|
|
|
|
*** Using ~org-babel-do-load-languages~ to load your babel plugins
|
|
You don't need ~org-babel-do-load-languages~. Doom lazy loads babel plugins
|
|
based on the language name in ~#+BEGIN_SRC~ blocks needed. As long as the babel
|
|
plugin is installed and the plugin is named after its language (e.g.
|
|
~#+BEGIN_SRC rust~ will load ~ob-rust~), you don't need to do anything else.
|
|
|
|
There may be some special cases, however. Doom tries to handle a couple of them
|
|
(e.g. with ob-jupyter, ob-ipython and ob-async). If you are experiencing errors
|
|
while trying to use a certain language in org src blocks, check out the [[file:../modules/lang/org/README.org][:lang
|
|
org module documentation]] for details on how to add support for it.
|
|
|
|
*** Using ~delete-trailing-whitespaces~ or ~whitespace-cleanup~ to manage leftover whitespace
|
|
#+BEGIN_SRC elisp
|
|
(add-hook 'after-save-hook #'delete-trailing-whitespace)
|
|
;; or
|
|
(add-hook 'after-save-hook #'whitespace-cleanup)
|
|
#+END_SRC
|
|
|
|
These two lines are a common sight in Emacs configs, but they are unnecessary
|
|
for Doom Emacs. We already use the more sophisticated =wsbutler= to manage
|
|
extraneous whitespace. However, you might have the impression that it isn't
|
|
working. That's because =wsbutler= works in two unusual ways, meant to be less
|
|
imposing than its alternatives:
|
|
|
|
1. It only cleans up trailing whitespace /on lines that you've touched/ (but
|
|
always strips newlines at EOF).
|
|
|
|
Why do this? Because I believe file-wide reformatting should be a deliberate
|
|
act (and not blindly automated). If it is necessary, chances are you're
|
|
working on somebody else's project -- or with other people, but here, large
|
|
scale whitespace changes could cause problems or simply be rude. We don't
|
|
endorse PRs that are 1% contribution and 99% whitespace!
|
|
|
|
However, if it's truly deliberate, ~M-x delete-trailing-whitespaces~ and ~M-x
|
|
whitespace-cleanup~ are available to be called =deliberately=, instead.
|
|
|
|
2. =wsbutler= replaces trailing whitespace and newlines with *virtual*
|
|
whitespace. This is whitespace that only exists in the Emacs buffer, but
|
|
isn't actually written to the file.
|
|
|
|
Why do this? Because you might have wanted to use that space for something in
|
|
your current editing session, and it would be inconvenient for the editor to
|
|
delete it before you got to it.
|
|
|
|
If you use it, it's there. If you don't, it isn't written to the file.
|
|
|
|
* Troubleshoot
|
|
When problems arise, and they will, you will need to debug them. Fortunately,
|
|
Emacs (and Doom) provide you with tools to make this easier. I recommend
|
|
becoming acquainted with them. They will be yours (and our) best tool for
|
|
understanding the problem.
|
|
|
|
** I've run into an issue, where do I start?
|
|
Before you file a bug report, there are a number of things you should try first:
|
|
|
|
+ You'll find [[file:faq.org::Common%20Issues][a list of common issues & errors in the FAQ]]. That is a good place
|
|
to start. You can access and search this FAQ from inside Doom with =SPC h d f=
|
|
(or =C-h d f= for non-evil users).
|
|
|
|
+ Run ~doom doctor~ to diagnose any common issues with your environment or
|
|
config.
|
|
|
|
+ Run ~doom refresh~ to ensure the problem isn't caused by missing packages or
|
|
outdated autoloads files.
|
|
|
|
+ See if your issue is mentioned in the Common Issues section below.
|
|
|
|
+ Search Doom's issue tracker to see if your issue is mentioned there.
|
|
|
|
+ Ask for help on [[https://discord.gg/bcZ6P3y][our Discord server]]. This may not be immediately available to
|
|
everyone, so I won't fault you for skipping this step, but you'll sometimes
|
|
find help there quicker. In many cases, Henrik fixes issues.
|
|
|
|
** Looking up documentation and state from within Emacs
|
|
...
|
|
|
|
*** Variables, functions, faces, etc.
|
|
Emacs is a Lisp interpreter whose state you can access on-the-fly with tools
|
|
provided to you by Emacs itself. They're available on the =SPC h= prefix by
|
|
default. Use them to debug your sessions.
|
|
|
|
Here are some of the more important ones:
|
|
|
|
+ ~describe-variable~ (=SPC h v=)
|
|
+ ~describe-function~ (=SPC h f=)
|
|
+ ~describe-face~ (=SPC h F=)
|
|
+ ~describe-bindings~ (=SPC h b=)
|
|
+ ~describe-key~ (=SPC h k=)
|
|
+ ~describe-char~ (=SPC h '=)
|
|
+ ~find-library~ (=SPC h P=)
|
|
|
|
You can also evaluate code with ~eval-expression~ (=M-;= or =SPC ;=).
|
|
|
|
*** TODO For Doom Modules, packages, autodefs, etc.
|
|
+ ~doom/open-news~ (=SPC h n=) ::
|
|
...
|
|
+ ~doom/open-manual~ (=SPC h D=) ::
|
|
...
|
|
+ ~doom/describe-module~ (=SPC h d=) ::
|
|
Jumps to a module's documentation.
|
|
+ ~doom/describe-autodefs~ (=SPC h A=) ::
|
|
Jumps to the documentation for an autodef function/macro. These are special
|
|
functions that are always defined, whether or not their containing modules
|
|
are enabled.
|
|
+ ~doom/describe-package~ (=SPC h p=) ::
|
|
Look up packages that are installed, by whom (what modules) and where jump
|
|
to all the places it is being configured.
|
|
+ ~doom/info~ ::
|
|
...
|
|
|
|
** How to extract a backtrace from an error
|
|
If you encounter an error while using Doom Emacs, you're probably about to head
|
|
off and file a bug report (or request help on [[https://discord.gg/bcZ6P3y][our Discord server]]). Before you
|
|
do, please generate a backtrace to include with it.
|
|
|
|
To do so you must enable ~debug-on-error~ then recreate the error.
|
|
|
|
*** Enabling ~debug-on-error~
|
|
There are three ways to enable ~debug-on-error~:
|
|
|
|
1. Start Emacs with ~emacs --debug-init~. Use this for errors that occur at
|
|
startup.
|
|
2. Evil users can press =SPC h d d= and non-evil users can press =C-h d d=.
|
|
3. If the above don't work, there's always: ~M-x toggle-debug-on-error~
|
|
|
|
Now that ~debug-on-error~ is on, recreate the error. A window should pop up with
|
|
a backtrace.
|
|
|
|
*** A backtrace from ~bin/doom~
|
|
If the error you've encountered is emitted from ~bin/doom~, you can re-run the
|
|
same command with the ~-d~ or ~--debug~ switches to force it to emit a backtrace
|
|
when an error occurs. The ~DEBUG~ environment variable will work to.
|
|
|
|
#+BEGIN_SRC sh
|
|
doom -d refresh
|
|
doom --debug install
|
|
DEBUG=1 doom update
|
|
#+END_SRC
|
|
|
|
#+BEGIN_QUOTE
|
|
Note: switch order is important. ~-d~ / ~--debug~ /must/ come right after ~doom~
|
|
and before the subcommand. This will be fixed eventually.
|
|
#+END_QUOTE
|
|
|
|
** Evaluating Elisp on-the-fly
|
|
Often, you may find it helpful for debugging to evaluate some Emacs Lisp. Here
|
|
are couple things you can do:
|
|
|
|
+ Use =M-;= (bound to ~eval-expression~),
|
|
+ =SPC x= will open a scratch buffer. ~M-x emacs-lisp-mode~ will change it to
|
|
the appropriate major mode, then use ~+eval:region~ (=gr=) and ~+eval:buffer~
|
|
(=gR=) to evaluate code,
|
|
|
|
** How to determine the origin of a bug
|
|
** Testing in Doom's sandbox
|
|
"The sandbox" is one of Doom Emacs' features; it is a test bed for running elisp
|
|
in a fresh instance of Emacs with varying amounts of Doom loaded (none at all,
|
|
all of it, or somewhere in between). This can be helpful for isolating bugs to
|
|
determine who you should report a bug to.
|
|
|
|
If you can recreate a bug in vanilla Emacs than it should be reported to the
|
|
developers of the relevant plugins or, perhaps, the Emacs devs themselves.
|
|
|
|
Otherwise, it is best to bring it up on the Doom Emacs issue list, rather than
|
|
confusing and inundating the Emacs community with Doom-specific issues.
|
|
|
|
*** Opening the sandbox
|
|
There are three common ways to access the sandbox:
|
|
|
|
+ =SPC h E= (for evil users)
|
|
+ =C-h E= (for non-evil users)
|
|
+ ~M-x doom/sandbox~
|
|
|
|
Doing any of the above will pop up a ~*doom:sandbox*~ window. What you enter
|
|
into this buffer will be executed in the new instance of Emacs when you decide
|
|
to launch it.
|
|
|
|
*** Launching the sandbox
|
|
You have four options when it comes to launching the sandbox:
|
|
|
|
- =C-c C-c= :: This launches "vanilla Emacs". Vanilla means nothing is loaded;
|
|
purely Emacs and nothing else. If you can reproduce an error here, then the
|
|
issue likely lies in the plugin(s) you are testing or in Emacs itself.
|
|
- =C-c C-d= :: This launches "vanilla Doom", which is vanilla Emacs plus Doom's
|
|
core. This does not load your private config, nor any of Doom's (or your)
|
|
modules.
|
|
- =C-c C-p= :: This launches "vanilla Doom+". That is, Doom core plus the
|
|
modules that you have specified in the ~doom!~ block of your private config
|
|
(in =~/.doom.d/init.el=). This *does not* load your private config, however.
|
|
- =C-c C-f= :: This launches "full Doom". It loads Doom's core, your enabled
|
|
modules, and your private config. This instance should be identical to the
|
|
instance you launched it from.
|
|
|
|
#+BEGIN_QUOTE
|
|
All new instances will inherit your ~load-path~ so you can access any packages
|
|
you have installed.
|
|
#+END_QUOTE
|
|
*** Testing packages in the sandbox
|
|
Instances of Emacs launched from the sandbox have inherited your ~load-path~.
|
|
This means you can load packages -- even in Vanilla Emacs -- without worrying
|
|
about installing or setting them up. Just ~(require PACKAGE)~ and launch the
|
|
sandbox. e.g.
|
|
|
|
#+BEGIN_SRC elisp
|
|
(require 'magit)
|
|
(find-file "~/some/file/in/a/repo")
|
|
(call-interactively #'magit-status)
|
|
#+END_SRC
|
|
|
|
** TODO Bisecting your private config
|
|
** TODO Bisecting Doom Emacs
|