Browse Source

version 5.2.1 of org-index with speed improvements

U-IHM-NOTEBOOK\Olli 8 năm trước cách đây
mục cha
commit
def8a848ba
1 tập tin đã thay đổi với 132 bổ sung86 xóa
  1. 132 86
      contrib/lisp/org-index.el

+ 132 - 86
contrib/lisp/org-index.el

@@ -3,7 +3,7 @@
 ;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
 ;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
 
 
 ;; Author: Marc Ihm <org-index@2484.de>
 ;; Author: Marc Ihm <org-index@2484.de>
-;; Version: 5.2.0
+;; Version: 5.2.1
 ;; Keywords: outlines index
 ;; Keywords: outlines index
 
 
 ;; This file is not part of GNU Emacs.
 ;; This file is not part of GNU Emacs.
@@ -55,7 +55,8 @@
 ;;  - Add these lines to your .emacs:
 ;;  - Add these lines to your .emacs:
 ;;
 ;;
 ;;    (require 'org-index)
 ;;    (require 'org-index)
-;;    (global-set-key (kbd "C-c i") 'org-index-dispatch) ; this is optional
+;;    (global-set-key (kbd "C-c i") 'org-index-dispatch) ; this is optional but recommended
+;;    (org-index-prepare-when-idle)  ; this is optional, not needed initially; see its description
 ;;
 ;;
 ;;  - Restart your Emacs to make these lines effective.
 ;;  - Restart your Emacs to make these lines effective.
 ;;
 ;;
@@ -86,9 +87,12 @@
 
 
 ;;; Change Log:
 ;;; Change Log:
 
 
-;;   [2017-01-22 Su] Version 5.2.0
+;;   [2017-01-29 Su] Version 5.2.1
 ;;   - New command 'focus'
 ;;   - New command 'focus'
+;;   - Improved on speed by using the stored property "max-ref"
+;;   - Added org-index-prepare-when-idle
 ;;   - Fixed compatibility issue with emacs 24 (font-lock-ensure)
 ;;   - Fixed compatibility issue with emacs 24 (font-lock-ensure)
+;;   - Bugfixes
 ;;
 ;;
 ;;   [2016-10-19 We] Version 5.1.4
 ;;   [2016-10-19 We] Version 5.1.4
 ;;   - Bugfixes
 ;;   - Bugfixes
@@ -268,7 +272,6 @@ those pieces."
 
 
 ;; Variables to hold the configuration of the index table
 ;; Variables to hold the configuration of the index table
 (defvar org-index--maxrefnum nil "Maximum number from reference table, e.g. 153.")
 (defvar org-index--maxrefnum nil "Maximum number from reference table, e.g. 153.")
-(defvar org-index--nextref nil "Next reference, that can be used, e.g. 'R154'.")
 (defvar org-index--head nil "Header before number (e.g. 'R').")
 (defvar org-index--head nil "Header before number (e.g. 'R').")
 (defvar org-index--tail nil "Tail after number (e.g. '}' or ')'.")
 (defvar org-index--tail nil "Tail after number (e.g. '}' or ')'.")
 (defvar org-index--numcols nil "Number of columns in index table.")
 (defvar org-index--numcols nil "Number of columns in index table.")
@@ -296,7 +299,7 @@ those pieces."
 (defvar org-index--occur-stack nil "Stack with overlays for hiding lines.")
 (defvar org-index--occur-stack nil "Stack with overlays for hiding lines.")
 (defvar org-index--occur-tail-overlay nil "Overlay to cover invisible lines.")
 (defvar org-index--occur-tail-overlay nil "Overlay to cover invisible lines.")
 (defvar org-index--occur-lines-collected 0 "Number of lines collected in occur buffer; helpful for tests.")
 (defvar org-index--occur-lines-collected 0 "Number of lines collected in occur buffer; helpful for tests.")
-(defvar org-index--last-sort nil "Last column, the index has been sorted after.")
+(defvar org-index--last-sort-assumed nil "Last column, the index has been sorted after (best guess).")
 (defvar org-index--sort-timer nil "Timer to sort index in correct order.")
 (defvar org-index--sort-timer nil "Timer to sort index in correct order.")
 (defvar org-index--aligned nil "Remember for this Emacs session, if table has been aligned at least once.")
 (defvar org-index--aligned nil "Remember for this Emacs session, if table has been aligned at least once.")
 (defvar org-index--edit-widgets nil "List of widgets used to edit.")
 (defvar org-index--edit-widgets nil "List of widgets used to edit.")
@@ -313,7 +316,7 @@ those pieces."
 (defconst org-index--valid-headings '(ref id created last-accessed count keywords category level yank tags) "All valid headings.")
 (defconst org-index--valid-headings '(ref id created last-accessed count keywords category level yank tags) "All valid headings.")
 (defconst org-index--occur-buffer-name "*org-index-occur*" "Name of occur buffer.")
 (defconst org-index--occur-buffer-name "*org-index-occur*" "Name of occur buffer.")
 (defconst org-index--edit-buffer-name "*org-index-edit*" "Name of edit buffer.")
 (defconst org-index--edit-buffer-name "*org-index-edit*" "Name of edit buffer.")
-(defconst org-index--sort-idle-delay 300 "Delay in seconds after which buffer will sorted.")
+(defconst org-index--idle-delay 68 "Delay in seconds after which buffer will sorted or fontified.")
 (defvar org-index--short-help-text nil "Cache for result of `org-index--get-short-help-text.")
 (defvar org-index--short-help-text nil "Cache for result of `org-index--get-short-help-text.")
 (defvar org-index--shortcut-chars nil "Cache for result of `org-index--get-shortcut-chars.")
 (defvar org-index--shortcut-chars nil "Cache for result of `org-index--get-shortcut-chars.")
 
 
@@ -408,13 +411,15 @@ of subcommands to choose from:
 
 
   help: Show complete help text of org-index.
   help: Show complete help text of org-index.
 
 
-  focus: [f] Return to focus-node; need to set-focus [F] before.
+  focus: [f] Return to focus-node; need to set-focus before.
     The focused node is a single and special node, the location
     The focused node is a single and special node, the location
     of which is remembered and which can be found with a single
     of which is remembered and which can be found with a single
     key-sequence; it need not be part of the index though.  This
     key-sequence; it need not be part of the index though.  This
-    can be useful, if you mostly work in one node, but make
+    can be useful, if you mostly work in a single node, but make
     frequent excursions to others.
     frequent excursions to others.
 
 
+  set-focus: [F] Set focus-node for command focus.
+
   short-help: [?] Show one-line description of each subcommand.
   short-help: [?] Show one-line description of each subcommand.
     I.e. show this list but only first sentence each.
     I.e. show this list but only first sentence each.
 
 
@@ -482,11 +487,11 @@ interactive calls."
       ;;
       ;;
 
 
       ;; lets assume, that it has been sorted this way (we try hard to make sure)
       ;; lets assume, that it has been sorted this way (we try hard to make sure)
-      (unless org-index--last-sort (setq org-index--last-sort org-index-sort-by))
+      (unless org-index--last-sort-assumed (setq org-index--last-sort-assumed org-index-sort-by))
       ;; rearrange for index beeing sorted into default sort order after 300 secs of idle time
       ;; rearrange for index beeing sorted into default sort order after 300 secs of idle time
       (unless org-index--sort-timer
       (unless org-index--sort-timer
         (setq org-index--sort-timer
         (setq org-index--sort-timer
-              (run-with-idle-timer org-index--sort-idle-delay t 'org-index--sort-silent)))
+              (run-with-idle-timer org-index--idle-delay t 'org-index--sort-silent)))
 
 
 
 
       ;;
       ;;
@@ -569,7 +574,7 @@ interactive calls."
       ;;
       ;;
 
 
       ;; Arrange for beeing able to return
       ;; Arrange for beeing able to return
-      (when (and (memq command '(occur head index example sort maintain))
+      (when (and (memq command '(occur head index example sort maintain focus))
                  (not (string= (buffer-name) org-index--occur-buffer-name)))
                  (not (string= (buffer-name) org-index--occur-buffer-name)))
         (org-mark-ring-push))
         (org-mark-ring-push))
 
 
@@ -733,15 +738,16 @@ interactive calls."
 
 
        ((eq command 'ref)
        ((eq command 'ref)
 
 
-        (let (args)
+        (let (args newref)
 
 
           (setq args (org-index--collect-values-from-user org-index-edit-on-ref))
           (setq args (org-index--collect-values-from-user org-index-edit-on-ref))
-          (setq args (plist-put args 'ref org-index--nextref))
+          (setq newref (org-index--get-save-maxref))
+          (setq args (plist-put args 'ref newref))
           (apply 'org-index--do-new-line args)
           (apply 'org-index--do-new-line args)
 
 
-          (setq kill-new-text org-index--nextref)
+          (setq kill-new-text newref)
 
 
-          (setq message-text (format "Added new row with ref '%s'" org-index--nextref))))
+          (setq message-text (format "Added new row with ref '%s'" newref))))
 
 
 
 
        ((eq command 'yank)
        ((eq command 'yank)
@@ -809,7 +815,7 @@ interactive calls."
                              ""))
                              ""))
                    (symbol-name sort)
                    (symbol-name sort)
                    org-index-sort-by
                    org-index-sort-by
-                   org-index--sort-idle-delay
+                   org-index--idle-delay
                    (second groups-and-counts)
                    (second groups-and-counts)
                    (symbol-name sort)
                    (symbol-name sort)
                    (third groups-and-counts))))
                    (third groups-and-counts))))
@@ -842,21 +848,22 @@ interactive calls."
         (if org-index--id-focused-node
         (if org-index--id-focused-node
             (let (marker)
             (let (marker)
               (setq marker (org-id-find org-index--id-focused-node 'marker))
               (setq marker (org-id-find org-index--id-focused-node 'marker))
-              (unless marker (error "Could not find focused node"))
+              (unless marker (error "Could not find focus-node"))
               (pop-to-buffer-same-window (marker-buffer marker))
               (pop-to-buffer-same-window (marker-buffer marker))
               (goto-char (marker-position marker))
               (goto-char (marker-position marker))
               (org-index--unfold-buffer)
               (org-index--unfold-buffer)
               (move-marker marker nil)
               (move-marker marker nil)
-              (setq message-text "Moved to focused node"))
-          (setq message-text "No node is focused, use set-focus")))
+              (setq message-text "Jumped to focus-node"))
+          (setq message-text "No focus-node, use set-focus")))
 
 
        
        
        ((eq command 'set-focus)
        ((eq command 'set-focus)
         (let ((focus-id (org-id-get-create)))
         (let ((focus-id (org-id-get-create)))
-          (with-current-buffer org-index--buffer
+          (save-excursion
+            (set-buffer org-index--buffer)
             (org-entry-put org-index--point "id-focused-node" focus-id)
             (org-entry-put org-index--point "id-focused-node" focus-id)
             (setq org-index--id-focused-node focus-id)
             (setq org-index--id-focused-node focus-id)
-            (setq message-text "Focus has been set on node"))))
+            (setq message-text "Focus has been set on current node"))))
 
 
        
        
        ((eq command 'maintain)
        ((eq command 'maintain)
@@ -926,11 +933,11 @@ Optional argument KEYS-VALUES specifies content of new line."
 
 
   (let ((ref (plist-get keys-values 'ref)))
   (let ((ref (plist-get keys-values 'ref)))
     (org-index--verify-id)
     (org-index--verify-id)
-    (org-index--parse-table)
+    (org-index--parse-table t)
     (if (not (memq ref  '(t nil)))
     (if (not (memq ref  '(t nil)))
         (error "Column 'ref' accepts only 't' or 'nil'"))
         (error "Column 'ref' accepts only 't' or 'nil'"))
     (when ref
     (when ref
-      (setq ref org-index--nextref)
+      (setq ref (org-index--get-save-maxref))
       (setq keys-values (plist-put keys-values 'ref ref)))
       (setq keys-values (plist-put keys-values 'ref ref)))
 
 
     (apply 'org-index--do-new-line keys-values)
     (apply 'org-index--do-new-line keys-values)
@@ -1024,7 +1031,7 @@ Optional argument WITH-SHORT-HELP displays help screen upfront."
         (end-of-line)
         (end-of-line)
         (insert " (this text)")
         (insert " (this text)")
         (goto-char (point-min))
         (goto-char (point-min))
-        (unless (= (line-number-at-pos (point-max)) (length org-index--commands))
+        (unless (= (line-number-at-pos (point-max)) (1+ (length org-index--commands)))
           (error "Internal error, unable to properly extract one-line descriptions of subcommands"))
           (error "Internal error, unable to properly extract one-line descriptions of subcommands"))
         (setq org-index--short-help-text (buffer-string)))))
         (setq org-index--short-help-text (buffer-string)))))
 
 
@@ -1260,7 +1267,7 @@ argument VALUE specifies the value to search for."
     (error "Need a value to search for"))
     (error "Need a value to search for"))
   
   
   (org-index--verify-id)
   (org-index--verify-id)
-  (org-index--parse-table)
+  (org-index--parse-table t)
 
 
   (org-index--get-line column value))
   (org-index--get-line column value))
 
 
@@ -1364,24 +1371,25 @@ Argument COLUMN and VALUE specify line to get."
   (setq org-index--within-occur (string= (buffer-name) org-index--occur-buffer-name)))
   (setq org-index--within-occur (string= (buffer-name) org-index--occur-buffer-name)))
 
 
 
 
-(defun org-index--parse-table ()
+(defun org-index--parse-table (&optional no-reformat)
   "Parse content of index table."
   "Parse content of index table."
 
 
   (let (ref-field
   (let (ref-field
-        id-field
+        ref-num
         initial-point
         initial-point
         end-of-headings
         end-of-headings
         start-of-headings)
         start-of-headings)
 
 
     (with-current-buffer org-index--buffer
     (with-current-buffer org-index--buffer
 
 
-      (setq org-index--maxrefnum 0)
       (setq initial-point (point))
       (setq initial-point (point))
 
 
       (org-index--go-below-hline)
       (org-index--go-below-hline)
+      (unless no-reformat (org-reveal))
 
 
       ;; align and fontify table once for this emacs session
       ;; align and fontify table once for this emacs session
-      (unless org-index--aligned
+      (unless (or org-index--aligned no-reformat)
+        (message "Aligning and fontifying index table (once per emacs session)...")
         (org-table-align) ; needs to happen before fontification to be effective ?
         (org-table-align) ; needs to happen before fontification to be effective ?
         (let ((is-modified (buffer-modified-p))
         (let ((is-modified (buffer-modified-p))
               (below (point)))
               (below (point)))
@@ -1394,7 +1402,7 @@ Argument COLUMN and VALUE specify line to get."
 
 
       (org-index--go-below-hline)
       (org-index--go-below-hline)
       (beginning-of-line)
       (beginning-of-line)
-
+      
       ;; get headings to display during occur
       ;; get headings to display during occur
       (setq end-of-headings (point))
       (setq end-of-headings (point))
       (while (org-at-table-p) (forward-line -1))
       (while (org-at-table-p) (forward-line -1))
@@ -1402,78 +1410,101 @@ Argument COLUMN and VALUE specify line to get."
       (setq start-of-headings (point))
       (setq start-of-headings (point))
       (setq org-index--headings-visible (substring-no-properties (org-index--copy-visible start-of-headings end-of-headings)))
       (setq org-index--headings-visible (substring-no-properties (org-index--copy-visible start-of-headings end-of-headings)))
       (setq org-index--headings (buffer-substring start-of-headings end-of-headings))
       (setq org-index--headings (buffer-substring start-of-headings end-of-headings))
-
+      
       ;; count columns
       ;; count columns
       (org-table-goto-column 100)
       (org-table-goto-column 100)
       (setq org-index--numcols (- (org-table-current-column) 1))
       (setq org-index--numcols (- (org-table-current-column) 1))
-
+      
       ;; go to top of table
       ;; go to top of table
       (while (org-at-table-p)
       (while (org-at-table-p)
         (forward-line -1))
         (forward-line -1))
       (forward-line)
       (forward-line)
-
+      
       ;; parse line of headings
       ;; parse line of headings
       (org-index--parse-headings)
       (org-index--parse-headings)
 
 
-      ;; parse list of flags
-      (goto-char org-index--point)
-
-      ;; Retrieve any decorations around the number within the first nonempty ref-field
+      ;; read property or go through table to find maximum number
       (goto-char org-index--below-hline)
       (goto-char org-index--below-hline)
-      (while (and (org-at-table-p)
-                  (not (setq ref-field (org-index--get-or-set-field 'ref))))
-        (forward-line))
-
+      (setq ref-field (or (org-entry-get org-index--point "max-ref")
+                          (org-index--migrate-maxref-to-property)))
+      
+      (unless org-index--head (org-index--get-decoration-from-ref-field ref-field))
+      (setq org-index--maxrefnum (org-index--extract-refnum ref-field))
+    
       ;; Get id of focused node (if any)
       ;; Get id of focused node (if any)
       (setq org-index--id-focused-node (org-entry-get nil "id-focused-node"))
       (setq org-index--id-focused-node (org-entry-get nil "id-focused-node"))
 
 
-      ;; Some Checking
-      (unless ref-field
-        (org-index--report-index-error "Reference column is empty"))
-
-      (unless (string-match "^\\([^0-9]*\\)\\([0-9]+\\)\\([^0-9]*\\)$" ref-field)
-        (org-index--report-index-error
-         "First reference in index table ('%s') does not contain a number" ref-field))
-
-      ;; These are the decorations used within the first ref of index
-      (setq org-index--head (match-string 1 ref-field))
-      (setq org-index--tail (match-string 3 ref-field))
-      (setq org-index--ref-regex (concat (regexp-quote org-index--head)
-                                         "\\([0-9]+\\)"
-                                         (regexp-quote org-index--tail)))
-      (setq org-index--ref-format (concat org-index--head "%d" org-index--tail))
+      ;; check, if the table still seems to be sorted mixed
+      (unless no-reformat
+        (goto-char org-index--below-hline)
+        (when (eq org-index-sort-by 'mixed)
+          (let (count-first-line count-second-line)
+            (setq count-first-line (string-to-number (concat (org-index--get-or-set-field 'count) " 0")))
+            (forward-line)
+            (setq count-second-line (string-to-number (concat (org-index--get-or-set-field 'count) " 0")))
+            (forward-line -1)
+            (if (and (string< (org-index--get-or-set-field 'last-accessed)
+                              (org-index--get-mixed-time))
+                     (< count-first-line count-second-line))
+                (org-index--do-sort-index org-index-sort-by)))))
+
+      ;; save position below hline
+      (org-index--go-below-hline)
+      ;; go back to initial position
+      (goto-char initial-point))))
 
 
-      ;; check if the table still seems to be sorted mixed
-      (goto-char org-index--below-hline)
-      (when (eq org-index-sort-by 'mixed)
-          (org-index--go-below-hline)
-          (if (string< (org-index--get-or-set-field 'last-accessed)
-                       (org-index--get-mixed-time))
-              (org-index--do-sort-index org-index-sort-by)))
-      
-      ;; Go through table to find maximum number and do some checking
-      (let ((refnum 0))
 
 
-        (while (org-at-table-p)
+(defun org-index--get-decoration-from-ref-field (ref-field)
+  (unless (string-match "^\\([^0-9]*\\)\\([0-9]+\\)\\([^0-9]*\\)$" ref-field)
+    (org-index--report-index-error
+     "Reference in index table ('%s') does not contain a number" ref-field))
 
 
-          (setq ref-field (org-index--get-or-set-field 'ref))
-          (setq id-field (org-index--get-or-set-field 'id))
+  ;; These are the decorations used within the first ref of index
+  (setq org-index--head (match-string 1 ref-field))
+  (setq org-index--tail (match-string 3 ref-field))
+  (setq org-index--ref-regex (concat (regexp-quote org-index--head)
+                                     "\\([0-9]+\\)"
+                                     (regexp-quote org-index--tail)))
+  (setq org-index--ref-format (concat org-index--head "%d" org-index--tail)))
 
 
-          (if ref-field
-              (if (string-match org-index--ref-regex ref-field)
-                  ;; grab number
-                  (setq refnum (string-to-number (match-string 1 ref-field)))
-                (kill-whole-line)
-                (message "Removing line from index-table whose ref does not contain a number")))
 
 
-          ;; check, if higher ref
-          (if (> refnum org-index--maxrefnum) (setq org-index--maxrefnum refnum))
+(defun org-index--extract-refnum (ref-field)
+  (unless (string-match org-index--ref-regex ref-field)
+    (org-index--report-index-error
+     "Reference '%s' is not formatted properly (does not match '%s')" ref-field org-index--ref-regex))
+  (string-to-number (match-string 1 ref-field)))
 
 
-          (forward-line 1)))
 
 
-      (setq org-index--nextref (format "%s%d%s" org-index--head (1+ org-index--maxrefnum) org-index--tail))
-      ;; go back to initial position
-      (goto-char initial-point))))
+(defun org-index--migrate-maxref-to-property ()
+  "One-time migration: No property; need to go through whole table once to find max"
+  (org-index--go-below-hline)
+  (let (ref-field ref)
+    (message "One-time migration to set index-property maxref...")
+    (unless org-index--maxrefnum (setq org-index--maxrefnum 0))
+    (while (org-at-table-p)
+      (setq ref-field (org-index--get-or-set-field 'ref))
+      (when ref-field
+        (unless org-index--head (org-index--get-decoration-from-ref-field ref-field))
+        (setq ref-num (org-index--extract-refnum ref-field))
+        (if (> ref-num org-index--maxrefnum) (setq org-index--maxrefnum ref-num)))
+      (forward-line))
+    (unless org-index--maxrefnum
+      (org-index--report-index-error "No reference found in property max-ref and none in index."))
+    (setq ref (org-index--get-save-maxref t))
+    (org-index--go-below-hline)
+    (message "Done.")
+    ref))          
+
+
+(defun org-index--get-save-maxref (&optional no-inc)
+  "Get next reference, increment number and store it in index"
+  (let (ref)
+    (unless no-inc (setq org-index--maxrefnum (1+ org-index--maxrefnum)))
+    (setq ref (format org-index--ref-format org-index--maxrefnum))
+    (save-excursion
+      (set-buffer org-index--buffer)
+      (org-entry-put org-index--point "max-ref" ref))
+    ref))
 
 
 
 
 (defun org-index--refresh-parse-table ()
 (defun org-index--refresh-parse-table ()
@@ -1579,7 +1610,8 @@ Argument COLUMN and VALUE specify line to get."
           ;; restore modification state
           ;; restore modification state
           (set-buffer-modified-p is-modified)))
           (set-buffer-modified-p is-modified)))
 
 
-        (setq org-index--last-sort sort))))
+      (setq org-index--last-sort-assumed sort)
+      (setq org-index--last-sort-actual sort))))
 
 
 
 
 (defun org-index--do-sort-lines (what)
 (defun org-index--do-sort-lines (what)
@@ -1767,6 +1799,7 @@ specify flag TEMPORARY for th new table temporary, maybe COMPARE it with existin
     (with-current-buffer buffer
     (with-current-buffer buffer
       (goto-char (point-max))
       (goto-char (point-max))
       (insert (format "* %s %s\n" firstref title))
       (insert (format "* %s %s\n" firstref title))
+      (org-entry-put org-index--point "max-ref" firstref)
       (if temporary
       (if temporary
           (insert "
           (insert "
   Below you find your temporary index table, which WILL NOT LAST LONGER
   Below you find your temporary index table, which WILL NOT LAST LONGER
@@ -1997,7 +2030,7 @@ specify flag TEMPORARY for th new table temporary, maybe COMPARE it with existin
         ref-field
         ref-field
         key)
         key)
 
 
-    (unless sort (setq sort org-index--last-sort)) ; use default value
+    (unless sort (setq sort org-index--last-sort-assumed)) ; use default value
 
 
     (when (or with-ref
     (when (or with-ref
               (eq sort 'ref))
               (eq sort 'ref))
@@ -2188,7 +2221,7 @@ CREATE-REF and TAG-WITH-REF if given."
 
 
       (when (and create-ref
       (when (and create-ref
                  (not ref))
                  (not ref))
-        (setq ref org-index--nextref)
+        (setq ref (org-index--get-save-maxref))
         (setq args (plist-put args 'ref ref)))
         (setq args (plist-put args 'ref ref)))
 
 
       
       
@@ -2207,7 +2240,7 @@ CREATE-REF and TAG-WITH-REF if given."
                     (cons "Updated index line" nil))))
                     (cons "Updated index line" nil))))
 
 
         ;; no id here, create new line in index
         ;; no id here, create new line in index
-        (if ref (setq ref (plist-put args 'ref org-index--nextref)))
+        (if ref (setq args (plist-put args 'ref ref)))
         (setq yank (apply 'org-index--do-new-line args))
         (setq yank (apply 'org-index--do-new-line args))
 
 
         (setq ret
         (setq ret
@@ -3015,13 +3048,26 @@ If OTHER in separate window."
   "Sort index for default column to remove any effects of temporary sorting."
   "Sort index for default column to remove any effects of temporary sorting."
   (save-excursion
   (save-excursion
     (org-index--verify-id)
     (org-index--verify-id)
-    (org-index--parse-table)
+    (org-index--parse-table t)
     (org-index--on nil nil
     (org-index--on nil nil
       (org-index--do-sort-index org-index-sort-by)
       (org-index--do-sort-index org-index-sort-by)
       (org-table-align)
       (org-table-align)
       (remove-hook 'before-save-hook 'org-index--sort-silent))))
       (remove-hook 'before-save-hook 'org-index--sort-silent))))
 
 
 
 
+(defun org-index--idle-prepare ()
+  "For parsing table when idle."
+  (org-index--verify-id)
+  (org-index--parse-table))
+
+
+(defun org-index-prepare-when-idle ()
+  "Optionally fontify and sort index-table when idle, so that first interactive call is faster.
+You only need this if your index has grown so large, that first invocation of org-index needs 
+a noticable amount of time."
+  (run-with-idle-timer org-index--idle-delay nil 'org-index--idle-prepare))
+
+
 (defun org-index--copy-visible (beg end)
 (defun org-index--copy-visible (beg end)
   "Copy the visible parts of the region between BEG and END without adding it to `kill-ring'; copy of `org-copy-visible'."
   "Copy the visible parts of the region between BEG and END without adding it to `kill-ring'; copy of `org-copy-visible'."
   (let (snippets s)
   (let (snippets s)