Hi,

First of all, finally, I opened my emacs config (I did it in a way that is easy to have private-secret-sensitive parts not published).

So now I am more tempted to share with you when I find something useful here. What do you think about this idea?!

Since long time, I was wanting to have how much time it takes to render any org-agenda view. Because when it takes too much time, then I should spend time on archiving parts of my content that could be processed by the org-agenda-files.

I did some refactor to my stats and included the rendered time, it looks like this [1], and it is displayed always at the end of the org-agenda buffer. If I press g (refresh), all vars are updated. By the way, previously the time was in inactive timestamp format, but that way, the text was swallowed by the buffer!

It was simpler than expected [2]: just an advice at the beginning of org-agenda to start counting time, and another advice at the end of org-agenda that finalizes the counting and renders the time, and also other vars. (I am only proud of the first line with the org-agenda key, render time and timestamp; the other counters might be ugly!)

This solves my problem, but I think something like that would be nice in general to be available. Or... let me know if you figure out another solution

( Attached the simple patch and the whole thing for stats so if the link [2] is broken in the future is not relevant )

With love,
pinmacs

[1]
#+begin_src text
---
 Agenda 'at' rendered in 1.54s at 2025-12-18 22:01:38
    Total Deadlines: 10
    Total Schedules: 9
    Total TODOs: 35
    Count lines: 47
#+end_src

[2] https://codeberg.org/pedroberg/pinmacs-emacs-config/commit/ad7a9d7b34ad92a9ab99b9375e756b0ddb78010f
From ad7a9d7b34ad92a9ab99b9375e756b0ddb78010f Mon Sep 17 00:00:00 2001
From: pinmacs <[email protected]>
Date: Thu, 18 Dec 2025 21:53:08 +0100
Subject: [PATCH] org-agenda: add render time to stats

---
 emacs-config.org | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/emacs-config.org b/emacs-config.org
index 0c305f4..7d5c709 100644
--- a/emacs-config.org
+++ b/emacs-config.org
@@ -6536,6 +6536,16 @@ All selected bulk entries should have same todo keywords"
 :CUSTOM_ID: emacsconf_142
 :END:
 
+#+name: sourceblock_created_2025-12-18_21-27-16
+#+begin_src emacs-lisp
+(defvar my/org-agenda-start-time nil
+  "Stores the internal time when the agenda started.")
+
+;; start counting time when enters org-agenda
+(advice-add 'org-agenda :before (lambda (&rest _)
+                                  (setq my/org-agenda-start-time (current-time))))
+#+end_src
+
 #+name: sourceblock_created_2025-01-11_02-52-08
 #+begin_src emacs-lisp
 ;; thanks chatgpt o1
@@ -6569,7 +6579,10 @@ All selected bulk entries should have same todo keywords"
     ;; save keys first time, so when in rebuild (g key, or redo) we already have it
     (if org-keys
         (setq my/org-keys-saved org-keys))
-    (let ((dead-count (count-matching-lines "d\\."))
+    (let ((count-time (if my/org-agenda-start-time
+                        (float-time (time-since my/org-agenda-start-time))
+                      0))
+          (dead-count (count-matching-lines "d\\."))
           (sched-count (count-matching-lines ":  Scheduled:"))
           (todos-count (count-matching-lines "^  \\w+: "))
           (lines-buffer (count-lines (point-min) (point-max))))
@@ -6578,7 +6591,7 @@ All selected bulk entries should have same todo keywords"
       ;;   marking an item in agenda as done
       (if (> lines-buffer 1)
           ;; Insert the total count at the end of the first line
-          (insert (format "\n (Pressed: %s)\n    Total deadlines/schedules: %d; Total TODOs: %d; count lines: %d; ts: %s" my/org-keys-saved deadsched-count todos-count lines-buffer (my/get-inactive-timestamp)))))))
+          (insert (format "\n---\n Agenda '%s' rendered in %.2fs at %s\n    Total Deadlines: %d\n    Total Schedules: %d\n    Total TODOs: %d\n    Count lines: %d" my/org-keys-saved count-time (format-time-string "%F %T") dead-count sched-count todos-count lines-buffer))))))
 
 (add-hook 'org-agenda-finalize-hook 'my/org-agenda-custom-stats)
 #+end_src
**** org-agenda hooks
:PROPERTIES:
:CREATED:  [2025-01-11 Sat 02:52]
:CUSTOM_ID: emacsconf_142
:END:

#+name: sourceblock_created_2025-12-18_21-27-16
#+begin_src emacs-lisp
(defvar my/org-agenda-start-time nil
  "Stores the internal time when the agenda started.")

;; start counting time when enters org-agenda
(advice-add 'org-agenda :before (lambda (&rest _)
                                  (setq my/org-agenda-start-time (current-time))))
#+end_src

#+name: sourceblock_created_2025-01-11_02-52-08
#+begin_src emacs-lisp
;; thanks chatgpt o1
(defun my/org-agenda-hide-inactive-timestamps ()
  "Hide inactive timestamps (like [2024-12-28 Sat]) from agenda entries."
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "\\[[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}[^]]*\\]" nil t)
      (replace-match "" nil nil))))

(add-hook 'org-agenda-finalize-hook #'my/org-agenda-hide-inactive-timestamps)

;; count real lines I want
(defun count-matching-lines (pattern)
  "Count the number of lines in the current buffer that match PATTERN."
  (save-excursion
    (goto-char (point-min))
    (let ((count 0))
      (while (re-search-forward pattern nil t)
        (setq count (1+ count)))
      count)))
;; works as I want!
;;   (count-matching-lines "d\\.")
(defun my/org-agenda-custom-stats ()
  ;;(when (equal org-keys "t"))  ; Check if it's the custom agenda view
  (save-excursion  ; Ensure the point position is not changed
    ;;(goto-char (point-min))  ; Go to the beginning of the buffer
    ;;(end-of-line)
    ;; TODO stats better on the bottom (because I started using org-ql-block and it is more convenient)
    (end-of-buffer)
    ;; save keys first time, so when in rebuild (g key, or redo) we already have it
    (if org-keys
        (setq my/org-keys-saved org-keys))
    (let ((count-time (if my/org-agenda-start-time
                        (float-time (time-since my/org-agenda-start-time))
                      0))
          (dead-count (count-matching-lines "d\\."))
          (sched-count (count-matching-lines ":  Scheduled:"))
          (todos-count (count-matching-lines "^  \\w+: "))
          (lines-buffer (count-lines (point-min) (point-max))))
      ;; only make it when buffer has more than 1 line, this is
      ;;   because this function-hook is also triggered when
      ;;   marking an item in agenda as done
      (if (> lines-buffer 1)
          ;; Insert the total count at the end of the first line
          (insert (format "\n---\n Agenda '%s' rendered in %.2fs at %s\n    Total Deadlines: %d\n    Total Schedules: %d\n    Total TODOs: %d\n    Count lines: %d" my/org-keys-saved count-time (format-time-string "%F %T") dead-count sched-count todos-count lines-buffer))))))

(add-hook 'org-agenda-finalize-hook 'my/org-agenda-custom-stats)
#+end_src

Reply via email to