]> code.delx.au - gnu-emacs/blobdiff - lisp/textmodes/outline.el
(ispell-command-loop):
[gnu-emacs] / lisp / textmodes / outline.el
index cb5f2daa2119c1133541eca06c8503a5274fab56..f12518c4051fd4f3c7323bb842c4c63fe78f7617 100644 (file)
@@ -1,6 +1,6 @@
 ;;; outline.el --- outline mode commands for Emacs
 
-;; Copyright (C) 1986, 1993, 1994, 1995 Free Software Foundation, Inc.
+;; Copyright (C) 1986, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: outlines
 
 ;;; Code:
 
-;; Jan '86, Some new features added by Peter Desnoyers and rewritten by RMS.
-  
-(defvar outline-regexp nil
+(defgroup outlines nil
+  "Support for hierarchical outlining"
+  :prefix "outline-"
+  :group 'editing)
+
+(defcustom outline-regexp nil
   "*Regular expression to match the beginning of a heading.
 Any line whose beginning matches this regexp is considered to start a heading.
 The recommended way to set this is with a Local Variables: list
-in the file it applies to.  See also outline-heading-end-regexp.")
+in the file it applies to.  See also outline-heading-end-regexp."
+  :type '(choice regexp (const nil))
+  :group 'outlines)
 
 ;; Can't initialize this in the defvar above -- some major modes have
 ;; already assigned a local value to it.
 (or (default-value 'outline-regexp)
     (setq-default outline-regexp "[*\^L]+"))
   
-(defvar outline-heading-end-regexp "\n"
+(defcustom outline-heading-end-regexp "\n"
   "*Regular expression to match the end of a heading line.
 You can assume that point is at the beginning of a heading when this
 regexp is searched for.  The heading ends at the end of the match.
 The recommended way to set this is with a `Local Variables:' list
-in the file it applies to.")
+in the file it applies to."
+  :type 'regexp
+  :group 'outlines)
 
 (defvar outline-mode-prefix-map nil)
 
 (if outline-mode-prefix-map
     nil
   (setq outline-mode-prefix-map (make-sparse-keymap))
+  (define-key outline-mode-prefix-map "@" 'outline-mark-subtree)
   (define-key outline-mode-prefix-map "\C-n" 'outline-next-visible-heading)
   (define-key outline-mode-prefix-map "\C-p" 'outline-previous-visible-heading)
   (define-key outline-mode-prefix-map "\C-i" 'show-children)
@@ -129,10 +137,11 @@ in the file it applies to.")
   (define-key outline-mode-map "\C-c" outline-mode-prefix-map)
   (define-key outline-mode-map [menu-bar] outline-mode-menu-bar-map))
 
-(defvar outline-minor-mode nil
-  "Non-nil if using Outline mode as a minor mode of some other mode.")
+(defcustom outline-minor-mode nil
+  "Non-nil if using Outline mode as a minor mode of some other mode."
+  :type 'boolean
+  :group 'outlines)
 (make-variable-buffer-local 'outline-minor-mode)
-(put 'outline-minor-mode 'permanent-local t)
 (or (assq 'outline-minor-mode minor-mode-alist)
     (setq minor-mode-alist (append minor-mode-alist
                                   (list '(outline-minor-mode " Outl")))))
@@ -154,7 +163,7 @@ in the file it applies to.")
 (defvar outline-view-change-hook nil
   "Normal hook to be run after outline visibility changes.")
 
-;;;autoload
+;;;###autoload
 (defun outline-mode ()
   "Set major mode for editing outlines with selective display.
 Headings are lines which start with asterisks: one for major headings,
@@ -205,7 +214,7 @@ Turning on outline mode calls the value of `text-mode-hook' and then of
   (make-local-variable 'line-move-ignore-invisible)
   (setq line-move-ignore-invisible t)
   ;; Cause use of ellipses for invisible text.
-  (setq buffer-invisibility-spec '((t . t)))
+  (add-to-invisibility-spec '(outline . t))
   (make-local-variable 'paragraph-start)
   (setq paragraph-start (concat paragraph-start "\\|\\("
                                outline-regexp "\\)"))
@@ -221,10 +230,12 @@ Turning on outline mode calls the value of `text-mode-hook' and then of
   (add-hook 'change-major-mode-hook 'show-all)
   (run-hooks 'text-mode-hook 'outline-mode-hook))
 
-(defvar outline-minor-mode-prefix "\C-c@"
+(defcustom outline-minor-mode-prefix "\C-c@"
   "*Prefix key to use for Outline commands in Outline minor mode.
 The value of this variable is checked as part of loading Outline mode.
-After that, changing the prefix key requires manipulating keymaps.")
+After that, changing the prefix key requires manipulating keymaps."
+  :type 'string
+  :group 'outlines)
 
 (defvar outline-minor-mode-map nil)
 (if outline-minor-mode-map
@@ -240,7 +251,7 @@ After that, changing the prefix key requires manipulating keymaps.")
          (cons (cons 'outline-minor-mode outline-minor-mode-map)
                minor-mode-map-alist)))
 
-;;;autoload
+;;;###autoload
 (defun outline-minor-mode (&optional arg)
   "Toggle Outline minor mode.
 With arg, turn Outline minor mode on if arg is positive, off otherwise.
@@ -251,22 +262,29 @@ See the command `outline-mode' for more information on this mode."
          (> (prefix-numeric-value arg) 0)))
   (if outline-minor-mode
       (progn
+       (make-local-hook 'change-major-mode-hook)
+       ;; Turn off this mode if we change major modes.
+       (add-hook 'change-major-mode-hook
+                 '(lambda () (outline-minor-mode -1))
+                 nil t)
        (make-local-variable 'line-move-ignore-invisible)
        (setq line-move-ignore-invisible t)
        ;; Cause use of ellipses for invisible text.
-       (setq buffer-invisibility-spec '((t . t)))
+       (add-to-invisibility-spec '(outline . t))
        (run-hooks 'outline-minor-mode-hook))
     (setq line-move-ignore-invisible nil)
     ;; Cause use of ellipses for invisible text.
-    (setq buffer-invisibility-spec t))
+    (remove-from-invisibility-spec '(outline . t)))
   ;; When turning off outline mode, get rid of any outline hiding.
   (or outline-minor-mode
       (show-all))
   (force-mode-line-update))
 \f
-(defvar outline-level 'outline-level
-  "Function of no args to compute a header's nesting level in an outline.
-It can assume point is at the beginning of a header line.")
+(defcustom outline-level 'outline-level
+  "*Function of no args to compute a header's nesting level in an outline.
+It can assume point is at the beginning of a header line."
+  :type 'function
+  :group 'outlines)
 
 ;; This used to count columns rather than characters, but that made ^L
 ;; appear to be at level 2 instead of 1.  Columns would be better for
@@ -308,13 +326,14 @@ Only visible heading lines are considered."
   (beginning-of-line)
   (or (outline-on-heading-p)
       (let (found)
-       (while (not found)
-         (setq found
-               (and (re-search-backward (concat "^\\(" outline-regexp "\\)")
-                                        nil t)
-                    (outline-visible))))
-       found)
-      (error "before first heading")))
+       (save-excursion
+         (while (not found)
+           (or (re-search-backward (concat "^\\(" outline-regexp "\\)")
+                                   nil t)
+               (error "before first heading"))
+           (setq found (and (outline-visible) (point)))))
+       (goto-char found)
+       found)))
 
 (defun outline-on-heading-p ()
   "Return t if point is on a (visible) heading line."
@@ -358,6 +377,21 @@ A heading line is one that starts with a `*' (or that
   (interactive "p")
   (outline-next-visible-heading (- arg)))
 
+(defun outline-mark-subtree ()
+  "Mark the current subtree in an outlined document.
+This puts point at the start of the current subtree, and mark at the end."
+  (interactive)
+  (let ((beg))
+    (if (outline-on-heading-p)
+       ;; we are already looking at a heading
+       (beginning-of-line)
+      ;; else go back to previous heading
+      (outline-previous-visible-heading 1))
+    (setq beg (point))
+    (outline-end-of-subtree)
+    (push-mark (point))
+    (goto-char beg)))
+\f
 (defun outline-flag-region (from to flag)
   "Hides or shows lines from FROM to TO, according to FLAG.
 If FLAG is nil then text is shown, while if FLAG is t the text is hidden."
@@ -368,7 +402,7 @@ If FLAG is nil then text is shown, while if FLAG is t the text is hidden."
       (outline-discard-overlays (point) to 'outline)
       (if flag
          (let ((o (make-overlay (point) to)))
-           (overlay-put o 'invisible flag)
+           (overlay-put o 'invisible 'outline)
            (overlay-put o 'outline t)))))
   (run-hooks 'outline-view-change-hook))
 
@@ -381,25 +415,26 @@ If FLAG is nil then text is shown, while if FLAG is t the text is hidden."
   (if (< end beg)
       (setq beg (prog1 end (setq end beg))))
   (save-excursion
-    (goto-char beg)
-    (while (< (point) end)
-      (let ((overlays (overlays-at (point))))
-       (while overlays
-         (let ((o (car overlays)))
-           (if (overlay-get o prop)
-               ;; Either push this overlay outside beg...end
-               ;; or split it to exclude beg...end
-               ;; or delete it entirely (if it is contained in beg...end).
-               (if (< (overlay-start o) beg)
-                   (if (> (overlay-end o) end)
-                       (let ((o1 (outline-copy-overlay o)))
-                         (move-overlay o1 (overlay-start o1) beg)
-                     (move-overlay o (overlay-start o) beg)))
-                 (if (> (overlay-end o) end)
-                     (move-overlay o end (overlay-end o))
-                   (delete-overlay o)))))
-         (setq overlays (cdr overlays))))
-      (goto-char (next-overlay-change (point))))))
+    (let ((overlays (overlays-in beg end))
+         o
+         o1)
+      (while overlays
+       (setq o (car overlays))
+       (if (overlay-get o prop)
+           ;; Either push this overlay outside beg...end
+           ;; or split it to exclude beg...end
+           ;; or delete it entirely (if it is contained in beg...end).
+           (if (< (overlay-start o) beg)
+               (if (> (overlay-end o) end)
+                   (progn 
+                     (setq o1 (outline-copy-overlay o))
+                     (move-overlay o1 (overlay-start o1) beg)
+                     (move-overlay o end (overlay-end o)))
+                 (move-overlay o (overlay-start o) beg))
+             (if (> (overlay-end o) end)
+                 (move-overlay o end (overlay-end o))
+               (delete-overlay o))))
+       (setq overlays (cdr overlays))))))
 
 ;; Make a copy of overlay O, with the same beginning, end and properties.
 (defun outline-copy-overlay (o)