| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 | 
							- ;;; org-toc.el --- Table of contents for Org-mode buffer
 
- ;; Copyright 2007-2018 Free Software Foundation, Inc.
 
- ;;
 
- ;; Author: Bastien Guerry <bzg@gnu.org>
 
- ;; Keywords: Org table of contents
 
- ;; Homepage: http://www.cognition.ens.fr/~guerry/u/org-toc.el
 
- ;; Version: 0.8
 
- ;; 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 implements a browsable table of contents for Org files.
 
- ;; Put this file into your load-path and the following into your ~/.emacs:
 
- ;;   (require 'org-toc)
 
- ;;; Code:
 
- (provide 'org-toc)
 
- (eval-when-compile
 
-   (require 'cl))
 
- ;;; Custom variables:
 
- (defvar org-toc-base-buffer nil)
 
- (defvar org-toc-columns-shown nil)
 
- (defvar org-toc-odd-levels-only nil)
 
- (defvar org-toc-config-alist nil)
 
- (defvar org-toc-cycle-global-status nil)
 
- (defalias 'org-show-table-of-contents 'org-toc-show)
 
- (defgroup org-toc nil
 
-   "Options concerning the browsable table of contents of Org-mode."
 
-   :tag "Org TOC"
 
-   :group 'org)
 
- (defcustom org-toc-default-depth 1
 
-   "Default depth when invoking `org-toc-show' without argument."
 
-   :group 'org-toc
 
-   :type '(choice
 
- 	  (const :tag "same as base buffer" nil)
 
- 	  (integer :tag "level")))
 
- (defcustom org-toc-follow-mode nil
 
-   "Non-nil means navigating through the table of contents will
 
- move the point in the Org buffer accordingly."
 
-   :group 'org-toc
 
-   :type 'boolean)
 
- (defcustom org-toc-info-mode nil
 
-   "Non-nil means navigating through the table of contents will
 
- show the properties for the current headline in the echo-area."
 
-   :group 'org-toc
 
-   :type 'boolean)
 
- (defcustom org-toc-show-subtree-mode nil
 
-   "Non-nil means show subtree when going to headline or following
 
- it while browsing the table of contents."
 
-   :group 'org-toc
 
-   :type '(choice
 
- 	  (const :tag "show subtree" t)
 
- 	  (const :tag "show entry" nil)))
 
- (defcustom org-toc-recenter-mode t
 
-   "Non-nil means recenter the Org buffer when following the
 
- headlines in the TOC buffer."
 
-   :group 'org-toc
 
-   :type 'boolean)
 
- (defcustom org-toc-recenter 0
 
-   "Where to recenter the Org buffer when unfolding a subtree.
 
- This variable is only used when `org-toc-recenter-mode' is set to
 
- 'custom. A value >=1000 will call recenter with no arg."
 
-   :group 'org-toc
 
-   :type 'integer)
 
- (defcustom org-toc-info-exclude '("ALLTAGS")
 
-   "A list of excluded properties when displaying info in the
 
- echo-area. The COLUMNS property is always exluded."
 
-   :group 'org-toc
 
-   :type 'lits)
 
- ;;; Org TOC mode:
 
- (defvar org-toc-mode-map (make-sparse-keymap)
 
-   "Keymap for `org-toc-mode'.")
 
- (defun org-toc-mode ()
 
-   "A major mode for browsing the table of contents of an Org buffer.
 
- \\{org-toc-mode-map}"
 
-   (interactive)
 
-   (kill-all-local-variables)
 
-   (use-local-map org-toc-mode-map)
 
-   (setq mode-name "Org TOC")
 
-   (setq major-mode 'org-toc-mode))
 
- ;; toggle modes
 
- (define-key org-toc-mode-map "F" 'org-toc-follow-mode)
 
- (define-key org-toc-mode-map "S" 'org-toc-show-subtree-mode)
 
- (define-key org-toc-mode-map "s" 'org-toc-store-config)
 
- (define-key org-toc-mode-map "g" 'org-toc-restore-config)
 
- (define-key org-toc-mode-map "i" 'org-toc-info-mode)
 
- (define-key org-toc-mode-map "r" 'org-toc-recenter-mode)
 
- ;; navigation keys
 
- (define-key org-toc-mode-map "p" 'org-toc-previous)
 
- (define-key org-toc-mode-map "n" 'org-toc-next)
 
- (define-key org-toc-mode-map "f" 'org-toc-forward)
 
- (define-key org-toc-mode-map "b" 'org-toc-back)
 
- (define-key org-toc-mode-map [(left)] 'org-toc-back)
 
- (define-key org-toc-mode-map [(right)] 'org-toc-forward)
 
- (define-key org-toc-mode-map [(up)] 'org-toc-previous)
 
- (define-key org-toc-mode-map [(down)] 'org-toc-next)
 
- (define-key org-toc-mode-map "1" (lambda() (interactive) (org-toc-show 1 (point))))
 
- (define-key org-toc-mode-map "2" (lambda() (interactive) (org-toc-show 2 (point))))
 
- (define-key org-toc-mode-map "3" (lambda() (interactive) (org-toc-show 3 (point))))
 
- (define-key org-toc-mode-map "4" (lambda() (interactive) (org-toc-show 4 (point))))
 
- (define-key org-toc-mode-map " " 'org-toc-goto)
 
- (define-key org-toc-mode-map "q" 'org-toc-quit)
 
- (define-key org-toc-mode-map "x" 'org-toc-quit)
 
- ;; go to the location and stay in the base buffer
 
- (define-key org-toc-mode-map [(tab)] 'org-toc-jump)
 
- (define-key org-toc-mode-map "v" 'org-toc-jump)
 
- ;; go to the location and delete other windows
 
- (define-key org-toc-mode-map [(return)]
 
-   (lambda() (interactive) (org-toc-jump t)))
 
- ;; special keys
 
- (define-key org-toc-mode-map "c" 'org-toc-columns)
 
- (define-key org-toc-mode-map "?" 'org-toc-help)
 
- (define-key org-toc-mode-map ":" 'org-toc-cycle-subtree)
 
- (define-key org-toc-mode-map "\C-c\C-o" 'org-open-at-point)
 
- ;; global cycling in the base buffer
 
- (define-key org-toc-mode-map (kbd "C-S-<iso-lefttab>")
 
-   'org-toc-cycle-base-buffer)
 
- ;; subtree cycling in the base buffer
 
- (define-key org-toc-mode-map [(control tab)]
 
-   (lambda() (interactive) (org-toc-goto nil t)))
 
- ;;; Toggle functions:
 
- (defun org-toc-follow-mode ()
 
-   "Toggle follow mode in a `org-toc-mode' buffer."
 
-   (interactive)
 
-   (setq org-toc-follow-mode (not org-toc-follow-mode))
 
-   (message "Follow mode is %s"
 
- 	   (if org-toc-follow-mode "on" "off")))
 
- (defun org-toc-info-mode ()
 
-   "Toggle info mode in a `org-toc-mode' buffer."
 
-   (interactive)
 
-   (setq org-toc-info-mode (not org-toc-info-mode))
 
-   (message "Info mode is %s"
 
- 	   (if org-toc-info-mode "on" "off")))
 
- (defun org-toc-show-subtree-mode ()
 
-   "Toggle show subtree mode in a `org-toc-mode' buffer."
 
-   (interactive)
 
-   (setq org-toc-show-subtree-mode (not org-toc-show-subtree-mode))
 
-   (message "Show subtree mode is %s"
 
- 	   (if org-toc-show-subtree-mode "on" "off")))
 
- (defun org-toc-recenter-mode (&optional line)
 
-   "Toggle recenter mode in a `org-toc-mode' buffer. If LINE is
 
- specified, then make `org-toc-recenter' use this value."
 
-   (interactive "P")
 
-   (setq org-toc-recenter-mode (not org-toc-recenter-mode))
 
-   (when (numberp line)
 
-     (setq org-toc-recenter-mode t)
 
-     (setq org-toc-recenter line))
 
-   (message "Recenter mode is %s"
 
- 	   (if org-toc-recenter-mode
 
- 	       (format "on, line %d" org-toc-recenter) "off")))
 
- (defun org-toc-cycle-subtree ()
 
-   "Locally cycle a headline through two states: 'children and
 
- 'folded"
 
-   (interactive)
 
-   (let ((beg (point))
 
- 	(end (save-excursion (end-of-line) (point)))
 
- 	(ov (car (overlays-at (point))))
 
- 	status)
 
-     (if ov (setq status (overlay-get ov 'status))
 
-       (setq ov (make-overlay beg end)))
 
-     ;; change the folding status of this headline
 
-     (cond ((or (null status) (eq status 'folded))
 
- 	   (org-show-children)
 
- 	   (message "CHILDREN")
 
- 	   (overlay-put ov 'status 'children))
 
- 	  ((eq status 'children)
 
- 	   (show-branches)
 
- 	   (message "BRANCHES")
 
- 	   (overlay-put ov 'status 'branches))
 
- 	  (t (hide-subtree)
 
- 	     (message "FOLDED")
 
- 	     (overlay-put ov 'status 'folded)))))
 
- ;;; Main show function:
 
- ;; FIXME name this org-before-first-heading-p?
 
- (defun org-toc-before-first-heading-p ()
 
-   "Before first heading?"
 
-   (save-excursion
 
-     (null (re-search-backward org-outline-regexp-bol nil t))))
 
- ;;;###autoload
 
- (defun org-toc-show (&optional depth position)
 
-   "Show the table of contents of the current Org-mode buffer."
 
-   (interactive "P")
 
-   (if (eq major-mode 'org-mode)
 
-       (progn (setq org-toc-base-buffer (current-buffer))
 
- 	     (setq org-toc-odd-levels-only org-odd-levels-only))
 
-     (if (eq major-mode 'org-toc-mode)
 
- 	(org-pop-to-buffer-same-window org-toc-base-buffer)
 
-       (error "Not in an Org buffer")))
 
-   ;; create the new window display
 
-   (let ((pos (or position
 
- 		 (save-excursion
 
- 		   (if (org-toc-before-first-heading-p)
 
- 		       (progn (re-search-forward org-outline-regexp-bol nil t)
 
- 			      (match-beginning 0))
 
- 		     (point))))))
 
-     (setq org-toc-cycle-global-status org-cycle-global-status)
 
-     (delete-other-windows)
 
-     (and (get-buffer "*org-toc*") (kill-buffer "*org-toc*"))
 
-     (switch-to-buffer-other-window
 
-      (make-indirect-buffer org-toc-base-buffer "*org-toc*"))
 
-     ;; make content before 1st headline invisible
 
-     (goto-char (point-min))
 
-     (let* ((beg (point-min))
 
- 	   (end (and (re-search-forward "^\\*" nil t)
 
- 		     (1- (match-beginning 0))))
 
- 	   (ov (make-overlay beg end))
 
- 	   (help (format "Table of contents for %s (press ? for a quick help):\n"
 
- 			 (buffer-name org-toc-base-buffer))))
 
-       (overlay-put ov 'invisible t)
 
-       (overlay-put ov 'before-string help))
 
-     ;; build the browsable TOC
 
-     (cond (depth
 
- 	   (let* ((dpth (if org-toc-odd-levels-only
 
- 			    (1- (* depth 2)) depth)))
 
- 	     (org-content dpth)
 
- 	     (setq org-toc-cycle-global-status
 
- 		   `(org-content ,dpth))))
 
- 	   ((null org-toc-default-depth)
 
- 	    (if (eq org-toc-cycle-global-status 'overview)
 
- 		(progn (org-overview)
 
- 		       (setq org-cycle-global-status 'overview)
 
- 		       (run-hook-with-args 'org-cycle-hook 'overview))
 
- 	      (progn (org-overview)
 
- 		     ;; FIXME org-content to show only headlines?
 
- 		     (org-content)
 
- 		     (setq org-cycle-global-status 'contents)
 
- 		     (run-hook-with-args 'org-cycle-hook 'contents))))
 
- 	   (t (let* ((dpth0 org-toc-default-depth)
 
- 		     (dpth (if org-toc-odd-levels-only
 
- 			       (1- (* dpth0 2)) dpth0)))
 
- 		(org-content dpth)
 
- 		(setq org-toc-cycle-global-status
 
- 		      `(org-content ,dpth)))))
 
-     (goto-char pos))
 
-   (move-beginning-of-line nil)
 
-   (org-toc-mode)
 
-   (shrink-window-if-larger-than-buffer)
 
-   (setq buffer-read-only t))
 
- ;;; Navigation functions:
 
- (defun org-toc-goto (&optional jump cycle)
 
-   "From Org TOC buffer, follow the targeted subtree in the Org window.
 
- If JUMP is non-nil, go to the base buffer.
 
- If JUMP is 'delete, go to the base buffer and delete other windows.
 
- If CYCLE is non-nil, cycle the targeted subtree in the Org window."
 
-   (interactive)
 
-   (let ((pos (point))
 
- 	(toc-buf (current-buffer)))
 
-     (switch-to-buffer-other-window org-toc-base-buffer)
 
-     (goto-char pos)
 
-     (if cycle (org-cycle)
 
-       (progn (org-overview)
 
- 	     (if org-toc-show-subtree-mode
 
- 		 (org-show-subtree)
 
- 	       (org-show-entry))
 
- 	     (org-show-context)))
 
-     (if org-toc-recenter-mode
 
- 	(if (>= org-toc-recenter 1000) (recenter)
 
- 	  (recenter org-toc-recenter)))
 
-     (cond ((null jump)
 
- 	   (switch-to-buffer-other-window toc-buf))
 
- 	  ((eq jump 'delete)
 
- 	   (delete-other-windows)))))
 
- (defun org-toc-cycle-base-buffer ()
 
-   "Call `org-cycle' with a prefix argument in the base buffer."
 
-   (interactive)
 
-   (switch-to-buffer-other-window org-toc-base-buffer)
 
-   (org-cycle t)
 
-   (other-window 1))
 
- (defun org-toc-jump (&optional delete)
 
-   "From Org TOC buffer, jump to the targeted subtree in the Org window.
 
- If DELETE is non-nil, delete other windows when in the Org buffer."
 
-   (interactive "P")
 
-   (if delete (org-toc-goto 'delete)
 
-     (org-toc-goto t)))
 
- (defun org-toc-previous ()
 
-   "Go to the previous headline of the TOC."
 
-   (interactive)
 
-   (if (save-excursion
 
- 	  (beginning-of-line)
 
- 	  (re-search-backward "^\\*" nil t))
 
-     (outline-previous-visible-heading 1)
 
-     (message "No previous heading"))
 
-   (if org-toc-info-mode (org-toc-info))
 
-   (if org-toc-follow-mode (org-toc-goto)))
 
- (defun org-toc-next ()
 
-   "Go to the next headline of the TOC."
 
-   (interactive)
 
-   (outline-next-visible-heading 1)
 
-   (if org-toc-info-mode (org-toc-info))
 
-   (if org-toc-follow-mode (org-toc-goto)))
 
- (defun org-toc-forward ()
 
-   "Go to the next headline at the same level in the TOC."
 
-   (interactive)
 
-   (condition-case nil
 
-       (outline-forward-same-level 1)
 
-     (error (message "No next headline at this level")))
 
-   (if org-toc-info-mode (org-toc-info))
 
-   (if org-toc-follow-mode (org-toc-goto)))
 
- (defun org-toc-back ()
 
-   "Go to the previous headline at the same level in the TOC."
 
-   (interactive)
 
-   (condition-case nil
 
-       (outline-backward-same-level 1)
 
-     (error (message "No previous headline at this level")))
 
-   (if org-toc-info-mode (org-toc-info))
 
-   (if org-toc-follow-mode (org-toc-goto)))
 
- (defun org-toc-quit ()
 
-   "Quit the current Org TOC buffer."
 
-   (interactive)
 
-   (kill-buffer)
 
-   (other-window 1)
 
-   (delete-other-windows))
 
- ;;; Special functions:
 
- (defun org-toc-columns ()
 
-   "Toggle columns view in the Org buffer from Org TOC."
 
-   (interactive)
 
-   (let ((indirect-buffer (current-buffer)))
 
-     (org-pop-to-buffer-same-window org-toc-base-buffer)
 
-     (if (not org-toc-columns-shown)
 
- 	(progn (org-columns)
 
- 	       (setq org-toc-columns-shown t))
 
-       (progn (org-columns-remove-overlays)
 
- 	     (setq org-toc-columns-shown nil)))
 
-     (org-pop-to-buffer-same-window indirect-buffer)))
 
- (defun org-toc-info ()
 
-   "Show properties of current subtree in the echo-area."
 
-   (interactive)
 
-   (let ((pos (point))
 
- 	(indirect-buffer (current-buffer))
 
- 	props prop msg)
 
-     (org-pop-to-buffer-same-window org-toc-base-buffer)
 
-     (goto-char pos)
 
-     (setq props (org-entry-properties))
 
-     (while (setq prop (pop props))
 
-       (unless (or (equal (car prop) "COLUMNS")
 
- 		  (member (car prop) org-toc-info-exclude))
 
- 	(let ((p (car prop))
 
- 	      (v (cdr prop)))
 
- 	  (if (equal p "TAGS")
 
- 	      (setq v (mapconcat 'identity (split-string v ":" t) " ")))
 
- 	  (setq p (concat p ":"))
 
- 	  (add-text-properties 0 (length p) '(face org-special-keyword) p)
 
- 	  (setq msg (concat msg p " " v "  ")))))
 
-     (org-pop-to-buffer-same-window indirect-buffer)
 
-     (message msg)))
 
- ;;; Store and restore TOC configuration:
 
- (defun org-toc-store-config ()
 
-   "Store the current status of the tables of contents in
 
- `org-toc-config-alist'."
 
-   (interactive)
 
-   (let ((file (buffer-file-name org-toc-base-buffer))
 
- 	(pos (point))
 
- 	(hlcfg (org-toc-get-headlines-status)))
 
-     (setq org-toc-config-alist
 
- 	  (delete (assoc file org-toc-config-alist)
 
- 		  org-toc-config-alist))
 
-     (add-to-list 'org-toc-config-alist
 
- 		 `(,file ,pos ,org-toc-cycle-global-status ,hlcfg))
 
-     (message "TOC configuration saved: (%s)"
 
- 	     (if (listp org-toc-cycle-global-status)
 
- 		 (concat "org-content "
 
- 			 (number-to-string
 
- 			  (cadr org-toc-cycle-global-status)))
 
- 	       (symbol-name org-toc-cycle-global-status)))))
 
- (defun org-toc-restore-config ()
 
-   "Get the stored status in `org-toc-config-alist' and set the
 
- current table of contents to it."
 
-   (interactive)
 
-   (let* ((file (buffer-file-name org-toc-base-buffer))
 
- 	 (conf (cdr (assoc file org-toc-config-alist)))
 
- 	 (pos (car conf))
 
- 	 (status (cadr conf))
 
- 	 (hlcfg (caddr conf)) hlcfg0 ov)
 
-     (cond ((listp status)
 
- 	   (org-toc-show (cadr status) (point)))
 
- 	  ((eq status 'overview)
 
- 	   (org-overview)
 
- 	   (setq org-cycle-global-status 'overview)
 
- 	   (run-hook-with-args 'org-cycle-hook 'overview))
 
- 	  (t
 
- 	   (org-overview)
 
- 	   (org-content)
 
- 	   (setq org-cycle-global-status 'contents)
 
- 	   (run-hook-with-args 'org-cycle-hook 'contents)))
 
-     (while (setq hlcfg0 (pop hlcfg))
 
-       (save-excursion
 
- 	(goto-char (point-min))
 
- 	(when (search-forward (car hlcfg0) nil t)
 
- 	  (unless (overlays-at (match-beginning 0))
 
- 	    (setq ov (make-overlay (match-beginning 0)
 
- 				   (match-end 0))))
 
- 	  (cond ((eq (cdr hlcfg0) 'children)
 
- 		 (org-show-children)
 
- 		 (message "CHILDREN")
 
- 		 (overlay-put ov 'status 'children))
 
- 		((eq (cdr hlcfg0) 'branches)
 
- 		 (show-branches)
 
- 		 (message "BRANCHES")
 
- 		 (overlay-put ov 'status 'branches))))))
 
-     (goto-char pos)
 
-     (if org-toc-follow-mode (org-toc-goto))
 
-     (message "Last TOC configuration restored")
 
-     (sit-for 1)
 
-     (if org-toc-info-mode (org-toc-info))))
 
- (defun org-toc-get-headlines-status ()
 
-   "Return an alist of headlines and their associated folding
 
- status."
 
-   (let (output ovs)
 
-     (save-excursion
 
-       (goto-char (point-min))
 
-       (while (and (not (eobp))
 
- 		  (goto-char (next-overlay-change (point))))
 
- 	(when (looking-at org-outline-regexp-bol)
 
- 	  (add-to-list
 
- 	   'output
 
- 	   (cons (buffer-substring-no-properties
 
- 		  (match-beginning 0)
 
- 		  (save-excursion
 
- 		    (end-of-line) (point)))
 
- 		 (overlay-get
 
- 		  (car (overlays-at (point))) 'status))))))
 
-     ;; return an alist like (("* Headline" . 'status))
 
-     output))
 
- ;; In Org TOC buffer, hide headlines below the first level.
 
- (defun org-toc-help ()
 
-   "Display a quick help message in the echo-area for `org-toc-mode'."
 
-   (interactive)
 
-   (let ((st-start 0)
 
- 	(help-message
 
- 	 "\[space\]   show heading                     \[1-4\] hide headlines below this level
 
- \[TAB\]     jump to heading                  \[F\]   toggle follow mode (currently %s)
 
- \[return\]  jump and delete others windows   \[i\]   toggle info mode (currently %s)
 
- \[S-TAB\]   cycle subtree (in Org)           \[S\]   toggle show subtree mode (currently %s)
 
- \[C-S-TAB\] global cycle (in Org)            \[r\]   toggle recenter mode (currently %s)
 
- \[:\]       cycle subtree (in TOC)           \[c\]   toggle column view (currently %s)
 
- \[n/p\]     next/previous heading            \[s\]   save TOC configuration
 
- \[f/b\]     next/previous heading of same level
 
- \[q\]       quit the TOC                     \[g\]   restore last TOC configuration"))
 
-     (while (string-match "\\[[^]]+\\]" help-message st-start)
 
-       (add-text-properties (match-beginning 0)
 
-                            (match-end 0) '(face bold) help-message)
 
-       (setq st-start (match-end 0)))
 
-   (message help-message
 
-     (if org-toc-follow-mode "on" "off")
 
-     (if org-toc-info-mode "on" "off")
 
-     (if org-toc-show-subtree-mode "on" "off")
 
-     (if org-toc-recenter-mode (format "on, line %s" org-toc-recenter) "off")
 
-     (if org-toc-columns-shown "on" "off"))))
 
- ;;;;##########################################################################
 
- ;;;;  User Options, Variables
 
- ;;;;##########################################################################
 
- ;;; org-toc.el ends here
 
 
  |