updated org-favtable to version 2.2
authorMarc-Oliver Ihm <marc@ihm.name>
Thu, 28 Feb 2013 20:32:27 +0000 (21:32 +0100)
committerMarc-Oliver Ihm <marc@ihm.name>
Thu, 28 Feb 2013 20:32:27 +0000 (21:32 +0100)
code/elisp/org-favtable.el
org-contrib/index.org

index d0ca875..f0d422c 100755 (executable)
@@ -1,4 +1,4 @@
-;;; org-favtable.el --- Table of favorite references and links\r
+;;; org-favtable.el --- Lookup table of favorite references and links\r
 \r
 ;; Copyright (C) 2011-2013 Free Software Foundation, Inc.\r
 \r
@@ -6,7 +6,7 @@
 ;; Keywords: hypermedia, matching\r
 ;; Requires: org\r
 ;; Download: http://orgmode.org/worg/code/elisp/org-favtable.el\r
-;; Version: 2.1.0\r
+;; Version: 2.2.0\r
 \r
 ;;; License:\r
 \r
 \r
 ;; Purpose:\r
 ;;\r
-;;  Mark and find your favorite items and org-locations easily: Create and\r
-;;  update a lookup table of your favorite references and links. Often used\r
-;;  entries automatically bubble to the top of the table; entering some\r
-;;  keywords narrows it to just the matching entries; that way the right\r
-;;  one can be picked easily.\r
+;;  Mark and find your favorite things and locations in org easily: Create\r
+;;  and update a lookup table of your references and links. Often used\r
+;;  entries bubble to the top and entering some keywords displays only the\r
+;;  matching entries. That way the right entry one can be picked easily.\r
 ;;\r
-;;  References are essentially small numbers (e.g. "R237" or "-455-"), as\r
-;;  created by this package; links are normal org-mode links.\r
+;;  References are essentially small numbers (e.g. "R237" or "-455-"),\r
+;;  which are created by this package; they are well suited to be used\r
+;;  outside of org. Links are just normal org-mode links.\r
 ;;\r
 ;;\r
 ;; Setup:\r
 \r
 ;;; Change Log:\r
 \r
+;;   [2013-02-28 Th] Version 2.2.0:\r
+;;    - Allowed shortcuts like "h237" for command "head" with argument "237"\r
+;;    - Integrated with org-mark-ring-goto\r
+;;\r
 ;;   [2013-01-25 Fr] Version 2.1.0:\r
 ;;    - Added full support for links\r
 ;;    - New commands "missing" and "statistics"\r
 (require 'org-table)\r
 (require 'cl)\r
 \r
-(defvar org-favtable--version "2.1.0")\r
+(defvar org-favtable--version "2.2.0")\r
 (defvar org-favtable--preferred-command nil)\r
 \r
 (defvar org-favtable--commands '(occur head ref link enter leave goto + help reorder fill sort update highlight unhighlight missing statistics)\r
   "List of commands known to org-favtable:\r
  \r
+Commands known:\r
 \r
   occur: If you supply a keyword (text): Apply emacs standard\r
     occur operation on the table of favorites; ask for a\r
 \r
   leave: Leave the table of favorites. If the last command has\r
     been \"ref\", the new reference is copied and ready to yank.\r
+    This \"org-mark-ring-goto\" and can be called several times\r
+    in succession.\r
 \r
   enter: Just enter the node with the table of favorites.\r
 \r
     reference) about favtable.\r
 \r
 \r
+\r
+Two ways to save keystrokes:\r
+\r
 When prompting for a command, org-favtable puts the most likely\r
-chosen one (e.g. \"occur\" or \"ref\") at the front of the list,\r
-so that you may just type RET. \r
+one (e.g. \"occur\" or \"ref\") at the front of the list, so that\r
+you may just type RET.\r
 \r
 If this command needs additional input (like e.g. \"occur\"), you\r
 may supply this input right away, although you are still beeing\r
-prompted for the command.\r
+prompted for the command. So do an occur for the string \"foo\",\r
+you can just enter \"foo\" without even entering \"occur\".\r
+\r
+\r
+Another way to save keystrokes applies if you want to choose a\r
+command, that requrires a reference number (and would normally\r
+prompt for it): In that case you may just enter enough characters\r
+from your command, so that it appears first in the list of\r
+matches; then immediately enter the number of the reference you\r
+are searching for. So the input \"h237\" would execute the\r
+command \"head\" for reference \"237\" right away.\r
 \r
 ")\r
 \r
@@ -311,8 +331,7 @@ for help on single commands.
 ")\r
 \r
 \r
-(defvar org-favtable--windowconfig-before nil)\r
-(defvar org-favtable--marker-outside-before nil)\r
+(defvar org-favtable--text-to-yank nil)\r
 (defvar org-favtable--last-action nil)\r
 (defvar org-favtable--occur-buffer nil)\r
 (defvar org-favtable--ref-regex nil)\r
@@ -386,846 +405,846 @@ An example would be:
 \r
   (interactive "P")\r
 \r
-(let (within-node        ; True, if we are within node with favtable\r
-      result-is-visible  ; True, if node or occur is visible in any window\r
-      ref-node-buffer-and-point ; cons with buffer and point of favorites node\r
-      below-cursor              ; word below cursor\r
-      active-region             ; active region (if any)\r
-      link-id                   ; link of starting node, if required\r
-      guarded-search            ; with guard against additional digits\r
-      search-is-ref             ; true, if search is a reference\r
-      commands                ; currently active set of selectable commands\r
-      what-adjusted           ; True, if we had to adjust what\r
-      what-input    ; Input on what question (need not necessary be "what")\r
-      reorder-once  ; Column to use for single time sorting\r
-      parts         ; Parts of a typical reference number (which\r
-                    ; need not be a plain number); these are:\r
-      head               ; Any header before number (e.g. "R")\r
-      maxref             ; Maximum number from reference table (e.g. "153")\r
-      tail               ; Tail after number (e.g. "}" or "")\r
-      ref-regex          ; Regular expression to match a reference\r
-      has-reuse          ; True, if table contains a line for reuse\r
-      numcols            ; Number of columns in favtable\r
-      kill-new-text      ; Text that will be appended to kill ring\r
-      message-text       ; Text that will be issued as an explanation,\r
-                                                  ; what we have done\r
-      initial-ref-or-link                    ; initial position in reftable\r
-      )\r
+  (let (within-node        ; True, if we are within node with favtable\r
+        result-is-visible  ; True, if node or occur is visible in any window\r
+        ref-node-buffer-and-point ; cons with buffer and point of favorites node\r
+        below-cursor              ; word below cursor\r
+        active-region             ; active region (if any)\r
+        link-id                   ; link of starting node, if required\r
+        guarded-search            ; with guard against additional digits\r
+        search-is-ref             ; true, if search is a reference\r
+        commands                ; currently active set of selectable commands\r
+        what-adjusted           ; True, if we had to adjust what\r
+        what-input    ; Input on what question (need not necessary be "what")\r
+        reorder-once  ; Column to use for single time sorting\r
+        parts         ; Parts of a typical reference number (which\r
+                                                  ; need not be a plain number); these are:\r
+        head               ; Any header before number (e.g. "R")\r
+        maxref             ; Maximum number from reference table (e.g. "153")\r
+        tail               ; Tail after number (e.g. "}" or "")\r
+        ref-regex          ; Regular expression to match a reference\r
+        has-reuse          ; True, if table contains a line for reuse\r
+        numcols            ; Number of columns in favtable\r
+        kill-new-text      ; Text that will be appended to kill ring\r
+        message-text       ; Text that will be issued as an explanation,\r
+                           ; what we have done\r
+        initial-ref-or-link      ; Initial position in reftable\r
+        )\r
 \r
-  ;;\r
-  ;; Examine current buffer and location, before turning to favtable\r
-  ;;\r
+    ;;\r
+    ;; Examine current buffer and location, before turning to favtable\r
+    ;;\r
 \r
-  ;; Get the content of the active region or the word under cursor\r
-  (if (and transient-mark-mode\r
-           mark-active)\r
-      (setq active-region (buffer-substring (region-beginning) (region-end))))\r
-  (setq below-cursor (thing-at-point 'symbol))\r
+    ;; Get the content of the active region or the word under cursor\r
+    (if (and transient-mark-mode\r
+             mark-active)\r
+        (setq active-region (buffer-substring (region-beginning) (region-end))))\r
+    (setq below-cursor (thing-at-point 'symbol))\r
 \r
 \r
-  ;; Find out, if we are within favable or not\r
-  (setq within-node (string= (org-id-get) org-favtable-id))\r
+    ;; Find out, if we are within favable or not\r
+    (setq within-node (string= (org-id-get) org-favtable-id))\r
 \r
-  ;; Find out, if point in any window is within node with favtable\r
-  (mapc (lambda (x) (with-current-buffer (window-buffer x)\r
-                      (when (or \r
-                             (string= (org-id-get) org-favtable-id)\r
-                             (eq (window-buffer x) \r
-                                 org-favtable--occur-buffer))\r
-                        (setq result-is-visible t))))\r
-        (window-list))\r
-        \r
+    ;; Find out, if point in any window is within node with favtable\r
+    (mapc (lambda (x) (with-current-buffer (window-buffer x)\r
+                        (when (or \r
+                               (string= (org-id-get) org-favtable-id)\r
+                               (eq (window-buffer x) \r
+                                   org-favtable--occur-buffer))\r
+                          (setq result-is-visible t))))\r
+          (window-list))\r
+    \r
 \r
 \r
-  ;;\r
-  ;; Get decoration of references and highest reference from favtable\r
-  ;;\r
+    ;;\r
+    ;; Get decoration of references and highest reference from favtable\r
+    ;;\r
 \r
 \r
-  ;; Save initial ref or link\r
-  (if (and within-node\r
-           (org-at-table-p))\r
-      (setq initial-ref-or-link \r
-            (or (org-favtable--get-field 'ref)\r
-                (org-favtable--get-field 'link))))\r
+    ;; Save initial ref or link\r
+    (if (and within-node\r
+             (org-at-table-p))\r
+        (setq initial-ref-or-link \r
+              (or (org-favtable--get-field 'ref)\r
+                  (org-favtable--get-field 'link))))\r
 \r
-  ;; Find node\r
-  (setq ref-node-buffer-and-point (org-favtable--id-find))\r
-  (unless ref-node-buffer-and-point\r
-    (org-favtable--report-setup-error \r
-     (format "Cannot find node with id \"%s\"" org-favtable-id)))\r
-\r
-  ;; Get configuration of reftable; catch errors\r
-  (let ((error-message\r
-         (catch 'content-error\r
-\r
-           (with-current-buffer (car ref-node-buffer-and-point)\r
-             (unless (string= (org-id-get) org-favtable-id)\r
-\r
-               ;; Get marker for point within reftable-buffer, but only if outside\r
-               ;; of reftable (if point is within reftable, we will try to stay at\r
-               ;; the same ref)\r
-               (setq org-favtable--marker-outside-before (point-marker))\r
-               (goto-char (cdr ref-node-buffer-and-point)))\r
-\r
-             ;; parse table while still within buffer\r
-             (save-excursion\r
-               (setq parts (org-favtable--parse-and-adjust-table)))\r
-              \r
-             nil))))\r
-    (when error-message \r
-      (org-pop-to-buffer-same-window (car ref-node-buffer-and-point))\r
-      (org-reveal)\r
-      (error error-message)))\r
-\r
-  ;; Give names to parts of configuration\r
-  (setq head (nth 0 parts))\r
-  (setq maxref (nth 1 parts))\r
-  (setq tail (nth 2 parts))\r
-  (setq numcols (nth 3 parts))\r
-  (setq ref-regex (nth 4 parts))\r
-  (setq has-reuse (nth 5 parts))\r
-  (setq org-favtable--ref-regex ref-regex)\r
-  (setq org-favtable--format (concat head "%d" tail))\r
-\r
-  ;;\r
-  ;; Find out, what we are supposed to do\r
-  ;;\r
-\r
-  (if (equal what '(4)) (setq what 'leave))\r
-\r
-  ;; Set preferred action, that will be the default choice\r
-  (setq org-favtable--preferred-command\r
-        (if within-node\r
-            (if (memq org-favtable--last-action '(ref link))\r
-                'leave\r
-              'occur)\r
-          (if active-region\r
-              'ref\r
-            (if (and below-cursor (string-match ref-regex below-cursor))\r
-                'occur\r
-              nil))))\r
-    \r
-  ;; Ask user, what to do\r
-  (unless what\r
-    (setq commands (copy-list org-favtable--commands-some))\r
-    (while (progn\r
-             (setq what-input\r
-                   (org-icompleting-read \r
-                    "Please choose: " \r
-                    (mapcar 'symbol-name \r
-                            ;; Construct unique list of commands with\r
-                            ;; preferred one at front\r
-                            (delq nil (delete-dups \r
-                                       (append \r
-                                        (list org-favtable--preferred-command)\r
-                                        commands))))\r
-                    nil nil))\r
-\r
-\r
-             ;; if input starts with "+" any command (not only some) may follow\r
-             (when (string= (substring what-input 0 1) "+")\r
-               ;; make all commands available for selection\r
-               (setq commands (copy-list org-favtable--commands))\r
-               (unless (string= what-input "+") \r
-                 ;; not just "+", use following string\r
-                 (setq what-input (substring what-input 1))\r
-                 \r
-                 (let ((completions\r
-                        ;; get list of possible completions for what-input\r
-                        (all-completions what-input (mapcar 'symbol-name org-favtable--commands))))\r
-                   ;; use it, if unambigously\r
-                   (if (= (length completions) 1)\r
-                       (setq what-input (car completions))))))\r
+    ;; Find node\r
+    (setq ref-node-buffer-and-point (org-favtable--id-find))\r
+    (unless ref-node-buffer-and-point\r
+      (org-favtable--report-setup-error \r
+       (format "Cannot find node with id \"%s\"" org-favtable-id)))\r
+\r
+    ;; Get configuration of reftable; catch errors\r
+    (let ((error-message\r
+           (catch 'content-error\r
+\r
+             (with-current-buffer (car ref-node-buffer-and-point)\r
+               (save-excursion\r
+                 (unless (string= (org-id-get) org-favtable-id)\r
+                   (goto-char (cdr ref-node-buffer-and-point)))\r
+\r
+                 ;; parse table while still within buffer\r
+                 (setq parts (org-favtable--parse-and-adjust-table)))\r
+               \r
+               nil))))\r
+      (when error-message \r
+        (org-pop-to-buffer-same-window (car ref-node-buffer-and-point))\r
+        (org-reveal)\r
+        (error error-message)))\r
+\r
+    ;; Give names to parts of configuration\r
+    (setq head (nth 0 parts))\r
+    (setq maxref (nth 1 parts))\r
+    (setq tail (nth 2 parts))\r
+    (setq numcols (nth 3 parts))\r
+    (setq ref-regex (nth 4 parts))\r
+    (setq has-reuse (nth 5 parts))\r
+    (setq org-favtable--ref-regex ref-regex)\r
+    (setq org-favtable--ref-format (concat head "%d" tail))\r
 \r
+    ;;\r
+    ;; Find out, what we are supposed to do\r
+    ;;\r
 \r
-             (setq what (intern what-input))\r
+    (if (equal what '(4)) (setq what 'leave))\r
+\r
+    ;; Set preferred action, that will be the default choice\r
+    (setq org-favtable--preferred-command\r
+          (if within-node\r
+              (if (memq org-favtable--last-action '(ref link))\r
+                  'leave\r
+                'occur)\r
+            (if active-region\r
+                'ref\r
+              (if (and below-cursor (string-match ref-regex below-cursor))\r
+                  'occur\r
+                nil))))\r
+    \r
+    ;; Ask user, what to do\r
+    (unless what\r
+      (setq commands (copy-list org-favtable--commands-some))\r
+      (while (progn\r
+               (setq what-input\r
+                     (org-icompleting-read \r
+                      "Please choose: " \r
+                      (mapcar 'symbol-name \r
+                              ;; Construct unique list of commands with\r
+                              ;; preferred one at front\r
+                              (delq nil (delete-dups \r
+                                         (append \r
+                                          (list org-favtable--preferred-command)\r
+                                          commands))))\r
+                      nil nil))\r
+\r
+\r
+               ;; if input starts with "+", any command (not only some) may follow\r
+               ;; this allows input like "+sort" to be accepted\r
+               (when (string= (substring what-input 0 1) "+")\r
+                 ;; make all commands available for selection\r
+                 (setq commands (copy-list org-favtable--commands))\r
+                 (unless (string= what-input "+") \r
+                   ;; not just "+", use following string\r
+                   (setq what-input (substring what-input 1))\r
+                   \r
+                   (let ((completions\r
+                          ;; get list of possible completions for what-input\r
+                          (all-completions what-input (mapcar 'symbol-name commands))))\r
+                     ;; use it, if unambigously\r
+                     (if (= (length completions) 1)\r
+                         (setq what-input (car completions))))))\r
+\r
+\r
+               ;; if input ends in digits, save them away and do completions on head of input\r
+               ;; this allows input like "h224" to be accepted\r
+               (when (string-match "^\\([^0-9+]\\)\\([0-9]+\\)\\s *$" what-input)\r
+                 ;; use first match as input, even if ambigously\r
+                 (setq org-favtable--preferred-command \r
+                       (intern (first (all-completions (match-string 1 what-input) \r
+                                                       (mapcar 'symbol-name commands)))))\r
+                 ;; use digits as argument to commands\r
+                 (setq what-input (format org-favtable--ref-format \r
+                                          (string-to-number (match-string 2 what-input)))))\r
+\r
+               (setq what (intern what-input))\r
+               \r
+               ;; user is not required to input one of the commands; if\r
+               ;; not, take the first one and use the original input for\r
+               ;; next question\r
+               (if (memq what commands)\r
+                   ;; input matched one element of list, dont need original\r
+                   ;; input any more\r
+                   (setq what-input nil)\r
+                 ;; what-input will be used for next question, use first\r
+                 ;; command for what\r
+                 (setq what (or org-favtable--preferred-command\r
+                                (first commands)))\r
+                 ;; remove any trailing dot, that user might have added to\r
+                 ;; disambiguate his input\r
+                 (if (equal (substring what-input -1) ".")\r
+                     ;; but do this only, if dot was really necessary to\r
+                     ;; disambiguate\r
+                     (let ((shortened-what-input (substring what-input 0 -1)))\r
+                       (unless (test-completion shortened-what-input \r
+                                                (mapcar 'symbol-name \r
+                                                        commands))\r
+                         (setq what-input shortened-what-input)))))\r
                \r
-             ;; user is not required to input one of the commands; if\r
-             ;; not, take the first one and use the original input for\r
-             ;; next question\r
-             (if (memq what commands)\r
-                 ;; input matched one element of list, dont need original\r
-                 ;; input any more\r
-                 (setq what-input nil)\r
-               ;; what-input will be used for next question, use first\r
-               ;; command for what\r
-               (setq what (or org-favtable--preferred-command\r
-                              (first commands)))\r
-               ;; remove any trailing dot, that user might have added to\r
-               ;; disambiguate his input\r
-               (if (equal (substring what-input -1) ".")\r
-                   ;; but do this only, if dot was really necessary to\r
-                   ;; disambiguate\r
-                   (let ((shortened-what-input (substring what-input 0 -1)))\r
-                     (unless (test-completion shortened-what-input \r
-                                              (mapcar 'symbol-name \r
-                                                      commands))\r
-                       (setq what-input shortened-what-input)))))\r
-                     \r
-             ;; ask for reorder in loop, because we have to ask for\r
-             ;; what right again\r
-             (if (eq what 'reorder)\r
-                 (setq reorder-once\r
-                       (intern\r
-                        (org-icompleting-read \r
-                         "Please choose column to reorder reftable once: " \r
-                         (mapcar 'symbol-name '(ref count last-accessed))\r
-                         nil t))))\r
+               ;; ask for reorder in loop, because we have to ask for\r
+               ;; what right again\r
+               (if (eq what 'reorder)\r
+                   (setq reorder-once\r
+                         (intern\r
+                          (org-icompleting-read \r
+                           "Please choose column to reorder reftable once: " \r
+                           (mapcar 'symbol-name '(ref count last-accessed))\r
+                           nil t))))\r
                \r
-             ;; maybe ask initial question again\r
-             (memq what '(reorder +)))))\r
+               ;; maybe ask initial question again\r
+               (memq what '(reorder +)))))\r
 \r
 \r
-  ;;\r
-  ;; Get search, if required\r
-  ;;\r
+    ;;\r
+    ;; Get search, if required\r
+    ;;\r
 \r
-  ;; These actions need a search string:\r
-  (when (memq what '(goto occur head update))\r
+    ;; These actions need a search string:\r
+    (when (memq what '(goto occur head update))\r
 \r
-    ;; Maybe we've got a search string from the arguments\r
-    (unless search\r
-      (let (search-from-table\r
-            search-from-cursor)\r
+      ;; Maybe we've got a search string from the arguments\r
+      (unless search\r
+        (let (search-from-table\r
+              search-from-cursor)\r
           \r
-        ;; Search string can come from several sources:\r
-        ;; From ref column of table\r
-        (when within-node\r
-          (setq search-from-table (org-favtable--get-field 'ref)))      \r
-        ;; From string below cursor\r
-        (when (and (not within-node)\r
-                   below-cursor\r
-                   (string-match (concat "\\(" ref-regex "\\)") \r
-                                 below-cursor))\r
-          (setq search-from-cursor (match-string 1 below-cursor)))\r
+          ;; Search string can come from several sources:\r
+          ;; From ref column of table\r
+          (when within-node\r
+            (setq search-from-table (org-favtable--get-field 'ref)))      \r
+          ;; From string below cursor\r
+          (when (and (not within-node)\r
+                     below-cursor\r
+                     (string-match (concat "\\(" ref-regex "\\)") \r
+                                   below-cursor))\r
+            (setq search-from-cursor (match-string 1 below-cursor)))\r
           \r
-        ;; Depending on requested action, get search from one of the sources above\r
-        (cond ((eq what 'goto)\r
-               (setq search (or what-input search-from-cursor)))\r
-              ((memq what '(head occur))\r
-               (setq search (or what-input search-from-table search-from-cursor))))))\r
+          ;; Depending on requested action, get search from one of the sources above\r
+          (cond ((eq what 'goto)\r
+                 (setq search (or what-input search-from-cursor)))\r
+                ((memq what '(head occur))\r
+                 (setq search (or what-input search-from-table search-from-cursor))))))\r
 \r
 \r
-    ;; If we still do not have a search string, ask user explicitly\r
-    (unless search\r
+      ;; If we still do not have a search string, ask user explicitly\r
+      (unless search\r
         \r
-      (if what-input \r
-          (setq search what-input)\r
-        (setq search (read-from-minibuffer\r
-                      (cond ((memq what '(occur head))\r
-                             "Text or reference number to search for: ")\r
-                            ((eq what 'goto)\r
-                             "Reference number to search for, or enter \".\" for id of current node: ")\r
-                            ((eq what 'update)\r
-                             "Reference number to update: ")))))\r
-\r
-      (if (string-match "^\\s *[0-9]+\\s *$" search)\r
-          (setq search (format "%s%s%s" head (org-trim search) tail))))\r
+        (if what-input \r
+            (setq search what-input)\r
+          (setq search (read-from-minibuffer\r
+                        (cond ((memq what '(occur head))\r
+                               "Text or reference number to search for: ")\r
+                              ((eq what 'goto)\r
+                               "Reference number to search for, or enter \".\" for id of current node: ")\r
+                              ((eq what 'update)\r
+                               "Reference number to update: ")))))\r
+\r
+        (if (string-match "^\\s *[0-9]+\\s *$" search)\r
+            (setq search (format "%s%s%s" head (org-trim search) tail))))\r
       \r
-    ;; Clean up and examine search string\r
-    (if search (setq search (org-trim search)))\r
-    (if (string= search "") (setq search nil))\r
-    (setq search-is-ref (string-match ref-regex search))\r
-\r
-    ;; Check for special case\r
-    (when (and (memq what '(head goto))\r
-               (string= search "."))\r
-      (setq search (org-id-get))\r
-      (setq search-is-link t))\r
-\r
-    (when search-is-ref\r
-      (setq guarded-search (org-favtable--make-guarded-search search)))\r
+      ;; Clean up and examine search string\r
+      (if search (setq search (org-trim search)))\r
+      (if (string= search "") (setq search nil))\r
+      (setq search-is-ref (string-match ref-regex search))\r
+\r
+      ;; Check for special case\r
+      (when (and (memq what '(head goto))\r
+                 (string= search "."))\r
+        (setq search (org-id-get))\r
+        (setq search-is-link t))\r
+\r
+      (when search-is-ref\r
+        (setq guarded-search (org-favtable--make-guarded-search search)))\r
+\r
+      ;;\r
+      ;; Do some sanity checking before really starting\r
+      ;;\r
+\r
+      ;; Correct requested action, if nothing to search\r
+      (when (and (not search)\r
+                 (memq what '(search occur head)))\r
+        (setq what 'enter)\r
+        (setq what-adjusted t))\r
+\r
+      ;; For a proper reference as input, we do multi-occur\r
+      (if (and (string-match ref-regex search)\r
+               (eq what 'occur))\r
+          (setq what 'multi-occur))\r
+\r
+      ;; Check for invalid combinations of arguments; try to be helpful\r
+      (when (and (memq what '(head goto))\r
+                 (not search-is-link)\r
+                 (not search-is-ref))\r
+        (error "Can do '%s' only for a reference or link (not '%s'), try 'occur' to search for text" what search)))\r
 \r
+    \r
     ;;\r
-    ;; Do some sanity checking before really starting\r
+    ;; Prepare\r
     ;;\r
 \r
-    ;; Correct requested action, if nothing to search\r
-    (when (and (not search)\r
-               (memq what '(search occur head)))\r
-      (setq what 'enter)\r
-      (setq what-adjusted t))\r
+    ;; Get link if required before moving in\r
+    (if (eq what 'link)\r
+        (setq link-id (org-id-get-create)))\r
 \r
-    ;; For a proper reference as input, we do multi-occur\r
-    (if (and (string-match ref-regex search)\r
-             (eq what 'occur))\r
-        (setq what 'multi-occur))\r
+    ;; Move into table, if outside\r
+    (when (memq what '(enter ref link goto occur multi-occur missing statistics))\r
 \r
-    ;; Check for invalid combinations of arguments; try to be helpful\r
-    (when (and (memq what '(head goto))\r
-               (not search-is-link)\r
-               (not search-is-ref))\r
-      (error "Can do '%s' only for a reference or link (not '%s'), try 'occur' to search for text" what search)))\r
-\r
-    \r
-  ;;\r
-  ;; Prepare\r
-  ;;\r
-\r
-  ;; Get link if required before moving in\r
-  (if (eq what 'link)\r
-      (setq link-id (org-id-get-create)))\r
-\r
-  ;; Move into table, if outside\r
-  (when (memq what '(enter ref link goto occur multi-occur missing statistics))\r
-    ;; Save current window configuration\r
-    (when (or (not result-is-visible)\r
-              (not org-favtable--windowconfig-before))\r
-      (setq org-favtable--windowconfig-before (current-window-configuration)))\r
-\r
-    ;; Switch to favtable\r
-    (org-pop-to-buffer-same-window (car ref-node-buffer-and-point))\r
-    (goto-char (cdr ref-node-buffer-and-point))\r
-    (show-subtree)\r
-    (org-show-context)\r
-\r
-    ;; sort favtable\r
-    (org-favtable--sort-table reorder-once))\r
-\r
-  ;; Goto back to initial ref, because reformatting of table above might\r
-  ;; have moved point\r
-  (when initial-ref-or-link\r
-    (while (and (org-at-table-p)\r
-                (not (or\r
-                      (string= initial-ref-or-link (org-favtable--get-field 'ref))\r
-                      (string= initial-ref-or-link (org-favtable--get-field 'link)))))\r
-      (forward-line))\r
-    ;; did not find ref, go back to top\r
-    (if (not (org-at-table-p)) (goto-char top)))\r
+      ;; Support orgmode-standard of going back (buffer and position)\r
+      (org-mark-ring-push)\r
 \r
+      ;; Switch to favtable\r
+      (org-pop-to-buffer-same-window (car ref-node-buffer-and-point))\r
+      (goto-char (cdr ref-node-buffer-and-point))\r
+      (show-subtree)\r
+      (org-show-context)\r
 \r
-  ;;\r
-  ;; Actually do, what is requested\r
-  ;;\r
-\r
-  (cond\r
-\r
-\r
-   ((eq what 'help)\r
-      \r
-    (let ((help-what\r
-           ;; which sort of help ?\r
-           (intern\r
-            (concat \r
-             "help-"\r
-             (org-icompleting-read \r
-              "Help on: "\r
-              (mapcar 'symbol-name '(commands usage setup version example)) \r
-              nil t)))))\r
-\r
-      ;; help is taken from docstring of functions or variables\r
-      (cond ((eq help-what 'help-commands)\r
-             (org-favtable--show-help 'org-favtable--commands))\r
-            ((eq help-what 'help-usage)\r
-             (org-favtable--show-help 'org-favtable))\r
-            ((eq help-what 'help-setup)\r
-             (org-favtable--show-help 'org-favtable-id))\r
-            ((eq help-what 'help-version)\r
-             (org-favtable-version)))))\r
-\r
-\r
-   ((eq what 'multi-occur) \r
-      \r
-    ;; Conveniently position cursor on number to search for\r
-    (org-favtable--goto-top)\r
-    (let (found (initial (point)))\r
-      (while (and (not found)\r
-                  (forward-line)\r
-                  (org-at-table-p))\r
-        (save-excursion \r
-          (setq found (string= search \r
-                               (org-favtable--get-field 'ref)))))\r
-      (if found \r
-          (org-favtable--update-line nil)\r
-        (goto-char initial)))\r
-\r
-    ;; Construct list of all org-buffers\r
-    (let (buff org-buffers)\r
-      (dolist (buff (buffer-list))\r
-        (set-buffer buff)\r
-        (if (string= major-mode "org-mode")\r
-            (setq org-buffers (cons buff org-buffers))))\r
-\r
-      ;; Do multi-occur\r
-      (multi-occur org-buffers guarded-search)\r
-      (if (get-buffer "*Occur*")\r
-          (progn \r
-            (setq message-text (format "multi-occur for '%s'" search))\r
-            (setq org-favtable--occur-buffer (get-buffer "*Occur*"))\r
-            (other-window 1)\r
-            (toggle-truncate-lines 1))\r
-        (setq message-text (format "Did not find '%s'" search)))))\r
-\r
-\r
-   ((eq what 'head)\r
-\r
-    (let (link)\r
-      ;; link either from table or passed in as argument\r
-        \r
-      ;; try to get link\r
-      (if search-is-link \r
-          (setq link (org-trim search))\r
-        (if (and within-node\r
-                 (org-at-table-p))\r
-            (setq link (org-favtable--get-field 'link))))\r
-\r
-      ;; use link if available\r
-      (if (and link\r
-               (not (string= link "")))\r
-          (progn \r
-            (org-id-goto link)\r
-            (org-favtable--update-line search)\r
-            (setq message-text "Followed link"))\r
-\r
-        (message (format "Scanning headlines for '%s' ..." search))\r
-        (let (buffer point)\r
-          (if (catch 'found\r
-                (progn\r
-                  ;; loop over all headlines, stop on first match\r
-                  (org-map-entries \r
-                   (lambda () \r
-                     (when (looking-at (concat ".*" guarded-search))\r
-                       ;; remember location and bail out\r
-                       (setq buffer (current-buffer))\r
-                       (setq point (point))\r
-                       (throw 'found t)))          \r
-                   nil 'agenda)\r
-                  nil))\r
-\r
-              (progn\r
-                (org-favtable--update-line search)\r
-                (setq message-text (format "Found '%s'" search))\r
-                (org-pop-to-buffer-same-window buffer)\r
-                (goto-char point)\r
-                (org-reveal))\r
-            (setq message-text (format "Did not find '%s'" search)))))))\r
+      ;; sort favtable\r
+      (org-favtable--sort-table reorder-once))\r
 \r
+    ;; Goto back to initial ref, because reformatting of table above might\r
+    ;; have moved point\r
+    (when initial-ref-or-link\r
+      (while (and (org-at-table-p)\r
+                  (not (or\r
+                        (string= initial-ref-or-link (org-favtable--get-field 'ref))\r
+                        (string= initial-ref-or-link (org-favtable--get-field 'link)))))\r
+        (forward-line))\r
+      ;; did not find ref, go back to top\r
+      (if (not (org-at-table-p)) (goto-char top)))\r
 \r
-   ((eq what 'leave)\r
 \r
-    (when result-is-visible\r
+    ;;\r
+    ;; Actually do, what is requested\r
+    ;;\r
 \r
-      ;; If we are within the occur-buffer, switch over to get current line\r
-      (if (and (string= (buffer-name) "*Occur*")\r
-               (eq org-favtable--last-action 'occur))\r
-          (occur-mode-goto-occurrence))\r
+    (cond\r
 \r
-      (let (copy-column)              \r
-        ;; Try to copy requested column\r
-        (setq copy-column (org-favtable--column-num (if (eq org-favtable--last-action 'ref)\r
-                                                        'goto\r
-                                                      'copy)))\r
-            \r
-        ;; Add to kill ring\r
-        (if (memq org-favtable--last-action '(ref enter goto occur))\r
-            (setq kill-new-text \r
-                  (org-trim (org-table-get-field copy-column))))))\r
 \r
-    ;; Restore position within buffer with favtable\r
-    (with-current-buffer (car ref-node-buffer-and-point)\r
-      (when org-favtable--marker-outside-before\r
-        (goto-char (marker-position org-favtable--marker-outside-before))\r
-        (move-marker org-favtable--marker-outside-before nil)))\r
-\r
-    ;; Restore windowconfig\r
-    (if org-favtable--windowconfig-before \r
-        (progn  \r
-          ;; Restore initial window configuration\r
-          (set-window-configuration org-favtable--windowconfig-before)\r
-          (setq org-favtable--windowconfig-before nil)\r
-          ;; Goto initial position\r
-          (recenter)\r
-          (setq message-text "Back"))\r
-      ;; We did not have a window-configuration to restore, so we cannot\r
-      ;; pretend we have returned back\r
-      (setq message-text "Cannot leave; nowhere to go to")\r
-      (setq kill-new-text nil)))\r
-\r
-\r
-   ((eq what 'goto)\r
-\r
-    ;; Go downward in table to requested reference\r
-    (let (found (initial (point)))\r
+     ((eq what 'help)\r
+      \r
+      (let ((help-what\r
+             ;; which sort of help ?\r
+             (intern\r
+              (concat \r
+               "help-"\r
+               (org-icompleting-read \r
+                "Help on: "\r
+                (mapcar 'symbol-name '(commands usage setup version example)) \r
+                nil t)))))\r
+\r
+        ;; help is taken from docstring of functions or variables\r
+        (cond ((eq help-what 'help-commands)\r
+               (org-favtable--show-help 'org-favtable--commands))\r
+              ((eq help-what 'help-usage)\r
+               (org-favtable--show-help 'org-favtable))\r
+              ((eq help-what 'help-setup)\r
+               (org-favtable--show-help 'org-favtable-id))\r
+              ((eq help-what 'help-version)\r
+               (org-favtable-version)))))\r
+\r
+\r
+     ((eq what 'multi-occur) \r
+      \r
+      ;; Conveniently position cursor on number to search for\r
       (org-favtable--goto-top)\r
-      (while (and (not found)\r
-                  (forward-line)\r
-                  (org-at-table-p))\r
-        (save-excursion \r
-          (setq found \r
-                (string= search \r
-                         (org-favtable--get-field \r
-                          (if search-is-link 'link 'ref))))))\r
-      (if found\r
-          (progn\r
-            (setq message-text (format "Found '%s'" search))\r
+      (let (found (initial (point)))\r
+        (while (and (not found)\r
+                    (forward-line)\r
+                    (org-at-table-p))\r
+          (save-excursion \r
+            (setq found (string= search \r
+                                 (org-favtable--get-field 'ref)))))\r
+        (if found \r
             (org-favtable--update-line nil)\r
-            (org-table-goto-column (org-favtable--column-num 'ref))\r
-            (if (looking-back " ") (backward-char)))\r
-        (setq message-text (format "Did not find '%s'" search))\r
-        (goto-char initial)\r
-        (forward-line)\r
-        (setq what 'missed))))\r
+          (goto-char initial)))\r
 \r
+      ;; Construct list of all org-buffers\r
+      (let (buff org-buffers)\r
+        (dolist (buff (buffer-list))\r
+          (set-buffer buff)\r
+          (if (string= major-mode "org-mode")\r
+              (setq org-buffers (cons buff org-buffers))))\r
 \r
-   ((eq what 'occur)\r
-\r
-    ;; search for string: occur\r
-    (let (search-regexp\r
-          all-or-any\r
-          (search-words (split-string search "," t)))\r
-            \r
-      (if (< (length search-words) 2)\r
-          ;; only one word to search; use it as is\r
-          (setq search-regexp search)\r
-        ;; construct regexp to match any of the words (maybe throw out some matches later)\r
-        (setq search-regexp \r
-              (mapconcat (lambda (x) (concat "\\(" x "\\)")) search-words "\\|"))\r
-        (setq all-or-any\r
-              (intern \r
-               (org-icompleting-read \r
-                "Two or more words have been specified; show lines, that match: " '("all" "any")))))\r
-            \r
-      (save-restriction\r
-        (org-narrow-to-subtree)\r
-        (occur search-regexp)\r
-        (widen)\r
+        ;; Do multi-occur\r
+        (multi-occur org-buffers guarded-search)\r
         (if (get-buffer "*Occur*")\r
-            (with-current-buffer "*Occur*"\r
+            (progn \r
+              (setq message-text (format "multi-occur for '%s'" search))\r
+              (setq org-favtable--occur-buffer (get-buffer "*Occur*"))\r
+              (other-window 1)\r
+              (toggle-truncate-lines 1))\r
+          (setq message-text (format "Did not find '%s'" search)))))\r
 \r
-              ;; install helpful keyboard-shortcuts within occur-buffer\r
-              (let ((keymap (make-sparse-keymap)))\r
-                (set-keymap-parent keymap occur-mode-map)\r
 \r
-                (define-key keymap (kbd "RET") \r
-                  (lambda () (interactive) \r
-                    (org-favtable--occur-helper 'head)))\r
+     ((eq what 'head)\r
 \r
-                (define-key keymap (kbd "<C-return>") \r
-                  (lambda () (interactive) \r
-                    (org-favtable--occur-helper 'multi-occur)))\r
+      (let (link)\r
+        ;; link either from table or passed in as argument\r
+        \r
+        ;; try to get link\r
+        (if search-is-link \r
+            (setq link (org-trim search))\r
+          (if (and within-node\r
+                   (org-at-table-p))\r
+              (setq link (org-favtable--get-field 'link))))\r
+\r
+        ;; use link if available\r
+        (if (and link\r
+                 (not (string= link "")))\r
+            (progn \r
+              (org-id-goto link)\r
+              (org-favtable--update-line search)\r
+              (setq message-text "Followed link"))\r
+\r
+          (message (format "Scanning headlines for '%s' ..." search))\r
+          (let (buffer point)\r
+            (if (catch 'found\r
+                  (progn\r
+                    ;; loop over all headlines, stop on first match\r
+                    (org-map-entries \r
+                     (lambda () \r
+                       (when (looking-at (concat ".*" guarded-search))\r
+                         ;; remember location and bail out\r
+                         (setq buffer (current-buffer))\r
+                         (setq point (point))\r
+                         (throw 'found t)))          \r
+                     nil 'agenda)\r
+                    nil))\r
 \r
-                (define-key keymap (kbd "<M-return>") \r
-                  (lambda () (interactive) \r
-                    (org-favtable--occur-helper 'goto)))\r
+                (progn\r
+                  (org-favtable--update-line search)\r
+                  (setq message-text (format "Found '%s'" search))\r
+                  (org-pop-to-buffer-same-window buffer)\r
+                  (goto-char point)\r
+                  (org-reveal))\r
+              (setq message-text (format "Did not find '%s'" search)))))))\r
 \r
-                (define-key keymap (kbd "<C-M-return>") \r
-                  (lambda () (interactive) \r
-                    (org-favtable--occur-helper 'update)))\r
 \r
-                (use-local-map keymap))\r
+     ((eq what 'leave)\r
 \r
-              ;; Brush up occur buffer\r
-              (other-window 1)\r
-              (toggle-truncate-lines 1)\r
-              (let ((inhibit-read-only t)) \r
-                ;; insert some help text\r
-                (insert (substitute-command-keys \r
-                         "Type RET to find heading, C-RET for multi-occur, M-RET to go to occurence and C-M-RET to update line in reftable.\n\n"))\r
-                (forward-line 1)\r
-\r
-                ;; when matching all of multiple words, remove all lines that do not match one of the words\r
-                (when (eq all-or-any 'all)\r
-                  (mapc (lambda (x) (keep-lines x)) search-words))\r
-\r
-                ;; replace description from occur\r
-                (when all-or-any \r
-                  (forward-line -1)\r
-                  (kill-line)\r
-                  (let ((count (- (count-lines (point) (point-max)) 1)))\r
-                    (insert (format "%d %s for %s of %s" \r
-                                    count \r
-                                    (if (= count 1) "match" "matches")\r
-                                    all-or-any\r
-                                    search)))\r
-                  (forward-line)\r
-                  (beginning-of-line))\r
-                  \r
-                ;; Record link or reference for each line in\r
-                ;; occur-buffer, that is linked into reftable. Because if\r
-                ;; we later realign the reftable and then reuse the occur\r
-                ;; buffer, the original links might point nowehere.\r
-                (save-excursion\r
-                  (while (not (eq (point) (point-max)))\r
-                    (let ((beg (line-beginning-position))\r
-                          (end (line-end-position))\r
-                          pos ref link)\r
-\r
-                      ;; occur has saved the position into a special property\r
-                      (setq pos (get-text-property (point) 'occur-target))\r
-                      (when pos \r
-                        ;; but this property might soon point nowhere; so retrieve ref-or-link instead\r
-                        (with-current-buffer (marker-buffer pos)\r
-                          (goto-char pos)\r
-                          (setq ref (org-favtable--get-field 'ref))\r
-                          (setq link (org-favtable--get-field 'link))))\r
-                      ;; save as text property\r
-                      (put-text-property beg end 'org-favtable--ref ref)\r
-                      (put-text-property beg end 'org-favtable--link link))\r
-                    (forward-line))))\r
-                  \r
-              (setq message-text\r
-                    (format  "Occur for '%s'" search)))\r
-          (setq message-text\r
-                (format "Did not find any matches for '%s'" search))))))\r
+      (when result-is-visible\r
 \r
+        ;; If we are within the occur-buffer, switch over to get current line\r
+        (if (and (string= (buffer-name) "*Occur*")\r
+                 (eq org-favtable--last-action 'occur))\r
+            (occur-mode-goto-occurrence)))\r
+      \r
+      (setq kill-new-text org-favtable--text-to-yank)\r
+      (setq org-favtable--text-to-yank nil)\r
+      \r
+      ;; If "leave" has been called two times in succession, make\r
+      ;; org-mark-ring-goto believe it has been called two times too\r
+      (if (eq org-favtable--last-action 'leave) \r
+          (let ((this-command nil) (last-command nil))\r
+            (org-mark-ring-goto 1))\r
+        (org-mark-ring-goto 0)))\r
 \r
-   ((memq what '(ref link))\r
 \r
-    ;; add a new row (or reuse existing one)\r
-    (let (new)\r
+     ((eq what 'goto)\r
 \r
-      ;; go through table to find first entry to be reused\r
-      (when has-reuse\r
+      ;; Go downward in table to requested reference\r
+      (let (found (initial (point)))\r
         (org-favtable--goto-top)\r
-        ;; go through table\r
-        (while (and (org-at-table-p)\r
-                    (not new))\r
-          (when (string= \r
-                 (org-favtable--get-field 'count)\r
-                 ":reuse:")\r
-            (setq new (org-favtable--get-field 'ref))\r
-            (if new (org-table-kill-row)))\r
-          (forward-line)))\r
+        (while (and (not found)\r
+                    (forward-line)\r
+                    (org-at-table-p))\r
+          (save-excursion \r
+            (setq found \r
+                  (string= search \r
+                           (org-favtable--get-field \r
+                            (if search-is-link 'link 'ref))))))\r
+        (if found\r
+            (progn\r
+              (setq message-text (format "Found '%s'" search))\r
+              (org-favtable--update-line nil)\r
+              (org-table-goto-column (org-favtable--column-num 'ref))\r
+              (if (looking-back " ") (backward-char))\r
+              ;; remember string to copy\r
+              (setq org-favtable--text-to-yank \r
+                    (org-trim (org-table-get-field (org-favtable--column-num 'copy)))))\r
+          (setq message-text (format "Did not find '%s'" search))\r
+          (goto-char initial)\r
+          (forward-line)\r
+          (setq what 'missed))))\r
+\r
+\r
+     ((eq what 'occur)\r
+\r
+      ;; search for string: occur\r
+      (let (search-regexp\r
+            all-or-any\r
+            (search-words (split-string search "," t)))\r
+        \r
+        (if (< (length search-words) 2)\r
+            ;; only one word to search; use it as is\r
+            (setq search-regexp search)\r
+          ;; construct regexp to match any of the words (maybe throw out some matches later)\r
+          (setq search-regexp \r
+                (mapconcat (lambda (x) (concat "\\(" x "\\)")) search-words "\\|"))\r
+          (setq all-or-any\r
+                (intern \r
+                 (org-icompleting-read \r
+                  "Two or more words have been specified; show lines, that match: " '("all" "any")))))\r
         \r
-      ;; no ref to reuse; construct new reference\r
-      (unless new \r
-        (setq new (format "%s%d%s" head (1+ maxref) tail)))\r
+        (save-restriction\r
+          (org-narrow-to-subtree)\r
+          (occur search-regexp)\r
+          (widen)\r
+          (if (get-buffer "*Occur*")\r
+              (with-current-buffer "*Occur*"\r
+\r
+                ;; install helpful keyboard-shortcuts within occur-buffer\r
+                (let ((keymap (make-sparse-keymap)))\r
+                  (set-keymap-parent keymap occur-mode-map)\r
+\r
+                  (define-key keymap (kbd "RET") \r
+                    (lambda () (interactive) \r
+                      (org-favtable--occur-helper 'head)))\r
+\r
+                  (define-key keymap (kbd "<C-return>") \r
+                    (lambda () (interactive) \r
+                      (org-favtable--occur-helper 'multi-occur)))\r
+\r
+                  (define-key keymap (kbd "<M-return>") \r
+                    (lambda () (interactive) \r
+                      (org-favtable--occur-helper 'goto)))\r
+\r
+                  (define-key keymap (kbd "<C-M-return>") \r
+                    (lambda () (interactive) \r
+                      (org-favtable--occur-helper 'update)))\r
+\r
+                  (use-local-map keymap))\r
+\r
+                ;; Brush up occur buffer\r
+                (other-window 1)\r
+                (toggle-truncate-lines 1)\r
+                (let ((inhibit-read-only t)) \r
+                  ;; insert some help text\r
+                  (insert (substitute-command-keys \r
+                           "Type RET to find heading, C-RET for multi-occur, M-RET to go to occurence and C-M-RET to update line in reftable.\n\n"))\r
+                  (forward-line 1)\r
+\r
+                  ;; when matching all of multiple words, remove all lines that do not match one of the words\r
+                  (when (eq all-or-any 'all)\r
+                    (mapc (lambda (x) (keep-lines x)) search-words))\r
+\r
+                  ;; replace description from occur\r
+                  (when all-or-any \r
+                    (forward-line -1)\r
+                    (kill-line)\r
+                    (let ((count (- (count-lines (point) (point-max)) 1)))\r
+                      (insert (format "%d %s for %s of %s" \r
+                                      count \r
+                                      (if (= count 1) "match" "matches")\r
+                                      all-or-any\r
+                                      search)))\r
+                    (forward-line)\r
+                    (beginning-of-line))\r
+                  \r
+                  ;; Record link or reference for each line in\r
+                  ;; occur-buffer, that is linked into reftable. Because if\r
+                  ;; we later realign the reftable and then reuse the occur\r
+                  ;; buffer, the original links might point nowehere.\r
+                  (save-excursion\r
+                    (while (not (eq (point) (point-max)))\r
+                      (let ((beg (line-beginning-position))\r
+                            (end (line-end-position))\r
+                            pos ref link)\r
+\r
+                        ;; occur has saved the position into a special property\r
+                        (setq pos (get-text-property (point) 'occur-target))\r
+                        (when pos \r
+                          ;; but this property might soon point nowhere; so retrieve ref-or-link instead\r
+                          (with-current-buffer (marker-buffer pos)\r
+                            (goto-char pos)\r
+                            (setq ref (org-favtable--get-field 'ref))\r
+                            (setq link (org-favtable--get-field 'link))))\r
+                        ;; save as text property\r
+                        (put-text-property beg end 'org-favtable--ref ref)\r
+                        (put-text-property beg end 'org-favtable--link link))\r
+                      (forward-line))))\r
+                \r
+                (setq message-text\r
+                      (format  "Occur for '%s'" search)))\r
+            (setq message-text\r
+                  (format "Did not find any matches for '%s'" search))))))\r
+\r
+\r
+     ((memq what '(ref link))\r
+\r
+      ;; add a new row (or reuse existing one)\r
+      (let (new)\r
+\r
+        (when (eq what 'ref)\r
+            ;; go through table to find first entry to be reused\r
+          (when has-reuse\r
+            (org-favtable--goto-top)\r
+            ;; go through table\r
+            (while (and (org-at-table-p)\r
+                        (not new))\r
+              (when (string= \r
+                     (org-favtable--get-field 'count)\r
+                     ":reuse:")\r
+                (setq new (org-favtable--get-field 'ref))\r
+                (if new (org-table-kill-row)))\r
+              (forward-line)))\r
+          \r
+          ;; no ref to reuse; construct new reference\r
+          (unless new \r
+            (setq new (format "%s%d%s" head (1+ maxref) tail)))\r
 \r
-      ;; insert ref as very first row\r
-      (org-favtable--goto-top)\r
-      (org-table-insert-row)\r
+          ;; remember for org-mark-ring-goto\r
+          (setq org-favtable--text-to-yank new))\r
         \r
-      ;; fill special columns with standard values\r
-      (when (eq what 'ref)\r
-        (org-table-goto-column (org-favtable--column-num 'ref))\r
-        (insert new))\r
-      (when (eq what 'link)\r
-        (org-table-goto-column (org-favtable--column-num 'link))\r
-        (insert link-id))\r
-      (org-table-goto-column (org-favtable--column-num 'created))\r
-      (org-insert-time-stamp nil nil t)\r
-\r
-      ;; goto first nonempty field\r
-      (catch 'empty\r
-        (dotimes (col numcols)\r
-          (org-table-goto-column (+ col 1))\r
-          (if (string= (org-trim (org-table-get-field)) "")\r
-              (throw 'empty t)))\r
-        ;; none found, goto first\r
-        (org-table-goto-column 1))\r
-\r
-      (org-table-align)\r
-      (if active-region (setq kill-new-text active-region))\r
-      (if (eq what 'ref)\r
-          (setq message-text (format "Adding a new row with ref '%s'" new))\r
-        (setq message-text (format "Adding a new row linked to '%s'" link-id)))))\r
-\r
-\r
-   ((eq what 'enter)\r
-\r
-    ;; simply go into table\r
-    (org-favtable--goto-top)\r
-    (show-subtree)\r
-    (recenter)\r
-    (if what-adjusted\r
-        (setq message-text "Nothing to search for; at favtable")\r
-      (setq message-text "At favtable")))\r
+        ;; insert ref or link as very first row\r
+        (org-favtable--goto-top)\r
+        (org-table-insert-row)\r
+        \r
+        ;; fill special columns with standard values\r
+        (when (eq what 'ref)\r
+          (org-table-goto-column (org-favtable--column-num 'ref))\r
+          (insert new))\r
+        (when (eq what 'link)\r
+          (org-table-goto-column (org-favtable--column-num 'link))\r
+          (insert link-id))\r
+        (org-table-goto-column (org-favtable--column-num 'created))\r
+        (org-insert-time-stamp nil nil t)\r
+\r
+        ;; goto first empty field\r
+        (unless (catch 'empty\r
+                  (dotimes (col numcols)\r
+                    (org-table-goto-column (+ col 1))\r
+                    (if (string= (org-trim (org-table-get-field)) "")\r
+                        (throw 'empty t))))\r
+          ;; none found, goto first\r
+          (org-table-goto-column 1))\r
+\r
+        (org-table-align)\r
+        (if active-region (setq kill-new-text active-region))\r
+        (if (eq what 'ref)\r
+            (setq message-text (format "Adding a new row with ref '%s'" new))\r
+          (setq message-text (format "Adding a new row linked to '%s'" link-id)))))\r
+\r
+\r
+     ((eq what 'enter)\r
+\r
+      ;; simply go into table\r
+      (org-favtable--goto-top)\r
+      (show-subtree)\r
+      (recenter)\r
+      (if what-adjusted\r
+          (setq message-text "Nothing to search for; at favtable")\r
+        (setq message-text "At favtable")))\r
 \r
      \r
-   ((eq what 'fill)\r
-\r
-    ;; check if within reftable\r
-    (unless (and within-node\r
-                 (org-at-table-p))\r
-      (error "Not within table of favorites"))\r
-\r
-    ;; applies to missing refs and missing links alike\r
-    (let ((ref (org-favtable--get-field 'ref))\r
-          (link (org-favtable--get-field 'link)))\r
-\r
-      (if (and (not ref)\r
-               (not link))\r
-          ;; have already checked this during parse, check here anyway\r
-          (error "Columns ref and link are both empty in this line"))\r
-\r
-      ;; fill in new ref\r
-      (if (not ref)\r
-          (progn \r
-            (setq kill-new-text (format "%s%d%s" head (1+ maxref) tail))\r
-            (org-favtable--get-field 'ref kill-new-text)\r
-            (org-id-goto link)\r
-            (setq message-text "Filled reftable field with new reference"))\r
-\r
-        ;; fill in new link\r
-        (if (not link)\r
-            (progn\r
-              (setq guarded-search (org-favtable--make-guarded-search ref))\r
-              (message (format "Scanning headlines for '%s' ..." ref))\r
-              (let (link)\r
-                (if (catch 'found\r
-                      (org-map-entries \r
-                       (lambda () \r
-                         (when (looking-at (concat ".*" guarded-search))\r
-                           (setq link (org-id-get-create))\r
-                           (throw 'found t)))   \r
-                       nil 'agenda)\r
-                      nil)\r
-\r
-                    (progn\r
-                      (org-favtable--get-field 'link link)\r
-                      (setq message-text "Inserted link"))\r
-\r
-                  (setq message-text (format "Did not find reference '%s'" ref)))))\r
-          \r
-          ;; nothing is missing\r
-          (setq message-text "Columns 'ref' and 'link' are already filled; nothing to do")))))\r
-     \r
+     ((eq what 'fill)\r
 \r
-   ((eq what 'sort)\r
+      ;; check, if within reftable\r
+      (unless (and within-node\r
+                   (org-at-table-p))\r
+        (error "Not within table of favorites"))\r
 \r
-    ;; sort lines according to contained reference\r
-    (let (begin end where)\r
-      (catch 'aborted\r
-        ;; either active region or whole buffer\r
-        (if (and transient-mark-mode\r
-                 mark-active)\r
-            ;; sort only region\r
-            (progn\r
-              (setq begin (region-beginning))\r
-              (setq end (region-end))\r
-              (setq where "region"))\r
-          ;; sort whole buffer\r
-          (setq begin (point-min))\r
-          (setq end (point-max))\r
-          (setq where "whole buffer")\r
-          ;; make sure\r
-          (unless (y-or-n-p "Sort whole buffer ")\r
-            (setq message-text "Sort aborted")\r
-            (throw 'aborted nil)))\r
-          \r
-        (save-excursion\r
-          (save-restriction\r
-            (goto-char (point-min))\r
-            (narrow-to-region begin end)\r
-            (sort-subr nil 'forward-line 'end-of-line \r
-                       (lambda ()\r
-                         (if (looking-at (concat ".*" \r
-                                                 (org-favtable--make-guarded-search ref-regex 'dont-quote)))\r
-                             (string-to-number (match-string 1))\r
-                           0))))\r
-          (highlight-regexp ref-regex)\r
-          (setq message-text (format "Sorted %s from character %d to %d, %d lines" \r
-                                     where begin end\r
-                                     (count-lines begin end)))))))\r
-    \r
+      ;; applies to missing refs and missing links alike\r
+      (let ((ref (org-favtable--get-field 'ref))\r
+            (link (org-favtable--get-field 'link)))\r
 \r
-   ((eq what 'update)\r
+        (if (and (not ref)\r
+                 (not link))\r
+            ;; have already checked this during parse, check here anyway\r
+            (error "Columns ref and link are both empty in this line"))\r
 \r
-    ;; simply update line in reftable\r
-    (save-excursion\r
-      (let ((ref-or-link (if search-is-link "link" "reference")))\r
-        (beginning-of-line)\r
-        (if (org-favtable--update-line search)\r
-            (setq message-text (format "Updated %s '%s'" ref-or-link search))\r
-          (setq message-text (format "Did not find %s '%s'" ref-or-link search))))))\r
+        ;; fill in new ref\r
+        (if (not ref)\r
+            (progn \r
+              (setq kill-new-text (format "%s%d%s" head (1+ maxref) tail))\r
+              (org-favtable--get-field 'ref kill-new-text)\r
+              ;; remember for org-mark-ring-goto\r
+              (setq org-favtable--text-to-yank kill-new-text)\r
+              (org-id-goto link)\r
+              (setq message-text "Filled reftable field with new reference"))\r
+\r
+          ;; fill in new link\r
+          (if (not link)\r
+              (progn\r
+                (setq guarded-search (org-favtable--make-guarded-search ref))\r
+                (message (format "Scanning headlines for '%s' ..." ref))\r
+                (let (link)\r
+                  (if (catch 'found\r
+                        (org-map-entries \r
+                         (lambda () \r
+                           (when (looking-at (concat ".*" guarded-search))\r
+                             (setq link (org-id-get-create))\r
+                             (throw 'found t)))   \r
+                         nil 'agenda)\r
+                        nil)\r
+\r
+                      (progn\r
+                        (org-favtable--get-field 'link link)\r
+                        (setq message-text "Inserted link"))\r
+\r
+                    (setq message-text (format "Did not find reference '%s'" ref)))))\r
+            \r
+            ;; nothing is missing\r
+            (setq message-text "Columns 'ref' and 'link' are already filled; nothing to do")))))\r
+     \r
 \r
+     ((eq what 'sort)\r
 \r
-   ((memq what '(highlight unhighlight))\r
+      ;; sort lines according to contained reference\r
+      (let (begin end where)\r
+        (catch 'aborted\r
+          ;; either active region or whole buffer\r
+          (if (and transient-mark-mode\r
+                   mark-active)\r
+              ;; sort only region\r
+              (progn\r
+                (setq begin (region-beginning))\r
+                (setq end (region-end))\r
+                (setq where "region"))\r
+            ;; sort whole buffer\r
+            (setq begin (point-min))\r
+            (setq end (point-max))\r
+            (setq where "whole buffer")\r
+            ;; make sure\r
+            (unless (y-or-n-p "Sort whole buffer ")\r
+              (setq message-text "Sort aborted")\r
+              (throw 'aborted nil)))\r
+          \r
+          (save-excursion\r
+            (save-restriction\r
+              (goto-char (point-min))\r
+              (narrow-to-region begin end)\r
+              (sort-subr nil 'forward-line 'end-of-line \r
+                         (lambda ()\r
+                           (if (looking-at (concat ".*" \r
+                                                   (org-favtable--make-guarded-search ref-regex 'dont-quote)))\r
+                               (string-to-number (match-string 1))\r
+                             0))))\r
+            (highlight-regexp ref-regex)\r
+            (setq message-text (format "Sorted %s from character %d to %d, %d lines" \r
+                                       where begin end\r
+                                       (count-lines begin end)))))))\r
+     \r
 \r
-    (let ((where "buffer"))\r
+     ((eq what 'update)\r
+\r
+      ;; simply update line in reftable\r
       (save-excursion\r
-        (save-restriction\r
-          (when (and transient-mark-mode\r
-                     mark-active)\r
-            (narrow-to-region (region-beginning) (region-end))\r
-            (setq where "region"))\r
+        (let ((ref-or-link (if search-is-link "link" "reference")))\r
+          (beginning-of-line)\r
+          (if (org-favtable--update-line search)\r
+              (setq message-text (format "Updated %s '%s'" ref-or-link search))\r
+            (setq message-text (format "Did not find %s '%s'" ref-or-link search))))))\r
 \r
-          (if (eq what 'highlight)\r
-              (progn\r
-                (highlight-regexp ref-regex)\r
-                (setq message-text (format "Highlighted references in %s" where)))\r
-            (unhighlight-regexp ref-regex)\r
-            (setq message-text (format "Removed highlights for references in %s" where)))))))\r
 \r
+     ((eq what 'parse)\r
 \r
-   ((memq what '(missing statistics))\r
+      ;; Just parse the reftable, which is already done, so nothing to do\r
+      )\r
 \r
-    (org-favtable--goto-top)\r
-    (let (missing \r
-          ref-field\r
-          ref\r
-          min\r
-          max \r
-          (total 0))\r
-\r
-      ;; start with list of all references\r
-      (setq missing (mapcar (lambda (x) (format "%s%d%s" head x tail)) \r
-                            (number-sequence 1 maxref)))\r
-\r
-      ;; go through table and remove all refs, that we see\r
-      (while (and (forward-line)\r
-                  (org-at-table-p))\r
-\r
-        ;; get ref-field and number\r
-        (setq ref-field (org-favtable--get-field 'ref))\r
-        (if (and ref-field \r
-                 (string-match ref-regex ref-field))\r
-            (setq ref (string-to-number (match-string 1 ref-field))))\r
 \r
-        ;; remove existing refs from list\r
-        (if ref-field (setq missing (delete ref-field missing)))\r
+     ((memq what '(highlight unhighlight))\r
+\r
+      (let ((where "buffer"))\r
+        (save-excursion\r
+          (save-restriction\r
+            (when (and transient-mark-mode\r
+                       mark-active)\r
+              (narrow-to-region (region-beginning) (region-end))\r
+              (setq where "region"))\r
+\r
+            (if (eq what 'highlight)\r
+                (progn\r
+                  (highlight-regexp ref-regex)\r
+                  (setq message-text (format "Highlighted references in %s" where)))\r
+              (unhighlight-regexp ref-regex)\r
+              (setq message-text (format "Removed highlights for references in %s" where)))))))\r
 \r
-        ;; record min and max            \r
-        (if (or (not min) (< ref min)) (setq min ref))\r
-        (if (or (not max) (> ref max)) (setq max ref))\r
 \r
-        ;; count\r
-        (setq total (1+ total)))\r
+     ((memq what '(missing statistics))\r
 \r
-      ;; insert them, if requested\r
-      (forward-line -1)\r
-      (if (eq what 'statistics)\r
+      (org-favtable--goto-top)\r
+      (let (missing \r
+            ref-field\r
+            ref\r
+            min\r
+            max \r
+            (total 0))\r
+\r
+        ;; start with list of all references\r
+        (setq missing (mapcar (lambda (x) (format "%s%d%s" head x tail)) \r
+                              (number-sequence 1 maxref)))\r
+\r
+        ;; go through table and remove all refs, that we see\r
+        (while (and (forward-line)\r
+                    (org-at-table-p))\r
+\r
+          ;; get ref-field and number\r
+          (setq ref-field (org-favtable--get-field 'ref))\r
+          (if (and ref-field \r
+                   (string-match ref-regex ref-field))\r
+              (setq ref (string-to-number (match-string 1 ref-field))))\r
+\r
+          ;; remove existing refs from list\r
+          (if ref-field (setq missing (delete ref-field missing)))\r
+\r
+          ;; record min and max            \r
+          (if (or (not min) (< ref min)) (setq min ref))\r
+          (if (or (not max) (> ref max)) (setq max ref))\r
+\r
+          ;; count\r
+          (setq total (1+ total)))\r
+\r
+        ;; insert them, if requested\r
+        (forward-line -1)\r
+        (if (eq what 'statistics)\r
             \r
-          (setq message-text (format "Found %d references from %s to %s. %d references below highest do not appear in table. "\r
-                                     total \r
-                                     (format org-favtable--format min)   \r
-                                     (format org-favtable--format max)\r
-                                     (length missing)))\r
-\r
-        (if (y-or-n-p (format "Found %d missing references; do you wish to append them to the table of favorites" \r
-                              (length missing)))\r
-            (let (type)\r
-              (setq type (org-icompleting-read \r
-                          "Insert new lines for reuse by command \"new\" or just as missing ? " '("reuse" "missing")))\r
-              (mapc (lambda (x) \r
-                      (let (org-table-may-need-update) (org-table-insert-row t))\r
-                      (org-favtable--get-field 'ref x)\r
-                      (org-favtable--get-field 'count (format ":%s:" type)))\r
-                    missing)\r
-              (org-table-align)\r
-              (setq message-text (format "Inserted %d new lines for missing refernces" (length missing))))\r
-          (setq message-text (format "%d missing references." (length missing)))))))\r
+            (setq message-text (format "Found %d references from %s to %s. %d references below highest do not appear in table. "\r
+                                       total \r
+                                       (format org-favtable--format min)   \r
+                                       (format org-favtable--format max)\r
+                                       (length missing)))\r
+\r
+          (if (y-or-n-p (format "Found %d missing references; do you wish to append them to the table of favorites" \r
+                                (length missing)))\r
+              (let (type)\r
+                (setq type (org-icompleting-read \r
+                            "Insert new lines for reuse by command \"new\" or just as missing ? " '("reuse" "missing")))\r
+                (mapc (lambda (x) \r
+                        (let (org-table-may-need-update) (org-table-insert-row t))\r
+                        (org-favtable--get-field 'ref x)\r
+                        (org-favtable--get-field 'count (format ":%s:" type)))\r
+                      missing)\r
+                (org-table-align)\r
+                (setq message-text (format "Inserted %d new lines for missing refernces" (length missing))))\r
+            (setq message-text (format "%d missing references." (length missing)))))))\r
      \r
-      \r
-   (t (error "This is a bug: unmatched case '%s'" what)))\r
+     \r
+     (t (error "This is a bug: unmatched case '%s'" what)))\r
 \r
 \r
-  ;; remember what we have done for next time\r
-  (setq org-favtable--last-action what)\r
+    ;; remember what we have done for next time\r
+    (setq org-favtable--last-action what)\r
     \r
-  ;; tell, what we have done and what can be yanked\r
-  (if kill-new-text (setq kill-new-text \r
-                          (substring-no-properties kill-new-text)))\r
-  (if (string= kill-new-text "") (setq kill-new-text nil))\r
-  (let ((m (concat \r
-            message-text\r
-            (if (and message-text kill-new-text) \r
-                " and r" \r
-              (if kill-new-text "R" ""))\r
-            (if kill-new-text (format "eady to yank '%s'" kill-new-text) ""))))\r
-    (unless (string= m "") (message m)))\r
-  (if kill-new-text (kill-new kill-new-text))))\r
+    ;; tell, what we have done and what can be yanked\r
+    (if kill-new-text (setq kill-new-text \r
+                            (substring-no-properties kill-new-text)))\r
+    (if (string= kill-new-text "") (setq kill-new-text nil))\r
+    (let ((m (concat \r
+              message-text\r
+              (if (and message-text kill-new-text) \r
+                  " and r" \r
+                (if kill-new-text "R" ""))\r
+              (if kill-new-text (format "eady to yank '%s'" kill-new-text) ""))))\r
+      (unless (string= m "") (message m)))\r
+    (if kill-new-text (kill-new kill-new-text))))\r
 \r
 \r
 \r
@@ -1299,7 +1318,7 @@ An example would be:
        (format "First reference in table table of favorites ('%s') does not contain a number" ref-field) t))\r
     \r
 \r
-    ;; These are the decorations used within the first row of favtable\r
+    ;; These are the decorations used within the first ref of favtable\r
     (setq head (match-string 1 ref-field))\r
     (setq tail (match-string 3 ref-field))\r
     (setq ref-regex (concat (regexp-quote head)\r
@@ -1548,8 +1567,6 @@ An example would be:
     (org-favtable--show-help 'org-favtable-id))\r
 \r
   (error "")\r
-  (setq org-favtable--windowconfig-before nil)\r
-  (move-marker org-favtable--marker-outside-before nil)\r
   (setq org-favtable--last-action 'leave))\r
 \r
 \r
@@ -1651,7 +1668,7 @@ An example would be:
 \r
 \r
 (defun org-favtable-version ()\r
-  "Show version of org-favtable"\r
+  "Show version of org-favtable" (interactive)\r
   (message "org-favtable %s" org-favtable--version))\r
 \r
 \r
@@ -1659,6 +1676,21 @@ An example would be:
   (concat "\\b" (if dont-quote ref (regexp-quote ref)) "\\b"))\r
 \r
 \r
+(defun org-favtable-get-ref-regex-format ()\r
+  "return cons-cell with regular expression and format for references"\r
+  (unless org-favtable--ref-regex\r
+    (org-favtable 'parse))\r
+  (cons (org-favtable--make-guarded-search org-favtable--ref-regex 'dont-quote) org-favtable--ref-format))\r
+  \r
+\r
+(defadvice org-mark-ring-goto (after org-favtable--advice-text-to-yank activate)\r
+  "Make text from the favtable available for yank."\r
+  (when org-favtable--text-to-yank\r
+      (kill-new org-favtable--text-to-yank)\r
+      (message (format "Ready to yank '%s'" org-favtable--text-to-yank))\r
+      (setq org-favtable--text-to-yank nil)))\r
+\r
+\r
 (provide 'org-favtable)\r
 \r
 ;; Local Variables:\r
index 8160ba9..3c2098f 100644 (file)
@@ -185,6 +185,17 @@ hopefully have some documentation.
   Written by /Wes Hardaker/.
   [[repofile:contrib/lisp/org-export-generic.el][Link to raw file]].
 
+- /org-favtable.el/ -- Lookup table of favorite references and links ::
+  Mark and find your favorite things and locations in org easily: Create
+  and update a lookup table of your references and links. Often used
+  entries bubble to the top and entering some keywords displays only the
+  matching entries. That way the right entry one can be picked easily.
+
+  References are essentially small numbers (e.g. "R237" or "-455-"),
+  which are created by this package; they are well suited to be used
+  outside of org. Links are just normal org-mode links.
+  [[http://orgmode.org/worg/code/elisp/org-favtable.el][Link to raw file]].
+
 - [[file:org-feed.org][/org-feed.el/ -- add RSS feed items to Org files]] ::
   Read RSS feeds from the web, add new items to Org files, and trigger
   actions when items have changed.
@@ -304,17 +315,6 @@ hopefully have some documentation.
   This modules has been superseded by the Org Babel functionality,
   which is part of the Org core and [[http://orgmode.org/manual/Working-With-Source-Code.html#Working-With-Source-Code"][documented in the manual]].
 
-- /org-favtable.el/ -- Table of favorite references and links :: Mark
-  and find your favorite items and org-locations easily: Create and
-  update a lookup table of your favorite references and links. Often
-  used entries automatically bubble to the top of the table; entering
-  some keywords narrows it to just the matching entries; that way the
-  right one can be picked easily.
-
-  References are essentially small numbers (e.g. "R237" or "-455-"),
-  as created by this package; links are normal org-mode links.
-  [[http://orgmode.org/worg/code/elisp/org-favtable.el][Link to raw file]].
-
 - /org-registry.el/ -- a registry for Org links ::
   Find out from where links point to a given file or location.
   Written by /Bastien Guerry/.