]> code.delx.au - gnu-emacs/blobdiff - lisp/outline.el
Rename `MS-DOG' into `MS-DOS'.
[gnu-emacs] / lisp / outline.el
index 2d2663b12f293addc8b50283acd461cf5ea16235..92542bae7e307e7c6c73600aaa28d57e7a894876 100644 (file)
@@ -1,7 +1,7 @@
 ;;; outline.el --- outline mode commands for Emacs
 
-;; Copyright (C) 1986, 93, 94, 95, 97, 2000, 01, 2004
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1986, 1993, 1994, 1995, 1997, 2000, 2001, 2002,
+;;   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: outlines
@@ -20,8 +20,8 @@
 
 ;; 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., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
 
 ;;; Code:
 
+(defvar font-lock-warning-face)
+
+
 (defgroup outlines nil
-  "Support for hierarchical outlining"
+  "Support for hierarchical outlining."
   :prefix "outline-"
   :group 'editing)
 
 (defcustom outline-regexp "[*\^L]+"
-  "*Regular expression to match the beginning of a heading.
+  "Regular expression to match the beginning of a heading.
 Any line whose beginning matches this regexp is considered to start a heading.
 Note that Outline mode only checks this regexp at the start of a line,
 so the regexp need not (and usually does not) start with `^'.
@@ -53,7 +56,7 @@ in the file it applies to.  See also `outline-heading-end-regexp'."
   :group 'outlines)
 
 (defcustom outline-heading-end-regexp "\n"
-  "*Regular expression to match the end of a heading line.
+  "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
@@ -167,14 +170,45 @@ in the file it applies to."
                  0 '(outline-font-lock-face) nil t)))
   "Additional expressions to highlight in Outline mode.")
 
-(defface outline-1 '((t :inherit font-lock-function-name-face)) "Level 1.")
-(defface outline-2 '((t :inherit font-lock-variable-name-face)) "Level 2.")
-(defface outline-3 '((t :inherit font-lock-keyword-face)) "Level 3.")
-(defface outline-4 '((t :inherit font-lock-builtin-face)) "Level 4.")
-(defface outline-5 '((t :inherit font-lock-comment-face)) "Level 5.")
-(defface outline-6 '((t :inherit font-lock-constant-face)) "Level 6.")
-(defface outline-7 '((t :inherit font-lock-type-face)) "Level 7.")
-(defface outline-8 '((t :inherit font-lock-string-face)) "Level 8.")
+(defface outline-1
+  '((t :inherit font-lock-function-name-face))
+  "Level 1."
+  :group 'outlines)
+
+(defface outline-2
+  '((t :inherit font-lock-variable-name-face))
+  "Level 2."
+  :group 'outlines)
+
+(defface outline-3
+  '((t :inherit font-lock-keyword-face))
+  "Level 3."
+  :group 'outlines)
+
+(defface outline-4
+  '((t :inherit font-lock-builtin-face))
+  "Level 4."
+  :group 'outlines)
+
+(defface outline-5
+  '((t :inherit font-lock-comment-face))
+  "Level 5."
+  :group 'outlines)
+
+(defface outline-6
+  '((t :inherit font-lock-constant-face))
+  "Level 6."
+  :group 'outlines)
+
+(defface outline-7
+  '((t :inherit font-lock-type-face))
+  "Level 7."
+  :group 'outlines)
+
+(defface outline-8
+  '((t :inherit font-lock-string-face))
+  "Level 8."
+  :group 'outlines)
 
 (defvar outline-font-lock-faces
   [outline-1 outline-2 outline-3 outline-4
@@ -422,6 +456,20 @@ If INVISIBLE-OK is non-nil, an invisible heading line is ok too."
       (save-excursion (newline-and-indent)))
     (run-hooks 'outline-insert-heading-hook)))
 
+(defun outline-invent-heading (head up)
+  (save-match-data
+    ;; Let's try to invent one by repeating or deleting the last char.
+    (let ((new-head (if up (substring head 0 -1)
+                      (concat head (substring head -1)))))
+      (if (string-match (concat "\\`\\(?:" outline-regexp "\\)")
+                        new-head)
+          ;; Why bother checking that it is indeed higher/lower level ?
+          new-head
+        ;; Didn't work, so ask what to do.
+        (read-string (format "%s heading for `%s': "
+                             (if up "Parent" "Demoted") head)
+                     head nil nil t)))))
+
 (defun outline-promote (&optional children)
   "Promote headings higher up the tree.
 If prefix argument CHILDREN is given, promote also all the children.
@@ -440,13 +488,18 @@ in the region."
                        (save-excursion (outline-get-next-sibling) (point))))
    (t
     (outline-back-to-heading t)
-    (let* ((head (match-string 0))
+    (let* ((head (match-string-no-properties 0))
           (level (save-match-data (funcall outline-level)))
           (up-head (or (outline-head-from-level (1- level) head)
+                       ;; Use the parent heading, if it is really
+                       ;; one level less.
                        (save-excursion
                          (save-match-data
                            (outline-up-heading 1 t)
-                           (match-string 0))))))
+                           (and (= (1- level) (funcall outline-level))
+                                (match-string-no-properties 0))))
+                        ;; Bummer!! There is no lower level heading.
+                        (outline-invent-heading head 'up))))
 
       (unless (rassoc level outline-heading-alist)
        (push (cons head level) outline-heading-alist))
@@ -470,7 +523,7 @@ in the region."
                        (point)
                        (save-excursion (outline-get-next-sibling) (point))))
    (t
-    (let* ((head (match-string 0))
+    (let* ((head (match-string-no-properties 0))
           (level (save-match-data (funcall outline-level)))
           (down-head
            (or (outline-head-from-level (1+ level) head)
@@ -485,21 +538,13 @@ in the region."
                                  (<= (funcall outline-level) level))))
                    (unless (eobp)
                      (looking-at outline-regexp)
-                     (match-string 0))))
-               (save-match-data
-                 ;; Bummer!! There is no lower heading in the buffer.
-                 ;; Let's try to invent one by repeating the first char.
-                 (let ((new-head (concat (substring head 0 1) head)))
-                   (if (string-match (concat "\\`\\(?:" outline-regexp "\\)")
-                                     new-head)
-                       ;; Why bother checking that it is indeed lower level ?
-                       new-head
-                     ;; Didn't work: keep it as is so it's still a heading.
-                     head))))))
-
-    (unless (rassoc level outline-heading-alist)
-      (push (cons head level) outline-heading-alist))
-    (replace-match down-head nil t)))))
+                     (match-string-no-properties 0))))
+                ;; Bummer!! There is no higher-level heading in the buffer.
+                (outline-invent-heading head nil))))
+
+      (unless (rassoc level outline-heading-alist)
+       (push (cons head level) outline-heading-alist))
+      (replace-match down-head nil t)))))
 
 (defun outline-head-from-level (level head &optional alist)
   "Get new heading with level LEVEL from ALIST.
@@ -562,12 +607,11 @@ the match data is set appropriately."
 (defun outline-move-subtree-down (&optional arg)
   "Move the currrent subtree down past ARG headlines of the same level."
   (interactive "p")
-  (let ((re (concat "^\\(?:" outline-regexp "\\)"))
-       (movfunc (if (> arg 0) 'outline-get-next-sibling
+  (let ((movfunc (if (> arg 0) 'outline-get-next-sibling
                   'outline-get-last-sibling))
        (ins-point (make-marker))
        (cnt (abs arg))
-       beg end txt folded)
+       beg end folded)
     ;; Select the tree
     (outline-back-to-heading)
     (setq beg (point))
@@ -641,7 +685,7 @@ This puts point at the start of the current subtree, and mark at the end."
       (outline-previous-visible-heading 1))
     (setq beg (point))
     (outline-end-of-subtree)
-    (push-mark (point))
+    (push-mark (point) nil t)
     (goto-char beg)))
 \f
 
@@ -708,8 +752,8 @@ If FLAG is nil then text is shown, while if FLAG is t the text is hidden."
 (defun hide-entry ()
   "Hide the body directly following this heading."
   (interactive)
-  (outline-back-to-heading)
   (save-excursion
+    (outline-back-to-heading)
     (outline-end-of-heading)
     (outline-flag-region (point) (progn (outline-next-preface) (point)) t)))
 
@@ -723,7 +767,7 @@ Show the heading too, if it is currently invisible."
                         (progn (outline-next-preface) (point)) nil)))
 
 (defun hide-body ()
-  "Hide all of buffer except headings."
+  "Hide all body lines in buffer, leaving all headings visible."
   (interactive)
   (hide-region-body (point-min) (point-max)))
 
@@ -738,7 +782,8 @@ Show the heading too, if it is currently invisible."
        (narrow-to-region start end)
        (goto-char (point-min))
        (if (outline-on-heading-p)
-           (outline-end-of-heading))
+           (outline-end-of-heading)
+         (outline-next-preface))
        (while (not (eobp))
          (outline-flag-region (point)
                               (progn (outline-next-preface) (point)) t)
@@ -758,11 +803,12 @@ Show the heading too, if it is currently invisible."
   (outline-flag-subtree t))
 
 (defun hide-leaves ()
-  "Hide all body after this heading at deeper levels."
+  "Hide the body after this heading and at deeper levels."
   (interactive)
-  (outline-back-to-heading)
   (save-excursion
-    (outline-end-of-heading)
+    (outline-back-to-heading)
+;; Turned off to fix bug reported by Otto Maddox on 22 Nov 2005.
+;;    (outline-end-of-heading)
     (hide-region-body (point) (progn (outline-end-of-subtree) (point)))))
 
 (defun show-subtree ()
@@ -782,7 +828,13 @@ Show the heading too, if it is currently invisible."
 
 (defun hide-sublevels (levels)
   "Hide everything but the top LEVELS levels of headers, in whole buffer."
-  (interactive "p")
+  (interactive (list
+               (cond
+                (current-prefix-arg (prefix-numeric-value current-prefix-arg))
+                ((save-excursion (beginning-of-line)
+                                 (looking-at outline-regexp))
+                 (funcall outline-level))
+                (t 1))))
   (if (< levels 1)
       (error "Must keep at least one level of headers"))
   (let (outline-view-change-hook)
@@ -818,11 +870,12 @@ Show the heading too, if it is currently invisible."
 (defun outline-toggle-children ()
   "Show or hide the current subtree depending on its current state."
   (interactive)
-  (outline-back-to-heading)
-  (if (not (outline-invisible-p (line-end-position)))
-      (hide-subtree)
-    (show-children)
-    (show-entry)))
+  (save-excursion
+    (outline-back-to-heading)
+    (if (not (outline-invisible-p (line-end-position)))
+       (hide-subtree)
+      (show-children)
+      (show-entry))))
 
 (defun outline-flag-subtree (flag)
   (save-excursion
@@ -834,8 +887,7 @@ Show the heading too, if it is currently invisible."
 
 (defun outline-end-of-subtree ()
   (outline-back-to-heading)
-  (let ((opoint (point))
-       (first t)
+  (let ((first t)
        (level (funcall outline-level)))
     (while (and (not (eobp))
                (or first (> (funcall outline-level) level)))
@@ -995,5 +1047,5 @@ convenient way to make a table of contents of the buffer."
 (provide 'outline)
 (provide 'noutline)
 
-;;; arch-tag: 1724410e-7d4d-4f46-b801-49e18171e874
+;; arch-tag: 1724410e-7d4d-4f46-b801-49e18171e874
 ;;; outline.el ends here