doomemacs/modules
2017-06-03 12:05:43 +02:00
..
app
completion
feature
lang
private
tools
ui
README.org

DOOM Modules

Introduction

DOOM is comprised of its core files and then its modules. These modules loosely take after Spacemacs' layers, utilizing a small list of macros to manage and configure plugins and DOOM Emacs.

These macros are:

  • Package management

    • (featurep! MODULE SUBMODULE): returns t if :module submodule is activated
    • (load! NAME): loads NAME.el, relative to the current file
    • (require! MODULE SUBMODULE &optional RELOAD-P): activates a module & loads its config.el
    • (package! NAME &key recipe pin): declares a package and where to get it
    • (depends-on! MODULE SUBMODULE): loads a module's packages.el
  • Configuration

    • (set! SETTING &rest ARGS): safely cross-configure other modules
    • (def-package! NAME &rest PLIST): configure a package (wrapper around use-package)
    • (def-setting! SETTING &rest ARGS): defines a setting other modules can set!

The TL;DR of this document is:

  • Modules are comprised of: config.el, packages.el, either autoload.el or autoload/*.el, and +*.el files; these are all optional.
  • config.el is the only file loaded when a module is activated, and is where you configure the module and its plugins.
  • packages.el files inform DOOM what plugins to install and where from, using the package! macro. This macro accepts a MELPA-style recipe plist to specify a location other than the ELPA for fetching plugins.
  • Use set! to safely cross-configure modules; doom/describe-setting can help you discover what settings are available.
  • Packages are deferred by default; add :demand t to their def-package! declaration to load them immediately.

Overview

These modules are in their ideal load order.

:feature
Broad modules that bring essential functionality to Emacs as an editor.
:completion
Swappable completion modules for narrowing down candidate lists quickly.
:ui
Modules that affect the DOOM user interface or experience.
:tools
Small modules that add specific, non-essential functionality to Emacs.
:lang
Modules that bring support for a language or group of languages to Emacs.
:app
Opinionated and heavy modules that totally transform Emacs' UI to serve a specific purpose.
:private
Private configuration modules that are untracked by version control (except for my personal one; use it as a reference).

Enabling/disabling modules

Change the doom! block in your init.el file to enable/disable modules on startup. You'll need to restart Emacs.

Don't forget to run make afterwards to ensure that the needed packages are installed (and unneeded ones are uninstalled).

Remember: if you've byte-compiled your config, your changes won't take effect until you recompile or delete the \*.elc files.

The structure of a module

Modules are made up of four optional parts:

config.el
The heart of a module; loaded when the module is activated.
packages.el
Tells DOOM what packages to install and where from. Isn't loaded until package management commands are used.
autoload.el (or autoload/*.el)
Lazily-loaded functions for that module.
+*.el
Additional config files; not automatically loaded.

config.el

config.el is loaded immediately. It is the only file proactively loaded by the DOOM module system. Additional files must be explicitly loaded using load!.

It should expect dependencies (in packages.el) to be installed and available, but shouldn't make assumptions about what modules are activated (use featurep! for this).

Packages should be configured using after! or def-package! (an alias for use-package).

;; from modules/completion/company/config.el
(def-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)
   [...])
  • Packages are deferred by default: add :demand t to def-package! blocks to load them immediately.
  • Use featurep! to test DOOM module availability
  • Use set! to cross-configure modules safely, e.g. company backends:

    ;; from modules/lang/python/config.el
    (set! :company-backend 'python-mode '(company-anaconda))

packages.el

This file isn't loaded until you use DOOM's package management commands.

Evaluating them should be deterministic, idempotent, and without side-effects (besides updating doom-modules and doom-packages).

Packages are declared with the package! macro, e.g.

;; from modules/lang/org/packages.el
(package! org-bullets)

;; from modules/tools/rotate-text/packages.el
(package! rotate-text :recipe (:fetcher github :repo "debug-ito/rotate-text.el"))

The packages.el of another module can loaded with depends-on!:

;; from modules/feature/file-templates/packages.el
(depends-on! :feature snippets)

autoload.el OR autoload/*.el

Functions in these files are lazily loaded. doom/reload-autoloads will scan these and produce an autoloads.el file, which tells Emacs where to find these functions.

For example:

;; 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>")
  [...])

Autoload files named evil*.el will be ignored if :feature evil isn't loaded.

Additional files

The only convention is to prefix additional elisp files with a +, e.g. modules/feature/version-control/+git.el.

These are not loaded automatically. Use load! from config.el to do so.

;; from modules/feature/version-control/config.el
(load +git)

Appendix

  • Macros

    • (featurep! CATEGORY MODULE)
    • (load! NAME)
    • (package! NAME &key recipe pin)
    • (require! CATEGORY MODULE &optional RELOAD-P)
    • (def-package! NAME &rest PLIST)
    • (set! SETTING &rest ARGS)
    • (def-setting! NAME ARGLIST &rest BODY)
  • Commands

    • doom/reload
    • doom/reload-autoloads
    • doom/compile
    • doom/recompile
    • doom/compile-lite
    • doom/clean-cache
    • doom/clean-compiled