Refactor associate! with cl-defmacro

This commit is contained in:
Henrik Lissner 2018-06-16 11:34:42 +02:00
parent 5501b949ef
commit 126b7b6383
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395

View file

@ -361,7 +361,7 @@ Body forms can access the hook's arguments through the let-bound variable
(push `(setq-local ,var ,val) forms))) (push `(setq-local ,var ,val) forms)))
(nreverse forms)))) (nreverse forms))))
(defmacro associate! (mode &rest plist) (cl-defmacro associate! (mode &key modes match files when)
"Enables a minor mode if certain conditions are met. "Enables a minor mode if certain conditions are met.
The available conditions are: The available conditions are:
@ -377,37 +377,33 @@ The available conditions are:
Whenever FORM returns non-nil." Whenever FORM returns non-nil."
(declare (indent 1)) (declare (indent 1))
(unless noninteractive (unless noninteractive
(let ((modes (plist-get plist :modes)) (cond ((or files modes when)
(match (plist-get plist :match)) (when (and files
(files (plist-get plist :files)) (not (or (listp files)
(pred-form (plist-get plist :when))) (stringp files))))
(cond ((or files modes pred-form) (user-error "associate! :files expects a string or list of strings"))
(when (and files (let ((hook-name (intern (format "doom--init-mode-%s" mode))))
(not (or (listp files) `(progn
(stringp files)))) (fset ',hook-name
(user-error "associate! :files expects a string or list of strings")) (lambda ()
(let ((hook-name (intern (format "doom--init-mode-%s" mode)))) (and (fboundp ',mode)
`(progn (not (bound-and-true-p ,mode))
(fset ',hook-name (and buffer-file-name (not (file-remote-p buffer-file-name)))
(lambda () ,(if match `(if buffer-file-name (string-match-p ,match buffer-file-name)) t)
(and (fboundp ',mode) ,(or (not files)
(not (bound-and-true-p ,mode)) (doom--resolve-path-forms
(and buffer-file-name (not (file-remote-p buffer-file-name))) (if (stringp (car files)) (cons 'and files) files)
,(if match `(if buffer-file-name (string-match-p ,match buffer-file-name)) t) '(doom-project-root)))
,(or (not files) ,(or when t)
(doom--resolve-path-forms (,mode 1))))
(if (stringp (car files)) (cons 'and files) files) ,@(if (and modes (listp modes))
'(doom-project-root))) (cl-loop for hook in (doom--resolve-hook-forms modes)
,(or pred-form t) collect `(add-hook ',hook #',hook-name))
(,mode 1)))) `((add-hook 'after-change-major-mode-hook #',hook-name))))))
,@(if (and modes (listp modes)) (match
(cl-loop for hook in (doom--resolve-hook-forms modes) `(map-put doom-auto-minor-mode-alist ,match ',mode))
collect `(add-hook ',hook #',hook-name)) ((user-error "Invalid `associate!' rules for mode [%s] (:modes %s :match %s :files %s :when %s)"
`((add-hook 'after-change-major-mode-hook #',hook-name)))))) mode modes match files when)))))
(match
`(map-put doom-auto-minor-mode-alist ,match ',mode))
(t (user-error "associate! invalid rules for mode [%s] (modes %s) (match %s) (files %s)"
mode modes match files))))))
(defmacro file-exists-p! (spec &optional directory) (defmacro file-exists-p! (spec &optional directory)
"Returns t if the files in SPEC all exist. "Returns t if the files in SPEC all exist.