]> git.eshelyaron.com Git - emacs.git/commitdiff
(hs-special-modes-alist): Include also the
authorRichard M. Stallman <rms@gnu.org>
Thu, 29 May 1997 05:23:39 +0000 (05:23 +0000)
committerRichard M. Stallman <rms@gnu.org>
Thu, 29 May 1997 05:23:39 +0000 (05:23 +0000)
comment regexp in the alist. This is needed for modes like c++
where the comment beginning regexp is not easy to determine
from the syntax table.
Include ADJUST-BLOCK-BEGINNING in the alist.
(hs-hide-comments-when-hiding-all): Add autoload cookie.
(hs-show-hidden-short-form):
(hs-adjust-block-beginning): New variables.

Comment out `hs-menu-bar' as XEmacs support was removed.
(hs-c-end-regexp): Remove variable, obsoleted by the rewrite of
`hs-inside-comment-p'.

(hs-discard-overlays): No need to test if we are inside the
overlay, we surely are since we got the overlay using `overlays-at'.
(hs-hide-block-at-point): Rewritten to use the new variables.
Use only one parameter to specify the comment.
(hs-show-block-at-point): No need for the COMMENT-REG parameter.
(hs-safety-is-job-n): Correct typo.
(hs-hide-initial-comment-block): Add ^L to the chars to skip.
Take into account `hs-show-hidden-short-form' when testing.
(hs-inside-single-line-comment-p): Function deleted, obsoleted by
the rewrite of `hs-inside-comment-p'.
(hs-inside-comment-p): Rewritten from scratch. Semantics changed
when returning non-nil. We can be inside a comment, but that
comment might not be hidable (the car of the return value should
be non-nil to be hidable).
(hs-grok-mode-type): Rewrite to be more understandable.
`hs-c-end-regexp' does not exist any more.
Initialize `hs-c-start-regexp' from the alist if specified there.
Initialize `hs-adjust-block-beginning'.
(hs-find-block-beginning): Rewritten to be able to deal with the
situation when a block beginning spans multiple lines and the
point is on one of those lines.
(hs-already-hidden-p): Look first if we are inside a comment or a
block, go to their end and look there for the overlays.
(java-hs-adjust-block-beginning): New function.
(hs-hide-all): Hide a comment block only if `hs-inside-comment-p'
says is hidable.
(hs-hide-block): Simplify.
Handle properly the result of `hs-inside-comment-p'.
(hs-show-block): Likewise.
(hs-minor-mode): Doc string fixes.
Make `hs-adjust-block-beginning' buffer local.
Delete making `hs-c-end-regexp' buffer local as it was deleted.

lisp/progmodes/hideshow.el

index 826b7fd219b51cd83b16ba441f6641af31607742..45bc49a94b8e24727b805dab9bffa936bb771734 100644 (file)
@@ -87,9 +87,50 @@ Values other than these four will be interpreted as `signal'.")
 ;;;#autoload
 (defvar hs-special-modes-alist 
   '((c-mode "{" "}")
-    (c++-mode "{" "}")
-    (java-mode "\\(\\(public\\|private\\|protected\\|static\\|\\s-\\)+\\([a-zA-Z0-9_:]+[ \t]+\\)\\([a-zA-Z0-9_:]+\\)[ \t]*([^)]*)[ \t\n]*\\([ \t\n]throws[ \t]+[^{]+\\)*[ \t]*\\){" "}" java-hs-forward-sexp))
-  "*Alist of the form (MODE START-RE END-RE FORWARD-SEXP-FUNC).
+    (c++-mode "{" "}" "/[*/]")
+    (java-mode   "\\(\\(\\([ \t]*\\(\\(public\\|private\\|protected\\|abstract\\|static\\|\\final\\)[ \t\n]+\\)+\\(synchronized[ \t\n]*\\)?[a-zA-Z0-9_:]+[ \t\n]*\\(\\[[ \t\n]*\\][ \t\n]*\\)?\\([a-zA-Z0-9_:]+[ \t\n]*\\)([^)]*)\\([ \n\t]+throws[ \t\n][^{]+\\)?\\)\\|\\([ \t]*static[^{]*\\)\\)[ \t\n]*{\\)"  "}"  "/[*/]" java-hs-forward-sexp java-hs-adjust-block-beginning))
+; I tested the java regexp using the following:
+;(defvar hsj-public)
+;(defvar hsj-syncronised)
+;(defvar hsj-type)
+;(defvar hsj-fname)
+;(defvar hsj-par)
+;(defvar hsj-throws)
+;(defvar hsj-static)
+
+;(setq hsj-public "[ \t]*\\(\\(public\\|private\\|protected\\|abstract\\|static\\|\\final\\)[ \t\n]+\\)+")
+;(setq hsj-syncronised "\\(synchronized[ \t\n]*\\)?")
+;(setq hsj-type "[a-zA-Z0-9_:]+[ \t\n]*\\(\\[[ \t\n]*\\][ \t\n]*\\)?")
+;(setq hsj-fname "\\([a-zA-Z0-9_:]+[ \t\n]*\\)")
+;(setq hsj-par "([^)]*)")
+;(setq hsj-throws "\\([ \n\t]+throws[ \t\n][^{]+\\)?")
+
+;(setq hsj-static "[ \t]*static[^{]*")
+
+
+;(setq hs-block-start-regexp (concat
+;                           "\\("
+;                               "\\("
+;                                    "\\("
+;                                       hsj-public
+;                                       hsj-syncronised
+;                                       hsj-type
+;                                       hsj-fname
+;                                       hsj-par
+;                                       hsj-throws
+;                                    "\\)"
+;                                    "\\|"
+;                                    "\\("
+;                                       hsj-static
+;                                    "\\)"
+;                               "\\)"
+;                                  "[ \t\n]*{"
+;                            "\\)"  
+;                                  ))
+
+  "*Alist for initializing the hideshow variables for different modes.
+It has the form 
+(MODE START-RE END-RE COMMENT-START-RE FORWARD-SEXP-FUNC ADJUST-BEG-FUNC).
 If present, hideshow will use these values for the start and end regexps,
 respectively.  Since Algol-ish languages do not have single-character
 block delimiters, the function `forward-sexp' which is used by hideshow
@@ -102,9 +143,15 @@ more values, use
 
 For example:
 
-\t(pushnew '(simula-mode \"begin\" \"end\" simula-next-statement)
+\t(pushnew '(simula-mode \"begin\" \"end\" \"!\" simula-next-statement)
 \t     hs-special-modes-alist :test 'equal)
 
+See the documentation for `hs-adjust-block-beginning' to see what
+is the use of ADJUST-BEG-FUNC.
+
+If any of those is left nil, hideshow will try to guess some values, see
+`hs-grok-mode-type' for this.
+
 Note that the regexps should not contain leading or trailing whitespace.")
 
 (defvar hs-minor-mode-hook 'hs-hide-initial-comment-block
@@ -122,6 +169,49 @@ These commands include `hs-show-all', `hs-show-block' and `hs-show-region'.")
 (defvar hs-minor-mode-prefix "\C-c"
   "*Prefix key to use for hideshow commands in hideshow minor mode.")
 
+;;;#autoload
+(defvar hs-hide-comments-when-hiding-all t 
+  "Hide the comments too when you do an `hs-hide-all'." )
+
+;;;#autoload
+(defvar hs-show-hidden-short-form t
+  "Leave only the first line visible in a hidden block.
+If t only the first line is visible when a block is in the hidden state, 
+else both the first line and the last line are showed. Also if t and 
+`hs-adjust-block-beginning' is set, it is used also.
+
+An example of how this works: (in c-mode)
+original:
+                      
+/* My function main
+   some more stuff about main
+*/
+int
+main(void)
+{
+  int x=0;
+  return 0;
+}
+
+
+hidden and hs-show-hidden-short-form is nil
+/* My function main...
+*/                        
+int
+main(void)
+{...
+}
+
+hidden and hs-show-hidden-short-form is t
+/* My function main...
+int                   
+main(void)                  
+{ ...
+
+
+The latest has the disadvantage of not being symetrical, but it saves
+screen lines ...
+")
 
 ;;;----------------------------------------------------------------------------
 ;;; internal variables
@@ -133,18 +223,14 @@ Use the command `hs-minor-mode' to toggle this variable.")
 (defvar hs-minor-mode-map nil
   "Mode map for hideshow minor mode.")
 
-(defvar hs-menu-bar nil
-  "Menu bar for hideshow minor mode (Xemacs only).")
+;(defvar hs-menu-bar nil
+;  "Menu bar for hideshow minor mode (Xemacs only).")
 
 (defvar hs-c-start-regexp nil
   "Regexp for beginning of comments.  
 Differs from mode-specific comment regexps in that 
 surrounding whitespace is stripped.")
 
-(defvar hs-c-end-regexp nil
-  "Regexp for end of comments.
-See `hs-c-start-regexp'.")
-
 (defvar hs-block-start-regexp nil
   "Regexp for beginning of block.")
 
@@ -159,8 +245,24 @@ either `(' or `)' -- `hs-forward-sexp-func' would just be `forward-sexp'.
 For other modes such as simula, a more specialized function
 is necessary.")
 
-(defvar hs-hide-comments-when-hiding-all t 
-  "Hide the comments too when you do an `hs-hide-all'." )
+(defvar hs-adjust-block-beginning nil
+  "Function used to tweak the block beginning.
+It has effect only if `hs-show-hidden-short-form' is t. The block it
+is hidden from the point returned by this function, as opposed to
+hiding it from the point returned when searching
+`hs-block-start-regexp'.  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 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
+buffer after the block beginning.
+
+It should return the position from where we should start hiding.
+
+It should not move the point.  
+
+See `java-hs-adjust-block-beginning' for an example of using this.")
 
 ;(defvar hs-emacs-type 'fsf
 ;  "Used to support both Emacs and Xemacs.")
@@ -175,7 +277,7 @@ is necessary.")
 ;;;----------------------------------------------------------------------------
 ;;; support funcs
 
-;; snarfed from noutline.el;
+;; snarfed from outline.el;
 (defun hs-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."
@@ -203,67 +305,79 @@ If FLAG is nil then text is shown, while if FLAG is t the text is hidden."
        (while overlays
          (let ((o (car overlays)))
            (if (eq (overlay-get o prop) value)
-               (if (or 
-                    (and (> (overlay-end o) beg) (< (overlay-end o) end))
-                    (and (< (overlay-start o) beg) (< (overlay-start o) end)))
-                   (delete-overlay o))))
+                   (delete-overlay o)))
          (setq overlays (cdr overlays))))
       (goto-char (next-overlay-change (point))))))
 
-(defun hs-hide-block-at-point (&optional end comment c-reg)
+(defun hs-hide-block-at-point (&optional end comment-reg)
   "Hide block iff on block beginning, optional END means reposition at end.
-COMMENT true means that it should hide a comment block, C-REG is a list
-of the form (BEGIN . END) and specifies the limits of the comment." 
-  (if comment
-      (let ((reg (if c-reg  c-reg (hs-inside-comment-p))))
-       (goto-char (nth 1 reg))
-       (forward-line -1)
+COMMENT-REG is a list of the form (BEGIN . END) and specifies the limits 
+of the comment, or nil if the block is not a comment." 
+  (if comment-reg
+      (progn 
+       ;; goto the end of line at the end of the comment
+       (goto-char (nth 1 comment-reg))
+       (unless hs-show-hidden-short-form (forward-line -1))
        (end-of-line)
-       (hs-flag-region (car reg)  (point) t)
-       (goto-char (if end (nth 1 reg) (car reg)))
-       )
+       (hs-flag-region (car comment-reg)  (point) t) 
+       (goto-char (if end (nth 1 comment-reg) (car comment-reg))))
       (if (looking-at hs-block-start-regexp)
-         (let* ((p (point))
+         (let* ((p ;; p is the point at the end of the block beginning
+                 (if (and  hs-show-hidden-short-form 
+                           hs-adjust-block-beginning)
+                     ;; we need to adjust the block beginning
+                     (funcall hs-adjust-block-beginning (match-end 0)) 
+                   (match-end 0)))
+                ;; q is the point at the end of the block
                 (q (progn (funcall hs-forward-sexp-func 1) (point))))
-           (forward-line -1) (end-of-line)
-           (if (and (< p (point)) (> (count-lines p q) 1))
-           (hs-flag-region p (point) t))
-       (goto-char (if end q p))))))
-
-(defun hs-show-block-at-point (&optional end)
-  "Show block iff on block beginning.  Optional END means reposition at end."
-  (if (looking-at hs-block-start-regexp)
-      (let* ((p (point))
-            (q
-             (condition-case error     ; probably unbalanced paren
-                 (progn
-                   (funcall hs-forward-sexp-func 1)
-                   (point))
-               (error
-                (cond
-                 ((eq hs-unbalance-handler-method 'ignore)
-                  ;; just ignore this block
-                  (point))
-                 ((eq hs-unbalance-handler-method 'top-level)
-                  ;; try to get out of rat's nest and expose the whole func
-                  (if (/= (current-column) 0) (beginning-of-defun))
-                  (setq p (point))
-                  (re-search-forward (concat "^" hs-block-start-regexp)
-                                     (point-max) t 2)
-                  (point))
-                 ((eq hs-unbalance-handler-method 'next-line)
-                  ;; assumption is that user knows what s/he's doing
-                  (beginning-of-line) (setq p (point))
-                  (end-of-line 2) (point))
-                 (t
-                  ;; pass error through -- this applies to `signal', too
-                  (signal (car error) (cdr error))))))))
-       (hs-flag-region p q nil)
-       (goto-char (if end (1+ (point)) p)))))
+           ;; position the point so we can call `hs-flag-region'
+           (unless hs-show-hidden-short-form (forward-line -1))
+           (end-of-line)
+           (if (and (< p (point)) (> (count-lines p q) 
+                                     (if hs-show-hidden-short-form 1 2)))
+               (hs-flag-region p (point) t))
+           (goto-char (if end q p))))))
+
+(defun hs-show-block-at-point (&optional end comment-reg)
+  "Show block iff on block beginning.  Optional END means reposition at end.
+COMMENT-REG is a list of the forme (BEGIN . END) and specifies the limits 
+of the comment. It should be nil when hiding a block." 
+  (if comment-reg
+      (when (car comment-reg)
+       (hs-flag-region (car comment-reg) (nth 1 comment-reg) nil)
+       (goto-char (if end (nth 1 comment-reg) (car comment-reg))))
+    (if (looking-at hs-block-start-regexp)
+       (let* ((p (point))
+              (q
+               (condition-case error   ; probably unbalanced paren
+                   (progn
+                     (funcall hs-forward-sexp-func 1)
+                     (point))
+                 (error
+                  (cond
+                   ((eq hs-unbalance-handler-method 'ignore)
+                    ;; just ignore this block
+                    (point))
+                   ((eq hs-unbalance-handler-method 'top-level)
+                    ;; try to get out of rat's nest and expose the whole func
+                    (if (/= (current-column) 0) (beginning-of-defun))
+                    (setq p (point))
+                    (re-search-forward (concat "^" hs-block-start-regexp)
+                                       (point-max) t 2)
+                    (point))
+                   ((eq hs-unbalance-handler-method 'next-line)
+                    ;; assumption is that user knows what s/he's doing
+                    (beginning-of-line) (setq p (point))
+                    (end-of-line 2) (point))
+                   (t
+                    ;; pass error through -- this applies to `signal', too
+                    (signal (car error) (cdr error))))))))
+         (hs-flag-region p q nil)
+         (goto-char (if end (1+ (point)) p))))))
 
 (defun hs-safety-is-job-n ()
   "Warn `buffer-invisibility-spec' does not contain hs."
-    (if (or buffer-invisibility-spec (assq hs buffer-invisibility-spec) )
+    (if (or buffer-invisibility-spec (assq 'hs buffer-invisibility-spec) )
        nil
       (message "Warning: `buffer-invisibility-spec' does not contain hs!!")
       (sit-for 2)))
@@ -276,82 +390,122 @@ file beginning, so if you have huge RCS logs you won't see them!"
       (let ((p (point))
            c-reg)
        (goto-char (point-min))
-       (skip-chars-forward " \t\n")
+       (skip-chars-forward " \t\n^L")
        (setq c-reg (hs-inside-comment-p))
-       (if (and c-reg (> (count-lines (car c-reg) (nth 1 c-reg)) 2))
+       ;; see if we have enough comment lines to hide
+       (if (and c-reg (> (count-lines (car c-reg) (nth 1 c-reg)) 
+                         (if hs-show-hidden-short-form 1 2)))
            (hs-hide-block)
          (goto-char p))))
 
-(defun hs-inside-single-line-comment-p ()
-  "Look to see if we are on a single line comment."
-  (save-excursion
-    (beginning-of-line)
-    (looking-at (concat "^[ \t]*" hs-c-start-regexp))))
-
 (defun hs-inside-comment-p ()
   "Returns non-nil if point is inside a comment, otherwise nil.
 Actually, returns a list containing the buffer position of the start 
-and the end of the comment."
-  (save-excursion
-    (let ((p (point))
-         q
-         p-aux)
-      (if (string= comment-end "")     ; single line
-           (if (not (hs-inside-single-line-comment-p))
-               nil
-             ;;find-beginning-of-the-chained-single-line-comments
-             (beginning-of-line)
-             (forward-comment (- (buffer-size)))
-             (skip-chars-forward " \t\n")
-             (beginning-of-line)
-             (setq q (point))
-             (goto-char p)
-             ;;find-end-of-the-chained-single-line-comments
-             (forward-comment (buffer-size))
-             (skip-chars-backward " \t\n")
-             (list q   (point)))
-       (re-search-forward hs-c-end-regexp (point-max) 1)
-       (forward-comment (buffer-size))
-       (skip-chars-backward " \t\n")
-       (end-of-line)
-       (setq q (point))
-       (forward-comment (- 0 (buffer-size)))
-       (re-search-forward hs-c-start-regexp (point-max) 1)
-       (setq p-aux (- (point) (length comment-start)))
-       (if (and (>= p-aux 0) (< p-aux p))
-           (list (match-beginning 0) q))))))
+and the end of the comment. A comment block can be hided only if on its 
+starting line there are only white spaces preceding the actual comment 
+beginning, if we are inside of a comment but this condition is not 
+we return a list having a nil as its car and the end of comment position
+as cdr."
+  (save-excursion 
+    ;; the idea is to look backwards for a comment start regexp, do a
+    ;; forward comment, and see if we are inside, then extend extend
+    ;; forward and backward as long as we have comments
+    (let ((q (point)))
+      (when (or (looking-at hs-c-start-regexp)
+             (re-search-backward hs-c-start-regexp (point-min) t))
+       (forward-comment (- (buffer-size)))
+       (skip-chars-forward " \t\n\f")
+       (let ((p (point))
+             (not-hidable nil))
+         (beginning-of-line)
+         (unless (looking-at (concat "[ \t]*" hs-c-start-regexp))
+           ;; we are in this situation: (example)
+           ;; (defun bar ()
+           ;;      (foo)
+           ;;                ) ; comment
+           ;;                 ^
+           ;;   the point was here before doing (beginning-of-line)
+           ;; here we should advance till the next comment which 
+           ;; eventually has only white spaces preceding it on the same
+           ;; line 
+           (goto-char p)
+           (forward-comment 1)
+           (skip-chars-forward " \t\n\f")
+           (setq p (point))
+           (while (and (< (point) q) 
+                       (> (point) p) 
+                       (not (looking-at hs-c-start-regexp)))
+             (setq p (point))  ;; use this to avoid an infinit 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)))
+         ;; 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))))))))
 
 (defun hs-grok-mode-type ()
   "Setup variables for new buffers where applicable."
-  (if (and (boundp 'comment-start)
-          (boundp 'comment-end))
-      (progn
-       (setq hs-c-start-regexp (regexp-quote comment-start))
-       (if (string-match " +$" hs-c-start-regexp)
-           (setq hs-c-start-regexp
-                 (substring hs-c-start-regexp 0 (1- (match-end 0)))))
-       (setq hs-c-end-regexp (if (string= "" comment-end) "\n"
-                               (regexp-quote comment-end)))
-       (if (string-match "^ +" hs-c-end-regexp)
-           (setq hs-c-end-regexp
-                 (substring hs-c-end-regexp (match-end 0))))
-       (let ((lookup (assoc major-mode hs-special-modes-alist)))
-         (setq hs-block-start-regexp (or (nth 1 lookup) "\\s\(")
-               hs-block-end-regexp (or (nth 2 lookup) "\\s\)")
-               hs-forward-sexp-func (or (nth 3 lookup) 'forward-sexp))))))
+  (when (and (boundp 'comment-start)
+            (boundp 'comment-end))
+    (let ((lookup (assoc major-mode hs-special-modes-alist)))
+      (setq hs-block-start-regexp (or (nth 1 lookup) "\\s\(")
+           hs-block-end-regexp (or (nth 2 lookup) "\\s\)")
+           hs-c-start-regexp (or (nth 3 lookup)
+                                 (let ((c-start-regexp 
+                                        (regexp-quote comment-start)))
+                                   (if (string-match " +$" c-start-regexp)
+                                        (substring c-start-regexp 0 (1- (match-end 0)))
+                                     c-start-regexp)))
+           hs-forward-sexp-func (or (nth 4 lookup) 'forward-sexp)
+           hs-adjust-block-beginning (nth 5 lookup)))))
 
 (defun hs-find-block-beginning ()
-  "Repositions point at block-start.  
-Return point, or nil if top-level." 
+  "Repositions point at block-start.
+Return point, or nil if top-level."
   (let (done
+       (try-again t)
        (here (point))
        (both-regexps (concat "\\(" hs-block-start-regexp "\\)\\|\\("
                              hs-block-end-regexp "\\)")))
+    (beginning-of-line)
+    ;; A block beginning can span on multiple lines, if the point
+    ;; is on one of those lines, trying a regexp search from
+    ;; that point would fail to find the block beginning, so we look
+    ;; backwards for the block beginning, or a block end.
+    (while try-again
+      (setq try-again nil)
+      (when (re-search-backward both-regexps (point-min) t)
+       (if (match-beginning 1) ; found a block beginning
+           (if (save-match-data (hs-inside-comment-p)) 
+               ;;but it was inside a comment, so we have to look for
+               ;;it again
+               (setq try-again t)
+             ;; that's what we were looking for
+             (setq done (match-beginning 0)))
+         ;; we found a block end, look to see if we were on a block
+         ;; beginning when we started
+         (if (and 
+              (re-search-forward hs-block-start-regexp (point-max) t)
+              (>= here (match-beginning 0)) (< here (match-end 0)))
+             (setq done (match-beginning 0))))))
+    (goto-char here)
     (while (and (not done)
+               ;; This had problems because the regexp can match something
+               ;; inside of a comment!
+               ;; Since inside a comment we can have incomplete sexps
+               ;; this would have signaled an error.
+               (or (forward-comment (-(buffer-size))) t); `or' is a hack to
+                                                        ; make it return t
                (re-search-backward both-regexps (point-min) t))
       (if (match-beginning 1)          ; start of start-regexp
-         (setq done (match-beginning 1))
-       (goto-char (match-end 2))       ; end of end-regexp
+         (setq done (match-beginning 0))
+       (goto-char (match-end 0))       ; end of end-regexp
        (funcall hs-forward-sexp-func -1)))
     (goto-char (or done here))
     done))
@@ -361,8 +515,16 @@ Return point, or nil if top-level."
   (list 'if 'hs-minor-mode (cons 'progn body)))
 
 (defun hs-already-hidden-p ()
-  "Return non-nil if point is in an already-hidden block otherwise nil."
+  "Return non-nil if point is in an already-hidden block, otherwise nil."
   (save-excursion
+    (let ((c-reg (hs-inside-comment-p)))
+      (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)))))
     (end-of-line)
     (let ((overlays (overlays-at (point)))
          (found nil))
@@ -382,6 +544,17 @@ Return point, or nil if top-level."
          (forward-sexp 1))
       (forward-sexp 1))))
 
+(defun java-hs-adjust-block-beginning (arg)
+  "Function to be assigned to `hs-adjust-block-beginning'.
+Arg is a position in buffer just after {. This goes back to the end of
+the function header. The purpose is to save some space on the screen
+when displaying hidden blocks."
+  (save-excursion
+    (goto-char arg)
+    (forward-char -1)
+    (forward-comment (- (buffer-size)))
+    (point)))
+
 ;;;----------------------------------------------------------------------------
 ;;; commands
 
@@ -398,7 +571,8 @@ If `hs-hide-comments-when-hiding-all' is t also hides the comments."
      (hs-flag-region (point-min) (point-max) nil) ; eliminate weirdness
      (goto-char (point-min))
      (if hs-hide-comments-when-hiding-all 
-        (let ((count 0)
+        (let (c-reg
+              (count 0)
               (block-and-comment-re  ;; this should match 
                (concat "\\(^"        ;; the block beginning and comment start
                        hs-block-start-regexp  
@@ -411,14 +585,13 @@ If `hs-hide-comments-when-hiding-all' is t also hides the comments."
                   (message "Hiding ... %d" (setq count (1+ count))))
               ;;found a comment
               (setq c-reg (hs-inside-comment-p))
-              (if c-reg 
-                  (progn 
-                    (goto-char (nth 1 c-reg))
-                    (if (> (count-lines (car c-reg) (nth 1 c-reg)) 2)
-                        (progn
-                          (hs-hide-block-at-point t t c-reg)
-                          (message "Hiding ... %d" 
-                                   (setq count (1+ count))))))))))
+              (if (and c-reg (car c-reg))
+                  (if (> (count-lines (car c-reg) (nth 1 c-reg)) 
+                         (if hs-show-hidden-short-form 1 2))
+                      (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)
             (top-level-re (concat "^" hs-block-start-regexp)))
         (while 
@@ -446,48 +619,39 @@ See documentation for `run-hooks'."
 
 (defun hs-hide-block (&optional end)
   "Selects a block and hides it.  
-With prefix arg, reposition at end.  Block is defined as a sexp for
-lispish modes, mode-specific otherwise.  Comments are blocks, too.  
-Upon completion, point is at repositioned and the normal hook 
+With prefix arg, reposition at end. Block is defined as a sexp for
+lispish modes, mode-specific otherwise. Comments are blocks, too.
+Upon completion, point is at repositioned and the normal hook
 `hs-hide-hook' is run.  See documentation for `run-hooks'."
   (interactive "P")
   (hs-life-goes-on
    (let ((c-reg (hs-inside-comment-p)))
-     (if c-reg
-        (cond 
-         ((<= (count-lines (car c-reg) (nth 1 c-reg)) 2)
+     (cond
+      ((and c-reg (or (null (nth 0 c-reg)) 
+                     (<= (count-lines (car c-reg) (nth 1 c-reg)) 
+                         (if hs-show-hidden-short-form 1 2))))
           (message "Not enough comment lines to hide!"))
-         (t
-          (goto-char (nth 1 c-reg))
-          (hs-hide-block-at-point end t c-reg)
-          (hs-safety-is-job-n)
-          (run-hooks 'hs-hide-hook)))
-       (if (or (looking-at hs-block-start-regexp)
+      ((or c-reg (looking-at hs-block-start-regexp)
               (hs-find-block-beginning))
-          (progn
-            (hs-hide-block-at-point end)
-            (hs-safety-is-job-n)
-            (run-hooks 'hs-hide-hook)))))))
+       (hs-hide-block-at-point end c-reg)
+       (hs-safety-is-job-n)
+       (run-hooks 'hs-hide-hook))))))
 
 (defun hs-show-block (&optional end)
   "Selects a block and shows it.
-With prefix arg, reposition at end.  Upon completion, point is 
+With prefix arg, reposition at end. Upon completion, point is
 repositioned and the normal hook `hs-show-hook' is run.  
 See documentation for `hs-hide-block' and `run-hooks'."
   (interactive "P")
   (hs-life-goes-on
    (let ((c-reg (hs-inside-comment-p)))
-     (if c-reg
-        (progn
-          (hs-flag-region (car c-reg) (nth 1 c-reg) nil)
-          (hs-safety-is-job-n)
-          (goto-char (if end (nth 1 c-reg) (car c-reg))))
-       (if (or (looking-at hs-block-start-regexp)
-              (hs-find-block-beginning))
+     (if (or c-reg
+            (looking-at hs-block-start-regexp)
+            (hs-find-block-beginning))
           (progn
-            (hs-show-block-at-point end)
+            (hs-show-block-at-point end c-reg)
             (hs-safety-is-job-n)
-            (run-hooks 'hs-show-hook)))))))
+            (run-hooks 'hs-show-hook))))))
 
 (defun hs-show-region (beg end)
   "Shows all lines from BEG to END, without doing any block analysis.
@@ -515,13 +679,21 @@ Should be bound to a mouse key."
   "Toggle hideshow minor mode.
 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 variables
-`selective-display' and `selective-display-ellipses' are set to t.
+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 the doc 
 for `run-hooks'.
 
+The main commands are: `hs-hide-all', `hs-show-all', `hs-hide-block'
+and `hs-show-block'. 
+Also see the documentation for the variable `hs-show-hidden-short-form'.
+
 Turning hideshow minor mode off reverts the menu bar and the
-variables to default values and disables the hideshow commands."
+variables to default values and disables the hideshow commands.
+
+Key bindings:
+\\{hs-minor-mode-map}"
+
   (interactive "P")
   (setq hs-minor-mode
         (if (null arg)
@@ -577,8 +749,7 @@ variables to default values and disables the hideshow commands."
   (define-key hs-minor-mode-map [menu-bar Hide/Show hs-show-block]
     '("Show Block" . hs-show-block))
   (define-key hs-minor-mode-map [menu-bar Hide/Show hs-hide-block]
-    '("Hide Block" . hs-hide-block))
-  )
+    '("Hide Block" . hs-hide-block)))
 
 ;; some housekeeping
 (or (assq 'hs-minor-mode minor-mode-map-alist)
@@ -592,16 +763,16 @@ variables to default values and disables the hideshow commands."
 ;; make some variables buffer-local
 (make-variable-buffer-local 'hs-minor-mode)
 (make-variable-buffer-local 'hs-c-start-regexp)
-(make-variable-buffer-local 'hs-c-end-regexp)
 (make-variable-buffer-local 'hs-block-start-regexp)
 (make-variable-buffer-local 'hs-block-end-regexp)
 (make-variable-buffer-local 'hs-forward-sexp-func)
+(make-variable-buffer-local 'hs-adjust-block-beginning)
 (put 'hs-minor-mode 'permanent-local t)
 (put 'hs-c-start-regexp 'permanent-local t)
-(put 'hs-c-end-regexp 'permanent-local t)
 (put 'hs-block-start-regexp 'permanent-local t)
 (put 'hs-block-end-regexp 'permanent-local t)
 (put 'hs-forward-sexp-func 'permanent-local t)
+(put 'hs-adjust-block-beginning 'permanent-local t)
 
 
 ;;;----------------------------------------------------------------------------