]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/hideshow.el
Restore arch taglines
[gnu-emacs] / lisp / progmodes / hideshow.el
index 6573ab35e68d97fb3a5b27a716ea66b463e964b5..7013c3856e3f3269ae3173b9ead0b52708d16d7f 100644 (file)
@@ -1,11 +1,11 @@
-;;; hideshow.el --- minor mode cmds to selectively display blocks of code
+;;; hideshow.el --- minor mode cmds to selectively display code/comment blocks
 
-;; Copyright (C) 1994, 95, 96, 97, 98, 99 Free Software Foundation
+;; Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01 Free Software Foundation
 
-;; Author: Thien-Thi Nguyen <ttn@netcom.com>
+;; Author: Thien-Thi Nguyen <ttn@gnu.org>
 ;;      Dan Nicolaescu <dann@ics.uci.edu>
 ;; Keywords: C C++ java lisp tools editing comments blocks hiding outlines
-;; Maintainer-Version: 5.9
+;; Maintainer-Version: 5.31
 ;; Time-of-Day-Author-Most-Likely-to-be-Recalcitrant: early morning
 
 ;; This file is part of GNU Emacs.
 
 ;; * Commands provided
 ;;
-;; This file provides `hs-minor-mode'. When active, eight commands are
-;; available, implementing block hiding and showing.  They (and their
+;; This file provides Hideshow Minor Mode.  When active, nine commands
+;; are available, implementing block hiding and showing.  They (and their
 ;; keybindings) are:
 ;;
-;;   hs-hide-block                      C-c h
-;;   hs-show-block                      C-c s
-;;   hs-hide-all                        C-c H
-;;   hs-show-all                        C-c S
-;;   hs-show-region                     C-c R
-;;   hs-hide-level                      C-c L
-;;   hs-mouse-toggle-hiding             [(shift button-2)]
+;;   hs-hide-block                      C-c @ C-h
+;;   hs-show-block                      C-c @ C-s
+;;   hs-hide-all                        C-c @ C-M-h
+;;   hs-show-all                        C-c @ C-M-s
+;;   hs-hide-level                      C-c @ C-l
+;;   hs-toggle-hiding                   C-c @ C-c
+;;   hs-mouse-toggle-hiding             [(shift mouse-2)]
 ;;   hs-hide-initial-comment-block
 ;;
 ;; Blocks are defined per mode.  In c-mode, c++-mode and java-mode, they
 ;; The command `M-x hs-minor-mode' toggles the minor mode or sets it
 ;; (similar to other minor modes).
 
+;; * Suggested usage
+;;
+;; First make sure hideshow.el is in a directory in your `load-path'.
+;; You can optionally byte-compile it using `M-x byte-compile-file'.
+;; Then, add the following to your ~/.emacs:
+;;
+;; (load-library "hideshow")
+;; (add-hook 'X-mode-hook               ; other modes similarly
+;;           '(lambda () (hs-minor-mode 1)))
+;;
+;; where X = {emacs-lisp,c,c++,perl,...}.  You can also manually toggle
+;; hideshow minor mode by typing `M-x hs-minor-mode'.  After hideshow is
+;; activated or deactivated, `hs-minor-mode-hook' is run w/ `run-hooks'.
+;;
+;; Additionally, Joseph Eydelnant writes:
+;;   I enjoy your package hideshow.el Ver. 5.24 2001/02/13
+;;   a lot and I've been looking for the following functionality:
+;;   toggle hide/show all with a single key.
+;;   Here are a few lines of code that lets me do just that.
+;;
+;;   (defvar my-hs-hide nil "Current state of hideshow for toggling all.")
+;;   ;;;###autoload
+;;   (defun my-toggle-hideshow-all () "Toggle hideshow all."
+;;     (interactive)
+;;     (setq my-hs-hide (not my-hs-hide))
+;;     (if my-hs-hide
+;;         (hs-hide-all)
+;;       (hs-show-all)))
+;;
+;; [Your hideshow hacks here!]
+
 ;; * Customization
 ;;
 ;; You can use `M-x customize-variable' on the following variables:
 ;;
-;;   hs-hide-comments-when-hiding-all -- self-explanatory!
-;;   hs-isearch-open                  -- what kind of hidden blocks to
+;; - hs-hide-comments-when-hiding-all -- self-explanatory!
+;; - hs-hide-all-non-comment-function -- if non-nil, when doing a
+;;                                       `hs-hide-all', this function
+;;                                       is called w/ no arguments
+;; - hs-isearch-open                  -- what kind of hidden blocks to
 ;;                                       open when doing isearch
 ;;
+;; Some languages (e.g., Java) are deeply nested, so the normal behavior
+;; of `hs-hide-all' (hiding all but top-level blocks) results in very
+;; little information shown, which is not very useful.  You can use the
+;; variable `hs-hide-all-non-comment-function' to implement your idea of
+;; what is more useful.  For example, the following code shows the next
+;; nested level in addition to the top-level:
+;;
+;;   (defun ttn-hs-hide-level-1 ()
+;;     (hs-hide-level 1)
+;;     (forward-sexp 1))
+;;   (setq hs-hide-all-non-comment-function 'ttn-hs-hide-level-1)
+;;
 ;; Hideshow works w/ incremental search (isearch) by setting the variable
 ;; `hs-headline', which is the line of text at the beginning of a hidden
 ;; block that contains a match for the search.  You can have this show up
 ;; Hooks are run after some commands:
 ;;
 ;;   hs-hide-hook     in      hs-hide-block, hs-hide-all, hs-hide-level
-;;   hs-show-hook             hs-show-block, hs-show-all, hs-show-region
+;;   hs-show-hook             hs-show-block, hs-show-all
 ;;
-;; All hooks are run w/ `run-hooks'.  See docs for each variable or hook
-;; for more info.
+;; One of `hs-hide-hook' or `hs-show-hook' is run for the toggling
+;; commands when the result of the toggle is to hide or show blocks,
+;; respectively.  All hooks are run w/ `run-hooks'.  See docs for each
+;; variable or hook for more info.
 ;;
 ;; Normally, hideshow tries to determine appropriate values for block
 ;; and comment definitions by examining the buffer's major mode.  If
 ;; submitting it for inclusion in hideshow.el.  See docstring for
 ;; `hs-special-modes-alist' for more info on the entry format.
 
-;; * Suggested usage
-;;
-;; First make sure hideshow.el is in a directory in your `load-path'.
-;; You can optionally byte-compile it using `M-x byte-compile-file'.
-;; Then, add the following to your ~/.emacs:
-;;
-;; (load-library "hideshow")
-;; (add-hook 'X-mode-hook 'hs-minor-mode)   ; other modes similarly
-;;
-;; where X = {emacs-lisp,c,c++,perl,...}.  You can also manually toggle
-;; hideshow minor mode by typing `M-x hs-minor-mode'.  After hideshow is
-;; activated, `hs-minor-mode-hook' is run w/ `run-hooks'.  A good hook
-;; to add is `hs-hide-initial-comment-block'.
-
 ;; * Bugs
 ;;
 ;; (1) Hideshow does not work w/ emacs 18 because emacs 18 lacks the
 ;;     writes this, please send me a copy.
 ;;
 ;; (2) Sometimes `hs-headline' can become out of sync.  To reset, type
-;;     `M-x hs-minor-mode' twice (that is, deactivate then activate
+;;     `M-x hs-minor-mode' twice (that is, deactivate then re-activate
 ;;     hideshow).
 ;;
-;; (3) Hideshow 5.x is developed and tested on GNU Emacs 20.4.
+;; (3) Hideshow 5.x is developed and tested on GNU Emacs 20.7.
 ;;     XEmacs compatibility may have bitrotted since 4.29.
 ;;
+;; (4) Some buffers can't be `byte-compile-file'd properly.  This is because
+;;     `byte-compile-file' inserts the file to be compiled in a temporary
+;;     buffer and switches `normal-mode' on.  In the case where you have
+;;     `hs-hide-initial-comment-block' in `hs-minor-mode-hook', the hiding of
+;;     the initial comment sometimes hides parts of the first statement (seems
+;;     to be only in `normal-mode'), so there are unbalanced "(" and ")".
+;;
+;;     The workaround is to clear `hs-minor-mode-hook' when byte-compiling:
+;;
+;;     (defadvice byte-compile-file (around
+;;                                   byte-compile-file-hideshow-off
+;;                                   act)
+;;       (let ((hs-minor-mode-hook nil))
+;;         ad-do-it))
+;;
+;; (5) Hideshow interacts badly with Ediff and `vc-diff'.  At the moment, the
+;;     suggested workaround is to turn off hideshow entirely, for example:
+;;
+;;     (defun turn-off-hideshow () (hs-minor-mode -1))
+;;     (add-hook 'ediff-prepare-buffer-hook 'turn-off-hideshow)
+;;     (add-hook 'vc-before-checkin-hook 'turn-off-hideshow)
+;;
+;;     In the case of `vc-diff', here is a less invasive workaround:
+;;
+;;     (add-hook 'vc-before-checkin-hook
+;;               '(lambda ()
+;;                  (goto-char (point-min))
+;;                  (hs-show-block)))
+;;
+;;     Unfortunately, these workarounds do not restore hideshow state.
+;;     If someone figures out a better way, please let me know.
+
+;; * Correspondance
+;;
 ;; Correspondance welcome; please indicate version number.  Send bug
-;; reports and inquiries to <ttn@netcom.com>.
+;; reports and inquiries to <ttn@gnu.org>.
 
 ;; * Thanks
 ;;
 ;; Thanks go to the following people for valuable ideas, code and
 ;; bug reports.
 ;;
-;;     adahome@ix.netcom.com                 Dean Andrews
-;;     alfh@ifi.uio.no                       Alf-Ivar Holm
-;;     bauer@itsm.uni-stuttgart.de           Holger Bauer
-;;     christoph.conrad@post.rwth-aachen.de  Christoph Conrad
-;;     d.love@dl.ac.uk                       Dave Love
-;;     dirk@ida.ing.tu-bs.de                 Dirk Herrmann
-;;     gael@gnlab030.grenoble.hp.com         Gael Marziou
-;;     jan.djarv@sa.erisoft.se               Jan Djarv
-;;     leray@dev-lme.pcc.philips.com         Guillaume Leray
-;;     moody@mwt.net                         Moody Ahmad
-;;     preston.f.crow@dartmouth.edu          Preston F. Crow
-;;     qhslali@aom.ericsson.se               Lars Lindberg
-;;     reto@synopsys.com                     Reto Zimmermann
-;;     sheff@edcsgw2.cr.usgs.gov             Keith Sheffield
-;;     smes@post1.com                        Chew Meng Kuan
-;;     tonyl@eng.sun.com                     Tony Lam
-;;     ware@cis.ohio-state.edu               Pete Ware
-;;
-;; Special thanks go to Dan Nicolaescu <dann@ics.uci.edu>, who reimplemented
-;; hideshow using overlays (rather than selective display), added isearch
-;; magic, folded in custom.el compatibility, generalized comment handling,
-;; incorporated mouse support, and maintained the code in general.  Version
-;; 4.0 is largely due to his efforts.
+;;     Dean Andrews, Alf-Ivar Holm, Holger Bauer, Christoph Conrad, Dave
+;;     Love, Dirk Herrmann, Gael Marziou, Jan Djarv, Guillaume Leray,
+;;     Moody Ahmad, Preston F. Crow, Lars Lindberg, Reto Zimmermann,
+;;     Keith Sheffield, Chew Meng Kuan, Tony Lam, Pete Ware, François
+;;     Pinard, Stefan Monnier, Joseph Eydelnant, Michael Ernst
+;;
+;; Special thanks go to Dan Nicolaescu, who reimplemented hideshow using
+;; overlays (rather than selective display), added isearch magic, folded
+;; in custom.el compatibility, generalized comment handling, incorporated
+;; mouse support, and maintained the code in general.  Version 4.0 is
+;; largely due to his efforts.
 
 ;; * History
 ;;
   :group 'hideshow)
 
 (defcustom hs-minor-mode-hook nil
-  "*Hook called when hideshow minor mode is activated."
+  "*Hook called when hideshow minor mode is activated or deactivated."
   :type 'hook
-  :group 'hideshow)
+  :group 'hideshow
+  :version "21.1")
 
-(defcustom hs-isearch-open 'block
+(defcustom hs-isearch-open 'code
   "*What kind of hidden blocks to open when doing `isearch'.
 One of the following symbols:
 
-  block   -- open only blocks
-  comment -- open only comments
-  t       -- open both blocks and comments
-  nil     -- open neither blocks nor comments
+  code    -- open only code blocks
+  comment -- open only comment blocks
+  t       -- open both code and comment blocks
+  nil     -- open neither code nor comment blocks
 
 This has effect iff `search-invisible' is set to `open'."
-  :type '(choice (const :tag "open only blocks" block)
-                 (const :tag "open only comments" comment)
-                 (const :tag "open both blocks and comments" t)
+  :type '(choice (const :tag "open only code blocks" code)
+                 (const :tag "open only comment blocks" comment)
+                 (const :tag "open both code and comment blocks" t)
                  (const :tag "don't open any of them" nil))
   :group 'hideshow)
 
@@ -223,8 +280,9 @@ defined as text surrounded by START and END.
 As a special case, START may be a list of the form (COMPLEX-START
 MDATA-SELECTOR), where COMPLEX-START is a regexp w/ multiple parts and
 MDATA-SELECTOR an integer that specifies which sub-match is the proper
-place to adjust point, before calling `hs-forward-sexp-func'.  For
-example, see the `hs-special-modes-alist' entry for `bibtex-mode'.
+place to adjust point, before calling `hs-forward-sexp-func'.  Point
+is adjusted to the beginning of the specified match.  For example,
+see the `hs-special-modes-alist' entry for `bibtex-mode'.
 
 For some major modes, `forward-sexp' does not work properly.  In those
 cases, FORWARD-SEXP-FUNC specifies another function to use instead.
@@ -236,13 +294,18 @@ If any of the elements is left nil or omitted, hideshow tries to guess
 appropriate values.  The regexps should not contain leading or trailing
 whitespace.  Case does not matter.")
 
+(defvar hs-hide-all-non-comment-function nil
+  "*Function called if non-nil when doing `hs-hide-all' for non-comments.")
+
 (defvar hs-hide-hook nil
   "*Hook called (with `run-hooks') at the end of commands to hide text.
-These commands include `hs-hide-all', `hs-hide-block' and `hs-hide-level'.")
+These commands include the toggling commands (when the result is to hide
+a block), `hs-hide-all', `hs-hide-block' and `hs-hide-level'.")
 
 (defvar hs-show-hook nil
   "*Hook called (with `run-hooks') at the end of commands to show text.
-These commands include `hs-show-all', `hs-show-block' and `hs-show-region'.")
+These commands include the toggling commands (when the result is to show
+a block), `hs-show-all' and `hs-show-block'..")
 
 ;;---------------------------------------------------------------------------
 ;; internal variables
@@ -254,6 +317,9 @@ Use the command `hs-minor-mode' to toggle or set this variable.")
 (defvar hs-minor-mode-map nil
   "Keymap for hideshow minor mode.")
 
+(defvar hs-minor-mode-menu nil
+  "Menu for hideshow minor mode.")
+
 (defvar hs-c-start-regexp nil
   "Regexp for beginning of comments.
 Differs from mode-specific comment regexps in that
@@ -285,11 +351,11 @@ as opposed to hiding it from the position returned when searching
 for `hs-block-start-regexp'.
 
 For example, in c-like modes, if we wish to also hide the curly braces
-(if you think they occupy too much space on the screen), this function
+\(if you think they occupy too much space on the screen), this function
 should return the starting point (at the end of line) of the hidden
 region.
 
-It is called with a single argument ARG which is the the position in
+It is called with a single argument ARG which is the position in
 buffer after the block beginning.
 
 It should return the position from where we should start hiding.
@@ -329,9 +395,9 @@ Note that `mode-line-format' is buffer-local.")
 ;       (setq buffer-invisibility-spec
 ;             (cons arg buffer-invisibility-spec)))))
 ;   (defun remove-from-invisibility-spec (arg)
-;     (if buffer-invisibility-spec
-;         (setq buffer-invisibility-spec
-;               (delete arg buffer-invisibility-spec)))))
+;     (when buffer-invisibility-spec
+;       (setq buffer-invisibility-spec
+;             (delete arg buffer-invisibility-spec)))))
 
 ;; hs-match-data
 (defalias 'hs-match-data 'match-data)
@@ -340,18 +406,32 @@ Note that `mode-line-format' is buffer-local.")
 ;; support functions
 
 (defun hs-discard-overlays (from to)
+  "Delete hideshow overlays in region defined by FROM and TO."
   (when (< to from)
     (setq from (prog1 to (setq to from))))
-  (mapcar (lambda (ov)
-            (when (overlay-get ov 'hs)
-              (delete-overlay ov)))
-          (overlays-in from to)))
+  (let ((ovs (overlays-in from to)))
+    (while ovs
+      (let ((ov (car ovs)))
+       (when (overlay-get ov 'hs)
+         (delete-overlay ov)))
+      (setq ovs (cdr ovs)))))
 
 (defun hs-isearch-show (ov)
+  "Delete overlay OV, and set `hs-headline' to nil.
+
+This function is meant to be used as the `isearch-open-invisible'
+property of an overlay."
   (setq hs-headline nil)
-  (hs-flag-region (overlay-start ov) (overlay-end ov) nil))
+  (delete-overlay ov))
 
 (defun hs-isearch-show-temporary (ov hide-p)
+  "Hide or show overlay OV, and set `hs-headline', all depending on HIDE-P.
+If HIDE-P is non-nil, `hs-headline' is set to nil and overlay OV is hidden.
+Otherwise, `hs-headline' is set to the line of text at the head of OV, and
+OV is shown.
+
+This function is meant to be used as the `isearch-open-invisible-temporary'
+property of an overlay."
   (setq hs-headline
        (if hide-p
            nil
@@ -369,8 +449,8 @@ Note that `mode-line-format' is buffer-local.")
 (defun hs-flag-region (from to flag)
   "Hide or show lines from FROM to TO, according to FLAG.
 If FLAG is nil then text is shown, while if FLAG is non-nil the text is
-hidden.  Actually flag is really either `comment' or `block' depending
-on what kind of block it is suppose to hide."
+hidden.  FLAG must be one of the symbols `code' or `comment', depending
+on what kind of block is to be hidden."
   (save-excursion
     ;; first clear it all out
     (hs-discard-overlays from to)
@@ -378,14 +458,16 @@ on what kind of block it is suppose to hide."
     (when flag
       (let ((overlay (make-overlay from to)))
         (overlay-put overlay 'invisible 'hs)
-        (overlay-put overlay 'intangible t)
         (overlay-put overlay 'hs flag)
-        (when (or (eq hs-isearch-open t) (eq hs-isearch-open flag))
-          (mapcar
-           (lambda (pair)
-             (overlay-put overlay (car pair) (cdr pair)))
-          '((isearch-open-invisible . hs-isearch-show)
-            (isearch-open-invisible-temporary . hs-isearch-show-temporary))))
+        (when (or (eq hs-isearch-open t)
+                  (eq hs-isearch-open flag)
+                  ;; deprecated backward compatibility -- `block'<=>`code'
+                  (and (eq 'block hs-isearch-open)
+                       (eq 'code  flag)))
+         (overlay-put overlay 'isearch-open-invisible 'hs-isearch-show)
+         (overlay-put overlay
+                      'isearch-open-invisible-temporary
+                      'hs-isearch-show-temporary))
         overlay))))
 
 (defun hs-forward-sexp (match-data arg)
@@ -415,29 +497,29 @@ The block beginning is adjusted by `hs-adjust-block-beginning'
 and then further adjusted to be at the end of the line."
   (if comment-reg
       (hs-hide-comment-region (car comment-reg) (cadr comment-reg) end)
-    (if (looking-at hs-block-start-regexp)
-        (let* ((mdata (hs-match-data t))
-               (pure-p (match-end 0))
-               (p
-                ;; `p' is the point at the end of the block beginning,
-                ;; which may need to be adjusted
-                (save-excursion
-                  (goto-char (funcall (or hs-adjust-block-beginning
-                                          'identity)
-                                      pure-p))
-                  ;; whatever the adjustment, we move to eol
-                  (end-of-line)
-                  (point)))
-               (q
-                ;; `q' is the point at the end of the block
-                (progn (hs-forward-sexp mdata 1)
-                       (end-of-line)
-                       (point))))
-          (if (and (< p (point)) (> (count-lines p q) 1))
-              (overlay-put (hs-flag-region p q 'block)
-                           'hs-ofs
-                           (- pure-p p)))
-          (goto-char (if end q (min p pure-p)))))))
+    (when (looking-at hs-block-start-regexp)
+      (let* ((mdata (hs-match-data t))
+             (pure-p (match-end 0))
+             (p
+              ;; `p' is the point at the end of the block beginning,
+              ;; which may need to be adjusted
+              (save-excursion
+                (goto-char (funcall (or hs-adjust-block-beginning
+                                        'identity)
+                                    pure-p))
+                ;; whatever the adjustment, we move to eol
+                (end-of-line)
+                (point)))
+             (q
+              ;; `q' is the point at the end of the block
+              (progn (hs-forward-sexp mdata 1)
+                     (end-of-line)
+                     (point))))
+        (when (and (< p (point)) (> (count-lines p q) 1))
+          (overlay-put (hs-flag-region p q 'code)
+                       'hs-ofs
+                       (- pure-p p)))
+        (goto-char (if end q (min p pure-p)))))))
 
 (defun hs-safety-is-job-n ()
   "Warn if `buffer-invisibility-spec' does not contain symbol `hs'."
@@ -486,16 +568,16 @@ as cdr."
               (setq p (point));; use this to avoid an infinite cycle
               (forward-comment 1)
               (skip-chars-forward " \t\n\f"))
-            (if (or (not (looking-at hs-c-start-regexp))
-                    (> (point) q))
-                ;; we cannot hide this comment block
-                (setq not-hidable t)))
+            (when (or (not (looking-at hs-c-start-regexp))
+                      (> (point) q))
+              ;; we cannot hide this comment block
+              (setq not-hidable t)))
           ;; goto the end of the comment
           (forward-comment (buffer-size))
           (skip-chars-backward " \t\n\f")
           (end-of-line)
-          (if (>= (point) q)
-              (list (if not-hidable nil p) (point))))))))
+          (when (>= (point) q)
+            (list (if not-hidable nil p) (point))))))))
 
 (defun hs-grok-mode-type ()
   "Set up hideshow variables for new buffers.
@@ -525,13 +607,12 @@ function; and adjust-block-beginning function."
                                         c-start-regexp)))
               hs-forward-sexp-func (or (nth 4 lookup) 'forward-sexp)
               hs-adjust-block-beginning (nth 5 lookup)))
-    (progn
-      (setq hs-minor-mode nil)
-      (error "%s Mode doesn't support Hideshow Minor Mode" mode-name))))
+    (setq hs-minor-mode nil)
+    (error "%s Mode doesn't support Hideshow Minor Mode" mode-name)))
 
 (defun hs-find-block-beginning ()
   "Reposition point at block-start.
-Return point, or nil if top-level."
+Return point, or nil if original point was not in a block."
   (let ((done nil)
         (here (point)))
     ;; look if current line is block start
@@ -585,11 +666,11 @@ and `case-fold-search' are both t."
       (if (and c-reg (nth 0 c-reg))
           ;; point is inside a comment, and that comment is hidable
           (goto-char (nth 0 c-reg))
-        (if (and (not c-reg)
-                 (hs-find-block-beginning)
-                 (looking-at hs-block-start-regexp))
-            ;; point is inside a block
-            (goto-char (match-end 0)))))
+        (when (and (not c-reg)
+                   (hs-find-block-beginning)
+                   (looking-at hs-block-start-regexp))
+          ;; point is inside a block
+          (goto-char (match-end 0)))))
     (end-of-line)
     (let ((overlays (overlays-at (point)))
           (found nil))
@@ -622,39 +703,34 @@ If `hs-hide-comments-when-hiding-all' is non-nil, also hide the comments."
    (save-excursion
      (hs-flag-region (point-min) (point-max) nil) ; eliminate weirdness
      (goto-char (point-min))
-     (if hs-hide-comments-when-hiding-all
-         (let ((c-reg nil)
-               (count 0)
-               (block-and-comment-re
-                (concat "\\("
-                        hs-block-start-regexp
-                        "\\)\\|\\("
-                        hs-c-start-regexp
-                        "\\)")))
-           (while (re-search-forward block-and-comment-re (point-max) t)
-             (if (match-beginning 1) ;; we have found a block beginning
-                 (progn
-                   (goto-char (match-beginning 1))
-                   (hs-hide-block-at-point t)
-                   (message "Hiding ... %d" (setq count (1+ count))))
-               ;;found a comment
-               (setq c-reg (hs-inside-comment-p))
-               (if (and c-reg (car c-reg))
-                   (if (> (count-lines (car c-reg) (nth 1 c-reg)) 1)
-                       (progn
-                         (hs-hide-block-at-point t c-reg)
-                         (message "Hiding ... %d" (setq count (1+ count))))
-                     (goto-char (nth 1 c-reg)))))))
-       (let ((count 0)
-             (buf-size (buffer-size)))
-         (while
+     (let ((count 0)
+           (re (concat "\\("
+                       hs-block-start-regexp
+                       "\\)"
+                       (if hs-hide-comments-when-hiding-all
+                           (concat "\\|\\("
+                                   hs-c-start-regexp
+                                   "\\)")
+                         ""))))
+       (while (progn
+                (unless hs-hide-comments-when-hiding-all
+                  (forward-comment (point-max)))
+                (re-search-forward re (point-max) t))
+         (if (match-beginning 1)
+             ;; we have found a block beginning
              (progn
-               (forward-comment buf-size)
-               (re-search-forward hs-block-start-regexp (point-max) t))
-           (goto-char (match-beginning 0))
-           (hs-hide-block-at-point t)
-           (message "Hiding ... %d" (setq count (1+ count))))))
-   (hs-safety-is-job-n))
+               (goto-char (match-beginning 1))
+               (if hs-hide-all-non-comment-function
+                   (funcall hs-hide-all-non-comment-function)
+                 (hs-hide-block-at-point t)))
+           ;; found a comment, probably
+           (let ((c-reg (hs-inside-comment-p)))         ; blech!
+             (when (and c-reg (car c-reg))
+               (if (> (count-lines (car c-reg) (nth 1 c-reg)) 1)
+                   (hs-hide-block-at-point t c-reg)
+                 (goto-char (nth 1 c-reg))))))
+         (message "Hiding ... %d" (setq count (1+ count)))))
+     (hs-safety-is-job-n))
    (beginning-of-line)
    (message "Hiding all blocks ... done")
    (run-hooks 'hs-hide-hook)))
@@ -696,17 +772,18 @@ See documentation for functions `hs-hide-block' and `run-hooks'."
    (or
     ;; first see if we have something at the end of the line
     (catch 'eol-begins-hidden-region-p
-      (let ((here (point)))
-        (mapcar (lambda (ov)
-                  (when (overlay-get ov 'hs)
-                    (goto-char
-                     (cond
-                      (end (overlay-end ov))
-                      ((eq 'comment (overlay-get ov 'hs)) here)
-                      (t (+ (overlay-start ov) (overlay-get ov 'hs-ofs)))))
-                    (delete-overlay ov)
-                    (throw 'eol-begins-hidden-region-p t)))
-                (save-excursion (end-of-line) (overlays-at (point))))
+      (let ((here (point))
+           (ovs (save-excursion (end-of-line) (overlays-at (point)))))
+       (while ovs
+         (let ((ov (car ovs)))
+           (when (overlay-get ov 'hs)
+             (goto-char
+              (cond (end (overlay-end ov))
+                    ((eq 'comment (overlay-get ov 'hs)) here)
+                    (t (+ (overlay-start ov) (overlay-get ov 'hs-ofs)))))
+             (delete-overlay ov)
+             (throw 'eol-begins-hidden-region-p t)))
+         (setq ovs (cdr ovs)))
         nil))
     ;; not immediately obvious, look for a suitable block
     (let ((c-reg (hs-inside-comment-p))
@@ -725,18 +802,6 @@ See documentation for functions `hs-hide-block' and `run-hooks'."
     (hs-safety-is-job-n)
     (run-hooks 'hs-show-hook))))
 
-(defun hs-show-region (beg end)
-  "Show all lines from BEG to END, without doing any block analysis.
-Note: `hs-show-region' is intended for use when `hs-show-block' signals
-\"unbalanced parentheses\" and so is an emergency measure only.  You may
-become very confused if you use this command indiscriminately.
-The hook `hs-show-hook' is run; see `run-hooks'."
-  (interactive "r")
-  (hs-life-goes-on
-   (hs-flag-region beg end nil)
-   (hs-safety-is-job-n)
-   (run-hooks 'hs-show-hook)))
-
 (defun hs-hide-level (arg)
   "Hide all blocks ARG levels below this block.
 The hook `hs-hide-hook' is run; see `run-hooks'."
@@ -749,6 +814,15 @@ The hook `hs-hide-hook' is run; see `run-hooks'."
    (hs-safety-is-job-n)
    (run-hooks 'hs-hide-hook)))
 
+(defun hs-toggle-hiding ()
+  "Toggle hiding/showing of a block.
+See `hs-hide-block' and `hs-show-block'."
+  (interactive)
+  (hs-life-goes-on
+   (if (hs-already-hidden-p)
+       (hs-show-block)
+     (hs-hide-block))))
+
 (defun hs-mouse-toggle-hiding (e)
   "Toggle hiding/showing of a block.
 This command should be bound to a mouse key.
@@ -757,9 +831,7 @@ See `hs-hide-block' and `hs-show-block'."
   (interactive "@e")
   (hs-life-goes-on
    (mouse-set-point e)
-   (if (hs-already-hidden-p)
-       (hs-show-block)
-     (hs-hide-block))))
+   (hs-toggle-hiding)))
 
 (defun hs-hide-initial-comment-block ()
   "Hide the first block of comments in a file.
@@ -783,15 +855,16 @@ With ARG, turn hideshow minor mode on if ARG is positive, off otherwise.
 When hideshow minor mode is on, the menu bar is augmented with hideshow
 commands and the hideshow commands are enabled.
 The value '(hs . t) is added to `buffer-invisibility-spec'.
-Last, the normal hook `hs-minor-mode-hook' is run; see `run-hooks'.
 
 The main commands are: `hs-hide-all', `hs-show-all', `hs-hide-block',
-`hs-show-block', `hs-hide-level' and `hs-show-region'.  There is also
+`hs-show-block', `hs-hide-level' and `hs-toggle-hiding'.  There is also
 `hs-hide-initial-comment-block' and `hs-mouse-toggle-hiding'.
 
 Turning hideshow minor mode off reverts the menu bar and the
 variables to default values and disables the hideshow commands.
 
+Lastly, the normal hook `hs-minor-mode-hook' is run using `run-hooks'.
+
 Key bindings:
 \\{hs-minor-mode-map}"
 
@@ -802,21 +875,19 @@ Key bindings:
                        (> (prefix-numeric-value arg) 0)))
   (if hs-minor-mode
       (progn
-        (easy-menu-add hs-minor-mode-menu)
-        (make-variable-buffer-local 'line-move-ignore-invisible)
-        (setq line-move-ignore-invisible t)
-        (add-to-invisibility-spec '(hs . t))            ; hs invisible
         (hs-grok-mode-type)
-        (run-hooks 'hs-minor-mode-hook))
+        (easy-menu-add hs-minor-mode-menu)
+        (set (make-local-variable 'line-move-ignore-invisible) t)
+        (add-to-invisibility-spec '(hs . t)))
     (easy-menu-remove hs-minor-mode-menu)
-    (remove-from-invisibility-spec '(hs . t))))
+    (remove-from-invisibility-spec '(hs . t)))
+  (run-hooks 'hs-minor-mode-hook))
 
 ;;---------------------------------------------------------------------------
 ;; load-time actions
 
 ;; keymaps and menus
-(if hs-minor-mode-map
-    nil
+(unless hs-minor-mode-map
   (setq hs-minor-mode-map (make-sparse-keymap))
   (easy-menu-define hs-minor-mode-menu
     hs-minor-mode-map
@@ -829,15 +900,15 @@ Key bindings:
            (lambda (ent)
              (define-key hs-minor-mode-map (aref ent 2) (aref ent 1))
              (if (aref ent 0) ent "-----"))
-           ;; I believe there is nothing bound on these keys.
+           ;; These bindings roughly imitate those used by Outline mode.
            ;; menu entry      command                key
-           '(["Hide Block"    hs-hide-block          "\C-ch"]
-             ["Show Block"    hs-show-block          "\C-cs"]
-             ["Hide All"      hs-hide-all            "\C-cH"]
-             ["Show All"      hs-show-all            "\C-cS"]
-             ["Hide Level"    hs-hide-level          "\C-cL"]
-             ["Show Region"   hs-show-region         "\C-cR"]
-             [nil             hs-mouse-toggle-hiding [(shift button2)]]
+           '(["Hide Block"    hs-hide-block          "\C-c@\C-h"]
+             ["Show Block"    hs-show-block          "\C-c@\C-s"]
+             ["Hide All"      hs-hide-all            "\C-c@\C-\M-h"]
+             ["Show All"      hs-show-all            "\C-c@\C-\M-s"]
+             ["Hide Level"    hs-hide-level          "\C-c@\C-l"]
+             ["Toggle Hiding" hs-toggle-hiding       "\C-c@\C-c"]
+             [nil             hs-mouse-toggle-hiding [(shift mouse-2)]]
              )))))
 
 ;; some housekeeping
@@ -850,20 +921,23 @@ Key bindings:
                                    (list '(hs-minor-mode " hs")))))
 
 ;; make some variables permanently buffer-local
-(mapcar (lambda (var)
-          (make-variable-buffer-local var)
-          (put var 'permanent-local t))
-        '(hs-minor-mode
-          hs-c-start-regexp
-          hs-block-start-regexp
-          hs-block-start-mdata-select
-          hs-block-end-regexp
-          hs-forward-sexp-func
-          hs-adjust-block-beginning))
+(let ((vars '(hs-minor-mode
+             hs-c-start-regexp
+             hs-block-start-regexp
+             hs-block-start-mdata-select
+             hs-block-end-regexp
+             hs-forward-sexp-func
+             hs-adjust-block-beginning)))
+  (while vars
+    (let ((var (car vars)))
+      (make-variable-buffer-local var)
+      (put var 'permanent-local t))
+    (setq vars (cdr vars))))
 
 ;;---------------------------------------------------------------------------
 ;; that's it
 
 (provide 'hideshow)
 
+;;; arch-tag: 378b6852-e82a-466a-aee8-d9c73859a65e
 ;;; hideshow.el ends here