version 5.2.1 of org-index with speed improvements
This commit is contained in:
parent
401eecb52c
commit
def8a848ba
|
@ -3,7 +3,7 @@
|
|||
;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Marc Ihm <org-index@2484.de>
|
||||
;; Version: 5.2.0
|
||||
;; Version: 5.2.1
|
||||
;; Keywords: outlines index
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
@ -55,7 +55,8 @@
|
|||
;; - Add these lines to your .emacs:
|
||||
;;
|
||||
;; (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.
|
||||
;;
|
||||
|
@ -86,9 +87,12 @@
|
|||
|
||||
;;; Change Log:
|
||||
|
||||
;; [2017-01-22 Su] Version 5.2.0
|
||||
;; [2017-01-29 Su] Version 5.2.1
|
||||
;; - 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)
|
||||
;; - Bugfixes
|
||||
;;
|
||||
;; [2016-10-19 We] Version 5.1.4
|
||||
;; - Bugfixes
|
||||
|
@ -268,7 +272,6 @@ those pieces."
|
|||
|
||||
;; 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--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--tail nil "Tail after number (e.g. '}' or ')'.")
|
||||
(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-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--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--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.")
|
||||
|
@ -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--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--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--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.
|
||||
|
||||
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
|
||||
of which is remembered and which can be found with a single
|
||||
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.
|
||||
|
||||
set-focus: [F] Set focus-node for command focus.
|
||||
|
||||
short-help: [?] Show one-line description of each subcommand.
|
||||
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)
|
||||
(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
|
||||
(unless 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
|
||||
(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)))
|
||||
(org-mark-ring-push))
|
||||
|
||||
|
@ -733,15 +738,16 @@ interactive calls."
|
|||
|
||||
((eq command 'ref)
|
||||
|
||||
(let (args)
|
||||
(let (args newref)
|
||||
|
||||
(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)
|
||||
|
||||
(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)
|
||||
|
@ -809,7 +815,7 @@ interactive calls."
|
|||
""))
|
||||
(symbol-name sort)
|
||||
org-index-sort-by
|
||||
org-index--sort-idle-delay
|
||||
org-index--idle-delay
|
||||
(second groups-and-counts)
|
||||
(symbol-name sort)
|
||||
(third groups-and-counts))))
|
||||
|
@ -842,21 +848,22 @@ interactive calls."
|
|||
(if org-index--id-focused-node
|
||||
(let (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))
|
||||
(goto-char (marker-position marker))
|
||||
(org-index--unfold-buffer)
|
||||
(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)
|
||||
(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)
|
||||
(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)
|
||||
|
@ -926,11 +933,11 @@ Optional argument KEYS-VALUES specifies content of new line."
|
|||
|
||||
(let ((ref (plist-get keys-values 'ref)))
|
||||
(org-index--verify-id)
|
||||
(org-index--parse-table)
|
||||
(org-index--parse-table t)
|
||||
(if (not (memq ref '(t nil)))
|
||||
(error "Column 'ref' accepts only 't' or 'nil'"))
|
||||
(when ref
|
||||
(setq ref org-index--nextref)
|
||||
(setq ref (org-index--get-save-maxref))
|
||||
(setq keys-values (plist-put keys-values 'ref ref)))
|
||||
|
||||
(apply 'org-index--do-new-line keys-values)
|
||||
|
@ -1024,7 +1031,7 @@ Optional argument WITH-SHORT-HELP displays help screen upfront."
|
|||
(end-of-line)
|
||||
(insert " (this text)")
|
||||
(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"))
|
||||
(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"))
|
||||
|
||||
(org-index--verify-id)
|
||||
(org-index--parse-table)
|
||||
(org-index--parse-table t)
|
||||
|
||||
(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)))
|
||||
|
||||
|
||||
(defun org-index--parse-table ()
|
||||
(defun org-index--parse-table (&optional no-reformat)
|
||||
"Parse content of index table."
|
||||
|
||||
(let (ref-field
|
||||
id-field
|
||||
ref-num
|
||||
initial-point
|
||||
end-of-headings
|
||||
start-of-headings)
|
||||
|
||||
(with-current-buffer org-index--buffer
|
||||
|
||||
(setq org-index--maxrefnum 0)
|
||||
(setq initial-point (point))
|
||||
|
||||
(org-index--go-below-hline)
|
||||
(unless no-reformat (org-reveal))
|
||||
|
||||
;; 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 ?
|
||||
(let ((is-modified (buffer-modified-p))
|
||||
(below (point)))
|
||||
|
@ -1394,7 +1402,7 @@ Argument COLUMN and VALUE specify line to get."
|
|||
|
||||
(org-index--go-below-hline)
|
||||
(beginning-of-line)
|
||||
|
||||
|
||||
;; get headings to display during occur
|
||||
(setq end-of-headings (point))
|
||||
(while (org-at-table-p) (forward-line -1))
|
||||
|
@ -1402,80 +1410,103 @@ Argument COLUMN and VALUE specify line to get."
|
|||
(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 (buffer-substring start-of-headings end-of-headings))
|
||||
|
||||
|
||||
;; count columns
|
||||
(org-table-goto-column 100)
|
||||
(setq org-index--numcols (- (org-table-current-column) 1))
|
||||
|
||||
|
||||
;; go to top of table
|
||||
(while (org-at-table-p)
|
||||
(forward-line -1))
|
||||
(forward-line)
|
||||
|
||||
|
||||
;; parse line of 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)
|
||||
(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)
|
||||
(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"))
|
||||
;; 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)))))
|
||||
|
||||
(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
|
||||
(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)
|
||||
|
||||
(setq ref-field (org-index--get-or-set-field 'ref))
|
||||
(setq id-field (org-index--get-or-set-field 'id))
|
||||
|
||||
(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))
|
||||
|
||||
(forward-line 1)))
|
||||
|
||||
(setq org-index--nextref (format "%s%d%s" org-index--head (1+ org-index--maxrefnum) org-index--tail))
|
||||
;; save position below hline
|
||||
(org-index--go-below-hline)
|
||||
;; go back to initial position
|
||||
(goto-char initial-point))))
|
||||
|
||||
|
||||
(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))
|
||||
|
||||
;; 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)))
|
||||
|
||||
|
||||
(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)))
|
||||
|
||||
|
||||
(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 ()
|
||||
"Fast refresh of selected results of parsing index table."
|
||||
|
||||
|
@ -1579,7 +1610,8 @@ Argument COLUMN and VALUE specify line to get."
|
|||
;; restore modification state
|
||||
(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)
|
||||
|
@ -1767,6 +1799,7 @@ specify flag TEMPORARY for th new table temporary, maybe COMPARE it with existin
|
|||
(with-current-buffer buffer
|
||||
(goto-char (point-max))
|
||||
(insert (format "* %s %s\n" firstref title))
|
||||
(org-entry-put org-index--point "max-ref" firstref)
|
||||
(if temporary
|
||||
(insert "
|
||||
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
|
||||
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
|
||||
(eq sort 'ref))
|
||||
|
@ -2188,7 +2221,7 @@ CREATE-REF and TAG-WITH-REF if given."
|
|||
|
||||
(when (and create-ref
|
||||
(not ref))
|
||||
(setq ref org-index--nextref)
|
||||
(setq ref (org-index--get-save-maxref))
|
||||
(setq args (plist-put args 'ref ref)))
|
||||
|
||||
|
||||
|
@ -2207,7 +2240,7 @@ CREATE-REF and TAG-WITH-REF if given."
|
|||
(cons "Updated index line" nil))))
|
||||
|
||||
;; 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 ret
|
||||
|
@ -3015,13 +3048,26 @@ If OTHER in separate window."
|
|||
"Sort index for default column to remove any effects of temporary sorting."
|
||||
(save-excursion
|
||||
(org-index--verify-id)
|
||||
(org-index--parse-table)
|
||||
(org-index--parse-table t)
|
||||
(org-index--on nil nil
|
||||
(org-index--do-sort-index org-index-sort-by)
|
||||
(org-table-align)
|
||||
(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)
|
||||
"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)
|
||||
|
|
Loading…
Reference in New Issue