2018-05-20 12:21:13 +02:00
|
|
|
;;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
|
|
|
|
2018-05-24 19:03:36 +02:00
|
|
|
;; Eagerly load these libraries because this module may be loaded in a session
|
|
|
|
;; that hasn't been fully initialized (where autoloads files haven't been
|
|
|
|
;; generated or `load-path' populated).
|
2018-05-27 12:44:22 +02:00
|
|
|
(load! "autoload/debug")
|
2018-09-07 21:49:49 -04:00
|
|
|
(load! "autoload/files")
|
2018-05-27 12:44:22 +02:00
|
|
|
(load! "autoload/message")
|
2018-09-07 21:49:49 -04:00
|
|
|
(load! "autoload/packages")
|
2018-05-20 12:21:13 +02:00
|
|
|
|
|
|
|
|
|
|
|
;;
|
2018-05-24 19:03:36 +02:00
|
|
|
;; Dispatcher API
|
2018-05-20 12:21:13 +02:00
|
|
|
|
2018-05-24 19:03:36 +02:00
|
|
|
(defvar doom-auto-accept (getenv "YES")
|
|
|
|
"If non-nil, Doom will auto-accept any confirmation prompts during batch
|
2018-06-17 21:35:58 +02:00
|
|
|
commands like `doom-packages-install', `doom-packages-update' and
|
|
|
|
`doom-packages-autoremove'.")
|
2018-05-20 12:21:13 +02:00
|
|
|
|
2018-05-24 19:03:36 +02:00
|
|
|
(defconst doom--dispatch-command-alist ())
|
|
|
|
(defconst doom--dispatch-alias-alist ())
|
2018-05-20 12:21:13 +02:00
|
|
|
|
|
|
|
(defun doom--dispatch-format (desc &optional short)
|
2018-06-05 11:19:34 +02:00
|
|
|
(with-temp-buffer
|
|
|
|
(let ((fill-column 72))
|
|
|
|
(insert desc)
|
|
|
|
(goto-char (point-min))
|
|
|
|
(while (re-search-forward "\n\n[^ \n]" nil t)
|
|
|
|
(fill-paragraph)))
|
|
|
|
(if (not short)
|
|
|
|
(buffer-string)
|
|
|
|
(goto-char (point-min))
|
|
|
|
(buffer-substring-no-properties
|
|
|
|
(line-beginning-position)
|
|
|
|
(line-end-position)))))
|
2018-05-20 12:21:13 +02:00
|
|
|
|
|
|
|
(defun doom--dispatch-help (&optional command desc &rest args)
|
2018-05-24 19:03:36 +02:00
|
|
|
"Display help documentation for a dispatcher command. If COMMAND and DESC are
|
|
|
|
omitted, show all available commands, their aliases and brief descriptions."
|
2018-05-20 12:21:13 +02:00
|
|
|
(if command
|
|
|
|
(princ (doom--dispatch-format desc))
|
2018-09-07 21:49:49 -04:00
|
|
|
(print! (bold "%-10s\t%s\t%s") "Command:" "Alias" "Description")
|
2018-06-19 16:43:08 +02:00
|
|
|
(dolist (spec (cl-sort doom--dispatch-command-alist #'string-lessp
|
|
|
|
:key #'car))
|
2018-05-20 12:21:13 +02:00
|
|
|
(cl-destructuring-bind (command &key desc _body) spec
|
2018-05-24 19:03:36 +02:00
|
|
|
(let ((aliases (cl-loop for (alias . cmd) in doom--dispatch-alias-alist
|
|
|
|
if (eq cmd command)
|
|
|
|
collect (symbol-name alias))))
|
2018-05-20 12:21:13 +02:00
|
|
|
(print! " %-10s\t%s\t%s"
|
2018-05-24 19:03:36 +02:00
|
|
|
command (if aliases (string-join aliases ",") "")
|
2018-05-20 12:21:13 +02:00
|
|
|
(doom--dispatch-format desc t)))))))
|
|
|
|
|
2018-09-27 23:08:51 -04:00
|
|
|
(defun doom-dispatch (cmd args &optional show-help)
|
|
|
|
"Parses ARGS and invokes a dispatcher.
|
|
|
|
|
|
|
|
If SHOW-HELP is non-nil, show the documentation for said dispatcher."
|
|
|
|
(when (equal cmd "help")
|
|
|
|
(setq show-help t)
|
|
|
|
(when args
|
|
|
|
(setq cmd (car args)
|
|
|
|
args (cdr args))))
|
|
|
|
(cl-destructuring-bind (command &key desc body)
|
|
|
|
(let ((sym (intern cmd)))
|
|
|
|
(or (assq sym doom--dispatch-command-alist)
|
|
|
|
(assq (cdr (assq sym doom--dispatch-alias-alist))
|
|
|
|
doom--dispatch-command-alist)
|
2018-09-28 22:29:42 -04:00
|
|
|
(user-error "Invalid command: %s" sym)))
|
2018-09-27 23:08:51 -04:00
|
|
|
(if show-help
|
|
|
|
(apply #'doom--dispatch-help command desc args)
|
|
|
|
(funcall body args))))
|
2018-05-20 12:21:13 +02:00
|
|
|
|
2018-06-17 21:38:30 +02:00
|
|
|
(defmacro dispatcher! (command form &optional docstring)
|
2018-05-24 19:03:36 +02:00
|
|
|
"Define a dispatcher command. COMMAND is a symbol or a list of symbols
|
|
|
|
representing the aliases for this command. DESC is a string description. The
|
|
|
|
first line should be short (under 60 letters), as it will be displayed for
|
|
|
|
bin/doom help.
|
|
|
|
|
|
|
|
BODY will be run when this dispatcher is called."
|
2018-08-28 19:14:18 +02:00
|
|
|
(declare (indent defun) (doc-string 3))
|
2018-06-19 20:55:44 +02:00
|
|
|
(cl-destructuring-bind (cmd &rest aliases)
|
|
|
|
(doom-enlist command)
|
2018-06-19 16:43:08 +02:00
|
|
|
(macroexp-progn
|
|
|
|
(append
|
|
|
|
(when aliases
|
|
|
|
`((dolist (alias ',aliases)
|
2018-06-23 16:48:58 +02:00
|
|
|
(setf (alist-get alias doom--dispatch-alias-alist) ',cmd))))
|
|
|
|
`((setf (alist-get ',cmd doom--dispatch-command-alist)
|
|
|
|
(list :desc ,docstring
|
2018-09-07 21:49:49 -04:00
|
|
|
:body (lambda (args) (ignore args) ,form))))))))
|
2018-05-24 19:03:36 +02:00
|
|
|
|
2018-05-20 12:21:13 +02:00
|
|
|
|
|
|
|
;;
|
2018-09-07 19:36:16 -04:00
|
|
|
;; Dummy dispatch commands (no-op because they're handled especially)
|
2018-05-24 19:03:36 +02:00
|
|
|
|
2018-06-17 21:38:30 +02:00
|
|
|
(dispatcher! run :noop
|
2018-05-20 12:21:13 +02:00
|
|
|
"Run Doom Emacs from bin/doom's parent directory.
|
|
|
|
|
|
|
|
All arguments are passed on to Emacs (except for -p and -e).
|
|
|
|
|
|
|
|
doom run
|
|
|
|
doom run -nw init.el
|
|
|
|
|
2018-05-24 19:03:36 +02:00
|
|
|
WARNING: this command exists for convenience and testing. Doom will suffer
|
2018-09-09 23:16:55 -04:00
|
|
|
additional overhead by being started this way. For the best performance, it is
|
|
|
|
best to run Doom out of ~/.emacs.d and ~/.doom.d.")
|
2018-05-20 12:21:13 +02:00
|
|
|
|
2018-06-17 21:38:30 +02:00
|
|
|
(dispatcher! (doctor doc) :noop
|
2018-09-09 23:16:55 -04:00
|
|
|
"Checks for issues with your environment & Doom config.
|
2018-09-07 21:49:49 -04:00
|
|
|
|
2018-09-09 23:16:55 -04:00
|
|
|
Also checks for missing dependencies for any enabled modules.")
|
2018-05-21 15:42:27 +02:00
|
|
|
|
2018-06-17 21:38:30 +02:00
|
|
|
(dispatcher! (help h) :noop
|
2018-05-21 15:42:27 +02:00
|
|
|
"Look up additional information about a command.")
|
|
|
|
|
2018-06-17 21:38:30 +02:00
|
|
|
|
2018-05-20 12:21:13 +02:00
|
|
|
;;
|
2018-09-07 21:49:49 -04:00
|
|
|
;; Real dispatch commands
|
2018-05-20 12:21:13 +02:00
|
|
|
|
2018-09-07 21:49:49 -04:00
|
|
|
(load! "cli/autoloads")
|
|
|
|
(load! "cli/byte-compile")
|
|
|
|
(load! "cli/debug")
|
|
|
|
(load! "cli/packages")
|
|
|
|
(load! "cli/patch-macos")
|
|
|
|
(load! "cli/quickstart")
|
|
|
|
(load! "cli/upgrade")
|
|
|
|
(load! "cli/test")
|
2018-05-20 12:21:13 +02:00
|
|
|
|
2018-05-28 12:19:58 +02:00
|
|
|
|
2018-09-07 21:49:49 -04:00
|
|
|
;;
|
2018-06-17 21:35:58 +02:00
|
|
|
(defun doom-refresh (&optional force-p)
|
2018-05-30 11:42:35 +02:00
|
|
|
"Ensure Doom is in a working state by checking autoloads and packages, and
|
|
|
|
recompiling any changed compiled files. This is the shotgun solution to most
|
|
|
|
problems with doom."
|
2018-06-17 21:35:58 +02:00
|
|
|
(doom-reload-doom-autoloads force-p)
|
2018-05-30 11:42:35 +02:00
|
|
|
(unwind-protect
|
2018-06-19 16:43:08 +02:00
|
|
|
(progn
|
|
|
|
(ignore-errors
|
|
|
|
(doom-packages-autoremove doom-auto-accept))
|
|
|
|
(ignore-errors
|
|
|
|
(doom-packages-install doom-auto-accept)))
|
2018-06-17 21:35:58 +02:00
|
|
|
(doom-reload-package-autoloads force-p)
|
|
|
|
(doom-byte-compile nil 'recompile)))
|
2018-05-30 11:42:35 +02:00
|
|
|
|
2018-09-07 21:49:49 -04:00
|
|
|
(dispatcher! (refresh re) (doom-refresh 'force)
|
|
|
|
"Refresh Doom. Same as autoremove+install+autoloads.
|
2018-06-11 23:20:45 +02:00
|
|
|
|
2018-09-07 21:49:49 -04:00
|
|
|
This is the equivalent of running autoremove, install, autoloads, then
|
|
|
|
recompile. Run this whenever you:
|
2018-06-11 23:20:45 +02:00
|
|
|
|
2018-09-07 21:49:49 -04:00
|
|
|
1. Modify your `doom!' block,
|
|
|
|
2. Add or remove `package!' blocks to your config,
|
|
|
|
3. Add or remove autoloaded functions in module autoloaded files.
|
|
|
|
4. Update Doom outside of Doom (e.g. with git)")
|
2018-06-11 23:20:45 +02:00
|
|
|
|
2018-06-20 12:03:23 +02:00
|
|
|
(provide 'core-cli)
|
|
|
|
;;; core-cli.el ends here
|