Add config/private; for ~/.doom.d & ~/.config/doom support #406

A modules/ submodule will be symlinked to ~/.emacs.d/modules/private.
This commit is contained in:
Henrik Lissner 2018-02-14 23:18:10 -05:00
parent 6d7db48dc1
commit b3dcba54eb
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
7 changed files with 133 additions and 36 deletions

View file

@ -74,6 +74,11 @@ missing) and shouldn't be deleted.")
(defvar doom-reload-hook nil (defvar doom-reload-hook nil
"A list of hooks to run when `doom/reload-load-path' is called.") "A list of hooks to run when `doom/reload-load-path' is called.")
(defvar doom-extra-module-paths ()
"Additional paths for modules that are outside of `doom-modules-dir'.
`doom//reload-autoloads', `doom//byte-compile' and `doom-initialize-packages'
will include the directories in this list.")
(defvar doom--site-load-path load-path (defvar doom--site-load-path load-path
"The load path of built in Emacs libraries.") "The load path of built in Emacs libraries.")
@ -213,9 +218,7 @@ This aggressively reloads core autoload files."
(when (or force-p (not doom-packages)) (when (or force-p (not doom-packages))
(setq doom-packages nil) (setq doom-packages nil)
(_load (expand-file-name "packages.el" doom-core-dir)) (_load (expand-file-name "packages.el" doom-core-dir))
(cl-loop for (module . submodule) in (doom-module-pairs) (mapc #'_load (doom-module-paths "packages.el"))))))
for path = (doom-module-path module submodule "packages.el")
do (_load path 'noerror))))))
(defun doom-module-path (module submodule &optional file) (defun doom-module-path (module submodule &optional file)
"Get the full path to a module: e.g. :lang emacs-lisp maps to "Get the full path to a module: e.g. :lang emacs-lisp maps to
@ -237,10 +240,15 @@ This aggressively reloads core autoload files."
(defun doom-module-paths (&optional append-file) (defun doom-module-paths (&optional append-file)
"Returns a list of absolute file paths to activated modules, with APPEND-FILE "Returns a list of absolute file paths to activated modules, with APPEND-FILE
added, if the file exists." added, if the file exists."
(cl-loop for (module . submodule) in (doom-module-pairs) (let ((fn (if append-file #'file-exists-p #'file-directory-p)))
for path = (doom-module-path module submodule append-file) (append (cl-loop for (module . submodule) in (doom-module-pairs)
if (file-exists-p path) for path = (doom-module-path module submodule append-file)
collect path)) if (funcall fn path)
collect path)
(cl-loop for dir in doom-extra-module-paths
for path = (if append-file (expand-file-name append-file dir) dir)
if (funcall fn path)
collect path))))
(defun doom-module-flags (module submodule) (defun doom-module-flags (module submodule)
"Returns a list of flags provided for MODULE SUBMODULE." "Returns a list of flags provided for MODULE SUBMODULE."
@ -295,18 +303,17 @@ Used by `require!' and `depends-on!'."
"Bootstraps DOOM Emacs and its modules. "Bootstraps DOOM Emacs and its modules.
MODULES is an malformed plist of modules to load." MODULES is an malformed plist of modules to load."
(let (init-forms config-forms mode) (let (init-forms config-forms module)
(dolist (m modules) (dolist (m modules)
(cond ((keywordp m) (setq mode m)) (cond ((keywordp m) (setq module m))
((not mode) (error "No namespace specified in `doom!' for %s" m)) ((not module) (error "No namespace specified in `doom!' for %s" m))
(t (t
(let* ((module mode) (let ((submodule (if (listp m) (car m) m))
(submodule (if (listp m) (car m) m)) (flags (if (listp m) (cdr m))))
(flags (if (listp m) (cdr m)))
(path (doom-module-path module submodule)))
(doom-module-enable module submodule flags) (doom-module-enable module submodule flags)
(push `(load! init ,path t) init-forms) (let ((path (doom-module-path module submodule)))
(push `(load! config ,path t) config-forms))))) (push `(load! init ,path t) init-forms)
(push `(load! config ,path t) config-forms))))))
`(let (file-name-handler-alist) `(let (file-name-handler-alist)
(setq doom-modules ',doom-modules) (setq doom-modules ',doom-modules)
,@(nreverse init-forms) ,@(nreverse init-forms)
@ -393,20 +400,22 @@ If NOERROR is non-nil, don't throw an error if the file doesn't exist."
The module is only loaded once. If RELOAD-P is non-nil, load it again." The module is only loaded once. If RELOAD-P is non-nil, load it again."
(when (or reload-p (not (doom-module-enabled-p module submodule))) (when (or reload-p (not (doom-module-enabled-p module submodule)))
(let ((module-path (doom-module-path module submodule))) (let ((module-path (doom-module-path module submodule)))
(if (not (file-directory-p module-path)) (when (hash-table-p doom-modules)
(lwarn 'doom-modules :warning "Couldn't find module '%s %s'" (doom-module-enable module submodule flags))
module submodule) (if (file-directory-p module-path)
(when (hash-table-p doom-modules) `(condition-case-unless-debug ex
(doom-module-enable module submodule flags)) (progn
`(condition-case-unless-debug ex (load! init ,module-path t)
(progn (if after-init-time
(load! init ,module-path t) (load! config ,module-path t)
(load! config ,module-path t)) (add-hook! 'doom-init-hook (load! config ,module-path t))))
('error ('error
(lwarn 'doom-modules :error (lwarn 'doom-modules :error
"%s in '%s %s' -> %s" "%s in '%s %s' -> %s"
(car ex) ,module ',submodule (car ex) ,module ',submodule
(error-message-string ex)))))))) (error-message-string ex))))
(warn 'doom-modules :warning "Couldn't find module '%s %s'"
module submodule)))))
(defmacro featurep! (module &optional submodule flag) (defmacro featurep! (module &optional submodule flag)
"Returns t if MODULE SUBMODULE is enabled. If FLAG is provided, returns t if "Returns t if MODULE SUBMODULE is enabled. If FLAG is provided, returns t if
@ -562,10 +571,10 @@ This should be run whenever init.el or an autoload file is modified. Running
(let ((auto-dir (expand-file-name "autoload" path)) (let ((auto-dir (expand-file-name "autoload" path))
(auto-file (expand-file-name "autoload.el" path))) (auto-file (expand-file-name "autoload.el" path)))
(when (file-exists-p auto-file) (when (file-exists-p auto-file)
(push auto-file targets)) (push (file-truename auto-file) targets))
(when (file-directory-p auto-dir) (when (file-directory-p auto-dir)
(dolist (file (doom-packages--files auto-dir "\\.el$")) (dolist (file (doom-packages--files auto-dir "\\.el$"))
(push file targets))))) (push (file-truename file) targets)))))
(when (file-exists-p doom-autoload-file) (when (file-exists-p doom-autoload-file)
(delete-file doom-autoload-file) (delete-file doom-autoload-file)
(message "Deleted old autoloads.el")) (message "Deleted old autoloads.el"))
@ -577,7 +586,9 @@ This should be run whenever init.el or an autoload file is modified. Running
"✕ Nothing in %s") "✕ Nothing in %s")
(t (t
"✓ Scanned %s")) "✓ Scanned %s"))
(file-relative-name file doom-emacs-dir))) (if (file-in-directory-p file doom-emacs-dir)
(file-relative-name file doom-emacs-dir)
(abbreviate-file-name file))))
(make-directory (file-name-directory doom-autoload-file) t) (make-directory (file-name-directory doom-autoload-file) t)
(let ((buf (find-file-noselect doom-autoload-file t)) (let ((buf (find-file-noselect doom-autoload-file t))
current-sexp) current-sexp)
@ -709,16 +720,24 @@ If RECOMPILE-P is non-nil, only recompile out-of-date core files."
"Delete all the compiled elc files in your Emacs configuration. This excludes "Delete all the compiled elc files in your Emacs configuration. This excludes
compiled packages.'" compiled packages.'"
(interactive) (interactive)
(ignore-errors (doom-initialize-packages))
(let ((targets (let ((targets
(append (list (expand-file-name "init.elc" doom-emacs-dir)) (append (list (expand-file-name "init.elc" doom-emacs-dir))
(doom-packages--files doom-core-dir "\\.elc$") (doom-packages--files doom-core-dir "\\.elc$")
(doom-packages--files doom-modules-dir "\\.elc$"))) (doom-packages--files doom-modules-dir "\\.elc$")
(cl-loop for dir in doom-extra-module-paths
if (file-directory-p dir)
nconc (doom-packages--files dir "\\.elc$"))))
(default-directory doom-emacs-dir)) (default-directory doom-emacs-dir))
(unless (cl-loop for path in targets (unless (cl-loop for path in targets
if (file-exists-p path) if (file-exists-p path)
collect path collect path
and do (delete-file path) and do (delete-file path)
and do (message "✓ Deleted %s" (file-relative-name path))) and do
(message "✓ Deleted %s"
(if (file-in-directory-p path doom-emacs-dir)
(file-relative-name path)
(abbreviate-file-name path))))
(message "Everything is clean")))) (message "Everything is clean"))))

View file

@ -143,5 +143,10 @@
;; Spacemacs-inspired keybinding scheme, a custom yasnippet library, and ;; Spacemacs-inspired keybinding scheme, a custom yasnippet library, and
;; additional ex commands for evil-mode. Use it as a reference for your ;; additional ex commands for evil-mode. Use it as a reference for your
;; own modules. ;; own modules.
(default +bindings +snippets +evil-commands)) (default +bindings +snippets +evil-commands)
;; This allows you to store your private module at $XDG_CONFIG_HOME/doom.
;; Without +xdg it uses ~/.doom.d/. If your config directory doesn't
;; exist, this module does nothing.
(private +xdg))

View file

@ -0,0 +1,23 @@
#+TITLE: :config private
This module enables support for an external private module and nested
submodules, either at =~/.doom.d= (or =$XDG_CONFIG_HOME/doom= with the ~+xdg~
flag).
* Table of Contents :TOC:
- [[Module Flags][Module Flags]]
- [[Features][Features]]
- [[Private sub-modules][Private sub-modules]]
* Module Flags
+ ~+xdg~ Tells this module to respect XDG conventions and look for your private
config in ~$XDG_CONFIG_HOME/doom~ (falls back to =~/.config/doom=).
* Features
** Private sub-modules
Modules placed in the =modules/= subdirectory of your external config are
symlinked to =~/.emacs.d/modules/private=, and can be activated from ~doom!~:
#+BEGIN_SRC emacs-lisp
(doom! :private private-module1 private-module2 ...)
#+END_SRC

View file

@ -0,0 +1,6 @@
;;; config/private/autoload.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+private/find-in-config "config/private/autoload" nil t)
(+default--def-find-in! config +private-config-path)
;;;###autoload (autoload '+private/browse-config "config/private/autoload" nil t)
(+default--def-browse-in! config +private-config-path)

View file

@ -0,0 +1,4 @@
;;; config/private/config.el -*- lexical-binding: t; -*-
(load (expand-file-name "config.el" +private-config-path)
'noerror 'nomessage)

View file

@ -0,0 +1,25 @@
;;; config/private/init.el -*- lexical-binding: t; -*-
(defvar +private-config-path
(if (featurep! +xdg)
(expand-file-name "doom/" (or (getenv "XDG_CONFIG_HOME") "~/.config"))
"~/.doom.d")
"The directory that serves as the root of your external private config for
Doom Emacs.")
(defvar +private-modules-path
(expand-file-name "modules/" +private-config-path)
"The path to your private, external modules. This will be symlinked to
external/ in `doom-modules-dir'.")
(defvar +private-module-prefix "private"
"TODO")
;; Ensure `doom//reload-autoloads', `doom//byte-compile' and
;; `doom-initialize-packages' all include this module in their operations.
(add-to-list 'doom-extra-module-paths +private-config-path)
;;
(load (expand-file-name "init.el" +private-config-path)
'noerror 'nomessage)

View file

@ -0,0 +1,15 @@
;; -*- no-byte-compile: t; -*-
;;; config/private/packages.el
(when (file-directory-p +private-modules-path)
;; automatically symlinks your private modules to `doom-modules-dir'.
(let ((symlink (expand-file-name +private-module-prefix doom-modules-dir)))
(if (and (file-directory-p symlink)
(not (file-symlink-p symlink)))
(lwarn "config/private" :warning
"modules/%s already exists; can't create symlink" +private-module-prefix)
(make-symbolic-link +private-modules-path symlink t))))
;;
(load (expand-file-name "packages.el" +private-config-path)
'noerror 'nomessage)