branch: elpa/annotate
commit 634a953ea018edd55e4cf51343c306e5b39a472f
Author: cage <cage@invalid>
Commit: cage <cage@invalid>

    - increased version number;
    
    - added code to implement annotation's text expansion;
    
    - updated README, changelog and NEWS files.
---
 Changelog   |  9 +++++++++
 NEWS.org    |  8 ++++++++
 README.org  | 14 ++++++++++++++
 annotate.el | 32 +++++++++++++++++++++++++++++---
 4 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/Changelog b/Changelog
index d7f4f7d05e..a471f96bcf 100644
--- a/Changelog
+++ b/Changelog
@@ -1,10 +1,19 @@
+2025-03-20 cage
+
+       Merge pull request #168 from cage2/optimize-searching-for-annotations
+
 2025-03-19 cage
 
+       * Changelog,
+       * NEWS.org,
        * annotate.el:
 
        - optimized 'annotate-annotations-overlay-in-range' by jumping from an
        annotation to another, instead of scanning every single character of
        the buffer.
+       - increased version number;
+       - updated NEWS file and changelog;
+       - fixed docstring.
 
 2025-03-06 cage
 
diff --git a/NEWS.org b/NEWS.org
index 95ea04b051..daa4ad8b37 100644
--- a/NEWS.org
+++ b/NEWS.org
@@ -1,3 +1,11 @@
+- 2025-04-23 v2.4.0 cage ::
+
+  This version adds annotation's text expansion feature:
+
+  #+BEGIN_SRC text
+  "%d foo" → "2025-04-23 foo"
+  #+END_SRC
+
 - 2025-03-05 v2.3.1 cage ::
 
   This version optimizes a function that searches for annotations in a buffer; 
this changes should speed up commands like 
~annotate-toggle-all-annotations-text~.
diff --git a/README.org b/README.org
index 5a36f2574f..b8a0b7faf4 100644
--- a/README.org
+++ b/README.org
@@ -221,6 +221,20 @@ Shows or hides the annotation's text in the whole buffer.
 **  annotate-autosave
 Whether annotations should be saved after each user action, e.g. new 
annotation created, existing one amended or deleted. Boolean value, default is 
~nil~ i.e. do not perform autosave and update the annotations in a buffer, just 
after killing buffer or quitting Emacs.
 
+** annotate-annotation-expansion-map
+
+The Expansion map for the annotation text. If a substring  in the annotation 
text matches the string in the car value of each cons cell of this alist, it is 
expanded with the results of  passing the cdr of each cell to a system shell. 
Example below.
+
+The expression:
+
+#+BEGIN_SRC lisp
+  (setf annotate-annotation-expansion-map
+       '(("%d" . "date +%Y-%m-%d")))
+#+END_SRC
+
+Will expand any occurrence of "%d" in the annotation's text with
+the current date (format: "YYYY-MM-DD").
+
 * More documentation
 
 Please check ~M-x customize-group RET annotate~ as there is extensive 
documentation for each customizable variable.
diff --git a/annotate.el b/annotate.el
index b666ae1533..3c1310fefc 100644
--- a/annotate.el
+++ b/annotate.el
@@ -7,7 +7,7 @@
 ;; Maintainer: Bastian Bechtold <bastibe....@mailbox.org>, cage 
<cage-...@twistfold.it>
 ;; URL: https://github.com/bastibe/annotate.el
 ;; Created: 2015-06-10
-;; Version: 2.3.1
+;; Version: 2.4.0
 
 ;; This file is NOT part of GNU Emacs.
 
@@ -58,7 +58,7 @@
 ;;;###autoload
 (defgroup annotate nil
   "Annotate files without changing them."
-  :version "2.3.1"
+  :version "2.4.0"
   :group 'text)
 
 (defvar annotate-mode-map
@@ -256,6 +256,18 @@ annotation as defined in the database."
 e.g. new annotation created, existing one amended or deleted."
   :type 'boolean)
 
+(defcustom annotate-annotation-expansion-map '(("%d" . "date +%Y-%m-%d"))
+  "The expansion map for the annotation text. If a substring  in the 
annotation text matches the string in the car value of each cons cell of this 
alist, it is expanded with the results of  passing the cdr of each cell to a 
system shell. Example below.
+
+The expression:
+
+(setf annotate-annotation-expansion-map
+      '((\"%d\" . \"date +%Y-%m-%d\")))
+
+Will expand any occurrence of \"%d\" in the annotation's text with
+the current date (format: \"YYYY-MM-DD\")"
+  :type  '(alist :key-type string :value-type string))
+
 (defconst annotate-prop-chain-position
   'position)
 
@@ -727,6 +739,19 @@ specified by `FROM' and `TO'."
   (cl-count-if (lambda (a) (char-equal a ?\n))
                (buffer-substring-no-properties from to)))
 
+(defun annotate--expand-annotation-text (annotation-text)
+  (cl-loop with results = annotation-text
+          for expansion in annotate-annotation-expansion-map
+          when (string-match-p (car expansion) results)
+          do (let ((expansion-results (string-trim (shell-command-to-string 
(cdr expansion)))))
+               (setf results
+                     (replace-regexp-in-string (car expansion)
+                                               expansion-results
+                                               results
+                                               t
+                                               t)))
+          finally (return results)))
+
 (defun annotate-annotate (&optional color-index)
   "Create, modify, or delete annotation.
 if `COLOR-INDEX' is not null must be an index that adresses an element both in
@@ -741,7 +766,8 @@ and
                 ;; create a new annotation in the region returned by 
`annotate-bound'
                 (cl-destructuring-bind (start end)
                     (annotate-bounds)
-                  (let ((annotation-text (read-from-minibuffer 
annotate-annotation-prompt)))
+                  (let* ((raw-text        (read-from-minibuffer 
annotate-annotation-prompt))
+                        (annotation-text (annotate--expand-annotation-text 
raw-text)))
                     (condition-case nil
                         (annotate-create-annotation start end annotation-text 
nil color-index)
                       (annotate-no-new-line-at-end-file-error

Reply via email to