[comp.emacs] Hiding comments in C mode

dsill@NSWC-OAS.ARPA (Dave Sill) (01/21/88)

Last month in "Computer Language", a bunch of people were asked about
the future of computing.  One person mentioned something about editors
being able to hide comments on command.  How hard would it be to add
this feature to GNU's C mode?  It sure would be handy, and a boon to
readability, to be able to compress comments into /**/.  Kinda like
outline mode...

=========
"I shed, therefore, I am."
					-- ALF

rap@dana.UUCP (Rob Peck) (01/22/88)

In article <8801202039.AA09434@ucbvax.Berkeley.EDU>, dsill@NSWC-OAS.ARPA (Dave Sill) writes:

> being able to hide comments on command.  How hard would it be to add
> this feature to GNU's C mode?  It sure would be handy, and a boon to
> readability, to be able to compress comments into /**/.  Kinda like
> outline mode...

It seems that to get a similar effect, (have not tried yet, but see
no reason why not), you could:

Mark beginning of C source
Move to end of C source
Copy region to buffer:   no-comments
Switch to buffer:	 no-comments
Loop the following:
Find "/*" 
Set Mark
Find "*/" cursor-left onto the "*"
Delete-region
Repeat loop until end of buffer

And view that new buffer.  Problem would come in if you wanted to
make changes (or add new comments) and then want to push that back
into the source - hmmm maybe a combination of diff and patch
(but I don't have time to do it, though I do agree, neat idea -
usually I have so many comments in my code folks find it difficult
to see the code itself.)

Rob Peck					...ihnp4!hplabs!dana!rap

mayer@hplabsz.HPL.HP.COM (Niels Mayer) (01/23/88)

>In article <8801202039.AA09434@ucbvax.Berkeley.EDU>, dsill@NSWC-OAS.ARPA (Dave Sill) writes:
>
>> being able to hide comments on command.  How hard would it be to add
>> this feature to GNU's C mode?  It sure would be handy, and a boon to
>> readability, to be able to compress comments into /**/.  Kinda like
>> outline mode...

While in the midst of intercourse, a sudden, wonderful "what if..." (tm)
sprang to mind, so I hopped out of the jacuzzi, dialed up, logged in, and
dropped out to the usenet and wrote:

Wouldn't it be nice to do selective display of C ifdefs in addition to C
comments. Something like that might make the source code in highly portable
programs such as gnuemacs much easier to deal with.
-------------------------------------------------------------------------------
	    Niels Mayer -- hplabs!mayer -- mayer@hplabs.hp.com
		       Hewlett-Packard Laboratories
			      Palo Alto, CA.
				   *

gaynor@topaz.rutgers.edu (Silver) (01/24/88)

Check out outline-mode, and see if it's capable of doing what you
want.  I think that if you define outline-regexp carefully, you might
just pull it off, and then you'll have a lot of functionality.

Otherwise, I've just this minute written two-minute commands that make
use the selective-display feature.  I make no guarantees on this code.
I didn't test them but for 2 minutes or so, neither do I intend to do
anything with them at all.  Make sure to set selective-display t in
your c-mode-hook or something.  They're still a little frazzled around
the edges, magic numbers and all that rot.

To be honest, I wonder at the original request.  You want to hide the
comments, and not the code?  Are they especially rude and offensive,
or do I just not seeing the reasoning?
        ___
        \o/
Cheers,  V  [Ag]
        _|_

LOOKING FOR ENTRY-LEVELISH C/LISP PROGRAMMING, SOFTWARE ENGINEERING
Andy Gaynor   201-545-0458   81 Hassart St, New Brunswick, NJ 08901
  gaynor@topaz.rutgers.edu   ...!rutgers!topaz.rutgers.edu!gaynor
     "There is no Editor but Emacs, and Lisp is its Prophet."
----------------------------------------------------------------------
(defun c-hide-comment ()
"Hide the current or next comment.
Inserts 2 C-m's, so don't save it hidden.
Leaves point beyond comment."
  (interactive)
  (let (begin end)
    (re-search-forward "[^\C-m]/\\*\\|[^\C-m]\\*/")
    (if (equal (preceding-char) ?*)
      (progn (setq begin (1+ (match-beginning 0)))
	     (re-search-forward "[^\C-m]\\*/")
	     (setq end (point)))
      (progn (setq end (match-end 0))
	     (re-search-backward "[^\C-m]/\\*")
	     (setq begin (1+ (point)))))

    (goto-char begin)
    (insert "\C-m")
    (goto-char (1- end))
    (insert "\C-m")
    (subst-char-in-region begin end ?\n ?\C-m t)
    (goto-char (+ 2 end))))

(defun c-show-comment ()
"Show the next hidden comment.
Removes the C-m's inserted by c-hide-comment.
Leaves point beyond comment."
  (interactive)
  (let (begin end)
    (re-search-forward "\C-m/\\*\\|\C-m\\*/")
    (if (equal (preceding-char) ?*)
      (progn (setq begin (match-beginning 0))
	     (re-search-forward "\C-m\\*/")
	     (setq end (point)))
      (progn (setq end (match-end 0))
	     (re-search-backward "\C-m/\\*")
	     (setq begin (point))))

    (goto-char begin)
    (delete-char 1 nil)
    (goto-char (- end 4))
    (delete-char 1 nil)

    (subst-char-in-region begin end ?\C-m ?\n t)
    (goto-char (1- end))))

daveb@geac.UUCP (David Collier-Brown) (01/24/88)

  Another way of "hiding" latge numbers of comments is to make them
unnecessary: When I get a function that starts looking over-complex
I re-write it in c-web, thereby reducing the need for putting the
comments right in the code.

  For example,

@*lsproj/lcproj -- list projects@>
@*Identifying the Physical Directory to List@>
.PP
The first task is figuring out what to list.  This is done by
context, much as lc does. We wish to list the closest enclosing
project if no directory or project is given and the rightmost
project in the pathname if a pathname is given.
.PP
Regrettably, this is harder that it appears.

.PP
First, we go to the current project directory if we're in a
subdirectory of it.  This is to allow any parameters not beginning
with "/" to be interpreted as relative to the current project, not
just the current directory (which might not be a project directory).

@<includes@>=
#include <strings.h> /* or string.h... Portability? faugh! */

@<goto vars@>=	
	extern char *getcwd(/* char * space, int size */),
		*strtok(/* char *source | NULL, char *seperators */);
	char	*currentWorkingDirectory,
		*p,		/* Pointer to current token. */
		*currentProject;

@<go to current project directory@>=
	if ((currentWorkingDirectory =
	    getcwd((char *)NULL,MAXLINE)) == NULL) {
		fprintf(stderr,"%s: Could not allocate enough memory to contain\n",
			ProgName);
		fprintf(stderr,"the name of the working directory.\n");
		fprintf(stderr,"Halting"); 	
		<report message from errno>
		exit(SYSTEM_ERROR);
	}
	/* Postcondition: a working directory's name was found. */
	/* It may or may not exist, but we pretend it must. */
	assert(*currentWorkingDirectory != NULL);

-- 
 David Collier-Brown.                 {mnetor yetti utgpu}!geac!daveb
 Geac Computers International Inc.,   |  Computer Science loses its
 350 Steelcase Road,Markham, Ontario, |  memory (if not its mind) 
 CANADA, L3R 1B3 (416) 475-0525 x3279 |  every 6 months.

liberte@uiucdcsb.cs.uiuc.edu (01/25/88)

Related to the hiding of comments, one sometimes wishes to hide
ifdefs selectively.  I have a hide-ifdef-mode.  I added the use of a
general parser (that is probably overkill) to handle #if expressions but
the rest of it is in pretty good working order.  Request by mail if
you are interested.

Dan LaLiberte
liberte@a.cs.uiuc.edu
uiucdcs!liberte

dsill@NSWC-OAS.ARPA (Dave Sill) (01/26/88)

In article <17561@topaz.rutgers.edu> Silver <gaynor@TOPAZ.RUTGERS.EDU> writes:
>Check out outline-mode, and see if it's capable of doing what you
>want.  I think that if you define outline-regexp carefully, you might
>just pull it off, and then you'll have a lot of functionality.

I don't lisp.  One of these days I'll convince myself to learn.

>To be honest, I wonder at the original request.  You want to hide the
>comments, and not the code?

Right.  For example:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define TRUE 1		/* For function return values only */
#define FALSE 0		/* For fn returns or comparisons */

int
foo (x)
int x;			/* Input, number of widgets */
{
/* This function blah blah blah...
    :
   Returns TRUE if blah blah blah...
/*
    int n;
    register char *s;
    :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

would be displayed as:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define TRUE 1		/*  */
#define FALSE 0		/*  */

int
foo (x)
int x;			/*  */
{
/*  */
    int n;
    register char *s;
    :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

>Are they especially rude and offensive, or do I just not [see] the
>reasoning?

They're neither rude nor offensive, just in the way at the moment.

A fringe benefit would be that unclosed comments would be easier to
spot.  E.g.:

	:
	x=y/*z;
	*z=foo(y);		/* blah blah blah... */
	:

would display as:

	:
	x=y/*  */
	:

making the unintentional /* more obvious.  (Of course appropriate
white-space would have prevented the problem in the first place.)

There should be the following commands:

	c-hide-comment
	c-expose-comment
	c-hide-comments-region
	c-expose-comments-region
	c-hide-all-comments
	c-expose-all-comments

and maybe more.  Of course, writing out a C-mode buffer should be
automatically preceded by a call to c-expose-all-comments.  It would
be nice if attempts to modify a "/*  */" automatically called
c-expose-comment.

=========
The opinions expressed above are mine.

"There's no sensation to compare with this/
 Suspended animation, state of bliss."
					-- Pink Floyd

allbery@axcess.UUCP (Brandon S. Allbery) (01/28/88)

In article <8801202039.AA09434@ucbvax.Berkeley.EDU>, dsill@NSWC-OAS.ARPA (Dave Sill) writes:
+---------------
| the future of computing.  One person mentioned something about editors
| being able to hide comments on command.  How hard would it be to add
| this feature to GNU's C mode?  It sure would be handy, and a boon to
| readability, to be able to compress comments into /**/.  Kinda like
| outline mode...
+---------------

My "yacc" mode would benefit from being able to selective-display out stuff
between matched { } as well.

My thoughts on this -- no idea how implementable -- is to teach Emacs about a
standard way of handling paired strings.  A list "matched-string-list" could
be used to define these:

(("{" "}" t) ("(" ")" t) ("/*" "*/" nil) ("[" "]" t) ("\"" "\"" nil))

The list is made up of lists of (open-string, close-string, nest-flag).  The
nest-flag is "t" if the balanced strings can balance with themselves and with
other balancing strings; "nil" means the strings don't balance with themselves
and Emacs should balance other strings only within the current pair of strings
(i.e. a parenthesis inside a comment or string should never try to balance a
parenthesis outside the comment or string).  This would replace the current
implementation as part of the syntax table (the current way of handling e.g. C
comments looks like a kluge to me!).

Now for selective-display:  it is currently defined for "t"/"nil" or a number,
I would like it to take one of these matched-string-lists, and hide everything
between the balanced strings.

How doable is this?  I assume it has to be C code.
-- 
 ___  ________________,	Brandon S. Allbery	       cbosgd \
'   \/  __   __,  __,	aXcess Company		       mandrill|
 __  | /__> <__  <__	6615 Center St. #A1-105		       !ncoast!
/  ` | \__. .__> .__>	Mentor, OH 44060-4101	       necntc  | axcess!allbery
\___/\________________.	Moderator, comp.sources.misc   hoptoad/