From 126b7b6383f2133acf2331d392ee41290fb91ff6 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 16 Jun 2018 11:34:42 +0200 Subject: [PATCH] Refactor associate! with cl-defmacro --- core/core-lib.el | 60 ++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/core/core-lib.el b/core/core-lib.el index 54c70314c..ba118a2cd 100644 --- a/core/core-lib.el +++ b/core/core-lib.el @@ -361,7 +361,7 @@ Body forms can access the hook's arguments through the let-bound variable (push `(setq-local ,var ,val) 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. The available conditions are: @@ -377,37 +377,33 @@ The available conditions are: Whenever FORM returns non-nil." (declare (indent 1)) (unless noninteractive - (let ((modes (plist-get plist :modes)) - (match (plist-get plist :match)) - (files (plist-get plist :files)) - (pred-form (plist-get plist :when))) - (cond ((or files modes pred-form) - (when (and files - (not (or (listp files) - (stringp files)))) - (user-error "associate! :files expects a string or list of strings")) - (let ((hook-name (intern (format "doom--init-mode-%s" mode)))) - `(progn - (fset ',hook-name - (lambda () - (and (fboundp ',mode) - (not (bound-and-true-p ,mode)) - (and buffer-file-name (not (file-remote-p buffer-file-name))) - ,(if match `(if buffer-file-name (string-match-p ,match buffer-file-name)) t) - ,(or (not files) - (doom--resolve-path-forms - (if (stringp (car files)) (cons 'and files) files) - '(doom-project-root))) - ,(or pred-form t) - (,mode 1)))) - ,@(if (and modes (listp modes)) - (cl-loop for hook in (doom--resolve-hook-forms modes) - collect `(add-hook ',hook #',hook-name)) - `((add-hook 'after-change-major-mode-hook #',hook-name)))))) - (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)))))) + (cond ((or files modes when) + (when (and files + (not (or (listp files) + (stringp files)))) + (user-error "associate! :files expects a string or list of strings")) + (let ((hook-name (intern (format "doom--init-mode-%s" mode)))) + `(progn + (fset ',hook-name + (lambda () + (and (fboundp ',mode) + (not (bound-and-true-p ,mode)) + (and buffer-file-name (not (file-remote-p buffer-file-name))) + ,(if match `(if buffer-file-name (string-match-p ,match buffer-file-name)) t) + ,(or (not files) + (doom--resolve-path-forms + (if (stringp (car files)) (cons 'and files) files) + '(doom-project-root))) + ,(or when t) + (,mode 1)))) + ,@(if (and modes (listp modes)) + (cl-loop for hook in (doom--resolve-hook-forms modes) + collect `(add-hook ',hook #',hook-name)) + `((add-hook 'after-change-major-mode-hook #',hook-name)))))) + (match + `(map-put doom-auto-minor-mode-alist ,match ',mode)) + ((user-error "Invalid `associate!' rules for mode [%s] (:modes %s :match %s :files %s :when %s)" + mode modes match files when))))) (defmacro file-exists-p! (spec &optional directory) "Returns t if the files in SPEC all exist.