|
@@ -3,7 +3,7 @@
|
|
|
;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
|
|
|
|
|
;; Author: Marc Ihm <org-index@2484.de>
|
|
|
-;; Version: 5.3.0
|
|
|
+;; Version: 5.4.0
|
|
|
;; Keywords: outlines index
|
|
|
|
|
|
;; This file is not part of GNU Emacs.
|
|
@@ -85,6 +85,12 @@
|
|
|
|
|
|
;;; Change Log:
|
|
|
|
|
|
+;; [2017-05-20 Sa] Version 5.4.0
|
|
|
+;; - Dedicated submenu for focus operations
|
|
|
+;; - Occur accepts a numeric argument as a day span
|
|
|
+;; - New customization `org-index-clock-into-focus'
|
|
|
+;; - Fixed delay after choosing an index line
|
|
|
+;;
|
|
|
;; [2017-03-26 Su] Version 5.3.0
|
|
|
;; - Focused can now be on a list of nodes (instead of a single one)
|
|
|
;; - Cleaned up undeclared dependencies
|
|
@@ -184,7 +190,7 @@
|
|
|
(require 'widget)
|
|
|
|
|
|
;; Version of this package
|
|
|
-(defvar org-index-version "5.3.0" "Version of `org-index', format is major.minor.bugfix, where \"major\" are incompatible changes and \"minor\" are new features.")
|
|
|
+(defvar org-index-version "5.4.0" "Version of `org-index', format is major.minor.bugfix, where \"major\" are incompatible changes and \"minor\" are new features.")
|
|
|
|
|
|
;; customizable options
|
|
|
(defgroup org-index nil
|
|
@@ -294,6 +300,11 @@ those pieces."
|
|
|
(const category)
|
|
|
(const keywords))))
|
|
|
|
|
|
+(defcustom org-index-clock-into-focus nil
|
|
|
+ "Clock into focused node."
|
|
|
+ :group 'org-index
|
|
|
+ :type 'boolean)
|
|
|
+
|
|
|
;; 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--head nil "Header before number (e.g. 'R').")
|
|
@@ -309,7 +320,7 @@ those pieces."
|
|
|
(defvar org-index--headings nil "Headlines of index-table as a string.")
|
|
|
(defvar org-index--headings-visible nil "Visible part of headlines of index-table as a string.")
|
|
|
(defvar org-index--ids-focused-nodes nil "Ids of focused node (if any).")
|
|
|
-(defvar org-index--id-last-goto-focus nil "Id of last node, that has been jumped to.")
|
|
|
+(defvar org-index--id-last-goto-focus nil "Id of last node, that has been focused to.")
|
|
|
|
|
|
;; Variables to hold context and state
|
|
|
(defvar org-index--last-fingerprint nil "Fingerprint of last line created.")
|
|
@@ -335,15 +346,19 @@ those pieces."
|
|
|
(defvar org-index--short-help-buffer-name "*org-index commands*" "Name of buffer to display short help.")
|
|
|
(defvar org-index--display-short-help nil "True, if short help should be displayed.")
|
|
|
(defvar org-index--short-help-displayed nil "True, if short help message has been displayed.")
|
|
|
+(defvar org-index--prefix-arg nil "True, if prefix argument has been received during input.")
|
|
|
(defvar org-index--minibuffer-saved-key nil "Temporarily save entry of minibuffer keymap.")
|
|
|
+(defvar org-index--after-focus-timer nil "Timer to clock in or update focused node after a delay.")
|
|
|
+(defvar org-index--after-focus-context nil "Context for after focus action.")
|
|
|
|
|
|
;; static information for this program package
|
|
|
-(defconst org-index--commands '(occur add kill head ping index ref yank column edit help short-help focus set-focus example sort find-ref highlight maintain) "List of commands available.")
|
|
|
+(defconst org-index--commands '(occur add kill head ping index ref yank column edit help short-help focus example sort find-ref highlight maintain) "List of commands available.")
|
|
|
(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.")
|
|
|
(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--after-focus-delay 6 "Number of seconds to wait before invoking after-focus action.")
|
|
|
|
|
|
|
|
|
(defmacro org-index--on (column value &rest body)
|
|
@@ -371,7 +386,7 @@ if VALUE cannot be found."
|
|
|
|
|
|
|
|
|
(defun org-index (&optional command search-ref arg)
|
|
|
- "Fast search-index for selected org nodes and things outside of org.
|
|
|
+ "Fast search-index for selected org nodes and things outside.
|
|
|
|
|
|
This function creates and updates an index table with keywords;
|
|
|
each line either points to a heading in org, references something
|
|
@@ -390,7 +405,7 @@ for its index table.
|
|
|
To start building up your index, use subcommands 'add', 'ref' and
|
|
|
'yank' to create entries and use 'occur' to find them.
|
|
|
|
|
|
-This is version 5.3.0 of org-index.el.
|
|
|
+This is version 5.4.0 of org-index.el.
|
|
|
|
|
|
|
|
|
The function `org-index' is the only interactive function of this
|
|
@@ -402,7 +417,9 @@ of subcommands to choose from:
|
|
|
occur: [o] Incrementally show matching lines from index.
|
|
|
Result is updated after every keystroke. You may enter a
|
|
|
list of words seperated by space or comma (`,'), to select
|
|
|
- lines that contain all of the given words.
|
|
|
+ lines that contain all of the given words. With a numeric
|
|
|
+ prefix argument, show lines, which have been accessed at
|
|
|
+ most this many days ago.
|
|
|
|
|
|
add: [a] Add the current node to index.
|
|
|
So that (e.g.) it can be found through the subcommand
|
|
@@ -434,23 +451,20 @@ of subcommands to choose from:
|
|
|
edit: [e] Present current line in edit buffer.
|
|
|
Can be invoked from index, from occur or from a headline.
|
|
|
|
|
|
- help: Show complete help text of `org-index'.
|
|
|
-
|
|
|
focus: [f] Return to first focused node; repeat to see them all.
|
|
|
- With prefix: reverse order. You Need to set-focus before.
|
|
|
The focused nodes are kept in a short list and can be found
|
|
|
by hitting a single key; they need not be part of the index
|
|
|
though. This can be useful, if you work in one or few nodes,
|
|
|
but make frequent excursions to others, which are part of the
|
|
|
- index.
|
|
|
+ index. With a prefix argument offer more options, e.g. to set
|
|
|
+ focus.
|
|
|
|
|
|
- set-focus: [F] Set focus to current node, with prefix: append.
|
|
|
- To truncate the list of focused nodes, just focus on a single
|
|
|
- node; to remove current node from focus list supply a double
|
|
|
- prefix.
|
|
|
+ help: Show complete help text of `org-index'.
|
|
|
+ I.e. this text.
|
|
|
|
|
|
- short-help: [?] Show one-line description of each subcommand.
|
|
|
- I.e. show this list but only first sentence each.
|
|
|
+ short-help: [?] Show this one-line description of each subcommand.
|
|
|
+ I.e. from the complete help, show only the first line for each
|
|
|
+ subcommand.
|
|
|
|
|
|
example: Create an example index, that will not be saved.
|
|
|
May serve as an example.
|
|
@@ -480,7 +494,11 @@ the most important subcommands with one additional key.
|
|
|
|
|
|
A numeric prefix argument is used as a reference number for
|
|
|
commands, that need one (e.g. 'head') or to modify their
|
|
|
-behaviour (e.g. 'focus').
|
|
|
+behaviour (e.g. 'occur').
|
|
|
+
|
|
|
+Also, a single prefix argument may be specified just before the
|
|
|
+final character (e.g. like `C-c i C-u f') or by just typing an
|
|
|
+upper case letter (e.g. `C-c i F').
|
|
|
|
|
|
Use from elisp: Optional argument COMMAND is a symbol naming the
|
|
|
command to execute. SEARCH-REF specifies a reference to search
|
|
@@ -536,6 +554,7 @@ interactive calls."
|
|
|
;; read command; if requested display help in read-loop
|
|
|
(setq org-index--display-short-help (eq command 'short-help))
|
|
|
(setq command (org-index--read-command))
|
|
|
+ (if org-index--prefix-arg (setq arg (or arg '(4))))
|
|
|
(setq org-index--display-short-help nil))
|
|
|
|
|
|
;;
|
|
@@ -761,7 +780,7 @@ interactive calls."
|
|
|
((eq command 'occur)
|
|
|
|
|
|
(set-buffer org-index--buffer)
|
|
|
- (org-index--do-occur))
|
|
|
+ (org-index--do-occur (if (numberp arg) arg nil)))
|
|
|
|
|
|
|
|
|
((eq command 'ref)
|
|
@@ -872,13 +891,11 @@ interactive calls."
|
|
|
|
|
|
|
|
|
((eq command 'focus)
|
|
|
- (setq message-text (org-index--goto-focus arg)))
|
|
|
+ (setq message-text (if arg
|
|
|
+ (org-index--more-focus-commands)
|
|
|
+ (org-index--goto-focus))))
|
|
|
|
|
|
-
|
|
|
- ((eq command 'set-focus)
|
|
|
- (setq message-text (org-index--set-focus arg)))
|
|
|
|
|
|
-
|
|
|
((eq command 'maintain)
|
|
|
(setq message-text (org-index--do-maintain)))
|
|
|
|
|
@@ -916,12 +933,20 @@ interactive calls."
|
|
|
Can be bound in global keyboard map as central entry point.
|
|
|
Optional argument ARG is passed on."
|
|
|
(interactive "P")
|
|
|
- (let (char command)
|
|
|
- (if (sit-for 1)
|
|
|
- (message "org-index (? for detailed prompt) -"))
|
|
|
- (setq char (key-description (read-key-sequence nil)))
|
|
|
- (if (string= char "C-g") (keyboard-quit))
|
|
|
- (if (string= char "SPC") (setq char "?"))
|
|
|
+ (let (char command (c-u-text (if arg " C-u " "")))
|
|
|
+ (while (not char)
|
|
|
+ (if (sit-for 1)
|
|
|
+ (message (concat "org-index (? for detailed prompt) -" c-u-text)))
|
|
|
+ (setq char (key-description (read-key-sequence nil)))
|
|
|
+ (if (string= char "C-g") (keyboard-quit))
|
|
|
+ (if (string= char "SPC") (setq char "?"))
|
|
|
+ (when (string= char (upcase char))
|
|
|
+ (setq char (downcase char))
|
|
|
+ (setq arg (or arg '(4))))
|
|
|
+ (when (string= char "C-u")
|
|
|
+ (setq arg (or arg '(4)))
|
|
|
+ (setq c-u-text " C-u ")
|
|
|
+ (setq char nil)))
|
|
|
(setq command (cdr (assoc char (org-index--get-shortcut-chars))))
|
|
|
(unless command
|
|
|
(message "No subcommand for '%s'; switching to detailed prompt" char)
|
|
@@ -964,19 +989,25 @@ Optional argument WITH-SHORT-HELP displays help screen upfront."
|
|
|
minibuffer-setup-fun
|
|
|
command)
|
|
|
(setq org-index--short-help-displayed nil)
|
|
|
+ (setq org-index--prefix-arg nil)
|
|
|
(add-hook 'minibuffer-setup-hook 'org-index--minibuffer-setup-function)
|
|
|
(add-hook 'minibuffer-exit-hook 'org-index--minibuffer-exit-function)
|
|
|
(unwind-protect
|
|
|
(setq command
|
|
|
- (intern
|
|
|
- (completing-read
|
|
|
- (concat
|
|
|
- "Please choose"
|
|
|
- (if org-index--display-short-help "" " (? for short help)")
|
|
|
- ": ")
|
|
|
- (mapcar 'symbol-name org-index--commands) nil t)))
|
|
|
+ (completing-read
|
|
|
+ (concat
|
|
|
+ "Please choose"
|
|
|
+ (if org-index--display-short-help "" " (? for short help)")
|
|
|
+ ": ")
|
|
|
+ (append (mapcar 'symbol-name org-index--commands)
|
|
|
+ (mapcar 'upcase-initials (mapcar 'symbol-name org-index--commands)))
|
|
|
+ nil t))
|
|
|
(remove-hook 'minibuffer-setup-hook 'org-index--minibuffer-setup-function)
|
|
|
(remove-hook 'minibuffer-exit-hook 'org-index--minibuffer-exit-function)
|
|
|
+ (unless (string= command (downcase command))
|
|
|
+ (setq command (downcase command))
|
|
|
+ (setq org-index--prefix-arg '(4)))
|
|
|
+ (setq command (intern command))
|
|
|
(when org-index--short-help-displayed
|
|
|
(quit-windows-on org-index--short-help-buffer-name)))
|
|
|
command))
|
|
@@ -986,12 +1017,16 @@ Optional argument WITH-SHORT-HELP displays help screen upfront."
|
|
|
"Prepare minibuffer for `org-index--read-command'."
|
|
|
(setq org-index--minibuffer-saved-key (local-key-binding (kbd "?")))
|
|
|
(local-set-key (kbd "?") 'org-index--display-short-help)
|
|
|
+ (local-set-key (kbd "C-u") (lambda () (interactive)
|
|
|
+ (setq org-index--prefix-arg t)
|
|
|
+ (message "C-u")))
|
|
|
(if org-index--display-short-help (org-index--display-short-help)))
|
|
|
|
|
|
|
|
|
(defun org-index--minibuffer-exit-function ()
|
|
|
"Restore minibuffer after `org-index--read-command'."
|
|
|
(local-set-key (kbd "?") org-index--minibuffer-saved-key)
|
|
|
+ (local-set-key (kbd "C-u") 'universal-argument)
|
|
|
(setq org-index--minibuffer-saved-key nil))
|
|
|
|
|
|
|
|
@@ -1002,7 +1037,7 @@ Optional argument WITH-SHORT-HELP displays help screen upfront."
|
|
|
(with-temp-buffer-window
|
|
|
org-index--short-help-buffer-name nil nil
|
|
|
(setq org-index--short-help-displayed t)
|
|
|
- (princ "Short help; all subcommands of `org-index', shortcuts in []\n")
|
|
|
+ (princ "Short help; shortcuts in []; capital letter acts like C-u.\n")
|
|
|
(princ (org-index--get-short-help-text)))
|
|
|
(with-current-buffer org-index--short-help-buffer-name
|
|
|
(let ((inhibit-read-only t)
|
|
@@ -1013,12 +1048,6 @@ Optional argument WITH-SHORT-HELP displays help screen upfront."
|
|
|
(setq height-after (window-height win))
|
|
|
(goto-char (point-min))
|
|
|
(end-of-line)
|
|
|
- (insert
|
|
|
- (if (> height-before height-after)
|
|
|
- "."
|
|
|
- (concat ", "
|
|
|
- (substitute-command-keys "\\[scroll-other-window]")
|
|
|
- " to scroll:")))
|
|
|
(goto-char (point-min)))))
|
|
|
|
|
|
|
|
@@ -1066,54 +1095,80 @@ Optional argument WITH-SHORT-HELP displays help screen upfront."
|
|
|
org-index--shortcut-chars)))
|
|
|
|
|
|
|
|
|
-(defun org-index--goto-focus (arg)
|
|
|
- "Goto focus node, one after the other; with ARG: reverse."
|
|
|
+(defun org-index--goto-focus ()
|
|
|
+ "Goto focus node, one after the other."
|
|
|
(if org-index--ids-focused-nodes
|
|
|
- (let ((maybe-reverse (lambda (&rest x) (if (equal arg '(4)) (reverse x) x)))
|
|
|
- last-id next-ids marker)
|
|
|
+ (let (last-id next-id this-id marker)
|
|
|
(setq last-id (or org-index--id-last-goto-focus
|
|
|
(last org-index--ids-focused-nodes)))
|
|
|
+ (setq this-id (org-id-get))
|
|
|
(setq next-id
|
|
|
- (car (or (cdr-safe (member last-id
|
|
|
- (apply maybe-reverse
|
|
|
- (append org-index--ids-focused-nodes
|
|
|
- org-index--ids-focused-nodes))))
|
|
|
- (apply maybe-reverse org-index--ids-focused-nodes))))
|
|
|
+ (if (and this-id
|
|
|
+ (string= this-id last-id))
|
|
|
+ (car (or (cdr-safe (member last-id
|
|
|
+ (append org-index--ids-focused-nodes
|
|
|
+ org-index--ids-focused-nodes)))
|
|
|
+ org-index--ids-focused-nodes))
|
|
|
+ (or last-id
|
|
|
+ (car org-index--ids-focused-nodes))))
|
|
|
(or (setq marker (org-id-find next-id 'marker))
|
|
|
(error "Could not find focus-node with id %s" next-id))
|
|
|
- (setq org-index--id-last-goto-focus next-id)
|
|
|
+
|
|
|
(pop-to-buffer-same-window (marker-buffer marker))
|
|
|
(goto-char (marker-position marker))
|
|
|
(org-index--unfold-buffer)
|
|
|
(move-marker marker nil)
|
|
|
- (if (cdr org-index--ids-focused-nodes)
|
|
|
- (format "Jumped to %s focus-node (out of %d)"
|
|
|
- (if (equal arg '(4)) "previous" "next")
|
|
|
+ (when org-index-clock-into-focus
|
|
|
+ (if org-index--after-focus-timer (cancel-timer org-index--after-focus-timer))
|
|
|
+ (setq org-index--after-focus-context
|
|
|
+ (cons (point-marker)
|
|
|
+ next-id))
|
|
|
+ (setq org-index--after-focus-timer
|
|
|
+ (run-at-time org-index--after-focus-delay nil
|
|
|
+ (lambda ()
|
|
|
+ (if org-index-clock-into-focus
|
|
|
+ (with-current-buffer (marker-buffer (car org-index--after-focus-context))
|
|
|
+ (org-with-point-at (marker-position (car org-index--after-focus-context)))
|
|
|
+ (org-clock-in)))
|
|
|
+ (org-index--update-line (cdr org-index--after-focus-context) t)
|
|
|
+ (move-marker (car org-index--after-focus-context) nil)
|
|
|
+ (setq org-index--after-focus-context nil)))))
|
|
|
+ (setq org-index--id-last-goto-focus next-id)
|
|
|
+ (if (cdr org-index--ids-focused-nodes)
|
|
|
+ (format "Jumped to next focus-node (out of %d)"
|
|
|
(length org-index--ids-focused-nodes))
|
|
|
"Jumped to single focus-node"))
|
|
|
"No nodes in focus, use set-focus"))
|
|
|
|
|
|
|
|
|
-(defun org-index--set-focus (arg)
|
|
|
- "Set focus node, with prefix ARG, append to list, with double prefix: delete."
|
|
|
- (let (id text)
|
|
|
+(defun org-index--more-focus-commands ()
|
|
|
+ "More commands for handling focused nodes."
|
|
|
+ (let (id text char prompt)
|
|
|
|
|
|
+ (setq prompt "Please specify action on the list focused nodes: set, append, delete (s,a,d or ? for short help) - ")
|
|
|
+ (while (not (memq char (list ?s ?a ?d)))
|
|
|
+ (setq char (read-char prompt))
|
|
|
+ (setq prompt "Actions on list of focused nodes: s)et single focus on this node, a)ppend this node to list, d)elete this node from list. Please choose - "))
|
|
|
(setq text
|
|
|
(cond
|
|
|
|
|
|
- ((not arg)
|
|
|
+ ((eq char ?s)
|
|
|
(setq id (org-id-get-create))
|
|
|
(setq org-index--ids-focused-nodes (list id))
|
|
|
+ (setq org-index--id-last-goto-focus id)
|
|
|
+ (if org-index-clock-into-focus (org-clock-in))
|
|
|
"Focus has been set on current node (1 node in focus)")
|
|
|
|
|
|
- ((equal arg '(4))
|
|
|
+ ((eq char ?a)
|
|
|
(setq id (org-id-get-create))
|
|
|
(unless (member id org-index--ids-focused-nodes)
|
|
|
(setq org-index--ids-focused-nodes (cons id org-index--ids-focused-nodes)))
|
|
|
(setq org-index--id-last-goto-focus id)
|
|
|
+ (setq org-index--id-last-goto-focus id)
|
|
|
+ (if org-index-clock-into-focus (org-clock-in))
|
|
|
"Current node has been appended to list of focused nodes (%d node%s in focus)")
|
|
|
|
|
|
- ((equal arg '(16))
|
|
|
+ ((eq char ?d)
|
|
|
(setq id (org-id-get))
|
|
|
(if (and id (member id org-index--ids-focused-nodes))
|
|
|
(progn
|
|
@@ -1122,6 +1177,7 @@ Optional argument WITH-SHORT-HELP displays help screen upfront."
|
|
|
org-index--ids-focused-nodes)))))
|
|
|
org-index--id-last-goto-focus))
|
|
|
(setq org-index--ids-focused-nodes (delete id org-index--ids-focused-nodes))
|
|
|
+ (setq org-index--id-last-goto-focus nil)
|
|
|
"Current node has been removed from list of focused nodes (%d node%s in focus)")
|
|
|
"Current node has not been in list of focused nodes (%d node%s in focus)"))))
|
|
|
|
|
@@ -1393,7 +1449,7 @@ Argument COLUMN and VALUE specify line to get."
|
|
|
;; read one character
|
|
|
(while (not (memq char (append (number-sequence ?0 ?9) (list ?\d ?\b ?\r ?\j ?\s ?.))))
|
|
|
(setq char (read-char prompt))
|
|
|
- (setq prompt "Go to specific position in index table. Digits specify a reference number, <space> goes to top of index, <backspace> or <delete> to last line created and <return> or `.' to index line of current node. Please choose - "))
|
|
|
+ (setq prompt "Go to specific position in index table. Digits specify a reference number, <space> goes to top of index, <backspace> or <delete> to last line created and <return> or `.' to index line of current node. Please choose - "))
|
|
|
|
|
|
(if (memq char (number-sequence ?0 ?9))
|
|
|
;; read rest of digits
|
|
@@ -2000,31 +2056,24 @@ specify flag TEMPORARY for th new table temporary, maybe COMPARE it with existin
|
|
|
(org-cycle)))
|
|
|
|
|
|
|
|
|
-(defun org-index--update-line (&optional ref-or-id-or-pos)
|
|
|
- "Update columns count and last-accessed in line REF-OR-ID-OR-POS."
|
|
|
+(defun org-index--update-line (&optional id-or-pos no-error)
|
|
|
+ "Update columns count and last-accessed in line ID-OR-POS.
|
|
|
+Optional argument NO-ERROR suppresses error."
|
|
|
|
|
|
(let (initial)
|
|
|
|
|
|
(with-current-buffer org-index--buffer
|
|
|
(unless buffer-read-only
|
|
|
|
|
|
- ;; search reference or id, if given (or assume, that we are already positioned right)
|
|
|
- (when ref-or-id-or-pos
|
|
|
- (setq initial (point))
|
|
|
- (goto-char org-index--below-hline)
|
|
|
- (while (and (org-at-table-p)
|
|
|
- (not (if (integerp ref-or-id-or-pos)
|
|
|
- (and (>= ref-or-id-or-pos (line-beginning-position))
|
|
|
- (< ref-or-id-or-pos (line-end-position)))
|
|
|
- (or (string= ref-or-id-or-pos (org-index--get-or-set-field 'ref))
|
|
|
- (string= ref-or-id-or-pos (org-index--get-or-set-field 'id))))))
|
|
|
- (forward-line)))
|
|
|
+ (setq initial (point))
|
|
|
|
|
|
- (if (not (org-at-table-p))
|
|
|
- (error "Did not find reference or id '%s'" ref-or-id-or-pos)
|
|
|
- (org-index--update-current-line))
|
|
|
-
|
|
|
- (if initial (goto-char initial))))))
|
|
|
+ (if (if (integerp id-or-pos)
|
|
|
+ (goto-char id-or-pos)
|
|
|
+ (org-index--go 'id id-or-pos))
|
|
|
+ (org-index--update-current-line)
|
|
|
+ (unless no-error (error "Did not find reference or id '%s'" (list id-or-pos))))
|
|
|
+
|
|
|
+ (goto-char initial)))))
|
|
|
|
|
|
|
|
|
(defun org-index--update-current-line ()
|
|
@@ -2643,7 +2692,7 @@ Return t or nil, leave point on line or at top of table, needs to be in buffer i
|
|
|
|
|
|
|
|
|
(defun org-index--find-id (id &optional other)
|
|
|
- "Perform command head: Find node with REF or ID and present it.
|
|
|
+ "Perform command head: Find node with ID and present it.
|
|
|
If OTHER in separate window."
|
|
|
|
|
|
(let (message marker)
|
|
@@ -2669,16 +2718,16 @@ If OTHER in separate window."
|
|
|
message))
|
|
|
|
|
|
|
|
|
-(defun org-index--do-occur ()
|
|
|
- "Perform command occur."
|
|
|
+(defun org-index--do-occur (&optional days)
|
|
|
+ "Perform command occur; optional narrow to DAYS back."
|
|
|
(let ((word "") ; last word to search for growing and shrinking on keystrokes
|
|
|
(prompt "Search for: ")
|
|
|
- (these-commands " NOTE: If you invoke the org-index subcommands edit or kill from within the occur buffer, the index is updated accordingly.")
|
|
|
+ (these-commands " NOTE: If you invoke the subcommands edit (`e') or kill (`C-c i k') from within this buffer, the index is updated accordingly")
|
|
|
(lines-wanted (window-body-height))
|
|
|
(lines-found 0) ; number of lines found
|
|
|
words ; list words that should match
|
|
|
occur-buffer
|
|
|
- begin ; position of first line
|
|
|
+ begin ; position of first line
|
|
|
help-text ; cons with help text short and long
|
|
|
search-text ; description of text to search for
|
|
|
done ; true, if loop is done
|
|
@@ -2688,7 +2737,8 @@ If OTHER in separate window."
|
|
|
initial-frame ; Frame when starting occur
|
|
|
key ; input from user in various forms
|
|
|
key-sequence
|
|
|
- key-sequence-raw)
|
|
|
+ key-sequence-raw
|
|
|
+ days-clause) ; clause to display for days back search
|
|
|
|
|
|
|
|
|
;; make and show buffer
|
|
@@ -2717,9 +2767,10 @@ If OTHER in separate window."
|
|
|
(forward-line)
|
|
|
|
|
|
;; initialize help text
|
|
|
+ (setq days-clause (if days (format " (%d days back)" days) ""))
|
|
|
(setq help-text (cons
|
|
|
(concat
|
|
|
- (propertize "Incremental occur" 'face 'org-todo)
|
|
|
+ (propertize (format "Incremental occur%s" days-clause) 'face 'org-todo)
|
|
|
(propertize "; ? toggles help and headlines.\n" 'face 'org-agenda-dimmed-todo-face))
|
|
|
(concat
|
|
|
(propertize
|
|
@@ -2735,6 +2786,19 @@ If OTHER in separate window."
|
|
|
(setq org-index--occur-tail-overlay (make-overlay (point-max) (point-max)))
|
|
|
(overlay-put org-index--occur-tail-overlay 'invisible t)
|
|
|
|
|
|
+ ;; do not enter loop if number of days is requested
|
|
|
+ (when days
|
|
|
+ (goto-char begin)
|
|
|
+ (setq lines-found (org-index--hide-with-overlays (cons word words) lines-wanted days))
|
|
|
+ (move-overlay org-index--occur-tail-overlay
|
|
|
+ (if org-index--occur-stack (cdr (assoc :end-of-visible (car org-index--occur-stack)))
|
|
|
+ (point-max))
|
|
|
+ (point-max))
|
|
|
+
|
|
|
+ (goto-char begin)
|
|
|
+ (setq done t))
|
|
|
+
|
|
|
+ ;; main loop
|
|
|
(while (not done)
|
|
|
|
|
|
(if in-c-backspace
|
|
@@ -2792,8 +2856,7 @@ If OTHER in separate window."
|
|
|
(if org-index--occur-stack (cdr (assoc :end-of-visible (car org-index--occur-stack)))
|
|
|
(point-max))
|
|
|
(point-max))
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
;; highlight shorter word
|
|
|
(unless (= (length word) 0)
|
|
|
(highlight-regexp (regexp-quote word) 'isearch))
|
|
@@ -2826,7 +2889,7 @@ If OTHER in separate window."
|
|
|
|
|
|
;; make overlays to hide lines, that do not match longer word any more
|
|
|
(goto-char begin)
|
|
|
- (setq lines-found (org-index--hide-with-overlays (cons word words) lines-wanted))
|
|
|
+ (setq lines-found (org-index--hide-with-overlays (cons word words) lines-wanted days))
|
|
|
(move-overlay org-index--occur-tail-overlay
|
|
|
(if org-index--occur-stack (cdr (assoc :end-of-visible (car org-index--occur-stack)))
|
|
|
(point-max))
|
|
@@ -2915,12 +2978,12 @@ If OTHER in separate window."
|
|
|
(setq org-index--occur-help-text
|
|
|
(cons
|
|
|
(org-index--wrap
|
|
|
- (propertize "Search is done; ? toggles help and headlines.\n" 'face 'org-agenda-dimmed-todo-face))
|
|
|
+ (propertize (format "Search is done%s; ? toggles help and headlines.\n" days-clause) 'face 'org-agenda-dimmed-todo-face))
|
|
|
(concat
|
|
|
(org-index--wrap
|
|
|
(propertize
|
|
|
(format
|
|
|
- (concat "Search is done."
|
|
|
+ (concat (format "Search is done%s." days-clause)
|
|
|
(if (< lines-collected lines-wanted)
|
|
|
" Showing all %d matches for "
|
|
|
" Showing one window of matches for ")
|
|
@@ -2953,6 +3016,10 @@ If OTHER in separate window."
|
|
|
(lambda () (interactive)
|
|
|
(message (org-index--occur-action t))))
|
|
|
|
|
|
+ (define-key keymap (kbd "e")
|
|
|
+ (lambda () (interactive)
|
|
|
+ (message (org-index 'edit))))
|
|
|
+
|
|
|
(define-key keymap (kbd "SPC")
|
|
|
(lambda () (interactive)
|
|
|
(org-index--refresh-parse-table)
|
|
@@ -2999,7 +3066,7 @@ If OTHER in separate window."
|
|
|
(goto-char pos)
|
|
|
(setq there (org-index--line-in-canonical-form)))
|
|
|
(unless (string= here there)
|
|
|
- (error "Occur buffer has become stale"))))
|
|
|
+ (error "Occur buffer has become stale; please repeat search"))))
|
|
|
|
|
|
|
|
|
(defun org-index--line-in-canonical-form ()
|
|
@@ -3033,7 +3100,7 @@ If OTHER in separate window."
|
|
|
(setq yank (replace-regexp-in-string (regexp-quote "\\vert") "|" yank nil 'literal))
|
|
|
(kill-new yank)
|
|
|
(org-mark-ring-goto)
|
|
|
- (if (string= (substring yank 0 3) "http")
|
|
|
+ (if (and (>= (length yank) 4) (string= (substring yank 0 4) "http"))
|
|
|
(progn
|
|
|
(browse-url yank)
|
|
|
(format "Opened '%s' in browser (and copied it too)" yank))
|
|
@@ -3042,8 +3109,10 @@ If OTHER in separate window."
|
|
|
(message "Not at table")))
|
|
|
|
|
|
|
|
|
-(defun org-index--hide-with-overlays (words lines-wanted)
|
|
|
- "Hide text that is currently visible and does not match WORDS by creating overlays; leave LINES-WANTED lines visible."
|
|
|
+(defun org-index--hide-with-overlays (words lines-wanted days)
|
|
|
+ "Hide text that is currently visible and does not match WORDS by creating overlays;
|
|
|
+leave LINES-WANTED lines visible.
|
|
|
+Argument DAYS hides older lines."
|
|
|
(let ((lines-found 0)
|
|
|
(end-of-visible (point))
|
|
|
overlay overlays start matched)
|
|
@@ -3063,12 +3132,21 @@ If OTHER in separate window."
|
|
|
(setq matched nil)
|
|
|
(setq start (point))
|
|
|
(while (and (not (eobp))
|
|
|
- (not
|
|
|
- (and
|
|
|
- (invisible-p (point))
|
|
|
- (< (point) (overlay-start org-index--occur-tail-overlay))))
|
|
|
- (not (and (org-index--test-words words)
|
|
|
- (setq matched t)))) ; for its side effect
|
|
|
+ (not (and
|
|
|
+ (invisible-p (point))
|
|
|
+ (< (point) (overlay-start org-index--occur-tail-overlay))))
|
|
|
+ ;; either regard words or days, but not both
|
|
|
+ (if days
|
|
|
+ (let ((last-accessed (org-index--get-or-set-field 'last-accessed)))
|
|
|
+ (if last-accessed
|
|
|
+ (not (and
|
|
|
+ (<= (- (time-to-days (current-time))
|
|
|
+ (time-to-days (org-read-date nil t last-accessed nil)))
|
|
|
+ days)
|
|
|
+ (setq matched t))) ; for its side effect
|
|
|
+ t))
|
|
|
+ (not (and (org-index--test-words words)
|
|
|
+ (setq matched t))))) ; for its side effect
|
|
|
(forward-line 1))
|
|
|
|
|
|
;; create overlay to hide this stretch
|