diff --git a/tempel.el b/tempel.el index 9804a52..04e867f 100644 --- a/tempel.el +++ b/tempel.el @@ -490,25 +490,27 @@ This is meant to be a source in `tempel-template-sources'." (unless (equal (car tempel--path-templates) timestamps) (setq tempel--path-templates (cons timestamps (mapcan #'tempel--file-read files)))))) + (cl-loop for (modes plist . templates) in (cdr tempel--path-templates) - if (tempel--condition-p modes plist) - append templates)) - -(defun tempel--condition-p (modes plist) - "Return non-nil if one of MODES matches and the PLIST condition is satisfied." - (and - (cl-loop - for m in modes thereis - (or (eq m #'fundamental-mode) - (derived-mode-p m) - (when-let ((remap (alist-get m (bound-and-true-p major-mode-remap-alist)))) - (derived-mode-p remap)))) - (or (not (plist-member plist :when)) - (save-excursion - (save-restriction - (save-match-data - (eval (plist-get plist :when) 'lexical))))))) + if (tempel--mode-matches-p modes) + collect (list modes plist templates))) + +(defun tempel--mode-matches-p (modes) + "Return non-nil if one of MODES matches." + (cl-loop + for m in modes thereis + (or (eq m #'fundamental-mode) + (derived-mode-p m) + (when-let ((remap (alist-get m (bound-and-true-p major-mode-remap-alist)))) + (derived-mode-p remap))))) + +(defun tempel--eval-condition (condition) + "Return non-nil if CONDITION is satisfied." + (save-excursion + (save-restriction + (save-match-data + (eval condition 'lexical))))) (defun tempel--templates () "Return templates for current mode." @@ -523,6 +525,16 @@ This is meant to be a source in `tempel-template-sources'." nil)) result)) + +(defun tempel--enabled-templates () + "Return enabled templates for the current mode." + (cl-loop + for (modes plist templates) in (tempel--templates) + if (tempel--eval-condition (if-let (condition (plist-get plist :when)) + (tempel--eval-condition condition) + t)) + append templates)) + (defun tempel--region () "Return region bounds." (when (use-region-p) @@ -687,7 +699,7 @@ command." (interactive (list t)) (if interactive (tempel--interactive #'tempel-expand) - (when-let ((templates (tempel--templates)) + (when-let ((templates (tempel--enabled-templates)) (bounds (tempel--prefix-bounds)) (name (buffer-substring-no-properties (car bounds) (cdr bounds))) @@ -714,7 +726,7 @@ Capf, otherwise like an interactive completion command." (insert tempel-trigger-prefix)) (tempel--interactive #'tempel-complete)) (let ((region (tempel--region))) - (when-let ((templates (tempel--templates)) + (when-let ((templates (tempel--enabled-templates)) (bounds (or (and (not region) (tempel--prefix-bounds)) (and (not tempel-trigger-prefix) (cons (point) (point)))))) (list (car bounds) (cdr bounds) @@ -745,7 +757,7 @@ If called interactively, select a template with `completing-read'." (interactive (list nil)) (tempel--insert (if (consp template-or-name) template-or-name - (let* ((templates (or (tempel--templates) + (let* ((templates (or (tempel--enabled-templates) (error "Tempel: No templates for %s" major-mode))) (completion-extra-properties (and tempel-insert-annotation @@ -796,16 +808,27 @@ If called interactively, select a template with `completing-read'." (default-value 'abbrev-minor-mode-table-alist)) (kill-local-variable 'abbrev-minor-mode-table-alist)) (when tempel-abbrev-mode - (let ((table (make-abbrev-table))) - (dolist (template (tempel--templates)) - (let* ((name (symbol-name (car template))) - (hook (make-symbol name))) - (fset hook (apply-partially #'tempel--abbrev-hook name (cdr template))) - (put hook 'no-self-insert t) - (define-abbrev table name 'Template hook :system t))) - (setq-local abbrev-minor-mode-table-alist - (cons `(tempel-abbrev-mode . ,table) - abbrev-minor-mode-table-alist))))) + (cl-loop + for (modes plist templates) in (tempel--templates) + do (let ((table (make-abbrev-table))) + (dolist (template templates) + (let* ((name (symbol-name (car template))) + (hook (make-symbol name))) + (fset hook (apply-partially #'tempel--abbrev-hook name (cdr template))) + (put hook 'no-self-insert t) + (define-abbrev table name 'Template hook :system t))) + + (when-let (condition (plist-get plist :when)) + (abbrev-table-put table + :enable-function + (lambda () + (tempel--eval-condition condition)))) + + + (setq-local abbrev-minor-mode-table-alist + (cons `(tempel-abbrev-mode . ,table) + abbrev-minor-mode-table-alist)) + )))) ;;;###autoload (define-globalized-minor-mode global-tempel-abbrev-mode