diff --git a/doc/org.texi b/doc/org.texi index 0bfee39ab..025baaaa3 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -10247,13 +10247,15 @@ argument to the @code{@{@{@{date@}@}@}} macro that will be used only if understood by @code{format-time-string}. @item @{@{@{time(@var{FORMAT})@}@}@} -@itemx @{@{@{modification-time(@var{FORMAT})@}@}@} +@itemx @{@{@{modification-time(@var{FORMAT}, @var{VC})@}@}@} @cindex time, macro @cindex modification time, macro These macros refer to the date and time when the document is exported and to -the modification date and time of the file being exported, respectively. -@var{FORMAT} should be a format string understood by -@code{format-time-string}. +the modification date and time, respectively. @var{FORMAT} should be a +format string understood by @code{format-time-string}. If the second +argument to the @code{modification-time} macro is non-@code{nil}, Org +retrieves the information from the version control system, using +@file{vc.el}, instead of the file attributes. @item @{@{@{input-file@}@}@} @cindex input file, macro diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 7a0a8908d..e46a08b08 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -105,6 +105,9 @@ becomes : ("pdf" . (lambda (file link) (foo))) +*** The ~{{{modification-time}}}~ macro can obtain time via =vc= +The modification time will be determined via =vc.el= if the second +argument is non-nil. See the manual for details. ** New features *** New org-protocol key=value syntax diff --git a/lisp/org-macro.el b/lisp/org-macro.el index e13537429..a838b9ea5 100644 --- a/lisp/org-macro.el +++ b/lisp/org-macro.el @@ -58,6 +58,10 @@ (declare-function org-file-contents "org" (file &optional noerror)) (declare-function org-mode "org" ()) (declare-function org-remove-double-quotes "org" (s)) +(declare-function org-with-wide-buffer "org-macs" (&rest body)) +(declare-function vc-backend "vc-hooks" (f)) +(declare-function vc-call "vc-hooks" (&rest args)) +(declare-function vc-exec-after "vc-dispatcher" (code)) ;;; Variables @@ -145,7 +149,8 @@ function installs the following ones: \"property\", (mapc update-templates (list (cons "input-file" (file-name-nondirectory visited-file)) (cons "modification-time" - (format "(eval (format-time-string \"$1\" '%s))" + (format "(eval (format-time-string \"$1\" (or (and (org-string-nw-p \"$2\") (org-macro--vc-modified-time %s)) '%s)))" + (prin1-to-string visited-file) (prin1-to-string (nth 5 (file-attributes visited-file))))))))) (setq org-macro-templates templates))) @@ -276,6 +281,30 @@ Return a list of arguments, as strings. This is the opposite of s nil t) "\000")) +(defun org-macro--vc-modified-time (file) + (save-window-excursion + (when (vc-backend file) + (let ((buf (get-buffer-create " *org-vc*")) + (case-fold-search t) + date) + (unwind-protect + (progn + (vc-call print-log file buf nil nil 1) + (with-current-buffer buf + (vc-exec-after + (lambda () + (goto-char (point-min)) + (when (re-search-forward "Date:?[ \t]*" nil t) + (let ((time (parse-time-string + (buffer-substring + (point) (line-end-position))))) + (when (cl-some #'identity time) + (setq date (apply #'encode-time time)))))))) + (let ((proc (get-buffer-process buf))) + (while (and proc (accept-process-output proc .5 nil t))))) + (kill-buffer buf)) + date)))) + (provide 'org-macro) ;;; org-macro.el ends here