Browse Source

Merge branch 'bugfix'

Ihor Radchenko 3 years ago
parent
commit
685d78f63c
2 changed files with 56 additions and 15 deletions
  1. 27 15
      lisp/oc-basic.el
  2. 29 0
      lisp/org-compat.el

+ 27 - 15
lisp/oc-basic.el

@@ -233,6 +233,8 @@ Return a hash table with citation references as keys and fields alist as values.
                 entries)))
                 entries)))
     entries))
     entries))
 
 
+(defvar org-cite-basic--file-id-cache nil
+  "Hash table linking files to their hash.")
 (defun org-cite-basic--parse-bibliography (&optional info)
 (defun org-cite-basic--parse-bibliography (&optional info)
   "List all entries available in the buffer.
   "List all entries available in the buffer.
 
 
@@ -245,14 +247,19 @@ table where keys are references and values are association lists between fields,
 as symbols, and values as strings or nil.
 as symbols, and values as strings or nil.
 
 
 Optional argument INFO is the export state, as a property list."
 Optional argument INFO is the export state, as a property list."
+  (unless (hash-table-p org-cite-basic--file-id-cache)
+    (setq org-cite-basic--file-id-cache (make-hash-table :test #'equal)))
   (if (plist-member info :cite-basic/bibliography)
   (if (plist-member info :cite-basic/bibliography)
       (plist-get info :cite-basic/bibliography)
       (plist-get info :cite-basic/bibliography)
     (let ((results nil))
     (let ((results nil))
       (dolist (file (org-cite-list-bibliography-files))
       (dolist (file (org-cite-list-bibliography-files))
         (when (file-readable-p file)
         (when (file-readable-p file)
           (with-temp-buffer
           (with-temp-buffer
-            (insert-file-contents file)
-	    (let* ((file-id (cons file (org-buffer-hash)))
+            (when (or (org-file-has-changed-p file)
+                      (not (gethash file org-cite-basic--file-id-cache)))
+              (insert-file-contents file)
+              (puthash file (org-buffer-hash) org-cite-basic--file-id-cache))
+	    (let* ((file-id (cons file (gethash file org-cite-basic--file-id-cache)))
                    (entries
                    (entries
                     (or (cdr (assoc file-id org-cite-basic--bibliography-cache))
                     (or (cdr (assoc file-id org-cite-basic--bibliography-cache))
                         (let ((table
                         (let ((table
@@ -753,19 +760,24 @@ Return nil if there are no bibliography files or no entries."
      (t
      (t
       (clrhash org-cite-basic--completion-cache)
       (clrhash org-cite-basic--completion-cache)
       (dolist (key (org-cite-basic--all-keys))
       (dolist (key (org-cite-basic--all-keys))
-        (let ((completion
-               (concat
-                (let ((author (org-cite-basic--get-author key nil 'raw)))
-                  (if author
-                      (truncate-string-to-width
-                       (replace-regexp-in-string " and " "; " author)
-                       org-cite-basic-author-column-end nil ?\s)
-                    (make-string org-cite-basic-author-column-end ?\s)))
-                org-cite-basic-column-separator
-                (let ((date (org-cite-basic--get-year key nil 'no-suffix)))
-                  (format "%4s" (or date "")))
-                org-cite-basic-column-separator
-                (org-cite-basic--get-field 'title key nil t))))
+        (let* ((entry (org-cite-basic--get-entry
+                       key
+                       ;; Supply pre-calculated bibliography to avoid
+                       ;; performance degradation.
+                       (list :cite-basic/bibliography entries)))
+               (completion
+                (concat
+                 (let ((author (org-cite-basic--get-author entry nil 'raw)))
+                   (if author
+                       (truncate-string-to-width
+                        (replace-regexp-in-string " and " "; " author)
+                        org-cite-basic-author-column-end nil ?\s)
+                     (make-string org-cite-basic-author-column-end ?\s)))
+                 org-cite-basic-column-separator
+                 (let ((date (org-cite-basic--get-year entry nil 'no-suffix)))
+                   (format "%4s" (or date "")))
+                 org-cite-basic-column-separator
+                 (org-cite-basic--get-field 'title entry nil t))))
           (puthash completion key org-cite-basic--completion-cache)))
           (puthash completion key org-cite-basic--completion-cache)))
       (unless (map-empty-p org-cite-basic--completion-cache) ;no key
       (unless (map-empty-p org-cite-basic--completion-cache) ;no key
         (puthash entries t org-cite-basic--completion-cache)
         (puthash entries t org-cite-basic--completion-cache)

+ 29 - 0
lisp/org-compat.el

@@ -73,6 +73,35 @@
 (defvar org-table-tab-recognizes-table.el)
 (defvar org-table-tab-recognizes-table.el)
 (defvar org-table1-hline-regexp)
 (defvar org-table1-hline-regexp)
 
 
+
+;;; Emacs < 29 compatibility
+
+(defvar org-file-has-changed-p--hash-table (make-hash-table :test #'equal)
+  "Internal variable used by `org-file-has-changed-p'.")
+
+(if (fboundp 'file-has-changed-p)
+    (defalias 'org-file-has-changed-p #'file-has-changed-p)
+  (defun org-file-has-changed-p (file &optional tag)
+    "Return non-nil if FILE has changed.
+The size and modification time of FILE are compared to the size
+and modification time of the same FILE during a previous
+invocation of `org-file-has-changed-p'.  Thus, the first invocation
+of `org-file-has-changed-p' always returns non-nil when FILE exists.
+The optional argument TAG, which must be a symbol, can be used to
+limit the comparison to invocations with identical tags; it can be
+the symbol of the calling function, for example."
+    (let* ((file (directory-file-name (expand-file-name file)))
+           (remote-file-name-inhibit-cache t)
+           (fileattr (file-attributes file 'integer))
+	   (attr (and fileattr
+                      (cons (file-attribute-size fileattr)
+		            (file-attribute-modification-time fileattr))))
+	   (sym (concat (symbol-name tag) "@" file))
+	   (cachedattr (gethash sym org-file-has-changed-p--hash-table)))
+      (when (not (equal attr cachedattr))
+        (puthash sym attr org-file-has-changed-p--hash-table)))))
+
+
 
 
 ;;; Emacs < 28.1 compatibility
 ;;; Emacs < 28.1 compatibility