diff --git a/lisp/org-id.el b/lisp/org-id.el index 296861002..8e86c5434 100644 --- a/lisp/org-id.el +++ b/lisp/org-id.el @@ -446,81 +446,56 @@ and time is the usual three-integer representation of time." Store the relation between files and corresponding IDs. This will scan all agenda files, all associated archives, and all files currently mentioned in `org-id-locations'. -When FILES is given, scan these files instead." +When FILES is given, scan also these files." (interactive) (if (not org-id-track-globally) (error "Please turn on `org-id-track-globally' if you want to track IDs") - (let* ((org-id-search-archives - (or org-id-search-archives - (and (symbolp org-id-extra-files) - (symbol-value org-id-extra-files) - (member 'agenda-archives org-id-extra-files)))) - (files - (or files - (append - ;; Agenda files and all associated archives - (org-agenda-files t org-id-search-archives) - ;; Explicit extra files - (if (symbolp org-id-extra-files) - (symbol-value org-id-extra-files) - org-id-extra-files) - ;; Files associated with live Org buffers - (delq nil - (mapcar (lambda (b) - (with-current-buffer b - (and (derived-mode-p 'org-mode) (buffer-file-name)))) - (buffer-list))) - ;; All files known to have IDs - org-id-files))) - org-agenda-new-buffers - file nfiles tfile ids reg found id seen (ndup 0)) - (when (member 'agenda-archives files) - (setq files (delq 'agenda-archives (copy-sequence files)))) - (setq nfiles (length files)) - (while (setq file (pop files)) - (unless silent - (message "Finding ID locations (%d/%d files): %s" - (- nfiles (length files)) nfiles file)) - (setq tfile (file-truename file)) - (when (and (file-exists-p file) (not (member tfile seen))) - (push tfile seen) - (setq ids nil) - (with-current-buffer (org-get-agenda-file-buffer file) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward "^[ \t]*:ID:[ \t]+\\(\\S-+\\)[ \t]*$" - nil t) - (setq id (match-string-no-properties 1)) - (if (member id found) - (progn - (message "Duplicate ID \"%s\", also in file %s" - id (or (car (delq - nil - (mapcar - (lambda (x) - (if (member id (cdr x)) - (car x))) - reg))) - (buffer-file-name))) - (when (= ndup 0) - (ding) - (sit-for 2)) - (setq ndup (1+ ndup))) - (push id found) - (push id ids))) - (push (cons (abbreviate-file-name file) ids) reg)))))) - (org-release-buffers org-agenda-new-buffers) - (setq org-agenda-new-buffers nil) - (setq org-id-locations reg) + (let* ((files (delete-dups + (mapcar #'file-truename + (append + ;; Agenda files and all associated archives + (org-agenda-files t org-id-search-archives) + ;; Explicit extra files + (unless (symbolp org-id-extra-files) + org-id-extra-files) + ;; All files known to have IDs + org-id-files + ;; function input + files)))) + (nfiles (length files)) + ids seen-ids (ndup 0) (i 0) file-id-alist) + (with-temp-buffer + (delay-mode-hooks + (org-mode) + (dolist (file files) + (unless silent + (setq i (1+ i)) + (message "Finding ID locations (%d/%d files): %s" + i nfiles file)) + (when (file-exists-p file) + (insert-file-contents file nil nil nil 'replace) + (setq ids (org-map-entries + (lambda () + (org-entry-get (point) "ID")) + "ID<>\"\"")) + (dolist (id ids) + (if (member id seen-ids) + (progn + (message "Duplicate ID \"%s\"" id) + (setq ndup (1+ ndup))) + (push id seen-ids))) + (when ids + (setq file-id-alist (cons (cons (abbreviate-file-name file) ids) + file-id-alist))))))) + (setq org-id-locations file-id-alist) (setq org-id-files (mapcar 'car org-id-locations)) - (org-id-locations-save) ;; this function can also handle the alist form + (org-id-locations-save) ;; now convert to a hash (setq org-id-locations (org-id-alist-to-hash org-id-locations)) - (if (> ndup 0) - (message "WARNING: %d duplicate IDs found, check *Messages* buffer" ndup) - (message "%d unique files scanned for IDs" (length org-id-files))) + (when (> ndup 0) + (warn "WARNING: %d duplicate IDs found, check *Messages* buffer" ndup)) + (message "%d files scanned, %d files contains IDs and in total %d IDs found." + nfiles (length org-id-files) (hash-table-count org-id-locations)) org-id-locations))) (defun org-id-locations-save () @@ -552,10 +527,12 @@ When FILES is given, scan these files instead." (defun org-id-add-location (id file) "Add the ID with location FILE to the database of ID locations." ;; Only if global tracking is on, and when the buffer has a file - (when (and org-id-track-globally id file) - (unless org-id-locations (org-id-locations-load)) - (puthash id (abbreviate-file-name file) org-id-locations) - (add-to-list 'org-id-files (abbreviate-file-name file)))) + (let ((afile (abbreviate-file-name file))) + (when (and org-id-track-globally id file) + (unless org-id-locations (org-id-locations-load)) + (puthash id afile org-id-locations) + (unless (member afile org-id-files) + (add-to-list 'org-id-files afile))))) (unless noninteractive (add-hook 'kill-emacs-hook 'org-id-locations-save)) @@ -565,7 +542,7 @@ When FILES is given, scan these files instead." (let (res x) (maphash (lambda (k v) - (if (setq x (member v res)) + (if (setq x (assoc v res)) (setcdr x (cons k (cdr x))) (push (list v k) res))) hash)