Hello,

When using org-clock-report I noticed that it can't handle directories
unlike org-agenda-files. I refactored the file handling from
org-agenda-files to be reuseable so it can be used in org-clock-report.

I wasn't sure on the wording of the name of the helper function. Feel
free to suggest different naming.

I also fixed the make target to install the githooks to work with
submodules.

Br,

Björn

>From 5c2369825d472e5feaaf63572d43c1babe1b599c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Kettunen?= <[email protected]>
Date: Tue, 3 Mar 2026 22:47:12 +0200
Subject: [PATCH 1/2] org-clock: clock-report be able to also take directories

* lisp/org-clock.el (org-dblock-write:clocktable): Expand
files in directories if any of the entries in scope is a directory.
Just like in org-agenda-files.

* lisp/org.el (org-file-list-expand):
(org-agenda-files): Refactor file expansion into separate function.

* doc/org-manual.org: Document.
* etc/ORG-NEWS: Announce
---
 doc/org-manual.org |  2 +-
 etc/ORG-NEWS       |  9 +++++++++
 lisp/org-clock.el  |  3 +++
 lisp/org.el        | 20 +++++++++++++-------
 4 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index 9c4c27877..cfcf8994b 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -7109,7 +7109,7 @@ *** The clock table
   | =treeN=                | the surrounding level N tree, for example =tree3=                   |
   | =tree=                 | the surrounding level 1 tree                                        |
   | =agenda=               | all agenda files                                                    |
-  | =("file" ...)=         | scan these files                                                    |
+  | =("file" "dir" "...)=  | scan these files or files in directories                            |
   | =FUNCTION=             | scan files returned by calling {{{var(FUNCTION)}}} with no argument |
   | =file-with-archives=   | current file and its archives                                       |
   | =agenda-with-archives= | all agenda files, including archives                                |
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 40fa1e6aa..3a7011a7a 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -40,6 +40,11 @@ into a "Tags" section and a "Priorities" section.
 Priorities can now be increased, decreased, set to the default, and
 set interactively from the priority context menus.
 
+*** Clocktable option =:scope %= list of files can now also include directories
+
+The scope option can now also include directories in the list of files.
+Files are resolved just like in ~org-agenda-files~.
+
 ** New and changed options
 
 # Changes dealing with changing default values of customizations,
@@ -60,6 +65,10 @@ variable.
 Given the completed and total number of tasks, format the percent
 cookie =[N%]=.
 
+*** New function ~org-file-list-expand~
+
+Expand list of flies according to ~org-agenda-file-regexp~.
+
 ** Removed or renamed functions and variables
 
 ** Miscellaneous
diff --git a/lisp/org-clock.el b/lisp/org-clock.el
index ce2d23a9b..b207724bf 100644
--- a/lisp/org-clock.el
+++ b/lisp/org-clock.el
@@ -2718,6 +2718,9 @@ (defun org-dblock-write:clocktable (params)
 	(org-clocktable-steps params)
 	(throw 'exit nil))
 
+      (when (consp files)
+        (setq files (org-file-list-expand files)))
+
       (org-agenda-prepare-buffers (if (consp files) files (list files)))
 
       (let ((origin (point))
diff --git a/lisp/org.el b/lisp/org.el
index fc51d4ba3..73829b946 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -15977,6 +15977,18 @@ (defun org-switchb (&optional arg)
 		      (mapcar #'list (mapcar #'buffer-name blist))
 		      nil t))))
 
+
+(defun org-file-list-expand (files)
+  "Expand list of FILES according to `org-agenda-file-regexp'."
+  (apply 'append
+	 (mapcar (lambda (f)
+		   (if (file-directory-p f)
+		       (directory-files
+			f t org-agenda-file-regexp)
+		     (list (expand-file-name f org-directory))))
+		 files)))
+
+
 (defun org-agenda-files (&optional unrestricted archives)
   "Get the list of agenda files.
 Optional UNRESTRICTED means return the full list even if a restriction
@@ -15990,13 +16002,7 @@ (defun org-agenda-files (&optional unrestricted archives)
 	  ((stringp org-agenda-files) (org-read-agenda-file-list))
 	  ((listp org-agenda-files) org-agenda-files)
 	  (t (error "Invalid value of `org-agenda-files'")))))
-    (setq files (apply 'append
-		       (mapcar (lambda (f)
-				 (if (file-directory-p f)
-				     (directory-files
-				      f t org-agenda-file-regexp)
-				   (list (expand-file-name f org-directory))))
-			       files)))
+    (setq files (org-file-list-expand files))
     (when org-agenda-skip-unavailable-files
       (setq files (delq nil
 			(mapcar (lambda (file)
-- 
2.53.0

>From d51062bd09f41ffbc382d2b28293622a33c26be0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Kettunen?= <[email protected]>
Date: Tue, 3 Mar 2026 22:33:27 +0200
Subject: [PATCH 2/2] * mk/targets.mk (GIT_HOOKS): Resolve correctly when in
 submodule

Requires at least Git 2.10, released in 2016 Q3.
---
 mk/targets.mk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mk/targets.mk b/mk/targets.mk
index cedde0522..fbcb85a0b 100644
--- a/mk/targets.mk
+++ b/mk/targets.mk
@@ -9,7 +9,7 @@ SUBDIRS       = $(OTHERDIRS) $(LISPDIRS)
 INSTSUB       = $(SUBDIRS:%=install-%)
 ORG_MAKE_DOC ?= info html pdf
 
-GITDIR        = .git/hooks
+GITDIR        = $(shell git rev-parse --git-path hooks)
 GITHOOKS      = commit-msg commit-msg-files.awk post-commit pre-commit prepare-commit-msg pre-push
 
 ifneq ($(wildcard .git),)
-- 
2.53.0

Reply via email to