2022-07-30 21:49:00 +02:00
|
|
|
;;; lisp/lib/debug.el -*- lexical-binding: t; -*-
|
2018-05-11 00:00:02 +02:00
|
|
|
|
Backport bits of CLI rewrite
The rewrite for Doom's CLI is taking a while, so I've backported a few
important changes in order to ease the transition and fix a couple bugs
sooner.
Fixes #2802, #2737, #2386
The big highlights are:
- Fix #2802: We now update recipe repos *before* updating/installing any
new packages. No more "Could not find package X in recipe repositories".
- Fix #2737: An edge case where straight couldn't reach a pinned
commit (particularly with agda).
- Doom is now smarter about what option it recommends when straight
prompts you to make a choice.
- Introduces a new init path for Doom. The old way:
- Launch in "minimal" CLI mode in non-interactive sessions
- Launch a "full" interactive mode otherwise.
The new way
- Launch in "minimal" CLI mode *only* for bin/doom
- Launch is a simple mode for non-interactive sessions that still need
access to your interactive config (like async org export/babel).
- Launch a "full" interactive mode otherwise.
This should fix compatibility issues with plugins that use the
async.el library or spawn child Emacs processes to fake
parallelization (like org's async export and babel functionality).
- Your private init.el is now loaded more reliably when running any
bin/doom command. This gives you an opportunity to configure its
settings.
- Added doom-first-{input,buffer,file}-hook hooks, which we use to queue
deferred activation of a number of packages. Users can remove these
modes from these hooks; altogether preventing them from loading,
rather than waiting for them to load to then disable them,
e.g. (after! smartparens (smartparens-global-mode -1)) -> (remove-hook
'doom-first-buffer #'smartparens-global-mode)
Hooks added to doom-first-*-hook variables will be removed once they
run.
This should also indirectly fix #2386, by preventing interactive modes
from running in non-interactive session.
- Added `doom/bump-*` commands to make bumping modules and packages
easier, and `doom/bumpify-*` commands for converting package!
statements into user/repo@sha1hash format for bump commits.
- straight.el is now commit-pinned, like all other packages. We also
more reliably install straight.el by cloning it ourselves, rather than
relying on its bootstrap.el.
This should prevent infinite "straight has diverged from master"
prompts whenever we change branches (though, you might have to put up
with it one more after this update -- see #2937 for workaround).
All the other minor changes:
- Moved core/autoload/cli.el to core/autoload/process.el
- The package manager will log attempts to check out pinned commits
- If package state is incomplete while rebuilding packages, emit a
simpler error message instead of an obscure one!
- Added -u switch to 'doom sync' to make it run 'doom update' afterwards
- Added -p switch to 'doom sync' to make it run 'doom purge' afterwards
- Replace doom-modules function with doom-modules-list
- The `with-plist!` macro was removed, since `cl-destructuring-bind`
already serves that purpose well enough.
- core/autoload/packages.el was moved into core-packages.el
- bin/doom will no longer die if DOOMDIR or DOOMLOCALDIR don't have a
trailing slash
- Introduces doom-debug-variables; a list of variables to toggle on
doom/toggle-debug-mode.
- The sandbox has been updated to reflect the above changes, also:
1. Child instances will no longer inherit the process environment of
the host instance,
2. It will no longer produce an auto-save-list directory in ~/.emacs.d
2020-05-14 15:00:23 -04:00
|
|
|
;;
|
|
|
|
;;; Doom's debug mode
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defvar doom-debug-variables
|
2021-03-12 21:02:20 -05:00
|
|
|
'(async-debug
|
|
|
|
debug-on-error
|
refactor!(cli): rewrite CLI framework libraries
BREAKING CHANGE: this changes Doom's CLI framework in subtle ways, which
is listed in greater detail below. If you've never extended Doom's CLI,
then this won't affect you, but otherwise it'd be recommended you read
on below.
This commit focuses on the CLI framework itself and backports some
foundational changes to its DSL and how it resolves command line
arguments to CLIs, validates input, displays documentation, and persists
state across sessions -- and more. This is done in preparation for the
final stretch towarding completing the CLI rewrite (see #4273).
This is also an effort to generalize Doom's CLI (both its framework and
bin/doom), to increase it versatility and make it a viable dev tool for
other Doom projects (on our Github org) and beyond.
However, there is a *lot* to cover so I'll try to be brief:
- Refactor: generalize Doom's CLI framework by moving all bin/doom
specific configuration/commands out of core-cli into bin/doom. This
makes it easier to use bin/doom as a project-agnostic development
tool (or for users to write their own).
- Refactor: change the namespace for CLI variables/functions from
doom-cli-X to doom-X.
- Fix: subcommands being mistaken as arguments. "doom make index" will
resolve to (defcli! (doom make index)) if it exists,
otherwise (defcli! (doom make)) with "index" as an argument. Before
this, it would resolve to the latter no matter what. &rest can
override this; with (defcli! (doom make) (&rest args)), (defcli! (doom
make index)) will never be invoked.
- Refactor!: redesign our output library (was core/autoload/output.el,
is now core/autoload/print.el), and how our CLI framework buffers and
logs output, and now merges logs across (exit! ...) restarts.
- Feat: add support for :before and :after pseudo commands. E.g.
(defcli! (:before doom help) () ...)
(defcli! (:after doom sync) () ...)
Caveat: unlike advice, only one of each can be defined per-command.
- Feat: option arguments now have rudimentary type validation (see
`doom-cli-option-arg-types`). E.g.
(defcli! (doom foo) ((foo ("--foo" num))) ...)
If NUM is not a numeric, it will throw a validation error.
Any type that isn't in `doom-cli-option-arg-types` will be treated as a
wildcard string type. `num` can also be replaced with a specification,
e.g. "HOST[:PORT]", and can be formatted by using symbol quotes:
"`HOST'[:`PORT']".
- Feat: it is no longer required that options *immediately* follow the command
that defines them (but it must be somewhere after it, not before). E.g.
With:
(defcli! (:before doom foo) ((foo ("--foo"))) ...)
(defcli! (doom foo baz) () ...)
Before:
FAIL: doom --foo foo baz
GOOD: doom foo --foo baz
FAIL: doom foo baz --foo
After:
FAIL: doom --foo foo baz
GOOD: doom foo --foo baz
GOOD: doom foo baz --foo
- Refactor: CLI session state is now kept in a doom-cli-context struct (which
can be bound to a CLI-local variable with &context in the arglist):
(defcli! (doom sync) (&context context)
(print! "Command: " (doom-cli-context-command context)))
These contexts are persisted across sessions (when restarted). This is
necessary to support seamless script restarting (i.e. execve
emulation) in post-3.0.
- Feat: Doom's CLI framework now understands "--". Everything after it will be
treated as regular arguments, instead of sub-commands or options.
- Refactor!: the semantics of &rest for CLIs has changed. It used to be "all
extra literal, non-option arguments". It now means *all* unprocessed
arguments, and its use will suppress "unrecognized option" errors, and
tells the framework not to process any further subcommands. Use &args
if you just want "all literal arguments following this command".
- Feat: add new auxiliary keywords for CLI arglists: &context, &multiple,
&flags, &args, &stdin, &whole, and &cli.
- &context SYM: binds the currently running context to SYM (a
`doom-cli-context` struct). Helpful for introspection or passing
along state when calling subcommands by hand (with `call!`).
- &stdin SYM: SYM will be bound to a string containing any input piped
into the running script, or nil if none. Use
`doom-cli-context-pipe-p` to detect whether the script has been
piped into or out of.
- &multiple OPTIONS...: allows all following OPTIONS to be repeated. E.g. "foo
-x a -x b -x c" will pass (list ("-x" . "a") ("-x" . "b") ("-x" .
"c")) as -x's value.
- &flags OPTIONS...: All options after "&flags" get an implicit --no-* switch
and cannot accept arguments. Will be set to :yes or :no depending on which flag is
provided, and nil if the flag isn't provided. Otherwise, a default
value can be specified in that options' arglist. E.g.
(defcli! (doom foo) (&flags (foo ("--foo" :no))) ...)
When called, this command sets FOO to :yes if --foo, :no if --no-foo, and
defaults to :no otherwise.
- &args SYM: this replaces what &rest used to be; it binds to SYM a
list of all unprocessed (non-option) arguments.
- &rest SYM: now binds SYM to a list of all unprocessed arguments, including
options. This also suppresses "unrecognized option" errors, but will render
any sub-commands inaccessible. E.g.
(defcli! (doom make) (&rest rest) ...)
;; These are now inaccessible!
(defcli! (doom make foo) (&rest rest) ...)
(defcli! (doom make bar) (&rest rest) ...)
- &cli SYM: binds SYM to the currently running `doom-cli` struct. Can also be
obtained via `(doom-cli-get (doom-cli-context-command context))`. Possibly
useful for introspection.
- feat: add defobsolete! macro for quickly defining obsolete commands.
- feat: add defalias! macro for quickly defining alias commands.
- feat: add defautoload! macro for defining an autoloaded command (won't
be loaded until it is called for).
- refactor!: rename defcligroup! to defgroup! for consistency.
- fix: CLIs will now recursively inherit plist properties from parent
defcli-group!'s (but will stack :prefix).
- refactor!: remove obsolete 'doom update':
- refactor!: further generalize 'doom ci'
- In an effort to generalize 'doom ci' (so other Doom--or
non-doom--projects can use it), all its subcommands have been
changed to operate on the current working directory's repo instead
of $EMACSDIR.
- Doom-specific CI configuration was moved to .github/ci.el.
- All 'doom ci' commands will now preload one of \$CURRENT_REPO_ROOT/ci.el or
\$DOOMDIR/ci.el before executing.
- refactor!: changed 'doom env'
- 'doom env {-c,--clear}' is now 'doom env {clear,c}'
- -r/--reject and -a/--allow may now be specified multiple times
- refactor!: rewrote CLI help framework and error handling to be more
sophisticated and detailed.
- feat: can now initiate $PAGER on output with (exit! :pager) (or use
:pager? to only invoke pager is output is longer than the terminal is
tall).
- refactor!: changed semantics+conventions for global bin/doom options
- Single-character global options are now uppercased, to distinguish them from
local options:
- -d (for debug mode) is now -D
- -y (to suppress prompts) is now -!
- -l (to load elisp) is now -L
- -h (short for --help) is now -?
- Replace --yes/-y switches with --force/-!
- -L/--load FILE: now silently ignores file errors.
- Add --strict-load FILE: does the same as -L/--load, but throws an error if
FILE does not exist/is unreadable.
- Add -E/--eval FORM: evaluates arbitrary lisp before commands are processed.
- -L/--load, --strict-load, and -E/--eval can now be used multiple times in
one command.
- Add --pager COMMAND to specify an explicit pager. Will also obey
$DOOMPAGER envvar. Does not obey $PAGER.
- Fix #3746: which was likely caused by the generated post-script overwriting
the old mid-execution. By salting the postscript filenames (with both an
overarching session ID and a step counter).
- Docs: document websites, environment variables, and exit codes in
'doom --help'
- Feat: add imenu support for def{cli,alias,obsolete}!
Ref: #4273
Fix: #3746
Fix: #3844
2022-06-18 19:16:06 +02:00
|
|
|
(debugger . doom-debugger)
|
|
|
|
(doom-print-level . debug)
|
Backport bits of CLI rewrite
The rewrite for Doom's CLI is taking a while, so I've backported a few
important changes in order to ease the transition and fix a couple bugs
sooner.
Fixes #2802, #2737, #2386
The big highlights are:
- Fix #2802: We now update recipe repos *before* updating/installing any
new packages. No more "Could not find package X in recipe repositories".
- Fix #2737: An edge case where straight couldn't reach a pinned
commit (particularly with agda).
- Doom is now smarter about what option it recommends when straight
prompts you to make a choice.
- Introduces a new init path for Doom. The old way:
- Launch in "minimal" CLI mode in non-interactive sessions
- Launch a "full" interactive mode otherwise.
The new way
- Launch in "minimal" CLI mode *only* for bin/doom
- Launch is a simple mode for non-interactive sessions that still need
access to your interactive config (like async org export/babel).
- Launch a "full" interactive mode otherwise.
This should fix compatibility issues with plugins that use the
async.el library or spawn child Emacs processes to fake
parallelization (like org's async export and babel functionality).
- Your private init.el is now loaded more reliably when running any
bin/doom command. This gives you an opportunity to configure its
settings.
- Added doom-first-{input,buffer,file}-hook hooks, which we use to queue
deferred activation of a number of packages. Users can remove these
modes from these hooks; altogether preventing them from loading,
rather than waiting for them to load to then disable them,
e.g. (after! smartparens (smartparens-global-mode -1)) -> (remove-hook
'doom-first-buffer #'smartparens-global-mode)
Hooks added to doom-first-*-hook variables will be removed once they
run.
This should also indirectly fix #2386, by preventing interactive modes
from running in non-interactive session.
- Added `doom/bump-*` commands to make bumping modules and packages
easier, and `doom/bumpify-*` commands for converting package!
statements into user/repo@sha1hash format for bump commits.
- straight.el is now commit-pinned, like all other packages. We also
more reliably install straight.el by cloning it ourselves, rather than
relying on its bootstrap.el.
This should prevent infinite "straight has diverged from master"
prompts whenever we change branches (though, you might have to put up
with it one more after this update -- see #2937 for workaround).
All the other minor changes:
- Moved core/autoload/cli.el to core/autoload/process.el
- The package manager will log attempts to check out pinned commits
- If package state is incomplete while rebuilding packages, emit a
simpler error message instead of an obscure one!
- Added -u switch to 'doom sync' to make it run 'doom update' afterwards
- Added -p switch to 'doom sync' to make it run 'doom purge' afterwards
- Replace doom-modules function with doom-modules-list
- The `with-plist!` macro was removed, since `cl-destructuring-bind`
already serves that purpose well enough.
- core/autoload/packages.el was moved into core-packages.el
- bin/doom will no longer die if DOOMDIR or DOOMLOCALDIR don't have a
trailing slash
- Introduces doom-debug-variables; a list of variables to toggle on
doom/toggle-debug-mode.
- The sandbox has been updated to reflect the above changes, also:
1. Child instances will no longer inherit the process environment of
the host instance,
2. It will no longer produce an auto-save-list directory in ~/.emacs.d
2020-05-14 15:00:23 -04:00
|
|
|
garbage-collection-messages
|
|
|
|
gcmh-verbose
|
2020-08-21 00:09:59 -04:00
|
|
|
init-file-debug
|
|
|
|
jka-compr-verbose
|
2022-06-21 14:40:15 +02:00
|
|
|
(message-log-max . 16384)
|
2022-08-08 17:51:29 +02:00
|
|
|
(warning-suppress-types . nil)
|
2020-08-21 00:09:59 -04:00
|
|
|
url-debug
|
2022-06-21 14:40:15 +02:00
|
|
|
use-package-verbose)
|
2020-08-21 00:09:59 -04:00
|
|
|
"A list of variable to toggle on `doom-debug-mode'.
|
|
|
|
|
|
|
|
Each entry can be a variable symbol or a cons cell whose CAR is the variable
|
|
|
|
symbol and CDR is the value to set it to when `doom-debug-mode' is activated.")
|
|
|
|
|
2022-07-30 21:20:56 +02:00
|
|
|
(defvar doom-debug--undefined-vars nil)
|
2020-08-21 00:09:59 -04:00
|
|
|
|
2022-07-30 21:20:56 +02:00
|
|
|
(defun doom-debug--watch-vars-h (&rest _)
|
|
|
|
(when-let (bound-vars (cl-delete-if-not #'boundp doom-debug--undefined-vars))
|
2020-08-21 00:09:59 -04:00
|
|
|
(doom-log "New variables available: %s" bound-vars)
|
|
|
|
(let ((message-log-max nil))
|
|
|
|
(doom-debug-mode -1)
|
|
|
|
(doom-debug-mode +1))))
|
Backport bits of CLI rewrite
The rewrite for Doom's CLI is taking a while, so I've backported a few
important changes in order to ease the transition and fix a couple bugs
sooner.
Fixes #2802, #2737, #2386
The big highlights are:
- Fix #2802: We now update recipe repos *before* updating/installing any
new packages. No more "Could not find package X in recipe repositories".
- Fix #2737: An edge case where straight couldn't reach a pinned
commit (particularly with agda).
- Doom is now smarter about what option it recommends when straight
prompts you to make a choice.
- Introduces a new init path for Doom. The old way:
- Launch in "minimal" CLI mode in non-interactive sessions
- Launch a "full" interactive mode otherwise.
The new way
- Launch in "minimal" CLI mode *only* for bin/doom
- Launch is a simple mode for non-interactive sessions that still need
access to your interactive config (like async org export/babel).
- Launch a "full" interactive mode otherwise.
This should fix compatibility issues with plugins that use the
async.el library or spawn child Emacs processes to fake
parallelization (like org's async export and babel functionality).
- Your private init.el is now loaded more reliably when running any
bin/doom command. This gives you an opportunity to configure its
settings.
- Added doom-first-{input,buffer,file}-hook hooks, which we use to queue
deferred activation of a number of packages. Users can remove these
modes from these hooks; altogether preventing them from loading,
rather than waiting for them to load to then disable them,
e.g. (after! smartparens (smartparens-global-mode -1)) -> (remove-hook
'doom-first-buffer #'smartparens-global-mode)
Hooks added to doom-first-*-hook variables will be removed once they
run.
This should also indirectly fix #2386, by preventing interactive modes
from running in non-interactive session.
- Added `doom/bump-*` commands to make bumping modules and packages
easier, and `doom/bumpify-*` commands for converting package!
statements into user/repo@sha1hash format for bump commits.
- straight.el is now commit-pinned, like all other packages. We also
more reliably install straight.el by cloning it ourselves, rather than
relying on its bootstrap.el.
This should prevent infinite "straight has diverged from master"
prompts whenever we change branches (though, you might have to put up
with it one more after this update -- see #2937 for workaround).
All the other minor changes:
- Moved core/autoload/cli.el to core/autoload/process.el
- The package manager will log attempts to check out pinned commits
- If package state is incomplete while rebuilding packages, emit a
simpler error message instead of an obscure one!
- Added -u switch to 'doom sync' to make it run 'doom update' afterwards
- Added -p switch to 'doom sync' to make it run 'doom purge' afterwards
- Replace doom-modules function with doom-modules-list
- The `with-plist!` macro was removed, since `cl-destructuring-bind`
already serves that purpose well enough.
- core/autoload/packages.el was moved into core-packages.el
- bin/doom will no longer die if DOOMDIR or DOOMLOCALDIR don't have a
trailing slash
- Introduces doom-debug-variables; a list of variables to toggle on
doom/toggle-debug-mode.
- The sandbox has been updated to reflect the above changes, also:
1. Child instances will no longer inherit the process environment of
the host instance,
2. It will no longer produce an auto-save-list directory in ~/.emacs.d
2020-05-14 15:00:23 -04:00
|
|
|
|
|
|
|
;;;###autoload
|
2020-05-25 02:58:07 -04:00
|
|
|
(define-minor-mode doom-debug-mode
|
2022-06-24 21:15:31 +02:00
|
|
|
"Toggle `debug-on-error' and `init-file-debug' for verbose logging."
|
2022-07-30 21:20:56 +02:00
|
|
|
:init-value init-file-debug
|
2020-05-25 02:58:07 -04:00
|
|
|
:global t
|
2020-08-21 00:09:59 -04:00
|
|
|
(let ((enabled doom-debug-mode))
|
2022-07-30 21:20:56 +02:00
|
|
|
(setq doom-debug--undefined-vars nil)
|
2020-08-21 00:09:59 -04:00
|
|
|
(dolist (var doom-debug-variables)
|
|
|
|
(cond ((listp var)
|
2022-07-30 21:20:56 +02:00
|
|
|
(pcase-let ((`(,var . ,val) var))
|
2021-05-06 00:28:39 -04:00
|
|
|
(if (boundp var)
|
|
|
|
(set-default
|
|
|
|
var (if (not enabled)
|
|
|
|
(prog1 (get var 'initial-value)
|
2022-08-07 18:59:21 +02:00
|
|
|
(put var 'initial-value nil))
|
2021-05-06 00:28:39 -04:00
|
|
|
(put var 'initial-value (symbol-value var))
|
|
|
|
val))
|
2022-07-30 21:20:56 +02:00
|
|
|
(add-to-list 'doom-debug--undefined-vars var))))
|
2020-08-21 00:09:59 -04:00
|
|
|
((if (boundp var)
|
|
|
|
(set-default var enabled)
|
2022-07-30 21:20:56 +02:00
|
|
|
(add-to-list 'doom-debug--undefined-vars var)))))
|
2020-10-11 16:26:04 -04:00
|
|
|
(when (called-interactively-p 'any)
|
|
|
|
(when (fboundp 'explain-pause-mode)
|
|
|
|
(explain-pause-mode (if enabled +1 -1))))
|
2020-08-21 00:09:59 -04:00
|
|
|
;; Watch for changes in `doom-debug-variables', or when packages load (and
|
|
|
|
;; potentially define one of `doom-debug-variables'), in case some of them
|
|
|
|
;; aren't defined when `doom-debug-mode' is first loaded.
|
|
|
|
(cond (enabled
|
2022-06-21 14:41:21 +02:00
|
|
|
(message "Debug mode enabled! (Run 'M-x view-echo-area-messages' to open the log buffer)")
|
|
|
|
;; Produce more helpful (and visible) error messages from errors
|
|
|
|
;; emitted from hooks (particularly mode hooks), that usually go
|
|
|
|
;; unnoticed otherwise.
|
|
|
|
(advice-add #'run-hooks :override #'doom-run-hooks)
|
|
|
|
;; Add time stamps to lines in *Messages*
|
2022-03-20 23:46:11 +01:00
|
|
|
(advice-add #'message :before #'doom--timestamped-message-a)
|
2022-07-30 21:20:56 +02:00
|
|
|
(add-variable-watcher 'doom-debug-variables #'doom-debug--watch-vars-h)
|
|
|
|
(add-hook 'after-load-functions #'doom-debug--watch-vars-h))
|
2020-08-21 00:09:59 -04:00
|
|
|
(t
|
2022-06-21 14:41:21 +02:00
|
|
|
(advice-remove #'run-hooks #'doom-run-hooks)
|
2022-03-20 23:46:11 +01:00
|
|
|
(advice-remove #'message #'doom--timestamped-message-a)
|
2022-07-30 21:20:56 +02:00
|
|
|
(remove-variable-watcher 'doom-debug-variables #'doom-debug--watch-vars-h)
|
|
|
|
(remove-hook 'after-load-functions #'doom-debug--watch-vars-h)
|
2022-06-21 14:41:21 +02:00
|
|
|
(message "Debug mode disabled!")))))
|
Backport bits of CLI rewrite
The rewrite for Doom's CLI is taking a while, so I've backported a few
important changes in order to ease the transition and fix a couple bugs
sooner.
Fixes #2802, #2737, #2386
The big highlights are:
- Fix #2802: We now update recipe repos *before* updating/installing any
new packages. No more "Could not find package X in recipe repositories".
- Fix #2737: An edge case where straight couldn't reach a pinned
commit (particularly with agda).
- Doom is now smarter about what option it recommends when straight
prompts you to make a choice.
- Introduces a new init path for Doom. The old way:
- Launch in "minimal" CLI mode in non-interactive sessions
- Launch a "full" interactive mode otherwise.
The new way
- Launch in "minimal" CLI mode *only* for bin/doom
- Launch is a simple mode for non-interactive sessions that still need
access to your interactive config (like async org export/babel).
- Launch a "full" interactive mode otherwise.
This should fix compatibility issues with plugins that use the
async.el library or spawn child Emacs processes to fake
parallelization (like org's async export and babel functionality).
- Your private init.el is now loaded more reliably when running any
bin/doom command. This gives you an opportunity to configure its
settings.
- Added doom-first-{input,buffer,file}-hook hooks, which we use to queue
deferred activation of a number of packages. Users can remove these
modes from these hooks; altogether preventing them from loading,
rather than waiting for them to load to then disable them,
e.g. (after! smartparens (smartparens-global-mode -1)) -> (remove-hook
'doom-first-buffer #'smartparens-global-mode)
Hooks added to doom-first-*-hook variables will be removed once they
run.
This should also indirectly fix #2386, by preventing interactive modes
from running in non-interactive session.
- Added `doom/bump-*` commands to make bumping modules and packages
easier, and `doom/bumpify-*` commands for converting package!
statements into user/repo@sha1hash format for bump commits.
- straight.el is now commit-pinned, like all other packages. We also
more reliably install straight.el by cloning it ourselves, rather than
relying on its bootstrap.el.
This should prevent infinite "straight has diverged from master"
prompts whenever we change branches (though, you might have to put up
with it one more after this update -- see #2937 for workaround).
All the other minor changes:
- Moved core/autoload/cli.el to core/autoload/process.el
- The package manager will log attempts to check out pinned commits
- If package state is incomplete while rebuilding packages, emit a
simpler error message instead of an obscure one!
- Added -u switch to 'doom sync' to make it run 'doom update' afterwards
- Added -p switch to 'doom sync' to make it run 'doom purge' afterwards
- Replace doom-modules function with doom-modules-list
- The `with-plist!` macro was removed, since `cl-destructuring-bind`
already serves that purpose well enough.
- core/autoload/packages.el was moved into core-packages.el
- bin/doom will no longer die if DOOMDIR or DOOMLOCALDIR don't have a
trailing slash
- Introduces doom-debug-variables; a list of variables to toggle on
doom/toggle-debug-mode.
- The sandbox has been updated to reflect the above changes, also:
1. Child instances will no longer inherit the process environment of
the host instance,
2. It will no longer produce an auto-save-list directory in ~/.emacs.d
2020-05-14 15:00:23 -04:00
|
|
|
|
|
|
|
|
refactor!(cli): rewrite CLI framework libraries
BREAKING CHANGE: this changes Doom's CLI framework in subtle ways, which
is listed in greater detail below. If you've never extended Doom's CLI,
then this won't affect you, but otherwise it'd be recommended you read
on below.
This commit focuses on the CLI framework itself and backports some
foundational changes to its DSL and how it resolves command line
arguments to CLIs, validates input, displays documentation, and persists
state across sessions -- and more. This is done in preparation for the
final stretch towarding completing the CLI rewrite (see #4273).
This is also an effort to generalize Doom's CLI (both its framework and
bin/doom), to increase it versatility and make it a viable dev tool for
other Doom projects (on our Github org) and beyond.
However, there is a *lot* to cover so I'll try to be brief:
- Refactor: generalize Doom's CLI framework by moving all bin/doom
specific configuration/commands out of core-cli into bin/doom. This
makes it easier to use bin/doom as a project-agnostic development
tool (or for users to write their own).
- Refactor: change the namespace for CLI variables/functions from
doom-cli-X to doom-X.
- Fix: subcommands being mistaken as arguments. "doom make index" will
resolve to (defcli! (doom make index)) if it exists,
otherwise (defcli! (doom make)) with "index" as an argument. Before
this, it would resolve to the latter no matter what. &rest can
override this; with (defcli! (doom make) (&rest args)), (defcli! (doom
make index)) will never be invoked.
- Refactor!: redesign our output library (was core/autoload/output.el,
is now core/autoload/print.el), and how our CLI framework buffers and
logs output, and now merges logs across (exit! ...) restarts.
- Feat: add support for :before and :after pseudo commands. E.g.
(defcli! (:before doom help) () ...)
(defcli! (:after doom sync) () ...)
Caveat: unlike advice, only one of each can be defined per-command.
- Feat: option arguments now have rudimentary type validation (see
`doom-cli-option-arg-types`). E.g.
(defcli! (doom foo) ((foo ("--foo" num))) ...)
If NUM is not a numeric, it will throw a validation error.
Any type that isn't in `doom-cli-option-arg-types` will be treated as a
wildcard string type. `num` can also be replaced with a specification,
e.g. "HOST[:PORT]", and can be formatted by using symbol quotes:
"`HOST'[:`PORT']".
- Feat: it is no longer required that options *immediately* follow the command
that defines them (but it must be somewhere after it, not before). E.g.
With:
(defcli! (:before doom foo) ((foo ("--foo"))) ...)
(defcli! (doom foo baz) () ...)
Before:
FAIL: doom --foo foo baz
GOOD: doom foo --foo baz
FAIL: doom foo baz --foo
After:
FAIL: doom --foo foo baz
GOOD: doom foo --foo baz
GOOD: doom foo baz --foo
- Refactor: CLI session state is now kept in a doom-cli-context struct (which
can be bound to a CLI-local variable with &context in the arglist):
(defcli! (doom sync) (&context context)
(print! "Command: " (doom-cli-context-command context)))
These contexts are persisted across sessions (when restarted). This is
necessary to support seamless script restarting (i.e. execve
emulation) in post-3.0.
- Feat: Doom's CLI framework now understands "--". Everything after it will be
treated as regular arguments, instead of sub-commands or options.
- Refactor!: the semantics of &rest for CLIs has changed. It used to be "all
extra literal, non-option arguments". It now means *all* unprocessed
arguments, and its use will suppress "unrecognized option" errors, and
tells the framework not to process any further subcommands. Use &args
if you just want "all literal arguments following this command".
- Feat: add new auxiliary keywords for CLI arglists: &context, &multiple,
&flags, &args, &stdin, &whole, and &cli.
- &context SYM: binds the currently running context to SYM (a
`doom-cli-context` struct). Helpful for introspection or passing
along state when calling subcommands by hand (with `call!`).
- &stdin SYM: SYM will be bound to a string containing any input piped
into the running script, or nil if none. Use
`doom-cli-context-pipe-p` to detect whether the script has been
piped into or out of.
- &multiple OPTIONS...: allows all following OPTIONS to be repeated. E.g. "foo
-x a -x b -x c" will pass (list ("-x" . "a") ("-x" . "b") ("-x" .
"c")) as -x's value.
- &flags OPTIONS...: All options after "&flags" get an implicit --no-* switch
and cannot accept arguments. Will be set to :yes or :no depending on which flag is
provided, and nil if the flag isn't provided. Otherwise, a default
value can be specified in that options' arglist. E.g.
(defcli! (doom foo) (&flags (foo ("--foo" :no))) ...)
When called, this command sets FOO to :yes if --foo, :no if --no-foo, and
defaults to :no otherwise.
- &args SYM: this replaces what &rest used to be; it binds to SYM a
list of all unprocessed (non-option) arguments.
- &rest SYM: now binds SYM to a list of all unprocessed arguments, including
options. This also suppresses "unrecognized option" errors, but will render
any sub-commands inaccessible. E.g.
(defcli! (doom make) (&rest rest) ...)
;; These are now inaccessible!
(defcli! (doom make foo) (&rest rest) ...)
(defcli! (doom make bar) (&rest rest) ...)
- &cli SYM: binds SYM to the currently running `doom-cli` struct. Can also be
obtained via `(doom-cli-get (doom-cli-context-command context))`. Possibly
useful for introspection.
- feat: add defobsolete! macro for quickly defining obsolete commands.
- feat: add defalias! macro for quickly defining alias commands.
- feat: add defautoload! macro for defining an autoloaded command (won't
be loaded until it is called for).
- refactor!: rename defcligroup! to defgroup! for consistency.
- fix: CLIs will now recursively inherit plist properties from parent
defcli-group!'s (but will stack :prefix).
- refactor!: remove obsolete 'doom update':
- refactor!: further generalize 'doom ci'
- In an effort to generalize 'doom ci' (so other Doom--or
non-doom--projects can use it), all its subcommands have been
changed to operate on the current working directory's repo instead
of $EMACSDIR.
- Doom-specific CI configuration was moved to .github/ci.el.
- All 'doom ci' commands will now preload one of \$CURRENT_REPO_ROOT/ci.el or
\$DOOMDIR/ci.el before executing.
- refactor!: changed 'doom env'
- 'doom env {-c,--clear}' is now 'doom env {clear,c}'
- -r/--reject and -a/--allow may now be specified multiple times
- refactor!: rewrote CLI help framework and error handling to be more
sophisticated and detailed.
- feat: can now initiate $PAGER on output with (exit! :pager) (or use
:pager? to only invoke pager is output is longer than the terminal is
tall).
- refactor!: changed semantics+conventions for global bin/doom options
- Single-character global options are now uppercased, to distinguish them from
local options:
- -d (for debug mode) is now -D
- -y (to suppress prompts) is now -!
- -l (to load elisp) is now -L
- -h (short for --help) is now -?
- Replace --yes/-y switches with --force/-!
- -L/--load FILE: now silently ignores file errors.
- Add --strict-load FILE: does the same as -L/--load, but throws an error if
FILE does not exist/is unreadable.
- Add -E/--eval FORM: evaluates arbitrary lisp before commands are processed.
- -L/--load, --strict-load, and -E/--eval can now be used multiple times in
one command.
- Add --pager COMMAND to specify an explicit pager. Will also obey
$DOOMPAGER envvar. Does not obey $PAGER.
- Fix #3746: which was likely caused by the generated post-script overwriting
the old mid-execution. By salting the postscript filenames (with both an
overarching session ID and a step counter).
- Docs: document websites, environment variables, and exit codes in
'doom --help'
- Feat: add imenu support for def{cli,alias,obsolete}!
Ref: #4273
Fix: #3746
Fix: #3844
2022-06-18 19:16:06 +02:00
|
|
|
;;
|
|
|
|
;;; Custom debuggers
|
|
|
|
|
|
|
|
(autoload 'backtrace-get-frames "backtrace")
|
|
|
|
|
|
|
|
(defun doom-backtrace ()
|
|
|
|
"Return a stack trace as a list of `backtrace-frame' objects."
|
|
|
|
;; (let* ((n 0)
|
|
|
|
;; (frame (backtrace-frame n))
|
|
|
|
;; (frame-list nil)
|
|
|
|
;; (in-program-stack nil))
|
|
|
|
;; (while frame
|
|
|
|
;; (when in-program-stack
|
|
|
|
;; (push (cdr frame) frame-list))
|
|
|
|
;; (when (eq (elt frame 1) debugger)
|
|
|
|
;; (setq in-program-stack t))
|
|
|
|
;; ;; (when (and (eq (elt frame 1) 'doom-cli-execute)
|
|
|
|
;; ;; (eq (elt frame 2) :doom))
|
|
|
|
;; ;; (setq in-program-stack nil))
|
|
|
|
;; (setq n (1+ n)
|
|
|
|
;; frame (backtrace-frame n)))
|
|
|
|
;; (nreverse frame-list))
|
|
|
|
(cdr (backtrace-get-frames debugger)))
|
|
|
|
|
|
|
|
(defun doom-backtrace-write-to-file (backtrace file)
|
|
|
|
"Write BACKTRACE to FILE with appropriate boilerplate."
|
|
|
|
(make-directory (file-name-directory file) t)
|
|
|
|
(let ((doom-print-indent 0))
|
|
|
|
(with-temp-file file
|
|
|
|
(insert ";; -*- lisp-interaction -*-\n")
|
|
|
|
(insert ";; vim: set ft=lisp:\n")
|
|
|
|
(insert (format ";; command=%S\n" command-line-args))
|
|
|
|
(insert (format ";; date=%S\n\n" (format-time-string "%Y-%m-%d %H-%M-%S" before-init-time)))
|
|
|
|
(insert ";;;; ENVIRONMENT\n" (with-output-to-string (doom/version)) "\n")
|
|
|
|
(let ((standard-output (current-buffer))
|
|
|
|
(print-quoted t)
|
|
|
|
(print-escape-newlines t)
|
|
|
|
(print-escape-control-characters t)
|
|
|
|
(print-symbols-bare t)
|
|
|
|
(print-level nil)
|
|
|
|
(print-circle nil)
|
|
|
|
(n -1))
|
|
|
|
(mapc (lambda (frame)
|
|
|
|
(princ (format ";;;; %d\n" (cl-incf n)))
|
|
|
|
(pp (list (cons (backtrace-frame-fun frame)
|
|
|
|
(backtrace-frame-args frame))
|
|
|
|
(backtrace-frame-locals frame)))
|
|
|
|
(terpri))
|
|
|
|
backtrace))
|
|
|
|
file)))
|
|
|
|
|
|
|
|
(defun doom-debugger (&rest args)
|
|
|
|
"Enter `debugger' in interactive sessions, `doom-cli-debugger' otherwise.
|
|
|
|
|
|
|
|
Writes backtraces to file and ensures the backtrace is recorded, so the user can
|
|
|
|
always access it."
|
|
|
|
(let ((backtrace (doom-backtrace)))
|
|
|
|
;; Work around Emacs's heuristic (in eval.c) for detecting errors in the
|
|
|
|
;; debugger, which would run this handler again on subsequent calls. Taken
|
|
|
|
;; from `ert--run-test-debugger'.
|
|
|
|
(cl-incf num-nonmacro-input-events)
|
|
|
|
;; TODO Write backtraces to file
|
|
|
|
;; TODO Write backtrace to a buffer in case recursive error interupts the
|
|
|
|
;; debugger (happens more often than it should).
|
|
|
|
(apply #'debug args)))
|
|
|
|
|
|
|
|
|
2022-03-20 23:46:11 +01:00
|
|
|
;;
|
|
|
|
;;; Time-stamped *Message* logs
|
|
|
|
|
|
|
|
(defun doom--timestamped-message-a (format-string &rest args)
|
|
|
|
"Advice to run before `message' that prepends a timestamp to each message.
|
|
|
|
|
|
|
|
Activate this advice with:
|
|
|
|
(advice-add 'message :before 'doom--timestamped-message-a)"
|
|
|
|
(when (and (stringp format-string)
|
|
|
|
message-log-max
|
|
|
|
(not (string-equal format-string "%s%s")))
|
|
|
|
(with-current-buffer "*Messages*"
|
|
|
|
(let ((timestamp (format-time-string "[%F %T] " (current-time)))
|
|
|
|
(deactivate-mark nil))
|
|
|
|
(with-silent-modifications
|
|
|
|
(goto-char (point-max))
|
|
|
|
(if (not (bolp))
|
|
|
|
(newline))
|
|
|
|
(insert timestamp))))
|
|
|
|
(let ((window (get-buffer-window "*Messages*")))
|
|
|
|
(when (and window (not (equal (selected-window) window)))
|
|
|
|
(with-current-buffer "*Messages*"
|
|
|
|
(goto-char (point-max))
|
|
|
|
(set-window-point window (point-max)))))))
|
|
|
|
|
|
|
|
|
Backport bits of CLI rewrite
The rewrite for Doom's CLI is taking a while, so I've backported a few
important changes in order to ease the transition and fix a couple bugs
sooner.
Fixes #2802, #2737, #2386
The big highlights are:
- Fix #2802: We now update recipe repos *before* updating/installing any
new packages. No more "Could not find package X in recipe repositories".
- Fix #2737: An edge case where straight couldn't reach a pinned
commit (particularly with agda).
- Doom is now smarter about what option it recommends when straight
prompts you to make a choice.
- Introduces a new init path for Doom. The old way:
- Launch in "minimal" CLI mode in non-interactive sessions
- Launch a "full" interactive mode otherwise.
The new way
- Launch in "minimal" CLI mode *only* for bin/doom
- Launch is a simple mode for non-interactive sessions that still need
access to your interactive config (like async org export/babel).
- Launch a "full" interactive mode otherwise.
This should fix compatibility issues with plugins that use the
async.el library or spawn child Emacs processes to fake
parallelization (like org's async export and babel functionality).
- Your private init.el is now loaded more reliably when running any
bin/doom command. This gives you an opportunity to configure its
settings.
- Added doom-first-{input,buffer,file}-hook hooks, which we use to queue
deferred activation of a number of packages. Users can remove these
modes from these hooks; altogether preventing them from loading,
rather than waiting for them to load to then disable them,
e.g. (after! smartparens (smartparens-global-mode -1)) -> (remove-hook
'doom-first-buffer #'smartparens-global-mode)
Hooks added to doom-first-*-hook variables will be removed once they
run.
This should also indirectly fix #2386, by preventing interactive modes
from running in non-interactive session.
- Added `doom/bump-*` commands to make bumping modules and packages
easier, and `doom/bumpify-*` commands for converting package!
statements into user/repo@sha1hash format for bump commits.
- straight.el is now commit-pinned, like all other packages. We also
more reliably install straight.el by cloning it ourselves, rather than
relying on its bootstrap.el.
This should prevent infinite "straight has diverged from master"
prompts whenever we change branches (though, you might have to put up
with it one more after this update -- see #2937 for workaround).
All the other minor changes:
- Moved core/autoload/cli.el to core/autoload/process.el
- The package manager will log attempts to check out pinned commits
- If package state is incomplete while rebuilding packages, emit a
simpler error message instead of an obscure one!
- Added -u switch to 'doom sync' to make it run 'doom update' afterwards
- Added -p switch to 'doom sync' to make it run 'doom purge' afterwards
- Replace doom-modules function with doom-modules-list
- The `with-plist!` macro was removed, since `cl-destructuring-bind`
already serves that purpose well enough.
- core/autoload/packages.el was moved into core-packages.el
- bin/doom will no longer die if DOOMDIR or DOOMLOCALDIR don't have a
trailing slash
- Introduces doom-debug-variables; a list of variables to toggle on
doom/toggle-debug-mode.
- The sandbox has been updated to reflect the above changes, also:
1. Child instances will no longer inherit the process environment of
the host instance,
2. It will no longer produce an auto-save-list directory in ~/.emacs.d
2020-05-14 15:00:23 -04:00
|
|
|
;;
|
|
|
|
;;; Hooks
|
|
|
|
|
2019-07-28 02:31:52 +02:00
|
|
|
;;;###autoload
|
|
|
|
(defun doom-run-all-startup-hooks-h ()
|
|
|
|
"Run all startup Emacs hooks. Meant to be executed after starting Emacs with
|
|
|
|
-q or -Q, for example:
|
|
|
|
|
|
|
|
emacs -Q -l init.el -f doom-run-all-startup-hooks-h"
|
|
|
|
(setq after-init-time (current-time))
|
2020-12-01 16:47:13 -05:00
|
|
|
(let ((inhibit-startup-hooks nil))
|
2021-05-05 16:12:35 -04:00
|
|
|
(doom-run-hooks 'after-init-hook
|
|
|
|
'delayed-warnings-hook
|
|
|
|
'emacs-startup-hook
|
|
|
|
'tty-setup-hook
|
|
|
|
'window-setup-hook)))
|
2019-07-28 02:31:52 +02:00
|
|
|
|
|
|
|
|
2019-04-23 20:58:19 -04:00
|
|
|
;;
|
|
|
|
;;; Helpers
|
|
|
|
|
2020-03-03 16:15:43 -05:00
|
|
|
(defsubst doom--collect-forms-in (file form)
|
2020-01-28 17:54:51 -05:00
|
|
|
(when (file-readable-p file)
|
|
|
|
(let (forms)
|
|
|
|
(with-temp-buffer
|
|
|
|
(insert-file-contents file)
|
2022-06-18 15:26:22 +02:00
|
|
|
(with-syntax-table emacs-lisp-mode-syntax-table
|
|
|
|
(while (re-search-forward (format "(%s " (regexp-quote form)) nil t)
|
|
|
|
(let ((ppss (syntax-ppss)))
|
|
|
|
(unless (or (nth 4 ppss)
|
|
|
|
(nth 3 ppss))
|
|
|
|
(save-excursion
|
|
|
|
(goto-char (match-beginning 0))
|
|
|
|
(push (sexp-at-point) forms))))))
|
2020-01-28 17:54:51 -05:00
|
|
|
(nreverse forms)))))
|
|
|
|
|
2018-02-10 17:27:02 -05:00
|
|
|
;;;###autoload
|
|
|
|
(defun doom-info ()
|
|
|
|
"Returns diagnostic information about the current Emacs session in markdown,
|
|
|
|
ready to be pasted in a bug report on github."
|
|
|
|
(require 'vc-git)
|
2022-07-30 21:49:00 +02:00
|
|
|
(require 'doom-packages)
|
2020-08-24 00:15:26 -04:00
|
|
|
(let ((default-directory doom-emacs-dir))
|
|
|
|
(letf! ((defun sh (&rest args) (cdr (apply #'doom-call-process args)))
|
2021-02-11 15:43:06 -05:00
|
|
|
(defun cat (file &optional limit)
|
|
|
|
(with-temp-buffer
|
|
|
|
(insert-file-contents file nil 0 limit)
|
|
|
|
(buffer-string)))
|
2020-08-24 00:15:26 -04:00
|
|
|
(defun abbrev-path (path)
|
|
|
|
(replace-regexp-in-string
|
2021-02-11 15:43:06 -05:00
|
|
|
(regexp-opt (list (user-login-name)) 'words) "$USER"
|
|
|
|
(abbreviate-file-name path)))
|
|
|
|
(defun symlink-path (file)
|
2021-04-17 18:08:01 -04:00
|
|
|
(format "%s%s" (abbrev-path file)
|
|
|
|
(if (file-symlink-p file) ""
|
|
|
|
(concat " -> " (abbrev-path (file-truename file)))))))
|
2021-03-07 00:03:04 -05:00
|
|
|
`((generated . ,(format-time-string "%b %d, %Y %H:%M:%S"))
|
2021-05-06 00:32:38 -04:00
|
|
|
(system . ,(delq
|
|
|
|
nil (list (doom-system-distro-version)
|
2021-05-10 04:46:14 -04:00
|
|
|
(when (executable-find "uname")
|
|
|
|
(sh "uname" "-msr"))
|
2021-05-06 00:32:38 -04:00
|
|
|
(window-system))))
|
2021-03-07 00:03:04 -05:00
|
|
|
(emacs . ,(delq
|
|
|
|
nil (list emacs-version
|
2021-04-29 16:51:49 -04:00
|
|
|
(bound-and-true-p emacs-repository-branch)
|
2021-03-08 10:18:49 -05:00
|
|
|
(and (stringp emacs-repository-version)
|
|
|
|
(substring emacs-repository-version 0 9))
|
2021-03-07 00:03:04 -05:00
|
|
|
(symlink-path doom-emacs-dir))))
|
|
|
|
(doom . ,(list doom-version
|
|
|
|
(sh "git" "log" "-1" "--format=%D %h %ci")
|
2022-08-13 21:27:11 +02:00
|
|
|
(symlink-path doom-user-dir)))
|
2021-03-07 00:03:04 -05:00
|
|
|
(shell . ,(abbrev-path shell-file-name))
|
|
|
|
(features . ,system-configuration-features)
|
|
|
|
(traits
|
|
|
|
. ,(mapcar
|
|
|
|
#'symbol-name
|
|
|
|
(delq
|
2022-06-24 21:15:31 +02:00
|
|
|
nil (list (cond (noninteractive 'batch)
|
2021-02-11 15:43:06 -05:00
|
|
|
((display-graphic-p) 'gui)
|
|
|
|
('tty))
|
|
|
|
(if (daemonp) 'daemon)
|
|
|
|
(if (and (require 'server)
|
|
|
|
(server-running-p))
|
|
|
|
'server-running)
|
2022-07-30 21:22:05 +02:00
|
|
|
(if (boundp 'chemacs-version)
|
|
|
|
(intern (format "chemacs-%s" chemacs-version)))
|
2021-02-11 15:43:06 -05:00
|
|
|
(if (file-exists-p doom-env-file)
|
|
|
|
'envvar-file)
|
|
|
|
(if (featurep 'exec-path-from-shell)
|
|
|
|
'exec-path-from-shell)
|
2022-07-04 02:34:51 +02:00
|
|
|
(if (file-symlink-p doom-emacs-dir)
|
2021-02-11 15:43:06 -05:00
|
|
|
'symlinked-emacsdir)
|
2022-08-13 21:27:11 +02:00
|
|
|
(if (file-symlink-p doom-user-dir)
|
2021-02-11 15:43:06 -05:00
|
|
|
'symlinked-doomdir)
|
2021-04-17 18:07:19 -04:00
|
|
|
(if (and (stringp custom-file) (file-exists-p custom-file))
|
|
|
|
'custom-file)
|
2021-02-11 15:43:06 -05:00
|
|
|
(if (doom-files-in `(,@doom-modules-dirs
|
|
|
|
,doom-core-dir
|
2022-08-13 21:27:11 +02:00
|
|
|
,doom-user-dir)
|
2021-02-11 15:43:06 -05:00
|
|
|
:type 'files :match "\\.elc$")
|
|
|
|
'byte-compiled-config)))))
|
2021-04-17 18:07:19 -04:00
|
|
|
(custom
|
|
|
|
,@(when (and (stringp custom-file)
|
|
|
|
(file-exists-p custom-file))
|
|
|
|
(cl-loop for (type var _) in (get 'user 'theme-settings)
|
|
|
|
if (eq type 'theme-value)
|
|
|
|
collect var)))
|
2021-03-07 00:03:04 -05:00
|
|
|
(modules
|
|
|
|
,@(or (cl-loop with cat = nil
|
|
|
|
for key being the hash-keys of doom-modules
|
|
|
|
if (or (not cat)
|
|
|
|
(not (eq cat (car key))))
|
|
|
|
do (setq cat (car key))
|
|
|
|
and collect cat
|
|
|
|
collect
|
|
|
|
(let* ((flags (doom-module-get cat (cdr key) :flags))
|
|
|
|
(path (doom-module-get cat (cdr key) :path))
|
2022-02-09 22:23:39 +01:00
|
|
|
(module
|
|
|
|
(append
|
|
|
|
(cond ((null path)
|
|
|
|
(list '&nopath))
|
|
|
|
((not (file-in-directory-p path doom-modules-dir))
|
|
|
|
(list '&user)))
|
|
|
|
(if flags
|
|
|
|
`(,(cdr key) ,@flags)
|
|
|
|
(list (cdr key))))))
|
2021-03-07 00:03:04 -05:00
|
|
|
(if (= (length module) 1)
|
|
|
|
(car module)
|
|
|
|
module)))
|
|
|
|
'("n/a")))
|
|
|
|
(packages
|
2021-03-27 18:08:56 -04:00
|
|
|
,@(condition-case e
|
|
|
|
(mapcar
|
|
|
|
#'cdr (doom--collect-forms-in
|
2022-08-13 21:27:11 +02:00
|
|
|
(doom-path doom-user-dir "packages.el")
|
2021-03-27 18:08:56 -04:00
|
|
|
"package!"))
|
|
|
|
(error (format "<%S>" e))))
|
|
|
|
(unpin
|
|
|
|
,@(condition-case e
|
|
|
|
(mapcan #'identity
|
|
|
|
(mapcar
|
|
|
|
#'cdr (doom--collect-forms-in
|
2022-08-13 21:27:11 +02:00
|
|
|
(doom-path doom-user-dir "packages.el")
|
2021-03-27 18:08:56 -04:00
|
|
|
"unpin!")))
|
|
|
|
(error (list (format "<%S>" e)))))
|
2021-03-07 00:03:04 -05:00
|
|
|
(elpa
|
2021-03-27 18:08:56 -04:00
|
|
|
,@(condition-case e
|
|
|
|
(progn
|
2022-06-21 14:41:21 +02:00
|
|
|
(unless (bound-and-true-p package--initialized)
|
|
|
|
(package-initialize))
|
2021-03-27 18:08:56 -04:00
|
|
|
(cl-loop for (name . _) in package-alist
|
|
|
|
collect (format "%s" name)))
|
|
|
|
(error (format "<%S>" e))))))))
|
2018-05-20 12:13:05 +02:00
|
|
|
|
2022-06-19 01:31:56 +02:00
|
|
|
;;;###autoload
|
|
|
|
(defun doom-info-string (&optional width nocolor)
|
|
|
|
"Return the `doom-info' as a compact string.
|
|
|
|
|
|
|
|
FILL-COLUMN determines the column at which lines will be broken."
|
|
|
|
(with-temp-buffer
|
|
|
|
(let ((doom-print-backend (unless nocolor doom-print-backend))
|
|
|
|
(doom-print-indent 0))
|
|
|
|
(dolist (spec (cl-remove-if-not #'cdr (doom-info)) (buffer-string))
|
|
|
|
;; FIXME Refactor this horrible cludge, either here or in `format!'
|
|
|
|
(insert! ((bold "%-10s ") (symbol-name (car spec)))
|
|
|
|
("%s\n"
|
|
|
|
(string-trim-left
|
|
|
|
(indent
|
|
|
|
(fill
|
|
|
|
(if (listp (cdr spec))
|
|
|
|
(mapconcat (doom-partial #'format "%s")
|
|
|
|
(cdr spec)
|
|
|
|
" ")
|
|
|
|
(cdr spec))
|
|
|
|
(- (or width 80) 11))
|
|
|
|
11))))))))
|
|
|
|
|
2018-05-20 12:13:05 +02:00
|
|
|
|
|
|
|
;;
|
2019-04-23 20:58:19 -04:00
|
|
|
;;; Commands
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom/version ()
|
2022-01-23 22:48:34 +01:00
|
|
|
"Display the running version of Doom core, module sources, and Emacs."
|
2019-04-23 20:58:19 -04:00
|
|
|
(interactive)
|
2022-06-19 01:31:32 +02:00
|
|
|
(print! "%s\n%s\n%s"
|
|
|
|
(format "%-13s v%-15s %s"
|
|
|
|
"GNU Emacs"
|
|
|
|
emacs-version
|
|
|
|
emacs-repository-version)
|
|
|
|
(format "%-13s v%-15s %s"
|
|
|
|
"Doom core"
|
|
|
|
doom-version
|
|
|
|
(or (cdr (doom-call-process
|
|
|
|
"git" "-C" doom-emacs-dir
|
|
|
|
"log" "-1" "--format=%D %h %ci"))
|
|
|
|
"n/a"))
|
|
|
|
;; NOTE This is a placeholder. Our modules will be moved to its own
|
|
|
|
;; repo eventually, and Doom core will later be capable of managing
|
|
|
|
;; them like package sources.
|
|
|
|
(format "%-13s v%-15s %s"
|
|
|
|
"Doom modules"
|
|
|
|
doom-modules-version
|
|
|
|
(or (cdr (doom-call-process
|
|
|
|
"git" "-C" doom-modules-dir
|
|
|
|
"log" "-1" "--format=%D %h %ci"))
|
|
|
|
"n/a"))))
|
2018-02-10 17:27:02 -05:00
|
|
|
|
2017-12-31 17:49:27 -05:00
|
|
|
;;;###autoload
|
2022-03-22 04:47:03 +01:00
|
|
|
(defun doom/info ()
|
2020-10-20 23:21:11 -04:00
|
|
|
"Collects some debug information about your Emacs session, formats it and
|
|
|
|
copies it to your clipboard, ready to be pasted into bug reports!"
|
2022-03-31 19:28:34 +02:00
|
|
|
(interactive)
|
|
|
|
(let ((buffer (get-buffer-create "*doom info*")))
|
|
|
|
(with-current-buffer buffer
|
|
|
|
(setq buffer-read-only t)
|
|
|
|
(with-silent-modifications
|
|
|
|
(erase-buffer)
|
2022-06-19 01:31:56 +02:00
|
|
|
(insert (doom-info-string 86)))
|
2022-03-31 19:28:34 +02:00
|
|
|
(pop-to-buffer buffer)
|
|
|
|
(kill-new (buffer-string))
|
|
|
|
(when (y-or-n-p "Your doom-info was copied to the clipboard.\n\nOpen pastebin.com?")
|
|
|
|
(browse-url "https://pastebin.com")))))
|
2020-11-04 19:41:48 -05:00
|
|
|
|
2018-05-20 12:13:59 +02:00
|
|
|
|
2019-04-23 20:58:19 -04:00
|
|
|
;;
|
2018-09-07 19:36:16 -04:00
|
|
|
;;; Profiling
|
2018-05-20 12:13:05 +02:00
|
|
|
|
|
|
|
(defvar doom--profiler nil)
|
|
|
|
;;;###autoload
|
2018-05-24 16:40:37 +02:00
|
|
|
(defun doom/toggle-profiler ()
|
2018-05-20 12:13:05 +02:00
|
|
|
"Toggle the Emacs profiler. Run it again to see the profiling report."
|
|
|
|
(interactive)
|
|
|
|
(if (not doom--profiler)
|
|
|
|
(profiler-start 'cpu+mem)
|
|
|
|
(profiler-report)
|
|
|
|
(profiler-stop))
|
|
|
|
(setq doom--profiler (not doom--profiler)))
|