| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 | 
							- ;;; org-registry.el --- a registry for Org links
 
- ;;
 
- ;; Copyright 2007-2013 Bastien Guerry
 
- ;;
 
- ;; Emacs Lisp Archive Entry
 
- ;; Filename: org-registry.el
 
- ;; Version: 0.1a
 
- ;; Author: Bastien Guerry <bzg@gnu.org>
 
- ;; Maintainer: Bastien Guerry <bzg@gnu.org>
 
- ;; Keywords: org, wp, registry
 
- ;; Description: Shows Org files where the current buffer is linked
 
- ;; URL: http://www.cognition.ens.fr/~guerry/u/org-registry.el
 
- ;;
 
- ;; This file is not part of GNU Emacs.
 
- ;;
 
- ;; This program is free software; you can redistribute it and/or modify
 
- ;; it under the terms of the GNU General Public License as published by
 
- ;; the Free Software Foundation; either version 3, or (at your option)
 
- ;; any later version.
 
- ;;
 
- ;; This program is distributed in the hope that it will be useful,
 
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
- ;; GNU General Public License for more details.
 
- ;;
 
- ;; You should have received a copy of the GNU General Public License
 
- ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
- ;;; Commentary:
 
- ;;
 
- ;; This library add a registry to your Org setup.
 
- ;;
 
- ;; Org files are full of links inserted with `org-store-link'. This links
 
- ;; point to e-mail, webpages, files, dirs, info pages, man pages, etc.
 
- ;; Actually, they come from potentially *everywhere* since Org lets you
 
- ;; define your own storing/following functions.
 
- ;;
 
- ;; So, what if you are on a e-mail, webpage or whatever and want to know if
 
- ;; this buffer has already been linked to somewhere in your agenda files?
 
- ;;
 
- ;; This is were org-registry comes in handy.
 
- ;;
 
- ;;     M-x org-registry-show will tell you the name of the file
 
- ;; C-u M-x org-registry-show will directly jump to the file
 
- ;;
 
- ;; In case there are several files where the link lives in:
 
- ;;
 
- ;;     M-x org-registry-show will display them in a new window
 
- ;; C-u M-x org-registry-show will prompt for a file to visit
 
- ;;
 
- ;; Add this to your Org configuration:
 
- ;;
 
- ;; (require 'org-registry)
 
- ;; (org-registry-initialize)
 
- ;;
 
- ;; If you want to update the registry with newly inserted links in the
 
- ;; current buffer: M-x org-registry-update
 
- ;;
 
- ;; If you want this job to be done each time you save an Org buffer,
 
- ;; hook 'org-registry-update to the local 'after-save-hook in org-mode:
 
- ;;
 
- ;; (org-registry-insinuate)
 
- ;;; Code:
 
- (eval-when-compile
 
-   (require 'cl))
 
- (defgroup org-registry nil
 
-   "A registry for Org."
 
-   :group 'org)
 
- (defcustom org-registry-file
 
-   (concat (getenv "HOME") "/.org-registry.el")
 
-   "The Org registry file."
 
-   :group 'org-registry
 
-   :type 'file)
 
- (defcustom org-registry-find-file 'find-file-other-window
 
-   "How to find visit files."
 
-   :type 'function
 
-   :group 'org-registry)
 
- (defvar org-registry-alist nil
 
-   "An alist containing the Org registry.")
 
- ;;;###autoload
 
- (defun org-registry-show (&optional visit)
 
-   "Show Org files where there are links pointing to the current
 
- buffer."
 
-   (interactive "P")
 
-   (org-registry-initialize)
 
-   (let* ((blink (or (org-remember-annotation) ""))
 
- 	 (link (when (string-match org-bracket-link-regexp blink)
 
- 		 (match-string-no-properties 1 blink)))
 
- 	 (desc (or (and (string-match org-bracket-link-regexp blink)
 
- 			(match-string-no-properties 3 blink)) "No description"))
 
- 	 (files (org-registry-assoc-all link))
 
- 	 file point selection tmphist)
 
-     (cond ((and files visit)
 
- 	   ;; result(s) to visit
 
- 	   (cond ((< 1 (length files))
 
- 		  ;; more than one result
 
- 		  (setq tmphist (mapcar (lambda(entry)
 
- 					  (format "%s (%d) [%s]"
 
- 						  (nth 3 entry) ; file
 
- 						  (nth 2 entry) ; point
 
- 						  (nth 1 entry))) files))
 
- 		  (setq selection (completing-read "File: " tmphist
 
- 						   nil t nil 'tmphist))
 
- 		  (string-match "\\(.+\\) (\\([0-9]+\\))" selection)
 
- 		  (setq file (match-string 1 selection))
 
- 		  (setq point (string-to-number (match-string 2 selection))))
 
- 		 ((eq 1 (length files))
 
- 		  ;; just one result
 
- 		  (setq file (nth 3 (car files)))
 
- 		  (setq point (nth 2 (car files)))))
 
- 	   ;; visit the (selected) file
 
- 	   (funcall org-registry-find-file file)
 
- 	   (goto-char point)
 
- 	   (unless (org-before-first-heading-p)
 
- 	     (org-show-context)))
 
- 	  ((and files (not visit))
 
- 	   ;; result(s) to display
 
- 	   (cond  ((eq 1 (length files))
 
- 		   ;; show one file
 
- 		   (message "Link in file %s (%d) [%s]"
 
- 			    (nth 3 (car files))
 
- 			    (nth 2 (car files))
 
- 			    (nth 1 (car files))))
 
- 		  (t (org-registry-display-files files link))))
 
- 	  (t (message "No link to this in org-agenda-files")))))
 
- (defun org-registry-display-files (files link)
 
-   "Display files in a separate window."
 
-   (switch-to-buffer-other-window
 
-    (get-buffer-create " *Org registry info*"))
 
-   (erase-buffer)
 
-   (insert (format "Files pointing to %s:\n\n" link))
 
-   (let (file)
 
-     (while (setq file (pop files))
 
-       (insert (format "%s (%d) [%s]\n" (nth 3 file)
 
- 		      (nth 2 file) (nth 1 file)))))
 
-   (shrink-window-if-larger-than-buffer)
 
-   (other-window 1))
 
- (defun org-registry-assoc-all (link &optional registry)
 
-   "Return all associated entries of LINK in the registry."
 
-   (org-registry-find-all
 
-    (lambda (entry) (string= link (car entry)))
 
-    registry))
 
- (defun org-registry-find-all (test &optional registry)
 
-   "Return all entries satisfying `test' in the registry."
 
-   (delq nil
 
-         (mapcar
 
-          (lambda (x) (and (funcall test x) x))
 
-          (or registry org-registry-alist))))
 
- ;;;###autoload
 
- (defun org-registry-visit ()
 
-   "If an Org file contains a link to the current location, visit
 
- this file."
 
-   (interactive)
 
-   (org-registry-show t))
 
- ;;;###autoload
 
- (defun org-registry-initialize (&optional from-scratch)
 
-   "Initialize `org-registry-alist'.
 
- If FROM-SCRATCH is non-nil or the registry does not exist yet,
 
- create a new registry from scratch and eval it. If the registry
 
- exists, eval `org-registry-file' and make it the new value for
 
- `org-registry-alist'."
 
-   (interactive "P")
 
-   (if (or from-scratch (not (file-exists-p org-registry-file)))
 
-       ;; create a new registry
 
-       (let ((files org-agenda-files) file)
 
- 	(while (setq file (pop files))
 
- 	  (setq file (expand-file-name file))
 
- 	  (mapc (lambda (entry)
 
- 		  (add-to-list 'org-registry-alist entry))
 
- 		(org-registry-get-entries file)))
 
- 	(when from-scratch
 
- 	  (org-registry-create org-registry-alist)))
 
-     ;; eval the registry file
 
-     (with-temp-buffer
 
-       (insert-file-contents org-registry-file)
 
-       (eval-buffer))))
 
- ;;;###autoload
 
- (defun org-registry-insinuate ()
 
-   "Call `org-registry-update' after saving in Org-mode.
 
- Use with caution.  This could slow down things a bit."
 
-   (interactive)
 
-   (add-hook 'org-mode-hook
 
- 	    (lambda() (add-hook 'after-save-hook
 
- 				'org-registry-update t t))))
 
- (defun org-registry-get-entries (file)
 
-   "List Org links in FILE that will be put in the registry."
 
-   (let (bufstr result)
 
-     (with-temp-buffer
 
-       (insert-file-contents file)
 
-       (goto-char (point-min))
 
-       (while (re-search-forward org-angle-link-re nil t)
 
- 	(let* ((point (match-beginning 0))
 
- 	       (link (match-string-no-properties 0))
 
- 	       (desc (match-string-no-properties 0)))
 
- 	    (add-to-list 'result (list link desc point file))))
 
-       (goto-char (point-min))
 
-       (while (re-search-forward org-bracket-link-regexp nil t)
 
- 	(let* ((point (match-beginning 0))
 
- 	       (link (match-string-no-properties 1))
 
- 	       (desc (or (match-string-no-properties 3) "No description")))
 
- 	    (add-to-list 'result (list link desc point file)))))
 
-     ;; return the list of new entries
 
-     result))
 
- ;;;###autoload
 
- (defun org-registry-update ()
 
-   "Update the registry for the current Org file."
 
-   (interactive)
 
-   (unless (eq major-mode 'org-mode) (error "Not in org-mode"))
 
-   (let* ((from-file (expand-file-name (buffer-file-name)))
 
- 	 (new-entries (org-registry-get-entries from-file)))
 
-     (with-temp-buffer
 
-       (unless (file-exists-p org-registry-file)
 
- 	(org-registry-initialize t))
 
-       (find-file org-registry-file)
 
-       (goto-char (point-min))
 
-       (while (re-search-forward (concat from-file "\")$") nil t)
 
- 	(let ((end (1+ (match-end 0)))
 
- 	      (beg (progn (re-search-backward "^(\"" nil t)
 
- 			  (match-beginning 0))))
 
- 	(delete-region beg end)))
 
-       (goto-char (point-min))
 
-       (re-search-forward "^(\"" nil t)
 
-       (goto-char (match-beginning 0))
 
-       (mapc (lambda (elem)
 
- 	      (insert (with-output-to-string (prin1 elem)) "\n"))
 
- 	    new-entries)
 
-       (save-buffer)
 
-       (kill-buffer (current-buffer)))
 
-     (message (format "Org registry updated for %s"
 
- 		     (file-name-nondirectory from-file)))))
 
- (defun org-registry-create (entries)
 
-   "Create `org-registry-file' with ENTRIES."
 
-   (let (entry)
 
-     (with-temp-buffer
 
-       (find-file org-registry-file)
 
-       (erase-buffer)
 
-       (insert
 
-        (with-output-to-string
 
- 	 (princ ";; -*- emacs-lisp -*-\n")
 
- 	 (princ ";; Org registry\n")
 
- 	 (princ ";; You shouldn't try to modify this buffer manually\n\n")
 
- 	 (princ "(setq org-registry-alist\n'(\n")
 
- 	 (while entries
 
- 	   (when (setq entry (pop entries))
 
- 	     (prin1 entry)
 
- 	     (princ "\n")))
 
- 	 (princ "))\n")))
 
-       (save-buffer)
 
-       (kill-buffer (current-buffer))))
 
-   (message "Org registry created"))
 
- (provide 'org-registry)
 
- ;;;  User Options, Variables
 
- ;;; org-registry.el ends here
 
 
  |