emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/tempel 12ab6b6988 2/2: Refactoring, minor simplificatio


From: ELPA Syncer
Subject: [elpa] externals/tempel 12ab6b6988 2/2: Refactoring, minor simplifications
Date: Thu, 10 Mar 2022 16:57:47 -0500 (EST)

branch: externals/tempel
commit 12ab6b698830daf8c65da930efd370593f16bfa9
Author: Daniel Mendler <mail@daniel-mendler.de>
Commit: Daniel Mendler <mail@daniel-mendler.de>

    Refactoring, minor simplifications
---
 README.org |  16 +++----
 tempel.el  | 144 +++++++++++++++++++++++++------------------------------------
 2 files changed, 66 insertions(+), 94 deletions(-)

diff --git a/README.org b/README.org
index 194823d877..2177373cbe 100644
--- a/README.org
+++ b/README.org
@@ -96,13 +96,13 @@ on on =use-package=.
 
 * Template file format
 
-The templates are defined in a Lisp file which is stored by default in the
-~user-emacs-directory~ (=~/.config/emacs/templates=). The templates are 
grouped by
-major mode with an optional ~:condition~. Each template is a list in the 
concise
-form of the Emacs Tempo syntax. The first element of each list is the name of
-the template. Behind the name, the Tempo syntax elements follow. Pre- and
-post-expansion operations can be specified per template by the optional keys
-=:pre= and =:post=.
+The templates are defined in a Lisp file configured by ~tempel-path~. By 
default
+the file or directory =~/.config/emacs/templates= is used. The templates are
+grouped by major mode with an optional ~:condition~. Each template is a list in
+the concise form of the Emacs Tempo syntax. The first element of each list is
+the name of the template. Behind the name, the Tempo syntax elements follow.
+Pre- and post-expansion operations can be specified per template by the 
optional
+keys =:pre= and =:post=.
 
 #+begin_src emacs-lisp
   ;; -*- mode: lisp -*-
@@ -228,7 +228,7 @@ applicable to the current context. The variable 
~tempel-template-sources~
 specifies a list of sources or a single source. A source can either be a
 function, which should return a list of applicable templates, or the symbol of 
a
 variable, which holds a list of templates, which apply to the current context.
-By default, Tempel configures only the source ~tempel-file-templates~. You may
+By default, Tempel configures only the source ~tempel-path-templates~. You may
 want to add global or local template variables to your user configuration:
 
 #+begin_src emacs-lisp
diff --git a/tempel.el b/tempel.el
index ed0202c038..c938755205 100644
--- a/tempel.el
+++ b/tempel.el
@@ -26,16 +26,16 @@
 
 ;;; Commentary:
 
-;; Tempel implements a simple template/snippet system. The template format is
-;; compatible with the template format of the Emacs Tempo library. Your
-;; templates are stored in the `tempel-template-paths' (by default the file
-;; "templates" in the `user-emacs-directory'). Bind the commands
-;; `tempel-complete', `tempel-expand' or `tempel-insert' to some keys in your
-;; user configuration. You can jump with the keys M-{ and M-} from field to
-;; field. `tempel-complete' and `tempel-expand' work best with the Corfu
-;; completion UI, while `tempel-insert' uses `completing-read' under the
-;; hood. You can also use `tempel-complete' and `tempel-expand' as
-;; `completion-at-point-functions'.
+;; Tempel implements a simple template/snippet system. The template
+;; format is compatible with the template format of the Emacs Tempo
+;; library. Your templates are stored in the `tempel-path' (by default
+;; the file "templates" in the `user-emacs-directory'). Bind the
+;; commands `tempel-complete', `tempel-expand' or `tempel-insert' to
+;; some keys in your user configuration. You can jump with the keys M-{
+;; and M-} from field to field. `tempel-complete' and `tempel-expand'
+;; work best with the Corfu completion UI, while `tempel-insert' uses
+;; `completing-read' under the hood. You can also use `tempel-complete'
+;; and `tempel-expand' as `completion-at-point-functions'.
 
 ;;; Code:
 
@@ -48,9 +48,9 @@
   :group 'editing
   :prefix "tempel-")
 
-(defcustom tempel-template-paths (expand-file-name "templates" 
user-emacs-directory)
-  "A file or a list of files and/or directories to look for snippets in."
-  :type '(choice (string list)))
+(defcustom tempel-path (expand-file-name "templates" user-emacs-directory)
+  "A file or a list of files and/or directories, containing templates."
+  :type '(choice string (string list)))
 
 (defcustom tempel-mark
   #(" " 0 1 (display (space :width (1)) face cursor))
@@ -78,10 +78,9 @@ A source can either be a function or a variable symbol. The 
functions
 must return a list of templates which apply to the buffer or context."
   :type 'hook)
 
-(defcustom tempel-auto-reload-templates-p t
-  "Non-nil means to reload snippets when files specified by 
`tempel-template-paths' change.
-If any file in `tempel-template-paths' is modified or new files are added or
-removed from `tempel-template-paths', reload the templates."
+(defcustom tempel-auto-reload t
+  "Reload templates when files specified by `tempel-path' change.
+If a file is modified, added or removed, reload the templates."
   :type 'boolean)
 
 (defface tempel-field
@@ -109,7 +108,10 @@ removed from `tempel-template-paths', reload the 
templates."
   "Face used for default values.")
 
 (defvar tempel--path-templates nil
-  "Templates loaded from the `tempel-template-paths'.")
+  "Templates loaded from the `tempel-path'.")
+
+(defvar tempel--path-timestamps nil
+  "Alist of files and modification times on the `tempel-path'.")
 
 (defvar tempel--history nil
   "Completion history used by `tempel-insert'.")
@@ -141,13 +143,6 @@ may be named with `tempel--name' or carry an evaluatable 
Lisp expression
     map)
   "Keymap to navigate across template fields.")
 
-(defvar tempel--modified 0
-  "Most recent modification time of files in `tempel-template-paths' since
-loading the templates.
-If templates have not been loaded yet, this is 0.")
-
-(defvar tempel--old-template-paths tempel-template-paths)
-
 (defun tempel--print-element (elt)
   "Return string representation of template ELT."
   (pcase elt
@@ -159,21 +154,15 @@ If templates have not been loaded yet, this is 0.")
     ((or 'n 'n> '> '& '% 'o) " ")
     (_ "_")))
 
-(defun tempel--expand-paths (paths)
-  "Return the list of files specified by PATHS.
-PATHS is a list of files and directories."
-  (let ((paths (if (listp paths) paths (list paths)))
-       (file-paths nil))
-    (dolist (path paths)
+(defun tempel--expand-path ()
+  "Return the list of files specified by `tempel-path'."
+  (let (files)
+    (dolist (path (if (listp tempel-path) tempel-path (list tempel-path)))
       (when (file-exists-p path)
-       (if (file-directory-p path)
-           (setq file-paths (append file-paths (directory-files-recursively 
path "[^z-a]+")))
-         (push path file-paths))))
-    file-paths))
-
-(defun tempel--load-templates ()
-  "Return templates specified `tempel-template-paths'."
-  (mapcan #'tempel--file-read (tempel--expand-paths tempel-template-paths)))
+        (if (file-directory-p path)
+            (setq files (nconc files (directory-files-recursively path "")))
+          (push path files))))
+    files))
 
 (defun tempel--annotate (templates width ellipsis sep name)
   "Annotate template NAME given the list of TEMPLATES.
@@ -399,35 +388,13 @@ PROMPT is the optional prompt/default value."
     (eval (plist-get plist :post) 'lexical)))
 
 (defun tempel--save ()
-  "Prompt to save any modified files in `tempel-template-paths'."
-  (let (modified)
-    (dolist (file (tempel--expand-paths tempel-template-paths))
-      (when-let (buff (get-file-buffer file))
-       (push file modified)))
-    (when (or (and (= (length modified) 1)
-                  (y-or-n-p "Save template file %s? " (car modified)))
-             (y-or-n-p "Save modified template files? "))
-      (mapc #'save-buffer modified))))
-
-(defun tempel--min-modification-time ()
-  "Return the earliest modification time (in seconds)."
-  (if-let (paths (tempel--expand-paths tempel-template-paths))
-      (apply #'min (mapcar (lambda (f) (time-convert 
(file-attribute-modification-time (file-attributes f)) 'integer))
-                          paths))
-    0))
-
-(defun tempel--paths-updated-p ()
-  "Return non-nil if files have been added or removed from 
`tempel-template-paths'."
-  (let* ((old (tempel--expand-paths tempel--old-template-paths))
-        (new (tempel--expand-paths tempel-template-paths))
-        (length-old (length old))
-        (length-new (length new)))
-    (not (and (= length-old length-new)
-             (= length-old (length (cl-intersection old new)))))))
-
-(defun tempel--files-modified-p ()
-  "Return non-nil if any files in `tempel-template-paths' have been modified 
since loading."
-  (< tempel--modified (tempel--min-modification-time)))
+  "Prompt to save modified files in `tempel-path'."
+  (cl-loop
+   for (file . _ts) in tempel--path-timestamps do
+   (when-let (buf (get-file-buffer file))
+     (with-current-buffer buf
+       (when (and (buffer-modified-p) (y-or-n-p (format "Save file %s? " 
file)))
+         (save-buffer buf))))))
 
 (defun tempel--file-read (file)
   "Load templates from FILE."
@@ -451,27 +418,32 @@ PROMPT is the optional prompt/default value."
       result)))
 
 (defun tempel-path-templates ()
-  "Return templates defined in `tempel-template-paths'.
+  "Return templates defined in `tempel-path'.
 Additionally, save any files in `tempel-template-sources' that have been
 modified since the last time this function was called.
 This is meant to be a source in `tempel-template-sources'."
-  (when (and tempel-auto-reload-templates-p
-            (or (zerop tempel--modified)
-                (tempel--files-modified-p)
-                (tempel--paths-updated-p)))
-    (setq tempel--modified (tempel--min-modification-time))
-    (setq tempel--old-template-paths tempel-template-paths)
-    (setq tempel--path-templates (tempel--load-templates)))
-  (let (templates)
-    (pcase-dolist (`(,modes ,plist . ,template) tempel--path-templates)
-      (when (and (seq-some (lambda (m) (or (derived-mode-p m) (eq m 
#'fundamental-mode))) modes)
-                (or (not (plist-member plist :condition))
-                    (save-excursion
-                      (save-restriction
-                        (save-match-data
-                          (eval (plist-get plist :condition) 'lexical))))))
-       (push template templates)))
-    (apply #'append (nreverse templates))))
+  (when tempel-auto-reload
+    (let* ((files (tempel--expand-path))
+           (timestamps (cl-loop
+                        for f in files collect
+                        (cons f (time-convert
+                                 (file-attribute-modification-time
+                                  (file-attributes f))
+                                 'integer)))))
+      (unless (equal tempel--path-timestamps timestamps)
+        (setq tempel--path-timestamps timestamps
+              tempel--path-templates (mapcan #'tempel--file-read files)))))
+  (cl-loop
+   for (modes plist . templates) in tempel--path-templates
+   if (and
+       (cl-loop for m in modes
+                thereis (or (derived-mode-p m) (eq m #'fundamental-mode)))
+       (or (not (plist-member plist :condition))
+           (save-excursion
+             (save-restriction
+               (save-match-data
+                 (eval (plist-get plist :condition) 'lexical))))))
+   append templates))
 
 (defun tempel--templates ()
   "Return templates for current mode."



reply via email to

[Prev in Thread] Current Thread [Next in Thread]