branch: elpa/annotate
commit fdf41ed93a31386a8b4fddaf01f15ee256e2f91f
Merge: 7b1c5aa531 65338aff67
Author: cage2 <1257703+ca...@users.noreply.github.com>
Commit: GitHub <nore...@github.com>

    Merge pull request #169 from cage2/master
    
    Added annotation's text expansion feature
---
 Changelog   |  9 +++++++++
 NEWS.org    |  8 ++++++++
 README.org  | 13 +++++++++++++
 annotate.el | 41 +++++++++++++++++++++++++++++++++++++----
 4 files changed, 67 insertions(+), 4 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..036c875cbd 100644
--- a/README.org
+++ b/README.org
@@ -221,6 +221,19 @@ 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 first item of each element of this list, it will 
be expanded with the results of passing the second item — as a command — to a 
system shell, if the third item is not null, the output string of the command's 
results will be trimmed (spaces or some others non printable characters will be 
removed from both ends, see: `string-trim'). Example below.
+
+The expression:
+
+#+BEGIN_SRC lisp
+  (setf annotate-annotation-expansion-map
+       '((\"%d\" \"date +%Y-%m-%d\" t)))
+#+END_SRC
+
+Will expand any occurrence of \"%d\" in the annotation's text with the current 
date (format: \"YYYY-MM-DD\"), moreover the results will be trimmed.
+
 * 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..fbaa32b382 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
@@ -251,11 +251,22 @@ of lines. The center of the region is the position of the
 annotation as defined in the database."
   :type 'number)
 
-(defcustom annotate-autosave nil
+(defcustom annotate-autosave t
   "Whether annotations should be saved after each user action,
 e.g. new annotation created, existing one amended or deleted."
   :type 'boolean)
 
+(defcustom annotate-annotation-expansion-map '()
+  "The expansion map for the annotation text. If a substring in the annotation 
text matches the string in the first item of each element of this list, it is 
expanded with the results of  passing the second item — as a command — to a 
system shell, if the third item is not null, the output string of the command's 
results are trimmed (spaces or some others non printable characters are removed 
from both ends, see: `string-trim'). Example below.
+
+The expression:
+
+(setf annotate-annotation-expansion-map
+      '((\"%d\" \"date +%Y-%m-%d\" t)))
+
+Will expand any occurrence of \"%d\" in the annotation's text with the current 
date (format: \"YYYY-MM-DD\"), moreover the results will be trimmed"
+  :type '(repeat (list string string boolean)))
+
 (defconst annotate-prop-chain-position
   'position)
 
@@ -727,6 +738,27 @@ 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-flet ((regex (expansion-item)
+                  (cl-first expansion-item))
+           (trimp (expansion-item)
+                  (cl-third expansion-item))
+           (command (expansion-item)
+                    (cl-second expansion-item)))
+  (cl-loop with results = annotation-text
+          for expansion in annotate-annotation-expansion-map
+          when (string-match-p (regex expansion) results)
+          do (let ((expansion-results (shell-command-to-string (command 
expansion))))
+               (when (trimp expansion)
+                 (setf expansion-results (string-trim expansion-results)))
+               (setf results
+                     (replace-regexp-in-string (regex 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 +773,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