2017-06-08 11:47:56 +02:00
|
|
|
;;; lang/emacs-lisp/autoload.el -*- lexical-binding: t; -*-
|
2017-01-16 23:30:11 -05:00
|
|
|
|
2018-05-25 00:46:11 +02:00
|
|
|
;;
|
2019-05-01 19:12:52 -04:00
|
|
|
;;; Library
|
2018-05-25 00:46:11 +02:00
|
|
|
|
2017-05-07 02:27:54 +02:00
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp-eval (beg end)
|
|
|
|
"Evaluate a region and print it to the echo area (if one line long), otherwise
|
|
|
|
to a pop up buffer."
|
2019-10-26 01:37:36 -04:00
|
|
|
(+eval-display-results
|
2019-11-24 19:40:00 -05:00
|
|
|
(string-trim-right
|
2022-06-18 18:10:51 +02:00
|
|
|
(let ((buffer (generate-new-buffer " *+eval-output*"))
|
|
|
|
(debug-on-error t))
|
|
|
|
(unwind-protect
|
|
|
|
(condition-case-unless-debug e
|
|
|
|
(let ((doom--current-module (ignore-errors (doom-module-from-path buffer-file-name))))
|
|
|
|
(eval-region beg end buffer load-read-function)
|
|
|
|
(with-current-buffer buffer
|
|
|
|
(let ((pp-max-width nil))
|
|
|
|
(require 'pp)
|
|
|
|
(pp-buffer)
|
|
|
|
(replace-regexp-in-string "\\\\n" "\n" (string-trim-left (buffer-string))))))
|
|
|
|
(error (format "ERROR: %s" e)))
|
|
|
|
(kill-buffer buffer))))
|
2019-10-26 01:37:36 -04:00
|
|
|
(current-buffer)))
|
2018-08-21 00:04:48 +02:00
|
|
|
|
2019-12-25 22:54:15 -05:00
|
|
|
|
2020-05-10 18:45:40 -04:00
|
|
|
;;
|
|
|
|
;;; Handlers
|
|
|
|
|
2019-12-25 22:54:15 -05:00
|
|
|
(defun +emacs-lisp--module-at-point ()
|
2021-04-26 00:24:39 +02:00
|
|
|
"Return (CATEGORY MODULE FLAG) at point inside a `doom!' block."
|
|
|
|
(let ((origin (point))
|
|
|
|
(syntax (syntax-ppss)))
|
|
|
|
(when (and (> (ppss-depth syntax) 0) (not (ppss-string-terminator syntax)))
|
|
|
|
(save-excursion
|
|
|
|
(let ((parens (ppss-open-parens syntax))
|
|
|
|
(doom-depth 1))
|
|
|
|
(while (and parens (progn (goto-char (car parens))
|
|
|
|
(not (looking-at "(doom!\\_>"))))
|
|
|
|
(setq parens (cdr parens)
|
|
|
|
doom-depth (1+ doom-depth)))
|
|
|
|
(when parens ;; Are we inside a `doom!' block?
|
2019-12-25 22:54:15 -05:00
|
|
|
(goto-char origin)
|
2021-04-26 00:24:39 +02:00
|
|
|
(let* ((doom-start (car parens))
|
|
|
|
(bare-symbol
|
|
|
|
(if (ppss-comment-depth syntax)
|
|
|
|
(= (save-excursion (beginning-of-thing 'list)) doom-start)
|
|
|
|
(null (cdr parens))))
|
|
|
|
(sexp-start (if bare-symbol
|
|
|
|
(beginning-of-thing 'symbol)
|
|
|
|
(or (cadr parens) (beginning-of-thing 'list))))
|
|
|
|
(match-start nil))
|
|
|
|
(goto-char sexp-start)
|
|
|
|
(while (and (not match-start)
|
|
|
|
(re-search-backward
|
|
|
|
"\\_<:\\(?:\\sw\\|\\s_\\)+\\_>" ;; Find a keyword.
|
|
|
|
doom-start 'noerror))
|
|
|
|
(unless (looking-back "(")
|
|
|
|
(let ((kw-syntax (syntax-ppss)))
|
|
|
|
(when (and (= (ppss-depth kw-syntax) doom-depth)
|
|
|
|
(not (ppss-string-terminator kw-syntax))
|
|
|
|
(not (ppss-comment-depth kw-syntax)))
|
|
|
|
(setq match-start (point))))))
|
|
|
|
(when match-start
|
|
|
|
(let (category module flag)
|
|
|
|
;; `point' is already at `match-start'.
|
|
|
|
(setq category (symbol-at-point))
|
|
|
|
(goto-char origin)
|
|
|
|
(if bare-symbol
|
|
|
|
(setq module (symbol-at-point))
|
|
|
|
(let ((symbol (symbol-at-point))
|
|
|
|
(head (car (list-at-point))))
|
|
|
|
(if (and (symbolp head) (not (keywordp head))
|
|
|
|
(not (eq head symbol)))
|
|
|
|
(setq module head
|
|
|
|
flag symbol)
|
|
|
|
(setq module symbol))))
|
|
|
|
(list category module flag))))))))))
|
2019-12-25 22:54:15 -05:00
|
|
|
|
|
|
|
;;;###autoload
|
2020-02-06 15:30:50 -05:00
|
|
|
(defun +emacs-lisp-lookup-definition (_thing)
|
2019-12-25 22:54:15 -05:00
|
|
|
"Lookup definition of THING."
|
|
|
|
(if-let (module (+emacs-lisp--module-at-point))
|
2021-02-26 22:06:41 +01:00
|
|
|
(doom/help-modules (car module) (cadr module) 'visit-dir)
|
2019-12-25 22:54:15 -05:00
|
|
|
(call-interactively #'elisp-def)))
|
|
|
|
|
2019-05-01 19:14:43 -04:00
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp-lookup-documentation (thing)
|
|
|
|
"Lookup THING with `helpful-variable' if it's a variable, `helpful-callable'
|
|
|
|
if it's callable, `apropos' otherwise."
|
2019-12-27 04:44:20 -05:00
|
|
|
(cond ((when-let (module (+emacs-lisp--module-at-point))
|
2019-12-25 22:54:15 -05:00
|
|
|
(doom/help-modules (car module) (cadr module))
|
|
|
|
(when (eq major-mode 'org-mode)
|
|
|
|
(with-demoted-errors "%s"
|
|
|
|
(re-search-forward
|
|
|
|
(if (caddr module)
|
2021-10-12 21:26:05 +02:00
|
|
|
"\\* Module flags$"
|
2019-12-25 22:54:15 -05:00
|
|
|
"\\* Description$"))
|
|
|
|
(when (caddr module)
|
|
|
|
(re-search-forward (format "=\\%s=" (caddr module))
|
|
|
|
nil t))
|
|
|
|
(when (invisible-p (point))
|
|
|
|
(org-show-hidden-entry))))
|
2020-01-12 22:35:03 -05:00
|
|
|
'deferred))
|
2020-01-11 17:21:35 -05:00
|
|
|
(thing (helpful-symbol (intern thing)))
|
|
|
|
((call-interactively #'helpful-at-point))))
|
2019-12-25 22:54:15 -05:00
|
|
|
|
2022-06-18 16:36:28 +02:00
|
|
|
;; DEPRECATED Remove when 28 support is dropped.
|
|
|
|
(unless (fboundp 'lisp--local-defform-body-p)
|
|
|
|
(fset 'lisp--local-defform-body-p #'ignore))
|
|
|
|
|
2020-05-10 18:45:40 -04:00
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp-indent-function (indent-point state)
|
|
|
|
"A replacement for `lisp-indent-function'.
|
|
|
|
|
|
|
|
Indents plists more sensibly. Adapted from
|
|
|
|
https://emacs.stackexchange.com/questions/10230/how-to-indent-keywords-aligned"
|
|
|
|
(let ((normal-indent (current-column))
|
|
|
|
(orig-point (point))
|
|
|
|
;; TODO Refactor `target' usage (ew!)
|
|
|
|
target)
|
|
|
|
(goto-char (1+ (elt state 1)))
|
|
|
|
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
|
|
|
|
(cond ((and (elt state 2)
|
2022-06-17 21:58:05 +02:00
|
|
|
(or (eq (char-after) ?:)
|
|
|
|
(not (looking-at-p "\\sw\\|\\s_"))))
|
|
|
|
(if (lisp--local-defform-body-p state)
|
|
|
|
(lisp-indent-defform state indent-point)
|
|
|
|
(unless (> (save-excursion (forward-line 1) (point))
|
|
|
|
calculate-lisp-indent-last-sexp)
|
|
|
|
(goto-char calculate-lisp-indent-last-sexp)
|
|
|
|
(beginning-of-line)
|
|
|
|
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t))
|
|
|
|
(backward-prefix-chars)
|
|
|
|
(current-column)))
|
2020-05-10 18:45:40 -04:00
|
|
|
((and (save-excursion
|
|
|
|
(goto-char indent-point)
|
|
|
|
(skip-syntax-forward " ")
|
|
|
|
(not (eq (char-after) ?:)))
|
|
|
|
(save-excursion
|
|
|
|
(goto-char orig-point)
|
|
|
|
(and (eq (char-after) ?:)
|
|
|
|
(eq (char-before) ?\()
|
|
|
|
(setq target (current-column)))))
|
|
|
|
(save-excursion
|
|
|
|
(move-to-column target t)
|
|
|
|
target))
|
|
|
|
((let* ((function (buffer-substring (point) (progn (forward-sexp 1) (point))))
|
|
|
|
(method (or (function-get (intern-soft function) 'lisp-indent-function)
|
|
|
|
(get (intern-soft function) 'lisp-indent-hook))))
|
|
|
|
(cond ((or (eq method 'defun)
|
|
|
|
(and (null method)
|
|
|
|
(> (length function) 3)
|
|
|
|
(string-match-p "\\`def" function)))
|
|
|
|
(lisp-indent-defform state indent-point))
|
|
|
|
((integerp method)
|
|
|
|
(lisp-indent-specform method state indent-point normal-indent))
|
|
|
|
(method
|
|
|
|
(funcall method indent-point state))))))))
|
2019-05-01 19:14:43 -04:00
|
|
|
|
2018-08-21 00:04:48 +02:00
|
|
|
|
|
|
|
;;
|
2019-05-01 19:12:52 -04:00
|
|
|
;;; Commands
|
2018-08-21 00:04:48 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
2019-02-18 01:56:38 -05:00
|
|
|
(defun +emacs-lisp/open-repl ()
|
2018-08-21 00:04:48 +02:00
|
|
|
"Open the Emacs Lisp REPL (`ielm')."
|
|
|
|
(interactive)
|
|
|
|
(pop-to-buffer
|
|
|
|
(or (get-buffer "*ielm*")
|
|
|
|
(progn (ielm)
|
|
|
|
(let ((buf (get-buffer "*ielm*")))
|
|
|
|
(bury-buffer buf)
|
|
|
|
buf)))))
|
2019-07-25 12:56:34 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp/buttercup-run-file ()
|
|
|
|
"Run all buttercup tests in the focused buffer."
|
|
|
|
(interactive)
|
2021-05-23 21:48:38 -04:00
|
|
|
(let ((load-path
|
|
|
|
(append (list (doom-path (dir!) "..")
|
|
|
|
(or (doom-project-root)
|
|
|
|
default-directory))
|
|
|
|
load-path))
|
|
|
|
(buttercup-suites nil))
|
2019-07-25 12:56:34 +02:00
|
|
|
(save-selected-window
|
|
|
|
(eval-buffer)
|
|
|
|
(buttercup-run))
|
|
|
|
(message "File executed successfully")))
|
2019-07-27 11:33:41 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp/buttercup-run-project ()
|
|
|
|
"Run all buttercup tests in the project."
|
|
|
|
(interactive)
|
|
|
|
(let* ((default-directory (doom-project-root))
|
|
|
|
(load-path (append (list (doom-path "test")
|
|
|
|
default-directory)
|
2021-05-23 21:48:38 -04:00
|
|
|
load-path))
|
|
|
|
(buttercup-suites nil))
|
2019-07-27 11:33:41 +02:00
|
|
|
(buttercup-run-discover)))
|
2018-08-21 00:04:48 +02:00
|
|
|
|
2020-05-10 18:45:40 -04:00
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp/edebug-instrument-defun-on ()
|
|
|
|
"Toggle on instrumentalisation for the function under `defun'."
|
|
|
|
(interactive)
|
|
|
|
(eval-defun 'edebugit))
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp/edebug-instrument-defun-off ()
|
|
|
|
"Toggle off instrumentalisation for the function under `defun'."
|
|
|
|
(interactive)
|
|
|
|
(eval-defun nil))
|
|
|
|
|
2018-08-21 00:04:48 +02:00
|
|
|
|
|
|
|
;;
|
2019-05-01 19:12:52 -04:00
|
|
|
;;; Hooks
|
2018-08-21 00:04:48 +02:00
|
|
|
|
2020-05-25 02:29:30 -04:00
|
|
|
(autoload 'straight-register-file-modification "straight")
|
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp-init-straight-maybe-h ()
|
|
|
|
"Make sure straight sees modifications to installed packages."
|
|
|
|
(when (file-in-directory-p (or buffer-file-name default-directory) doom-local-dir)
|
|
|
|
(add-hook 'after-save-hook #'straight-register-file-modification
|
|
|
|
nil 'local)))
|
|
|
|
|
2018-08-21 00:04:48 +02:00
|
|
|
;;;###autoload
|
2019-07-18 15:27:20 +02:00
|
|
|
(defun +emacs-lisp-extend-imenu-h ()
|
2019-05-01 19:13:44 -04:00
|
|
|
"Improve imenu support in `emacs-lisp-mode', including recognition for Doom's API."
|
2018-08-21 00:04:48 +02:00
|
|
|
(setq imenu-generic-expression
|
2019-06-16 14:36:10 +02:00
|
|
|
`(("Section" "^[ \t]*;;;;*[ \t]+\\([^\n]+\\)" 1)
|
2019-05-01 19:13:44 -04:00
|
|
|
("Evil commands" "^\\s-*(evil-define-\\(?:command\\|operator\\|motion\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
2018-08-21 00:04:48 +02:00
|
|
|
("Unit tests" "^\\s-*(\\(?:ert-deftest\\|describe\\) +\"\\([^\")]+\\)\"" 1)
|
2022-03-19 23:07:19 +01:00
|
|
|
("Package" "^\\s-*\\(?:;;;###package\\|(\\(?:package!\\|use-package!?\\|after!\\)\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
2018-08-21 00:04:48 +02:00
|
|
|
("Major modes" "^\\s-*(define-derived-mode +\\([^ ()\n]+\\)" 1)
|
2019-05-01 19:13:44 -04:00
|
|
|
("Minor modes" "^\\s-*(define-\\(?:global\\(?:ized\\)?-minor\\|generic\\|minor\\)-mode +\\([^ ()\n]+\\)" 1)
|
2018-08-21 00:04:48 +02:00
|
|
|
("Modelines" "^\\s-*(def-modeline! +\\([^ ()\n]+\\)" 1)
|
2019-03-09 02:42:03 -05:00
|
|
|
("Modeline segments" "^\\s-*(def-modeline-segment! +\\([^ ()\n]+\\)" 1)
|
2020-02-21 10:41:45 -05:00
|
|
|
("Advice" "^\\s-*(\\(?:def\\(?:\\(?:ine-\\)?advice!?\\)\\) +\\([^ )\n]+\\)" 1)
|
2018-08-21 00:04:48 +02:00
|
|
|
("Macros" "^\\s-*(\\(?:cl-\\)?def\\(?:ine-compile-macro\\|macro\\) +\\([^ )\n]+\\)" 1)
|
2019-03-09 02:42:03 -05:00
|
|
|
("Inline functions" "\\s-*(\\(?:cl-\\)?defsubst +\\([^ )\n]+\\)" 1)
|
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
|
|
|
("CLI Command" "^\\s-*(\\(def\\(?:cli\\|alias\\|obsolete\\|autoload\\)! +\\([^\n]+\\)\\)" 1)
|
2018-08-21 00:04:48 +02:00
|
|
|
("Functions" "^\\s-*(\\(?:cl-\\)?def\\(?:un\\|un\\*\\|method\\|generic\\|-memoized!\\) +\\([^ ,)\n]+\\)" 1)
|
|
|
|
("Variables" "^\\s-*(\\(def\\(?:c\\(?:onst\\(?:ant\\)?\\|ustom\\)\\|ine-symbol-macro\\|parameter\\|var\\(?:-local\\)?\\)\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2)
|
|
|
|
("Types" "^\\s-*(\\(cl-def\\(?:struct\\|type\\)\\|def\\(?:class\\|face\\|group\\|ine-\\(?:condition\\|error\\|widget\\)\\|package\\|struct\\|t\\(?:\\(?:hem\\|yp\\)e\\)\\)\\)\\s-+'?\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2))))
|
|
|
|
|
refactor!(emacs-lisp): flycheck config in non-packages
BREAKING CHANGE: This performs the following backwards-incompatible
changes:
- Replaces `+emacs-lisp-reduce-flycheck-errors-in-emacs-config-h` with a
`+emacs-lisp-non-package-mode` minor-mode.
- Removed the `+emacs-lisp-disable-flycheck-in-dirs` variable, as this
mechanism no longer checks a directory list to detect a "non-package".
If you've referenced either of these symbols, you'll need to
update/remove them from your config. No extra config is needed
otherwise.
Why: Doom has always tried to reduce the verbosity of Flycheck when
viewing elisp config files or scripts (i.e. non-packages). These are so
stateful that the byte-compiler, package-lint, and checkdoc inundate
users with false positives that are more overwhelming than helpful.
The heuristic for this has always been a simple "is this file in
$DOOMDIR or $EMACSDIR", but this wasn't robust enough, especially in
cases where symlinking was involved, so I've employed a new, more
general heuristic for detecting non-package files:
- The file isn't a theme in `custom-theme-load-path`,
- The file doesn't have a (provide ...) or (provide-theme ...)
statement whose first argument matches the file name,
- The file lives in a project with a .doommodule file (doom modules
never have convention package files in them),
- Or the file is a dotfile (like .dir-locals.el or .doomrc).
I've also tweaked byte-compile-warnings to yield a little more output,
but not by much. Whether this is too permissive or not will require
further testing to determine.
What's more, I've updated this to reflect recent changes to Doom's
startup process (in c05e615).
Ref: c05e61536ed9
2022-09-10 15:33:10 +02:00
|
|
|
(defun +emacs-lisp--in-package-buffer-p ()
|
|
|
|
(let* ((file-path (buffer-file-name (buffer-base-buffer)))
|
|
|
|
(file-base (if file-path (file-name-base file-path))))
|
|
|
|
(and (derived-mode-p 'emacs-lisp-mode)
|
|
|
|
(or (null file-base)
|
|
|
|
(locate-file file-base (custom-theme--load-path) '(".elc" ".el"))
|
|
|
|
(save-excursion
|
|
|
|
(save-restriction
|
|
|
|
(widen)
|
|
|
|
(goto-char (point-max))
|
|
|
|
(when (re-search-backward "^ *\\((provide\\)\\(?:-theme\\)? +'"
|
|
|
|
(max (point-min) (- (point-max) 512))
|
|
|
|
t)
|
|
|
|
(goto-char (match-beginning 1))
|
|
|
|
(ignore-errors
|
|
|
|
(and (stringp file-base)
|
|
|
|
(equal (symbol-name (doom-unquote (nth 1 (read (current-buffer)))))
|
|
|
|
file-base)))))))
|
|
|
|
(not (locate-dominating-file default-directory ".doommodule")))))
|
|
|
|
|
2018-08-21 00:04:48 +02:00
|
|
|
;;;###autoload
|
refactor!(emacs-lisp): flycheck config in non-packages
BREAKING CHANGE: This performs the following backwards-incompatible
changes:
- Replaces `+emacs-lisp-reduce-flycheck-errors-in-emacs-config-h` with a
`+emacs-lisp-non-package-mode` minor-mode.
- Removed the `+emacs-lisp-disable-flycheck-in-dirs` variable, as this
mechanism no longer checks a directory list to detect a "non-package".
If you've referenced either of these symbols, you'll need to
update/remove them from your config. No extra config is needed
otherwise.
Why: Doom has always tried to reduce the verbosity of Flycheck when
viewing elisp config files or scripts (i.e. non-packages). These are so
stateful that the byte-compiler, package-lint, and checkdoc inundate
users with false positives that are more overwhelming than helpful.
The heuristic for this has always been a simple "is this file in
$DOOMDIR or $EMACSDIR", but this wasn't robust enough, especially in
cases where symlinking was involved, so I've employed a new, more
general heuristic for detecting non-package files:
- The file isn't a theme in `custom-theme-load-path`,
- The file doesn't have a (provide ...) or (provide-theme ...)
statement whose first argument matches the file name,
- The file lives in a project with a .doommodule file (doom modules
never have convention package files in them),
- Or the file is a dotfile (like .dir-locals.el or .doomrc).
I've also tweaked byte-compile-warnings to yield a little more output,
but not by much. Whether this is too permissive or not will require
further testing to determine.
What's more, I've updated this to reflect recent changes to Doom's
startup process (in c05e615).
Ref: c05e61536ed9
2022-09-10 15:33:10 +02:00
|
|
|
(define-minor-mode +emacs-lisp-non-package-mode
|
|
|
|
"Reduce flycheck verbosity where it is appropriate.
|
|
|
|
|
|
|
|
Essentially, this means in any elisp file that either:
|
|
|
|
- Is not a theme in `custom-theme-load-path',
|
|
|
|
- Lacks a `provide' statement,
|
|
|
|
- Lives in a project with a .doommodule file,
|
|
|
|
- Is a dotfile (like .dir-locals.el or .doomrc).
|
|
|
|
|
|
|
|
This generally applies to your private config (`doom-user-dir') or Doom's source
|
|
|
|
\(`doom-emacs-dir')."
|
|
|
|
:since "3.0.0"
|
|
|
|
(unless (and (bound-and-true-p flycheck-mode)
|
|
|
|
(not (+emacs-lisp--in-package-buffer-p)))
|
|
|
|
(setq +emacs-lisp-non-package-mode nil))
|
|
|
|
(when (derived-mode-p 'emacs-lisp-mode)
|
|
|
|
(add-hook 'after-save-hook #'+emacs-lisp-non-package-mode nil t))
|
|
|
|
(if (not +emacs-lisp-non-package-mode)
|
|
|
|
(when (get 'flycheck-disabled-checkers 'initial-value)
|
|
|
|
(setq-local flycheck-disabled-checkers (get 'flycheck-disabled-checkers 'initial-value))
|
|
|
|
(kill-local-variable 'flycheck-emacs-lisp-check-form))
|
|
|
|
(with-memoization (get 'flycheck-disabled-checkers 'initial-value)
|
|
|
|
flycheck-disabled-checkers)
|
|
|
|
(setq-local flycheck-emacs-lisp-check-form
|
|
|
|
(prin1-to-string
|
|
|
|
`(progn
|
|
|
|
(setq doom-modules ',doom-modules
|
|
|
|
doom-disabled-packages ',doom-disabled-packages
|
|
|
|
byte-compile-warnings ',+emacs-lisp-linter-warnings)
|
|
|
|
(condition-case e
|
|
|
|
(progn
|
|
|
|
(require 'doom)
|
|
|
|
(require 'doom-cli)
|
|
|
|
(require 'doom-start)
|
|
|
|
(defmacro map! (&rest _)))
|
|
|
|
(error
|
|
|
|
(princ
|
|
|
|
(format "%s:%d:%d:Error:Failed to load Doom: %s\n"
|
2022-09-16 13:01:30 +02:00
|
|
|
(or ,(ignore-errors
|
|
|
|
(file-name-nondirectory
|
|
|
|
(buffer-file-name (buffer-base-buffer))))
|
|
|
|
(car command-line-args-left))
|
refactor!(emacs-lisp): flycheck config in non-packages
BREAKING CHANGE: This performs the following backwards-incompatible
changes:
- Replaces `+emacs-lisp-reduce-flycheck-errors-in-emacs-config-h` with a
`+emacs-lisp-non-package-mode` minor-mode.
- Removed the `+emacs-lisp-disable-flycheck-in-dirs` variable, as this
mechanism no longer checks a directory list to detect a "non-package".
If you've referenced either of these symbols, you'll need to
update/remove them from your config. No extra config is needed
otherwise.
Why: Doom has always tried to reduce the verbosity of Flycheck when
viewing elisp config files or scripts (i.e. non-packages). These are so
stateful that the byte-compiler, package-lint, and checkdoc inundate
users with false positives that are more overwhelming than helpful.
The heuristic for this has always been a simple "is this file in
$DOOMDIR or $EMACSDIR", but this wasn't robust enough, especially in
cases where symlinking was involved, so I've employed a new, more
general heuristic for detecting non-package files:
- The file isn't a theme in `custom-theme-load-path`,
- The file doesn't have a (provide ...) or (provide-theme ...)
statement whose first argument matches the file name,
- The file lives in a project with a .doommodule file (doom modules
never have convention package files in them),
- Or the file is a dotfile (like .dir-locals.el or .doomrc).
I've also tweaked byte-compile-warnings to yield a little more output,
but not by much. Whether this is too permissive or not will require
further testing to determine.
What's more, I've updated this to reflect recent changes to Doom's
startup process (in c05e615).
Ref: c05e61536ed9
2022-09-10 15:33:10 +02:00
|
|
|
0 0 (error-message-string e)))))
|
|
|
|
,(read (default-toplevel-value 'flycheck-emacs-lisp-check-form))))
|
|
|
|
flycheck-disabled-checkers (cons 'emacs-lisp-checkdoc
|
|
|
|
flycheck-disabled-checkers))))
|
2019-09-19 13:56:38 +09:00
|
|
|
|
2020-05-25 02:29:30 -04:00
|
|
|
|
|
|
|
;;
|
|
|
|
;;; Fontification
|
|
|
|
|
2020-04-29 23:09:46 -04:00
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp-truncate-pin ()
|
|
|
|
"Truncates long SHA1 hashes in `package!' :pin's."
|
|
|
|
(save-excursion
|
|
|
|
(goto-char (match-beginning 0))
|
|
|
|
(and (stringp (plist-get (sexp-at-point) :pin))
|
|
|
|
(search-forward ":pin" nil t)
|
2021-08-02 22:05:51 -04:00
|
|
|
(let ((start (re-search-forward "\"[^\"\n]\\{12\\}" nil t))
|
2020-04-30 02:31:51 -04:00
|
|
|
(finish (and (re-search-forward "\"" (line-end-position) t)
|
|
|
|
(match-beginning 0))))
|
|
|
|
(when (and start finish)
|
|
|
|
(put-text-property start finish 'display "...")))))
|
2020-04-29 23:09:46 -04:00
|
|
|
nil)
|
2020-05-25 02:29:30 -04:00
|
|
|
|
|
|
|
(defvar +emacs-lisp--face nil)
|
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp-highlight-vars-and-faces (end)
|
|
|
|
"Match defined variables and functions.
|
|
|
|
|
|
|
|
Functions are differentiated into special forms, built-in functions and
|
|
|
|
library/userland functions"
|
|
|
|
(catch 'matcher
|
|
|
|
(while (re-search-forward "\\(?:\\sw\\|\\s_\\)+" end t)
|
|
|
|
(let ((ppss (save-excursion (syntax-ppss))))
|
|
|
|
(cond ((nth 3 ppss) ; strings
|
|
|
|
(search-forward "\"" end t))
|
|
|
|
((nth 4 ppss) ; comments
|
|
|
|
(forward-line +1))
|
|
|
|
((let ((symbol (intern-soft (match-string-no-properties 0))))
|
|
|
|
(and (cond ((null symbol) nil)
|
|
|
|
((eq symbol t) nil)
|
2020-10-21 22:05:44 -04:00
|
|
|
((keywordp symbol) nil)
|
2020-05-25 02:29:30 -04:00
|
|
|
((special-variable-p symbol)
|
|
|
|
(setq +emacs-lisp--face 'font-lock-variable-name-face))
|
|
|
|
((and (fboundp symbol)
|
|
|
|
(eq (char-before (match-beginning 0)) ?\()
|
|
|
|
(not (memq (char-before (1- (match-beginning 0)))
|
|
|
|
(list ?\' ?\`))))
|
|
|
|
(let ((unaliased (indirect-function symbol)))
|
|
|
|
(unless (or (macrop unaliased)
|
|
|
|
(special-form-p unaliased))
|
|
|
|
(let (unadvised)
|
|
|
|
(while (not (eq (setq unadvised (ad-get-orig-definition unaliased))
|
|
|
|
(setq unaliased (indirect-function unadvised)))))
|
|
|
|
unaliased)
|
|
|
|
(setq +emacs-lisp--face
|
|
|
|
(if (subrp unaliased)
|
|
|
|
'font-lock-constant-face
|
|
|
|
'font-lock-function-name-face))))))
|
|
|
|
(throw 'matcher t)))))))
|
|
|
|
nil))
|
|
|
|
|
2022-09-12 16:14:11 +02:00
|
|
|
|
|
|
|
;;
|
|
|
|
;;; Advice
|
|
|
|
|
2022-09-12 17:11:16 +02:00
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp--add-doom-elisp-demos-a (fn symbol)
|
|
|
|
"Add Doom's own demos to `elisp-demos'.
|
|
|
|
|
|
|
|
Intended as :around advice for `elisp-demos--search'."
|
|
|
|
(let ((org-inhibit-startup t)
|
|
|
|
enable-dir-local-variables
|
|
|
|
org-mode-hook)
|
|
|
|
(or (funcall fn symbol)
|
|
|
|
(with-file-contents! (doom-path doom-docs-dir "examples.org")
|
|
|
|
(save-excursion
|
|
|
|
(when (re-search-backward
|
|
|
|
(format "^\\*+[ \t]+\\(?:TODO \\)?%s$"
|
|
|
|
(regexp-quote (symbol-name symbol)))
|
|
|
|
nil t)
|
|
|
|
(forward-line 1)
|
|
|
|
(let ((demos
|
|
|
|
(string-trim
|
|
|
|
(buffer-substring-no-properties
|
|
|
|
(point) (if (re-search-forward "^\\*+ " nil t)
|
|
|
|
(line-beginning-position)
|
|
|
|
(point-max))))))
|
|
|
|
(unless (string-blank-p demos)
|
|
|
|
demos))))))))
|
|
|
|
|
2022-09-12 16:14:11 +02:00
|
|
|
;;;###autoload (put 'map! 'indent-plists-as-data t)
|
|
|
|
;;;###autoload
|
|
|
|
(defun +emacs-lisp--calculate-lisp-indent-a (&optional parse-start)
|
|
|
|
"Add better indentation for quoted and backquoted lists.
|
|
|
|
|
|
|
|
Intended as :override advice for `calculate-lisp-indent'.
|
|
|
|
|
|
|
|
Adapted from 'https://www.reddit.com/r/emacs/comments/d7x7x8/finally_fixing_indentation_of_quoted_lists/'."
|
|
|
|
;; This line because `calculate-lisp-indent-last-sexp` was defined with
|
|
|
|
;; `defvar` with it's value ommited, marking it special and only defining it
|
|
|
|
;; locally. So if you don't have this, you'll get a void variable error.
|
|
|
|
(defvar calculate-lisp-indent-last-sexp)
|
|
|
|
(save-excursion
|
|
|
|
(beginning-of-line)
|
|
|
|
(let ((indent-point (point))
|
|
|
|
state
|
|
|
|
;; setting this to a number inhibits calling hook
|
|
|
|
(desired-indent nil)
|
|
|
|
(retry t)
|
|
|
|
calculate-lisp-indent-last-sexp containing-sexp)
|
|
|
|
(cond ((or (markerp parse-start) (integerp parse-start))
|
|
|
|
(goto-char parse-start))
|
|
|
|
((null parse-start)
|
|
|
|
(beginning-of-defun))
|
|
|
|
((setq state parse-start)))
|
|
|
|
(unless state
|
|
|
|
;; Find outermost containing sexp
|
|
|
|
(while (< (point) indent-point)
|
|
|
|
(setq state (parse-partial-sexp (point) indent-point 0))))
|
|
|
|
;; Find innermost containing sexp
|
|
|
|
(while (and retry
|
|
|
|
state
|
|
|
|
(> (elt state 0) 0))
|
|
|
|
(setq retry nil)
|
|
|
|
(setq calculate-lisp-indent-last-sexp (elt state 2))
|
|
|
|
(setq containing-sexp (elt state 1))
|
|
|
|
;; Position following last unclosed open.
|
|
|
|
(goto-char (1+ containing-sexp))
|
|
|
|
;; Is there a complete sexp since then?
|
|
|
|
(if (and calculate-lisp-indent-last-sexp
|
|
|
|
(> calculate-lisp-indent-last-sexp (point)))
|
|
|
|
;; Yes, but is there a containing sexp after that?
|
|
|
|
(let ((peek (parse-partial-sexp calculate-lisp-indent-last-sexp
|
|
|
|
indent-point 0)))
|
|
|
|
(if (setq retry (car (cdr peek))) (setq state peek)))))
|
|
|
|
(if retry
|
|
|
|
nil
|
|
|
|
;; Innermost containing sexp found
|
|
|
|
(goto-char (1+ containing-sexp))
|
|
|
|
(if (not calculate-lisp-indent-last-sexp)
|
|
|
|
;; indent-point immediately follows open paren. Don't call hook.
|
|
|
|
(setq desired-indent (current-column))
|
|
|
|
;; Find the start of first element of containing sexp.
|
|
|
|
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
|
|
|
|
(cond ((looking-at "\\s(")
|
|
|
|
;; First element of containing sexp is a list. Indent under
|
|
|
|
;; that list.
|
|
|
|
)
|
|
|
|
((> (save-excursion (forward-line 1) (point))
|
|
|
|
calculate-lisp-indent-last-sexp)
|
|
|
|
;; This is the first line to start within the containing sexp.
|
|
|
|
;; It's almost certainly a function call.
|
|
|
|
(if (or
|
|
|
|
;; Containing sexp has nothing before this line except the
|
|
|
|
;; first element. Indent under that element.
|
|
|
|
(= (point) calculate-lisp-indent-last-sexp)
|
|
|
|
|
|
|
|
(or
|
|
|
|
;; Align keywords in plists if each newline begins with
|
|
|
|
;; a keyword. This is useful for "unquoted plist
|
|
|
|
;; function" macros, like `map!' and `defhydra'.
|
|
|
|
(when-let ((first (elt state 1))
|
|
|
|
(char (char-after (1+ first))))
|
|
|
|
(and (eq char ?:)
|
|
|
|
(ignore-errors
|
|
|
|
(or (save-excursion
|
|
|
|
(goto-char first)
|
|
|
|
;; FIXME Can we avoid `syntax-ppss'?
|
|
|
|
(when-let* ((parse-sexp-ignore-comments t)
|
|
|
|
(end (scan-lists (point) 1 0))
|
|
|
|
(depth (ppss-depth (syntax-ppss))))
|
|
|
|
(and (re-search-forward "^\\s-*:" end t)
|
|
|
|
(= (ppss-depth (syntax-ppss))
|
|
|
|
(1+ depth)))))
|
|
|
|
(save-excursion
|
|
|
|
(cl-loop for pos in (reverse (elt state 9))
|
|
|
|
unless (memq (char-after (1+ pos)) '(?: ?\())
|
|
|
|
do (goto-char (1+ pos))
|
|
|
|
for fn = (read (current-buffer))
|
|
|
|
if (symbolp fn)
|
|
|
|
return (function-get fn 'indent-plists-as-data)))))))
|
|
|
|
|
|
|
|
;; Check for quotes or backquotes around.
|
|
|
|
(let ((positions (elt state 9))
|
|
|
|
(quotep 0))
|
|
|
|
(while positions
|
|
|
|
(let ((point (pop positions)))
|
|
|
|
(or (when-let (char (char-before point))
|
|
|
|
(cond
|
|
|
|
((eq char ?\())
|
|
|
|
((memq char '(?\' ?\`))
|
|
|
|
(or (save-excursion
|
|
|
|
(goto-char (1+ point))
|
|
|
|
(skip-chars-forward "( ")
|
|
|
|
(when-let (fn (ignore-errors (read (current-buffer))))
|
|
|
|
(if (and (symbolp fn)
|
|
|
|
(fboundp fn)
|
|
|
|
;; Only special forms and
|
|
|
|
;; macros have special
|
|
|
|
;; indent needs.
|
|
|
|
(not (functionp fn)))
|
|
|
|
(setq quotep 0))))
|
|
|
|
(cl-incf quotep)))
|
|
|
|
((memq char '(?, ?@))
|
|
|
|
(setq quotep 0))))
|
|
|
|
;; If the spelled out `quote' or `backquote'
|
|
|
|
;; are used, let's assume
|
|
|
|
(save-excursion
|
|
|
|
(goto-char (1+ point))
|
|
|
|
(and (looking-at-p "\\(\\(?:back\\)?quote\\)[\t\n\f\s]+(")
|
|
|
|
(cl-incf quotep 2)))
|
|
|
|
(setq quotep (max 0 (1- quotep))))))
|
|
|
|
(> quotep 0))))
|
|
|
|
;; Containing sexp has nothing before this line except the
|
|
|
|
;; first element. Indent under that element.
|
|
|
|
nil
|
|
|
|
;; Skip the first element, find start of second (the first
|
|
|
|
;; argument of the function call) and indent under.
|
|
|
|
(progn (forward-sexp 1)
|
|
|
|
(parse-partial-sexp (point)
|
|
|
|
calculate-lisp-indent-last-sexp
|
|
|
|
0 t)))
|
|
|
|
(backward-prefix-chars))
|
|
|
|
(t
|
|
|
|
;; Indent beneath first sexp on same line as
|
|
|
|
;; `calculate-lisp-indent-last-sexp'. Again, it's almost
|
|
|
|
;; certainly a function call.
|
|
|
|
(goto-char calculate-lisp-indent-last-sexp)
|
|
|
|
(beginning-of-line)
|
|
|
|
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp
|
|
|
|
0 t)
|
|
|
|
(backward-prefix-chars)))))
|
|
|
|
;; Point is at the point to indent under unless we are inside a string.
|
|
|
|
;; Call indentation hook except when overridden by lisp-indent-offset or
|
|
|
|
;; if the desired indentation has already been computed.
|
|
|
|
(let ((normal-indent (current-column)))
|
|
|
|
(cond ((elt state 3)
|
|
|
|
;; Inside a string, don't change indentation.
|
|
|
|
nil)
|
|
|
|
((and (integerp lisp-indent-offset) containing-sexp)
|
|
|
|
;; Indent by constant offset
|
|
|
|
(goto-char containing-sexp)
|
|
|
|
(+ (current-column) lisp-indent-offset))
|
|
|
|
;; in this case calculate-lisp-indent-last-sexp is not nil
|
|
|
|
(calculate-lisp-indent-last-sexp
|
|
|
|
(or
|
|
|
|
;; try to align the parameters of a known function
|
|
|
|
(and lisp-indent-function
|
|
|
|
(not retry)
|
|
|
|
(funcall lisp-indent-function indent-point state))
|
|
|
|
;; If the function has no special alignment or it does not apply
|
|
|
|
;; to this argument, try to align a constant-symbol under the
|
|
|
|
;; last preceding constant symbol, if there is such one of the
|
|
|
|
;; last 2 preceding symbols, in the previous uncommented line.
|
|
|
|
(and (save-excursion
|
|
|
|
(goto-char indent-point)
|
|
|
|
(skip-chars-forward " \t")
|
|
|
|
(looking-at ":"))
|
|
|
|
;; The last sexp may not be at the indentation where it
|
|
|
|
;; begins, so find that one, instead.
|
|
|
|
(save-excursion
|
|
|
|
(goto-char calculate-lisp-indent-last-sexp)
|
|
|
|
;; Handle prefix characters and whitespace following an
|
|
|
|
;; open paren. (Bug#1012)
|
|
|
|
(backward-prefix-chars)
|
|
|
|
(while (not (or (looking-back "^[ \t]*\\|([ \t]+"
|
|
|
|
(line-beginning-position))
|
|
|
|
(and containing-sexp
|
|
|
|
(>= (1+ containing-sexp) (point)))))
|
|
|
|
(forward-sexp -1)
|
|
|
|
(backward-prefix-chars))
|
|
|
|
(setq calculate-lisp-indent-last-sexp (point)))
|
|
|
|
(> calculate-lisp-indent-last-sexp
|
|
|
|
(save-excursion
|
|
|
|
(goto-char (1+ containing-sexp))
|
|
|
|
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
|
|
|
|
(point)))
|
|
|
|
(let ((parse-sexp-ignore-comments t)
|
|
|
|
indent)
|
|
|
|
(goto-char calculate-lisp-indent-last-sexp)
|
|
|
|
(or (and (looking-at ":")
|
|
|
|
(setq indent (current-column)))
|
|
|
|
(and (< (line-beginning-position)
|
|
|
|
(prog2 (backward-sexp) (point)))
|
|
|
|
(looking-at ":")
|
|
|
|
(setq indent (current-column))))
|
|
|
|
indent))
|
|
|
|
;; another symbols or constants not preceded by a constant as
|
|
|
|
;; defined above.
|
|
|
|
normal-indent))
|
|
|
|
;; in this case calculate-lisp-indent-last-sexp is nil
|
|
|
|
(desired-indent)
|
|
|
|
(normal-indent))))))
|
|
|
|
|
|
|
|
;; HACK: These functions are called often and as part of performance-sensitive
|
|
|
|
;; processes, so we compile them if the file isn't already compiled.
|
|
|
|
(mapc #'doom-compile-function '(+emacs-lisp-highlight-vars-and-faces
|
|
|
|
+emacs-lisp-truncate-pin
|
|
|
|
+emacs-lisp--calculate-lisp-indent-a))
|
|
|
|
|
|
|
|
;;; autoload.el ends here
|