From: southern@sunny.NoSubdomain.NoDomain (Lawrence Buja)
Subject: Re: hiding and exposing text
Reply-To: southern@ncar.ucar.edu
Organization: National Center for Atmospheric Research
Distribution: usa
Date: Thu, 13 Aug 1992 14:31:32 GMT

In article <MCCLEN.92Aug12205450@alder.uswest.com>, mcclen@uswest.com ( Chris McClenaghan) writes:
>I'm looking for a package of emacs lisp code that allows hiding
>of regions of text and subsequent exposure of the hidden text.
>I'd like to have more than one region of text hidden at a time.
>This should be interactive, but having the ability to predefine
>regular expressions or syntactic elements that would
>automatically be hidden would also be nice.
>
>As an example, I'd like to collapse the body of a while statement
>in C or C++ leaving just the while and condition with some sort
>of ellipsis mark that could be selected for exposing the text.
>Also, certain #ifdef's might automatically be hidden, leaving a
>mark for expansion.
>
>--
>Chris McClenaghan    mcclen@uswest.com
>


Below is some functions which I scooped off the comp.emacs.help
awhile back and modified to my tastes.  I really only ever use the
first function, hide-all-non-matching-lines.  It's quite powerful
when bound to a hot key or used in conjunction with
narrow-to-region (see function "lock") for isolating the definition
and uses of variables in large codes. 

With this available, I rarely do isearches anymore.  Instead I just
hide all the lines that don't contain target, go to the occurance
of target that I'm interested in, then redisplay the entire buffer.

To check for two or more targets, separate them with a \| 
(i.e. targeta\|targetb\|targetc ).

Cautions:

1. Be careful about deleting hidden text.  It's still there
   (marked by three dots ...) even though you can't see it.  The
   hidden text is conceptionally appended to the end of the previous
   visible line.  If you delete the whole previous line, including the
   ...'s, you've deleted all the hidden text up to the next visible line.

2. String searches will also "find" target strings even if they are
   hidden.  So be careful when doing global changes or running
   search&modify marcros.  

Note that 1. and 2. apply only to text hidden via hide-region.
1. and 2. do NOT apply to text hidden via narrow-to-region.

Good luck.

/\      Lawrence Buja           Climate and Global Dynamics Division
  \_][  southern@ncar.ucar.edu  National Center for Atmospheric Research
      \_________________________Boulder,_Colorado___80307-3000__________

;;Date: Sat, 3 Dec 88 14:08:15 cst
;;From: Daniel LaLiberte <liberte@M.CS.UIUC.EDU>
;;To: sboisen@IZAR.BBN.COM
;;Subject: Re:  elisp structure editing
;;
;;There are two ways to use selective display.  It can be used to
;;hide everything indented past some number of leading whitespaces,
;;or to hide only those lines that are preceded by CR.  My functions,
;;below, only use the latter.  They need some work, but maybe you
;;will be inspired to do that.  Also, keep in mind the problem with
;;comments.  You may suggest to RMS that comments should end with
;;either \n or \r; that would solve the problem.
;;
;;dan
;;
;;; Modified substantially 11/1/89 Aaron Larson. (alarson@src.honeywell.com)


(provide 'hide-sexp)

(defun hide-all-non-matching-lines (regexp)
"Similar to the CMS XEDIT ALL command.                  (all.el)
   - Hide all lines except those containing matches for REGEXP.
   - A match split across lines preserves all the lines it lies in.
   - Applies to all lines in buffer.
   - Entering nothing at the query will redisplay all lines."
  (interactive "sShow lines (regexp): ")
  (show-all)  
  (if (string-equal regexp "")     ()
  (save-excursion
    (goto-line 1)
    (or (bolp) (forward-line 1))
    (let ((start (point)))
      (while (not (eobp))
	;; Start is first char not preserved by previous match.
	(if (not (re-search-forward regexp nil 'move))
	    (hide-region start (point-max))
	  (let ((end (save-excursion (goto-char (match-beginning 0))
				     (forward-line -1)
				     (point))))
	    ;; Now end is first char preserved by the new match.
	    (if (< start end)
		(hide-region start end))))
	(setq start (point)))))))

(defun show-all ()
  "Show any hidden text in buffer.        (all.el)"
  (interactive)
  (show-region (point-min) (point-max))
  (message " "))


(setq locked 'unlocked)
(defun lock ()
  "If currently unlocked
     Narrow region to display only the current fortran subprogram,
     defun or paragraph depending on major-mode of the file.
   If currently locked
     widen and recenter to restore all text.   (all.el)"
  (interactive)
  (save-excursion

  (if (eq major-mode 'fortran-mode)     (mark-fortran-subprogram))
  (if (eq major-mode 'emacs-lisp-mode)  (mark-defun))
  (if (eq major-mode 'text-mode)        (mark-paragraph))
  (if (eq locked 'locked) (widen)    (narrow-to-region (point) (mark)))
;;(if (eq locked 'locked) (recenter) ())
  (if (eq locked 'locked) (setq locked 'unlocked) (setq locked 'locked))
	(setq start (point)) ))



(defun set-mark-widen ()
  "Set mark then show any hidden text in buffer.   (all.el)"
  (interactive)
  (show-region (point-min) (point-max))
  (set-mark-command nil)
)


(defun hide-non-top-level (&optional except-comments) 
  "Hide all non top level forms, with arguments doesn't hide top level 
comments (i.e. ';' in column 1)."
  (interactive "P")
  (hide-region (point-min) (point-max)
	       (if except-comments "(;" "(")))
    
    
 
(defun hide-sexp ()
  "Hide the lines within the current sexp.  Current sexp is defined as either 
the one immediately following point, or the surrounding one."
  (interactive)
  (save-excursion
    (forward-char)
    (backward-up-list 1)
    (hide-region
      (save-excursion (beginning-of-line)
		      (point))
      (progn (forward-sexp 1)
	     (point)))))

(defun show-sexp ()
  "Show the lines within the current sexp.  Current sexp is defined as either 
the one immediately following point, or the surrounding one."
  (interactive)
  (save-excursion
    (forward-char)
    (backward-up-list 1)
    (show-region
     (save-excursion
       (beginning-of-line)
       (point))
     (progn
       (forward-sexp 1)
       (point)))))

(defun hide-sub-sexps ()
  "Hide all the sub sexps in the current form."
  (interactive)
  (save-excursion
    (condition-case err
	(progn
	  (backward-up-list 1)
	  (down-list 1)
	  (forward-sexp 1)		; after function name
	  (while t			; run til end of list
	    (forward-sexp 1)
	    (hide-region 
	      (progn
		(forward-sexp -1) (point))
	      (progn
		(forward-sexp 1) (point))))
	  )
      (error nil))))
	  



;(setq minor-mode-alist (cons (quote (selective-display " Hiden"))
;			     minor-mode-alist))
(defun hide-text (arg)
  "Hide all text in buffer indented by more than the current column.
If an argument is given, then the argument is used instead of the current 
column.  In either case, a value less than 1 makes all text visible."
  (interactive "P")
  (setq arg (or arg (current-column)))
  (setq selective-display (if (< (prefix-numeric-value arg) 1)
			      nil
			    (prefix-numeric-value arg))))


(defun hide-region (from to &optional flag)
  (interactive "r")
  (hide-or-show-region from to ?\r flag))

(defun show-region (from to &optional flag)
  (interactive "r")
  (hide-or-show-region from to ?\n flag))

(defun hide-or-show-region (from to flag &optional show-lines-starting)
  "Hides or shows lines from FROM to TO, according to FLAG.  If FLAG
is \\n (newline character) then text is shown, while if FLAG is \\r
\(control-M) the text is hidden. Also twiddles the buffer-modified
flag to make up for a deficiency (in the documentation at least) of
subst-char-in-region.  Show-lines-starting should be a string containing
characters indicating that the lines starting with one of the characters
should not be hiden."
  (let ((modifiedp (buffer-modified-p))
	(buffer-read-only nil))
    (subst-char-in-region from to
			  (if (= flag ?\n) ?\r ?\n)
			  flag 'noundo)
    (if show-lines-starting
	(save-excursion
	  (goto-char from)
	  (let ((chars (concat (char-to-string ?\r) "[" (regexp-quote show-lines-starting) "]")))
	    (while (re-search-forward chars to t)
	      (backward-char 1)
	      (subst-char-in-region (- (point) 1) (point) ?\r ?\n 'noundo)))))
    (set-buffer-modified-p modifiedp))
  (setq selective-display t)
  (modify-syntax-entry ?\r ">")
  )


(defun hide-matching-lines (regexp)
  "Hide lines, from point to end of buffer, containing matches for REGEXP.
If a match is split across lines, all the lines it lies in are hidden."
  (interactive "sHide lines (containing match for regexp): ")
  (save-excursion
    (while (and (not (eobp))
		(re-search-forward regexp nil t))
      (hide-region (save-excursion (goto-char (match-beginning 0))
				   (forward-line -1)
				   (point))
		   (match-end 0))
      (forward-line 1))))


(defun forward-maybe-hidden-line (n)
  "Move forward a ``logical'' line, hidden or not."
  (goto-char
   (let* ((l (save-excursion
	      (forward-line n)
	      (point)))
	  (p (progn
	       (search-forward "\r" l 'move
			       (if (plusp n)
				   n
				   (- n 1)))
	       (point))))
     
     (if (plusp n)
	 (min l p)
	 (max l p)))))

(defun show-matching-lines (regexp)
  "Show lines, from point to end of buffer, containing matches for REGEXP.
If a match is split across lines, all the lines it lies in are shown.  (all.el)"
  (interactive "sShow lines (containing match for regexp): ")
  (save-excursion
    (while (and (not (eobp))
		(re-search-forward regexp nil t))
      (show-region (save-excursion (forward-maybe-hidden-line 0)
				   (point))
		   (progn
		     (forward-maybe-hidden-line 1)
		     (backward-char 1)
		     (point))))))





Date: Thu, 13 Aug 1992 21:18:32 PDT
X-Windows: The first fully modular software disaster.
From: jwz@lucid.com (Jamie Zawinski)
Subject: Re: Automatic load path failing?
Newsgroups: alt.lucid-emacs.help