| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 | 
							- ;;; org-indent.el --- Dynamic indentation for  Org-mode
 
- ;; Copyright (C) 2008 Free Software Foundation, Inc.
 
- ;;
 
- ;; Author: Carsten Dominik <carsten at orgmode dot org>
 
- ;; Keywords: outlines, hypermedia, calendar, wp
 
- ;; Homepage: http://orgmode.org
 
- ;; Version: 0.07
 
- ;;
 
- ;; This file is not part of GNU Emacs.
 
- ;;
 
- ;; This file 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.
 
- ;; GNU Emacs 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; see the file COPYING.  If not, write to the
 
- ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
- ;; Boston, MA 02110-1301, USA.
 
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
- ;;
 
- ;;; Commentary:
 
- ;; This is an experimental implementation of dynamic virtual indentation.
 
- ;; It works by adding overlays to a buffer to make sure lines are
 
- ;; indented according to outline structure.  While this works, there are
 
- ;; problems with the implementation:  It uses overlays, which use markers,
 
- ;; and for large files, this is using too much resources.  It might be
 
- ;; possible to com up with an implementation using text properties,
 
- ;; I believe this is less resource intensive.  However, it does not work
 
- ;; to put the text property onto the newline, because that interferes with
 
- ;; outline visibility.  Maybe this is a bug in outline?
 
- ;;; Indentation
 
- (defcustom org-startup-indented nil
 
-   "Non-nil means, turn on `org-indent-mode' on startup.
 
- This can also be configured on a per-file basis by adding one of
 
- the following lines anywhere in the buffer:
 
-    #+STARTUP: localindent
 
-    #+STARTUP: indent
 
-    #+STARTUP: noindent"
 
-   :group 'org-structure
 
-   :type '(choice
 
- 	  (const :tag "Not" nil)
 
- 	  (const :tag "Locally" local)
 
- 	  (const :tag "Globally (slow on startup in large files)" t)))
 
- (defconst org-indent-max 80
 
-   "Maximum indentation in characters")
 
- (defconst org-indent-strings nil
 
-   "Vector with all indentation strings.
 
- It is a const because it will be set only once in `org-indent-initialize'.")
 
- (defvar org-indent-inhibit-after-change nil
 
-   "Inhibit the action of the indentation after-change-hook.
 
- This variable should be scoped dynamically.")
 
- (defcustom org-indent-boundary-char ?\   ; comment to protect space char
 
-   "The end of the virtual indentation strings, a single-character string.
 
- The default is just a space, but if you wish, you can use \"|\" or so."
 
-   :group 'org-structure
 
-   :set (lambda (var val)
 
- 	 (set var val)
 
- 	 (and org-indent-strings (org-indent-initialize)))
 
-   :type 'character)
 
- (defun org-indent-initialize ()
 
-   "Initialize the indentation strings and set the idle times."
 
-   (unless org-indent-strings
 
- ;    (run-with-idle-timer 10   t 'org-indent-indent-buffer)
 
-     (run-with-idle-timer  0.5  t 'org-indent-refresh-section)
 
-     )
 
-   (setq org-indent-strings (make-vector (1+ org-indent-max) nil))
 
-   ;; Initialize the indentation strings
 
-   (aset org-indent-strings 0 "")
 
-   (loop for i from 1 to org-indent-max do
 
- 	(aset org-indent-strings i
 
- 	      (org-add-props 
 
- 		  (concat (make-string (1- i) ?\ )
 
- 			  (char-to-string org-indent-boundary-char))
 
- 		  nil 'face 'org-indent))))
 
- (define-minor-mode org-indent-mode
 
-   "Toggle the minor more `org-indent-mode'."
 
-   nil " Ind" nil
 
-   (if (org-bound-and-true-p org-inhibit-startup)
 
-       (setq org-indent-mode nil)
 
-     (if org-indent-mode
 
- 	(progn
 
- 	  (or org-indent-strings (org-indent-initialize))
 
- 	  (org-set-local 'org-adapt-indentation nil)
 
- 	  (org-add-hook 'after-change-functions
 
- 			'org-indent-after-change-function nil t)
 
- 	  (org-restart-font-lock)
 
- 	  (org-indent-indent-buffer))
 
-       (save-excursion
 
- 	(save-restriction
 
- 	  (org-indent-remove-overlays (point-min) (point-max))
 
- 	  (remove-hook 'after-change-functions
 
- 		       'org-indent-after-change-function 'local)
 
- 	  (kill-local-variable 'org-adapt-indentation))))))
 
- (defface org-indent
 
-   (org-compatible-face nil
 
-     '((((class color) (min-colors 16) (background dark)
 
- 	(:underline nil :strike-through nil :foreground "grey10")))
 
-       (((class color) (min-colors 16) (background light))
 
-        (:underline nil :strike-through nil :foreground "grey90"))
 
-       (t (:underline nil :strike-through nil))))
 
-   "Face for outline indentation.
 
- The default is to make it look like whitespace.  But you may find it
 
- useful to make it, for example, look like the fringes."
 
-   :group 'org-faces)
 
- (defun org-indent-indent-buffer ()
 
-   "Add indentation overlays for the whole buffer."
 
-   (interactive)
 
-   (when org-indent-mode
 
-     (save-excursion
 
-       (save-restriction
 
- 	(org-indent-remove-overlays (point-min) (point-max))
 
- 	(org-indent-add-overlays (point-min) (point-max))))))
 
- (defun org-indent-remove-overlays (beg end)
 
-   "Remove indentations between BEG and END."
 
-   (mapc (lambda (o)
 
- 	  (and (org-overlay-get o 'org-indent)
 
- 	       (org-delete-overlay o)))
 
- 	(org-overlays-in beg end)))
 
- (defun org-indent-add-overlays (beg end &optional n)
 
-   "Add indentation overlays between BEG and END.
 
- Assumes that BEG is at the beginning of a line."
 
-   (when org-indent-mode
 
-     (let (o)
 
-       (save-excursion
 
- 	(goto-char beg)
 
- 	(while (and (<= (point) end) (not (eobp)))
 
- 	  (cond
 
- 	   ((not (bolp)))
 
- 	   ((looking-at outline-regexp)
 
- 	    (setq n (- (match-end 0) (match-beginning 0)))
 
- 	    (org-indent-remove-overlays (max (point-min) (1- (point))) (point)))
 
- 	   (n
 
- 	    (org-indent-indent-line n)))
 
- 	  (beginning-of-line 2))))))
 
- (defun org-indent-indent-line (n)
 
-   "Add an indentation overlay with width N to the current line.
 
- Point is assumed to be at the beginning of the line for this."
 
-   (let (ov)
 
-     (setq ov (org-make-overlay (1- (point)) (point)))
 
-     (org-overlay-put ov 'after-string (aref org-indent-strings n))
 
-     (org-overlay-put ov 'evaporate t)
 
-     (org-overlay-put ov 'org-indent n)
 
-     (org-unmodified
 
-      (put-text-property (max (point-min) (1- (point)))
 
- 			(point-at-eol) 'org-indent-level n))))
 
- (defun org-indent-after-change-function (beg end ndel)
 
-   (if (or (not org-indent-mode) (= beg end)
 
- 	  org-indent-inhibit-after-change)
 
-       () ; not in the mood to do anything here....
 
-     (let ((inhibit-quit t) n)
 
-       (save-match-data
 
- 	(save-excursion
 
- 	  (save-restriction
 
- 	    (widen)
 
- 	    (goto-char beg)
 
- 	    (when (search-forward "\n" end t)
 
- 	      ;; a newline was inserted
 
- 	      (setq n (or (get-text-property beg 'org-indent-level)
 
- 			  (get-text-property
 
- 			   (or (save-excursion (previous-single-property-change
 
- 						beg 'org-indent-level))
 
- 			       (point-min))
 
- 			   'org-indent-level)
 
- 			  0))
 
- 	      (org-indent-local-refresh beg end n))))))))
 
- (defun org-indent-local-refresh (beg end n)
 
-   "Refresh indentation locally from BEG to END, starting with indentation N."
 
-   (goto-char end)
 
-   (setq end (min (point-max) (1+ (point-at-eol))))
 
-   (goto-char beg)
 
-   (beginning-of-line 0)
 
-   (org-indent-remove-overlays (max (point-min) (1- (point))) end)
 
-   (org-indent-add-overlays (point) end n))
 
- (defun org-indent-refresh-section ()
 
-   "Refresh indentation overlays in the current outline subtree."
 
-   (when org-indent-mode
 
-     (save-excursion
 
-       (let ((org-indent-inhibit-after-change t)
 
- 	    beg end)
 
- 	(condition-case nil
 
- 	    (progn
 
- 	      (outline-back-to-heading t)
 
- 	      (setq beg (point)))
 
- 	  (error (progn
 
- 		   (goto-char (point-min))
 
- 		   (setq beg (point)))))
 
- 	(outline-next-heading)
 
- 	(setq end (point))
 
- 	(org-indent-remove-overlays beg end)
 
- 	(org-indent-add-overlays beg end)))))
 
- (defun org-indent-refresh-subtree ()
 
-   "Refresh indentation overlays in the current outline subtree."
 
-   (when org-indent-mode
 
-     (save-excursion
 
-       (let ((org-indent-inhibit-after-change t)
 
- 	    beg end)
 
- 	(setq beg (point))
 
- 	(setq end (save-excursion (org-end-of-subtree t t)))
 
- 	(org-indent-remove-overlays beg end)
 
- 	(org-indent-add-overlays beg end)))))
 
- (provide 'org-indent)
 
- ;;; org-indent.el ends here
 
 
  |