Revise and update docstrings and comments

This commit is contained in:
Henrik Lissner 2019-05-01 19:12:52 -04:00
parent 4aa65aa019
commit 6d314c2795
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
17 changed files with 276 additions and 189 deletions

View file

@ -67,7 +67,10 @@
(stylus-mode :lang web) (stylus-mode :lang web)
(terra-mode :lang terra) (terra-mode :lang terra)
(vala-mode :lang vala)) (vala-mode :lang vala))
"TODO") "An alist mapping major modes to Doom modules.
This is used by `doom/help-modules' to auto-select the module corresponding to
the current major-modea.")
;; ;;
@ -201,12 +204,12 @@ The latest newsletter will be selected by default."
;;;###autoload ;;;###autoload
(defun doom/help-autodefs (autodef) (defun doom/help-autodefs (autodef)
"Open the documentation of an autodef. "Open documentation for an autodef.
An autodef is a Doom concept. It is a function or macro that is always defined, An autodef is a Doom concept. It is a function or macro that is always defined,
whether or not its containing module is disabled (in which case it will safely whether or not its containing module is disabled (in which case it will safely
no-op). This syntactic sugar lets you use them without needing to check if they no-op without evaluating its arguments). This syntactic sugar lets you use them
are available." without needing to check if they are available."
(interactive (interactive
(let* ((settings (let* ((settings
(cl-loop with case-fold-search = nil (cl-loop with case-fold-search = nil
@ -427,7 +430,7 @@ If prefix arg is present, refresh the cache."
;;;###autoload ;;;###autoload
(defun doom/help-package-config (package) (defun doom/help-package-config (package)
"Jump to a configuration block for PACKAGE." "Jump to any `def-package!', `after!' or ;;;###package block for PACKAGE."
(interactive (interactive
(list (doom--completing-package "Select package to search for: " current-prefix-arg))) (list (doom--completing-package "Select package to search for: " current-prefix-arg)))
(let* ((default-directory doom-emacs-dir) (let* ((default-directory doom-emacs-dir)

View file

@ -39,6 +39,7 @@ Accepts 'ansi and 'text-properties. nil means don't render colors.")
;;;###autoload ;;;###autoload
(defun doom-message-indent (width text &rest args) (defun doom-message-indent (width text &rest args)
"Indent TEXT by WIDTH spaces. If ARGS, format TEXT with them."
(with-temp-buffer (with-temp-buffer
(insert (apply #'format text args)) (insert (apply #'format text args))
(let ((fill-column 80)) (let ((fill-column 80))
@ -53,6 +54,7 @@ Accepts 'ansi and 'text-properties. nil means don't render colors.")
;;;###autoload ;;;###autoload
(defun doom-message-autofill (&rest msgs) (defun doom-message-autofill (&rest msgs)
"Ensure MSG is split into lines no longer than `fill-column'."
(with-temp-buffer (with-temp-buffer
(let ((fill-column 70)) (let ((fill-column 70))
(dolist (line msgs) (dolist (line msgs)

View file

@ -1,10 +1,15 @@
;;; core/cli/autoloads.el -*- lexical-binding: t; -*- ;;; core/cli/autoloads.el -*- lexical-binding: t; -*-
(dispatcher! (autoloads a) (doom-reload-autoloads nil 'force) (dispatcher! (autoloads a) (doom-reload-autoloads nil 'force)
"Regenerates Doom's autoloads file. "Regenerates Doom's autoloads files.
This file tells Emacs where to find your module's autoloaded functions and It scans and reads autoload cookies (;;;###autoload) in core/autoload/*.el,
plugins.") modules/*/*/autoload.el and modules/*/*/autoload/*.el, and generates
`doom-autoload-file', then compiles `doom-package-autoload-file' from the
concatenated autoloads files of all installed packages.
It also caches `load-path', `Info-directory-list', `doom-disabled-packages',
`package-activated-list' and `auto-mode-alist'.")
;; external variables ;; external variables
(defvar autoload-timestamps) (defvar autoload-timestamps)
@ -13,7 +18,7 @@ plugins.")
;; ;;
;; Helpers ;;; Helpers
(defvar doom-autoload-excluded-packages '(marshal gh) (defvar doom-autoload-excluded-packages '(marshal gh)
"Packages that have silly or destructive autoload files that try to load "Packages that have silly or destructive autoload files that try to load
@ -86,7 +91,7 @@ even if it doesn't need reloading!"
;; ;;
;; Doom autoloads ;;; Doom autoloads
(defun doom--file-cookie-p (file) (defun doom--file-cookie-p (file)
"Returns the return value of the ;;;###if predicate form in FILE." "Returns the return value of the ;;;###if predicate form in FILE."
@ -227,15 +232,13 @@ even if it doesn't need reloading!"
(replace-match "" t t))) (replace-match "" t t)))
(defun doom-reload-doom-autoloads (&optional force-p) (defun doom-reload-doom-autoloads (&optional force-p)
"Refreshes the autoloads.el file, specified by `doom-autoload-file', if "Refreshes `doom-autoload-file', if necessary (or if FORCE-P is non-nil).
necessary (or if FORCE-P is non-nil).
It scans and reads core/autoload/*.el, modules/*/*/autoload.el and It scans and reads autoload cookies (;;;###autoload) in core/autoload/*.el,
modules/*/*/autoload/*.el, and generates `doom-autoload-file'. This file tells modules/*/*/autoload.el and modules/*/*/autoload/*.el, and generates
Emacs where to find lazy-loaded functions. `doom-autoload-file'.
This should be run whenever your `doom!' block, or a module autoload file, is Run this whenever your `doom!' block, or a module autoload file, is modified."
modified."
(let* ((default-directory doom-emacs-dir) (let* ((default-directory doom-emacs-dir)
(doom-modules (doom-modules)) (doom-modules (doom-modules))
(targets (targets
@ -284,7 +287,7 @@ modified."
(save-excursion (save-excursion
(doom--generate-autodefs (reverse targets) enabled-targets) (doom--generate-autodefs (reverse targets) enabled-targets)
(print! (green "✓ Generated autodefs"))) (print! (green "✓ Generated autodefs")))
;; Remove byte-compile inhibiting file variables so we can byte-compile ;; Remove byte-compile-inhibiting file variables so we can byte-compile
;; the file, and autoload comments. ;; the file, and autoload comments.
(doom--cleanup-autoloads) (doom--cleanup-autoloads)
(print! (green "✓ Clean up autoloads"))) (print! (green "✓ Clean up autoloads")))
@ -295,9 +298,13 @@ modified."
;; ;;
;; Package autoloads ;;; Package autoloads
(defun doom--generate-package-autoloads () (defun doom--generate-package-autoloads ()
"Concatenates package autoload files, let-binds `load-file-name' around
them,and remove unnecessary `provide' statements or blank links.
Skips over packages in `doom-autoload-excluded-packages'."
(dolist (spec (doom-get-package-alist)) (dolist (spec (doom-get-package-alist))
(if-let* ((pkg (car spec)) (if-let* ((pkg (car spec))
(desc (cdr spec))) (desc (cdr spec)))
@ -314,6 +321,8 @@ modified."
(message "Couldn't find package desc for %s" (car spec))))) (message "Couldn't find package desc for %s" (car spec)))))
(defun doom--generate-var-cache () (defun doom--generate-var-cache ()
"Print a `setq' form for expensive-to-initialize variables, so we can cache
them in Doom's autoloads file."
(doom-initialize-packages) (doom-initialize-packages)
(prin1 `(setq load-path ',load-path (prin1 `(setq load-path ',load-path
auto-mode-alist ',auto-mode-alist auto-mode-alist ',auto-mode-alist
@ -323,6 +332,10 @@ modified."
(current-buffer))) (current-buffer)))
(defun doom--cleanup-package-autoloads () (defun doom--cleanup-package-autoloads ()
"Remove (some) forms that modify `load-path' or `auto-mode-alist'.
These variables are cached all at once and at later, so these removed statements
served no purpose but to waste cycles."
(while (re-search-forward "^\\s-*\\((\\(?:add-to-list\\|\\(?:when\\|if\\) (boundp\\)\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\)" nil t) (while (re-search-forward "^\\s-*\\((\\(?:add-to-list\\|\\(?:when\\|if\\) (boundp\\)\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\)" nil t)
(goto-char (match-beginning 1)) (goto-char (match-beginning 1))
(kill-sexp))) (kill-sexp)))

View file

@ -1,31 +1,42 @@
;;; core/cli/quickstart.el -*- lexical-binding: t; -*- ;;; core/cli/quickstart.el -*- lexical-binding: t; -*-
(dispatcher! (quickstart qs) (apply #'doom-quickstart args) (dispatcher! (quickstart qs) (apply #'doom-quickstart args)
"Quickly deploy a private module and Doom. "Guides you through setting up Doom for first time use.
This deploys a barebones config to ~/.doom.d (if it doesn't already exist). The This command does the following:
destination can be changed with the -p option, e.g.
1. Creates DOOMDIR at ~/.doom.d,
2. Copies ~/.emacs.d/init.example.el to DOOMDIR/init.el (if it doesn't exist),
3. Creates dummy files for DOOMDIR/{config,packages}.el,
4. Prompts you to generate an envvar file (via 'doom env refresh'),
5. Installs any dependencies of enabled modules (specified by DOOMDIR/init.el),
6. And prompts to install all-the-icons' fonts
This command is idempotent and safe to reuse.
The location of DOOMDIR can be changed with the -p option, or by setting the
DOOMDIR environment variable. e.g.
doom -p ~/.config/doom quickstart doom -p ~/.config/doom quickstart
DOOMDIR=~/.config/doom doom quickstart
Quickstart understands the following switches: Quickstart understands the following switches:
--no-config Don't deploy dummy config to ~/.doom.d --no-config Don't create DOOMDIR or dummy files therein
--no-install Don't auto-install packages --no-install Don't auto-install packages
--no-env Don't generate an envvars file (see `doom help env`) --no-env Don't generate an envvars file (see `doom help env`)
--no-fonts Don't install (or prompt to install) all-the-icons fonts --no-fonts Don't install (or prompt to install) all-the-icons fonts")
This command is idempotent and is safe to reuse.")
;; ;;
;; Library ;; Library
(defun doom-quickstart (&rest args) (defun doom-quickstart (&rest args)
"Quickly deploy a private module and Doom. "Quickly deploy a private module and setup Doom.
This deploys a barebones config to `doom-private-dir', installs all missing This deploys a barebones config to `doom-private-dir', installs all missing
packages and regenerates the autoloads file." packages, prompts to install all-the-icons fonts, generates an env file and
regenerates the autoloads file."
;; Create `doom-private-dir' ;; Create `doom-private-dir'
(let ((short-private-dir (abbreviate-file-name doom-private-dir))) (let ((short-private-dir (abbreviate-file-name doom-private-dir)))
(if (member "--no-config" args) (if (member "--no-config" args)

View file

@ -90,7 +90,10 @@ BODY will be run when this dispatcher is called."
;; ;;
;; Dummy dispatch commands (no-op because they're handled especially) ;; Dummy dispatch commands
;; These are handled by bin/doom, except we still want 'help CMD' to print out
;; documentation for them, so...
(dispatcher! run :noop (dispatcher! run :noop
"Run Doom Emacs from bin/doom's parent directory. "Run Doom Emacs from bin/doom's parent directory.

View file

@ -48,6 +48,9 @@ This is used by `associate!', `file-exists-p!' and `project-file-exists-p!'."
(spec))) (spec)))
(defun doom--resolve-hook-forms (hooks) (defun doom--resolve-hook-forms (hooks)
"Converts a list of modes into a list of hook symbols.
If a mode is quoted, it is left as is."
(declare (pure t) (side-effect-free t)) (declare (pure t) (side-effect-free t))
(cl-loop with quoted-p = (eq (car-safe hooks) 'quote) (cl-loop with quoted-p = (eq (car-safe hooks) 'quote)
for hook in (doom-enlist (doom-unquote hooks)) for hook in (doom-enlist (doom-unquote hooks))
@ -129,7 +132,7 @@ Accepts the same arguments as `message'."
;; Macros ;; Macros
(defmacro λ! (&rest body) (defmacro λ! (&rest body)
"A shortcut for inline interactive lambdas." "Expands to (lambda () (interactive) ,@body)."
(declare (doc-string 1)) (declare (doc-string 1))
`(lambda () (interactive) ,@body)) `(lambda () (interactive) ,@body))
@ -180,70 +183,21 @@ reverse this and trigger `after!' blocks at a more reasonable time."
(setq features (delq ',feature features)) (setq features (delq ',feature features))
(advice-add #',mode :before #',advice-fn) (advice-add #',mode :before #',advice-fn)
(defun ,advice-fn (&rest _) (defun ,advice-fn (&rest _)
;; Some plugins (like yasnippet) will invoke a mode early, e.g. to ;; Some plugins (like yasnippet) will invoke a mode early to parse
;; parse some code. This would prematurely trigger this function. This ;; code, which would prematurely trigger this. In those cases, well
;; checks for that: ;; behaved plugins will use `delay-mode-hooks', which we can check for:
(when (and ,(intern (format "%s-hook" mode)) (when (and ,(intern (format "%s-hook" mode))
(not delay-mode-hooks)) (not delay-mode-hooks))
;; Otherwise, announce to the world this package has been loaded, so ;; ...Otherwise, announce to the world this package has been loaded,
;; `after!' handlers can respond and configure elisp-mode as ;; so `after!' handlers can react.
;; expected.
(provide ',feature) (provide ',feature)
(advice-remove #',mode #',advice-fn)))))) (advice-remove #',mode #',advice-fn))))))
(defmacro after! (targets &rest body)
"A smart wrapper around `with-eval-after-load' that:
1. Suppresses warnings at compile-time
2. No-ops for TARGETS that are disabled by the user (via `package!')
3. Supports compound TARGETS statements (see below)
BODY is evaluated once TARGETS are loaded. TARGETS can either be:
- An unquoted package symbol (the name of a package)
(after! helm ...)
- An unquoted list of package symbols
(after! (magit git-gutter) ...)
- An unquoted, nested list of compound package lists, using :or/:any and/or :and/:all
(after! (:or package-a package-b ...) ...)
(after! (:and package-a package-b ...) ...)
(after! (:and package-a (:or package-b package-c) ...) ...)
Note that:
- :or and :any are equivalent
- :and and :all are equivalent
- If these are omitted, :and is assumed."
(declare (indent defun) (debug t))
(unless (and (symbolp targets)
(memq targets (bound-and-true-p doom-disabled-packages)))
(list (if (or (not (bound-and-true-p byte-compile-current-file))
(dolist (next (doom-enlist targets))
(unless (keywordp next)
(if (symbolp next)
(require next nil :no-error)
(load next :no-message :no-error)))))
#'progn
#'with-no-warnings)
(if (symbolp targets)
`(with-eval-after-load ',targets ,@body)
(pcase (car-safe targets)
((or :or :any)
(macroexp-progn
(cl-loop for next in (cdr targets)
collect `(after! ,next ,@body))))
((or :and :all)
(dolist (next (cdr targets))
(setq body `((after! ,next ,@body))))
(car body))
(_ `(after! (:and ,@targets) ,@body)))))))
(defmacro quiet! (&rest forms) (defmacro quiet! (&rest forms)
"Run FORMS without making any output." "Run FORMS without generating any output.
This silences calls to `message', `load-file', `write-region' and anything that
writes to `standard-output'."
`(cond (noninteractive `(cond (noninteractive
(let ((old-fn (symbol-function 'write-region))) (let ((old-fn (symbol-function 'write-region)))
(cl-letf ((standard-output (lambda (&rest _))) (cl-letf ((standard-output (lambda (&rest _)))
@ -263,7 +217,7 @@ BODY is evaluated once TARGETS are loaded. TARGETS can either be:
(defmacro add-transient-hook! (hook-or-function &rest forms) (defmacro add-transient-hook! (hook-or-function &rest forms)
"Attaches a self-removing function to HOOK-OR-FUNCTION. "Attaches a self-removing function to HOOK-OR-FUNCTION.
FORMS are evaluated once when that function/hook is first invoked, then never FORMS are evaluated once, when that function/hook is first invoked, then never
again. again.
HOOK-OR-FUNCTION can be a quoted hook or a sharp-quoted function (which will be HOOK-OR-FUNCTION can be a quoted hook or a sharp-quoted function (which will be
@ -287,14 +241,19 @@ advised)."
(add-hook ,hook-or-function #',fn ,append)))))) (add-hook ,hook-or-function #',fn ,append))))))
(defmacro add-hook! (&rest args) (defmacro add-hook! (&rest args)
"A convenience macro for `add-hook'. Takes, in order: "A convenience macro for adding N functions to M hooks.
If N and M = 1, there's no benefit to using this macro over `add-hook'.
This macro accepts, in order:
1. Optional properties :local and/or :append, which will make the hook 1. Optional properties :local and/or :append, which will make the hook
buffer-local or append to the list of hooks (respectively), buffer-local or append to the list of hooks (respectively),
2. The hooks: either an unquoted major mode, an unquoted list of major-modes, 2. The hook(s) to be added to: either an unquoted mode, an unquoted list of
a quoted hook variable or a quoted list of hook variables. If unquoted, the modes, a quoted hook variable or a quoted list of hook variables. If
hooks will be resolved by appending -hook to each symbol. unquoted, '-hook' will be appended to each symbol.
3. A function, list of functions, or body forms to be wrapped in a lambda. 3. The function(s) to be added: this can be one function, a list thereof, or
body forms (implicitly wrapped in a closure).
Examples: Examples:
(add-hook! 'some-mode-hook 'enable-something) (same as `add-hook') (add-hook! 'some-mode-hook 'enable-something) (same as `add-hook')
@ -306,9 +265,6 @@ Examples:
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2)) (add-hook! (one-mode second-mode) (setq v 5) (setq a 2))
(add-hook! :append :local (one-mode second-mode) (setq v 5) (setq a 2)) (add-hook! :append :local (one-mode second-mode) (setq v 5) (setq a 2))
Body forms can access the hook's arguments through the let-bound variable
`args'.
\(fn [:append :local] HOOKS FUNCTIONS)" \(fn [:append :local] HOOKS FUNCTIONS)"
(declare (indent defun) (debug t)) (declare (indent defun) (debug t))
(let ((hook-fn 'add-hook) (let ((hook-fn 'add-hook)
@ -339,19 +295,24 @@ Body forms can access the hook's arguments through the let-bound variable
`(progn ,@(if append-p (nreverse forms) forms))))) `(progn ,@(if append-p (nreverse forms) forms)))))
(defmacro remove-hook! (&rest args) (defmacro remove-hook! (&rest args)
"Convenience macro for `remove-hook'. Takes the same arguments as "A convenience macro for removing N functions from M hooks.
`add-hook!'.
Takes the same arguments as `add-hook!'.
If N and M = 1, there's no benefit to using this macro over `remove-hook'.
\(fn [:append :local] HOOKS FUNCTIONS)" \(fn [:append :local] HOOKS FUNCTIONS)"
(declare (indent defun) (debug t)) (declare (indent defun) (debug t))
`(add-hook! :remove ,@args)) `(add-hook! :remove ,@args))
(defmacro setq-hook! (hooks &rest rest) (defmacro setq-hook! (hooks &rest rest)
"Convenience macro for setting buffer-local variables in a hook. "Sets buffer-local variables on HOOKS.
(setq-hook! 'markdown-mode-hook (setq-hook! 'markdown-mode-hook
line-spacing 2 line-spacing 2
fill-column 80)" fill-column 80)
\(fn HOOKS &rest SYM VAL...)"
(declare (indent 1)) (declare (indent 1))
(unless (= 0 (% (length rest) 2)) (unless (= 0 (% (length rest) 2))
(signal 'wrong-number-of-arguments (list #'evenp (length rest)))) (signal 'wrong-number-of-arguments (list #'evenp (length rest))))
@ -400,8 +361,8 @@ The available conditions are:
:match REGEXP :match REGEXP
A regexp to be tested against the current file path. A regexp to be tested against the current file path.
:files SPEC :files SPEC
Accepts what `project-file-exists-p!' accepts. Checks if certain files exist Accepts what `project-file-exists-p!' accepts. Checks if certain files or
relative to the project root. directories exist relative to the project root.
:when FORM :when FORM
Whenever FORM returns non-nil." Whenever FORM returns non-nil."
(declare (indent 1)) (declare (indent 1))

View file

@ -233,10 +233,17 @@ non-nil, return paths of possible modules, activated or otherwise."
;; ;;
;; Check out `def-package!'s documentation for more about these two. ;; Check out `def-package!'s documentation for more about these two.
(defvar doom--deferred-packages-alist '(t)) (defvar doom--deferred-packages-alist '(t))
(after! use-package-core
;; :ensure and :pin don't work well with Doom, so we forcibly remove them. (with-eval-after-load 'use-package-core
(dolist (keyword '(:ensure :pin)) ;; Macros are already fontified, no need for this
(delq! keyword use-package-keywords)) (font-lock-remove-keywords 'emacs-lisp-mode use-package-font-lock-keywords)
;; Disable :ensure and :pin, because they don't work with Doom because we do
;; our own package management.
(with-eval-after-load 'use-package-ensure
(dolist (keyword '(:ensure :pin))
(delq! keyword use-package-keywords)
(delq! keyword use-package-defaults 'assq)))
;; Insert new deferring keywords ;; Insert new deferring keywords
(dolist (keyword '(:defer-incrementally :after-call)) (dolist (keyword '(:defer-incrementally :after-call))
@ -355,11 +362,13 @@ to least)."
(defvar doom-disabled-packages) (defvar doom-disabled-packages)
(defmacro def-package! (name &rest plist) (defmacro def-package! (name &rest plist)
"This is a thin wrapper around `use-package'. "Declares and configures a package.
It is ignored if the NAME package is disabled. This is a thin wrapper around `use-package', and is ignored if the NAME package
is disabled by the user (with `package!').
Supports two special properties over `use-package': See `use-package' to see what properties can be provided. Doom adds support for
two extra properties:
:after-call SYMBOL|LIST :after-call SYMBOL|LIST
Takes a symbol or list of symbols representing functions or hook variables. Takes a symbol or list of symbols representing functions or hook variables.
@ -380,15 +389,15 @@ Supports two special properties over `use-package':
NAME is implicitly added if this property is present and non-nil. No need to NAME is implicitly added if this property is present and non-nil. No need to
specify it. A value of `t' implies NAME, e.g. specify it. A value of `t' implies NAME, e.g.
(def-package! x (def-package! abc
;; This is equivalent to :defer-incrementally (x) ;; This is equivalent to :defer-incrementally (abc)
:defer-incrementally t :defer-incrementally t
...)" ...)"
(unless (or (memq name doom-disabled-packages) (unless (or (memq name doom-disabled-packages)
;; At compile-time, use-package will forcibly load its package to ;; At compile-time, use-package will forcibly load packages to
;; prevent compile-time errors. However, Doom users can ;; prevent compile-time errors. However, if a Doom user has
;; intentionally disable packages, resulting if file-missing ;; disabled packages you get file-missing package errors, so it's
;; package errors, so we preform this check at compile time: ;; necessary to check for packages at compile time:
(and (bound-and-true-p byte-compile-current-file) (and (bound-and-true-p byte-compile-current-file)
(not (locate-library (symbol-name name))))) (not (locate-library (symbol-name name)))))
`(use-package ,name ,@plist))) `(use-package ,name ,@plist)))
@ -478,5 +487,59 @@ CATEGORY and MODULE can be omitted When this macro is used from inside a module
(memq category (doom-module-get (car module-pair) (cdr module-pair) :flags))))) (memq category (doom-module-get (car module-pair) (cdr module-pair) :flags)))))
t)) t))
(defmacro after! (targets &rest body)
"Evaluate BODY after TARGETS have loaded.
This is a wrapper around `with-eval-after-load' that:
1. Suppresses warnings for disabled packages at compile-time
2. No-ops for TARGETS that are disabled by the user (via `package!')
3. Supports compound TARGETS statements (see below)
TARGETS can either be:
- An unquoted package symbol (the name of a package)
(after! helm BODY...)
- An unquoted list of package symbols (i.e. BODY is evaluated once both magit
and git-gutter have loaded)
(after! (magit git-gutter) BODY...)
- An unquoted, nested list of compound package lists, using :or/:any and/or :and/:all
(after! (:or package-a package-b ...) BODY...)
(after! (:and package-a package-b ...) BODY...)
(after! (:and package-a (:or package-b package-c) ...) BODY...)
Note that:
- :or and :any are equivalent
- :and and :all are equivalent
- If these are omitted, :and is implied."
(declare (indent defun) (debug t))
(unless (and (symbolp targets)
(memq targets (bound-and-true-p doom-disabled-packages)))
(list (if (or (not (bound-and-true-p byte-compile-current-file))
(dolist (next (doom-enlist targets))
(unless (keywordp next)
(if (symbolp next)
(require next nil :no-error)
(load next :no-message :no-error)))))
#'progn
#'with-no-warnings)
(if (symbolp targets)
`(with-eval-after-load ',targets ,@body)
(pcase (car-safe targets)
((or :or :any)
(macroexp-progn
(cl-loop for next in (cdr targets)
collect `(after! ,next ,@body))))
((or :and :all)
(dolist (next (cdr targets))
(setq body `((after! ,next ,@body))))
(car body))
(_ `(after! (:and ,@targets) ,@body)))))))
(provide 'core-modules) (provide 'core-modules)
;;; core-modules.el ends here ;;; core-modules.el ends here

View file

@ -6,15 +6,17 @@
emacs-version))) emacs-version)))
(defvar doom-debug-mode (or (getenv "DEBUG") init-file-debug) (defvar doom-debug-mode (or (getenv "DEBUG") init-file-debug)
"If non-nil, all doom functions will be verbose. Set DEBUG=1 in the command "If non-nil, Doom will log more.
line or use --debug-init to enable this.")
Use `doom/toggle-debug-mode' to toggle it. The --debug-init flag and setting the
DEBUG envvar will enable this at startup.")
;; ;;
;;; Constants ;;; Constants
(defconst doom-version "2.0.9" (defconst doom-version "2.0.9"
"Current version of DOOM emacs.") "Current version of Doom Emacs.")
(defconst EMACS26+ (> emacs-major-version 25)) (defconst EMACS26+ (> emacs-major-version 25))
(defconst EMACS27+ (> emacs-major-version 26)) (defconst EMACS27+ (> emacs-major-version 26))
@ -28,35 +30,39 @@ line or use --debug-init to enable this.")
;; ;;
(defvar doom-emacs-dir (defvar doom-emacs-dir
(eval-when-compile (file-truename user-emacs-directory)) (eval-when-compile (file-truename user-emacs-directory))
"The path to this emacs.d directory. Must end in a slash.") "The path to the currently loaded .emacs.d directory. Must end with a slash.")
(defvar doom-core-dir (concat doom-emacs-dir "core/") (defvar doom-core-dir (concat doom-emacs-dir "core/")
"The root directory of core Doom files.") "The root directory of Doom's core files. Must end with a slash.")
(defvar doom-modules-dir (concat doom-emacs-dir "modules/") (defvar doom-modules-dir (concat doom-emacs-dir "modules/")
"The root directory for Doom's modules.") "The root directory for Doom's modules. Must end with a slash.")
(defvar doom-local-dir (concat doom-emacs-dir ".local/") (defvar doom-local-dir (concat doom-emacs-dir ".local/")
"Root directory for local Emacs files. Use this as permanent storage for files "Root directory for local storage.
that are safe to share across systems (if this config is symlinked across
several computers).") Use this as a storage location for this system's installation of Doom Emacs.
These files should not be shared across systems. By default, it is used by
`doom-etc-dir' and `doom-cache-dir'. Must end with a slash.")
(defvar doom-etc-dir (concat doom-local-dir "etc/") (defvar doom-etc-dir (concat doom-local-dir "etc/")
"Directory for non-volatile storage. "Directory for non-volatile local storage.
Use this for files that don't change much, like servers binaries, external Use this for files that don't change much, like server binaries, external
dependencies or long-term shared data.") dependencies or long-term shared data. Must end with a slash.")
(defvar doom-cache-dir (concat doom-local-dir "cache/") (defvar doom-cache-dir (concat doom-local-dir "cache/")
"Directory for volatile storage. "Directory for volatile local storage.
Use this for files that change often, like cache files.") Use this for files that change often, like cache files. Must end with a slash.")
(defvar doom-packages-dir (concat doom-local-dir "packages/") (defvar doom-packages-dir (concat doom-local-dir "packages/")
"Where package.el and quelpa plugins (and their caches) are stored.") "Where package.el and quelpa plugins (and their caches) are stored.
Must end with a slash.")
(defvar doom-docs-dir (concat doom-emacs-dir "docs/") (defvar doom-docs-dir (concat doom-emacs-dir "docs/")
"Where the Doom manual is stored.") "Where Doom's documentation files are stored. Must end with a slash.")
(defvar doom-private-dir (defvar doom-private-dir
(or (getenv "DOOMDIR") (or (getenv "DOOMDIR")
@ -66,37 +72,44 @@ Use this for files that change often, like cache files.")
"~/.config")))) "~/.config"))))
(if (file-directory-p xdg-path) xdg-path)) (if (file-directory-p xdg-path) xdg-path))
"~/.doom.d/") "~/.doom.d/")
"Where your private customizations are placed. Must end in a slash. Respects "Where your private configuration is placed.
XDG directory conventions if ~/.config/doom exists.")
Defaults to ~/.config/doom, ~/.doom.d or the value of the DOOMDIR envvar;
whichever is found first. Must end in a slash.")
(defvar doom-autoload-file (concat doom-local-dir "autoloads.el") (defvar doom-autoload-file (concat doom-local-dir "autoloads.el")
"Where `doom-reload-doom-autoloads' will generate its core autoloads file.") "Where `doom-reload-doom-autoloads' stores its core autoloads.
This file is responsible for informing Emacs where to find all of Doom's
autoloaded core functions (in core/autoload/*.el).")
(defvar doom-package-autoload-file (concat doom-local-dir "autoloads.pkg.el") (defvar doom-package-autoload-file (concat doom-local-dir "autoloads.pkg.el")
"Where `doom-reload-package-autoloads' will generate its package.el autoloads "Where `doom-reload-package-autoloads' stores its package.el autoloads.
file.")
This file is compiled from the autoloads files of all installed packages
combined.")
(defvar doom-env-file (concat doom-local-dir "env") (defvar doom-env-file (concat doom-local-dir "env")
"The location of your env file, generated by `doom env refresh`. "The location of your envvar file, generated by `doom env refresh`.
This file contains environment variables scraped from your non and interactive This file contains environment variables scraped from your shell environment,
shell environment, and is loaded at startup (if it exist)s. This is helpful if which is loaded at startup (if it exists). This is helpful if Emacs can't
Emacs can't (easily) be launched from the correct shell session (particular for (easily) be launched from the correct shell session (particularly for MacOS
MacOS users).") users).")
;; ;;
;;; Doom core variables ;;; Doom core variables
(defvar doom-init-p nil (defvar doom-init-p nil
"Non-nil if `doom-initialize' has run.") "Non-nil if Doom has been initialized.")
(defvar doom-init-time nil (defvar doom-init-time nil
"The time it took, in seconds, for DOOM Emacs to initialize.") "The time it took, in seconds, for Doom Emacs to initialize.")
(defvar doom-emacs-changed-p nil (defvar doom-emacs-changed-p nil
"If non-nil, the running version of Emacs is different from the first time "If non-nil, the running version of Emacs is different from the first time
Doom was setup, which can cause problems.") Doom was setup, which may cause problems.")
(defvar doom-site-load-path (cons doom-core-dir load-path) (defvar doom-site-load-path (cons doom-core-dir load-path)
"The initial value of `load-path', before it was altered by "The initial value of `load-path', before it was altered by
@ -251,9 +264,10 @@ original value of `symbol-file'."
#'doom-try-run-hook)) #'doom-try-run-hook))
(add-hook 'hack-local-variables-hook #'doom|run-local-var-hooks) (add-hook 'hack-local-variables-hook #'doom|run-local-var-hooks)
;; If `enable-local-variables' is disabled, then `hack-local-variables-hook' is
;; never triggered.
(defun doom|run-local-var-hooks-if-necessary () (defun doom|run-local-var-hooks-if-necessary ()
"If `enable-local-variables' is disabled, then `hack-local-variables-hook' is "Run `doom|run-local-var-hooks' if `enable-local-variables' is disabled."
never triggered."
(unless enable-local-variables (unless enable-local-variables
(doom|run-local-var-hooks))) (doom|run-local-var-hooks)))
(add-hook 'after-change-major-mode-hook #'doom|run-local-var-hooks-if-necessary) (add-hook 'after-change-major-mode-hook #'doom|run-local-var-hooks-if-necessary)
@ -265,7 +279,8 @@ never triggered."
(defvar doom-incremental-packages '(t) (defvar doom-incremental-packages '(t)
"A list of packages to load incrementally after startup. Any large packages "A list of packages to load incrementally after startup. Any large packages
here may cause noticable pauses, so it's recommended you break them up into here may cause noticable pauses, so it's recommended you break them up into
sub-packages. For example, `org' is comprised of many packages, and can be broken up into: sub-packages. For example, `org' is comprised of many packages, and can be
broken up into:
(doom-load-packages-incrementally (doom-load-packages-incrementally
'(calendar find-func format-spec org-macs org-compat '(calendar find-func format-spec org-macs org-compat
@ -507,7 +522,7 @@ to least)."
(doom-initialize noninteractive) (doom-initialize noninteractive)
(unless noninteractive (unless noninteractive
(doom-initialize-modules)) (doom-initialize-modules))
(after! package (with-eval-after-load 'package
(require 'core-packages) (require 'core-packages)
(doom-initialize-packages)) (doom-initialize-packages))

View file

@ -1,9 +1,7 @@
Before you doom yourself, there are a few things you should know: Before you doom yourself, there are a few things you should know:
1. If you use GUI Emacs, run `M-x all-the-icons-install-fonts` so you don't get 1. Whenever you edit your doom! block in ~/.doom.d/init.el or modify your
weird symbols all over the place. modules, run:
2. Whenever you edit ~/.doom.d/init.el or modify modules, run:
bin/doom refresh bin/doom refresh
@ -11,20 +9,17 @@ Before you doom yourself, there are a few things you should know:
removed, and your autoloads files are up to date. This is important! If you removed, and your autoloads files are up to date. This is important! If you
forget to do this you will get errors! forget to do this you will get errors!
3. If something inexplicably goes wrong, it's a good idea to try: 2. If something inexplicably goes wrong, try `bin/doom doctor`
bin/doom doctor
This will diagnose common issues with your environment and setup, and may This will diagnose common issues with your environment and setup, and may
give you clues about what is wrong. give you clues about what is wrong.
4. To update doom, run 3. Use `bin/doom upgrade` to update Doom. Doing it any other way may require
additional work. When in doubt, run `bin/doom refresh`.
bin/doom upgrade 4. Check out `bin/doom help` to see what else `bin/doom` can do (and it is
recommended you add ~/.emacs.d/bin to your PATH).
Doing it any other way will require you run `bin/doom refresh` otherwise, 5. You can find Doom's documentation via `M-x doom/help` or `SPC h D`.
5. Check out `bin/doom help` to see what else it can do (it is recommended you
add ~/.emacs.d/bin to your PATH).
Have fun! Have fun!

View file

@ -111,7 +111,7 @@
;; Highjacks backspace to: ;; Highjacks backspace to:
;; a) balance spaces inside brackets/parentheses ( | ) -> (|) ;; a) balance spaces inside brackets/parentheses ( | ) -> (|)
;; b) delete space-indented `tab-width' steps at a time ;; b) delete up to nearest column multiple of `tab-width' at a time
;; c) close empty multiline brace blocks in one step: ;; c) close empty multiline brace blocks in one step:
;; { ;; {
;; | ;; |

View file

@ -1,7 +1,7 @@
;;; lang/emacs-lisp/autoload.el -*- lexical-binding: t; -*- ;;; lang/emacs-lisp/autoload.el -*- lexical-binding: t; -*-
;; ;;
;; Library ;;; Library
;;;###autoload ;;;###autoload
(defun +emacs-lisp-eval (beg end) (defun +emacs-lisp-eval (beg end)
@ -77,7 +77,7 @@ library/userland functions"
;; ;;
;; Commands ;;; Commands
;;;###autoload ;;;###autoload
(defun +emacs-lisp/open-repl () (defun +emacs-lisp/open-repl ()
@ -92,7 +92,7 @@ library/userland functions"
;; ;;
;; Hooks ;;; Hooks
;;;###autoload ;;;###autoload
(defun +emacs-lisp|extend-imenu () (defun +emacs-lisp|extend-imenu ()

View file

@ -14,7 +14,7 @@ This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
;; ;;
;; Config ;;; Config
(def-package! elisp-mode (def-package! elisp-mode
:mode ("\\.Cask\\'" . emacs-lisp-mode) :mode ("\\.Cask\\'" . emacs-lisp-mode)
@ -76,14 +76,13 @@ This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
;; ;;
;; Packages ;;; Packages
;; `auto-compile' ;;;###package auto-compile
(setq auto-compile-display-buffer nil (setq auto-compile-display-buffer nil
auto-compile-use-mode-line nil) auto-compile-use-mode-line nil)
;; `macrostep'
(when (featurep! :editor evil) (when (featurep! :editor evil)
(after! macrostep (after! macrostep
(evil-define-key* 'normal macrostep-keymap (evil-define-key* 'normal macrostep-keymap
@ -108,7 +107,7 @@ This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
(add-hook 'macrostep-mode-hook #'evil-normalize-keymaps))) (add-hook 'macrostep-mode-hook #'evil-normalize-keymaps)))
;; `overseer' ;;;###package overseer
(autoload 'overseer-test "overseer" nil t) (autoload 'overseer-test "overseer" nil t)
(remove-hook 'emacs-lisp-mode-hook 'overseer-enable-mode) (remove-hook 'emacs-lisp-mode-hook 'overseer-enable-mode)
@ -129,7 +128,7 @@ This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
;; ;;
;; Project modes ;;; Project modes
(def-project-mode! +emacs-lisp-ert-mode (def-project-mode! +emacs-lisp-ert-mode
:modes (emacs-lisp-mode) :modes (emacs-lisp-mode)

View file

@ -22,11 +22,12 @@
;; ;;
;; Major modes ;;; Major modes
(add-hook! (css-mode sass-mode stylus-mode) #'rainbow-mode) (add-hook! (css-mode sass-mode stylus-mode) #'rainbow-mode)
(after! css-mode ; built-in -- contains both css-mode & scss-mode ;; built-in, and contains both css-mode & scss-mode
(after! css-mode
;; css-mode hooks apply to scss and less-css modes ;; css-mode hooks apply to scss and less-css modes
(add-hook 'css-mode-hook #'rainbow-delimiters-mode) (add-hook 'css-mode-hook #'rainbow-delimiters-mode)
(unless EMACS26+ (unless EMACS26+
@ -41,7 +42,7 @@
;; ;;
;; Tools ;;; Tools
(when (featurep! +lsp) (when (featurep! +lsp)
(add-hook! (css-mode sass-mode less-css-mode) #'lsp!)) (add-hook! (css-mode sass-mode less-css-mode) #'lsp!))

View file

@ -45,8 +45,9 @@
;;;###autoload ;;;###autoload
(defun +css/comment-indent-new-line () (defun +css/comment-indent-new-line ()
"Continues the comment in an indented new line in css-mode and scss-mode. "Continues the comment in an indented new line.
Meant for `comment-line-break-function'."
Meant for `comment-line-break-function' in `css-mode' and `scss-mode'."
(interactive) (interactive)
(when (sp-point-in-comment) (when (sp-point-in-comment)
(let ((at-end (looking-at-p ".+\\*/")) (let ((at-end (looking-at-p ".+\\*/"))

View file

@ -3,7 +3,7 @@
;;;###autoload (autoload '+web:encode-html-entities "lang/web/autoload/evil" nil t) ;;;###autoload (autoload '+web:encode-html-entities "lang/web/autoload/evil" nil t)
(evil-define-operator +web:encode-html-entities (beg end &optional input) (evil-define-operator +web:encode-html-entities (beg end &optional input)
"Encodes HTML entities in the selected region." "Encodes HTML entities in INPUT or the selected region."
(interactive "<r><a>") (interactive "<r><a>")
(cond (input (cond (input
(insert (+web-encode-entities input))) (insert (+web-encode-entities input)))
@ -12,7 +12,7 @@
;;;###autoload (autoload '+web:decode-html-entities "lang/web/autoload/evil" nil t) ;;;###autoload (autoload '+web:decode-html-entities "lang/web/autoload/evil" nil t)
(evil-define-operator +web:decode-html-entities (beg end &optional input) (evil-define-operator +web:decode-html-entities (beg end &optional input)
"Decodes HTML entities in the selected region." "Decodes HTML entities in INPUT or the selected region."
(interactive "<r><a>") (interactive "<r><a>")
(cond (input (cond (input
(insert (+web-decode-entities input))) (insert (+web-decode-entities input)))

View file

@ -94,6 +94,10 @@ function @ http://ergoemacs.org/emacs/elisp_replace_html_entities_command.html"
"TODO" "TODO"
(+web--entities-string text t)) (+web--entities-string text t))
;;
;;; Commands
;;;###autoload ;;;###autoload
(defun +web/encode-entities-region (beg end) (defun +web/encode-entities-region (beg end)
"Encode HTML entities in region." "Encode HTML entities in region."
@ -108,8 +112,10 @@ function @ http://ergoemacs.org/emacs/elisp_replace_html_entities_command.html"
;;;###autoload ;;;###autoload
(defun +web/indent-or-yas-or-emmet-expand () (defun +web/indent-or-yas-or-emmet-expand ()
"Invoke `indent-for-tab-command' if at or before text bol, `yas-expand' if on "Do-what-I-mean on TAB.
a snippet, or `emmet-expand-yas'/`emmet-expand-line', depending on whether
Invokes `indent-for-tab-command' if at or before text bol, `yas-expand' if on a
snippet, or `emmet-expand-yas'/`emmet-expand-line', depending on whether
`yas-minor-mode' is enabled or not." `yas-minor-mode' is enabled or not."
(interactive) (interactive)
(call-interactively (call-interactively

View file

@ -5,10 +5,10 @@
;;;###autodef ;;;###autodef
(cl-defun set-lookup-handlers! (cl-defun set-lookup-handlers!
(modes &rest plist &key definition references documentation file xref-backend async) (modes &rest plist &key definition references documentation file xref-backend async)
"Define a jump target for major MODES. "Define jump handlers for major or minor MODES.
This overwrites previously defined handlers for MODES. If used on minor modes, This overwrites previously defined handlers for MODES. If used on minor modes,
they are combined with handlers defined for other minor modes or the major mode they are stacked onto handlers defined for other minor modes or the major mode
it's activated in. it's activated in.
This can be passed nil as its second argument to unset handlers for MODES. e.g. This can be passed nil as its second argument to unset handlers for MODES. e.g.
@ -33,10 +33,23 @@ Otherwise, these properties are available to be set:
Defines an xref backend for a major-mode. If you define :definition and Defines an xref backend for a major-mode. If you define :definition and
:references along with :xref-backend, those will have higher precedence. :references along with :xref-backend, those will have higher precedence.
:async BOOL :async BOOL
Indicates that the supplied handlers *after* this property are asynchronous. Indicates that *all* supplied FNs are asynchronous. Note: async handlers do
Note: async handlers do not fall back to the default handlers, due to their not fall back to the default handlers, due to their nature. To get around
nature. To get around this, you must write specialized wrappers to wait for this, you must write specialized wrappers to wait for the async response.
the async response and return 'fallback."
If you only want to specify one FN is async, use a PLIST instead:
(set-lookup-handlers! 'rust-mode
:definition '(racer-find-definition :async t))
Handlers can either be interactive or non-interactive. Non-interactive handlers
must take one argument: the identifier being looked up. This function must
change the current buffer or window or return non-nil when it succeeds.
If it doesn't change the current buffer, or it returns nil, the lookup module
will fall back to the next handler in `+lookup-definition-functions',
`+lookup-references-functions', `+lookup-file-functions' or
`+lookup-documentation-functions'."
(declare (indent defun)) (declare (indent defun))
(dolist (mode (doom-enlist modes)) (dolist (mode (doom-enlist modes))
(let ((hook (intern (format "%s-hook" mode))) (let ((hook (intern (format "%s-hook" mode)))
@ -60,7 +73,8 @@ Otherwise, these properties are available to be set:
'+lookup-references-functions '+lookup-references-functions
'+lookup-documentation-functions '+lookup-documentation-functions
'+lookup-file-functions '+lookup-file-functions
'xref-backend-functions))))) 'xref-backend-functions)
async))))
(add-hook hook fn)))))) (add-hook hook fn))))))