[comp.emacs] MicroEMACS 3.10 bugs, fixes and a MAJOR improvement to file completion

m2@insyte.UUCP (Mike Arena) (08/10/89)

I like MicroEMACS 3.10.  I am impressed with the level and scope of portability
that has been achieved.  However, I have a few complaints and fixes:

1) mlwrite() in display.c tries to do its own variable argument parsing based
on STACK_GROWS_UP.  This is ridiculous.  Of all the systems I've ported this
to (HPUX, VMS, SUNOS4, APOLLO, MSDOS), every one had <varargs.h> and some
handled the stack in strange ways (especially RISC machines and alignment).
If you have a standard facility, then use it.

2) The file char.[co] seems to be left out of several makefiles.  A minor nit
but I would have assumed that these makefiles were tested.

3) The VMS DESCRIP.MMS is referencing SMG.OBJ and VMSVT.C.  Where are these?
It seems that VMSVT.C was incorporated into VMS.C but the SMG stuff is nowhere
to be found (VMS4.7, VAXC2.3).

4) The file name completion routines were amazingly inefficient.  It actually
rescanned the entire directory for each CHARACTER that matched even if there
was only one matching entry.  Also, it would not complete directory names
which mostly defeats the purpose of the function.  The fixes below permit
directory names to be completed and will scan a directory ONCE.  While
scanning, the longest possible match is remebered.  If the match is a
directory, then the DIRSEPCHAR is appended.

5) For tcap.c, it was a good idea to have function key parsing that
standardized the names.  However, it is now quite difficult to deal with
application keypads.  I use a VT100 like terminal with 8 function keys
and an 18 key keypad.  Most of the keypad is wasted since a standard termcap
only allows for 10 function keys and a few special keys like delete character,
page up/down, etc.  I can't think of a solution so maybe I shouldn't complain.

Below are the 2 functions in unix.c which were changed.  Following these
is the comp_file() function in input.c.
----------------------------------------------------------------------
char *PASCAL NEAR getffile(fspec)

char *fspec;	/* pattern to match */

{
	register int index;		/* index into various strings */
	register int point;		/* index into other strings */
	register int extflag;		/* does the file have an extention? */
	int currentdir = FALSE;

	/* first parse the file path off the file spec */
	strcpy(path, fspec);
	index = strlen(path) - 1;
	while (index >= 0 && (path[index] != '/' &&
				path[index] != '\\' && path[index] != ':'))
		--index;
	path[index+1] = 0;
#if HPUX
	if (index < 0) {
		strcpy(path,"./");
		index = 1;
		currentdir = TRUE;
	}
#endif

	/* check for an extension */
	point = strlen(fspec) - 1;
	extflag = FALSE;
	while (point >= 0) {
		if (fspec[point] == '.') {
			extflag = TRUE;
			break;
		}
		point--;
	}

	/* open the directory pointer */
	if (dirptr != NULL) {
		closedir(dirptr);
		dirptr = NULL;
	}
	dirptr = opendir(path);
	if (dirptr == NULL)
		return(NULL);

#if HPUX
	if (currentdir == TRUE)
		path[0] = '\0';
#endif

	strcpy(rbuf, path);
	nameptr = &rbuf[strlen(rbuf)];

	/* and call for the first file */
	return(getnfile());
}

char *PASCAL NEAR getnfile()

{
	register struct direct *dp;	/* directory entry pointer */
	register int index;		/* index into various strings */
	struct stat fstat;

	/* and call for the next file */
nxtdir:	dp = readdir(dirptr);
	if (dp == NULL)
		return(NULL);

	/* check to make sure we skip directory entries */
	strcpy(nameptr, dp->d_name);
	stat(rbuf, &fstat);
	if (((fstat.st_mode & S_IFMT) != S_IFREG) &&
	    ((fstat.st_mode & S_IFMT) != S_IFDIR))
		goto nxtdir;

	if ((fstat.st_mode & S_IFMT) == S_IFDIR)
		strcat(rbuf,"/");

	/* return the next file name! */
	return(rbuf);
}
----------------------------------------------------------------------

Here is the modified comp_file():

comp_file(name, cpos)

char *name;	/* file containing the current name to complete */
int *cpos;	/* ptr to position of next character to insert */

{
	register char *fname;	/* trial file to complete */
	register int index;	/* index into strings to compare */
	register int matches;	/* number of matches for name */
	char longestmatch[NSTRING]; /* temp buffer for longest match */
	int longestlen;		/* length of longest match (always > *cpos) */

	/* everything (or nothing) matches an empty string */
	if (*cpos == 0)
		return;

	/* first, we start at the first file and scan the list */
	matches = 0;
	name[*cpos] = 0;
	fname = getffile(name);
	while (fname) {

		/* is this a match? */
		if (strncmp(name,fname,*cpos) == 0) {

			/* count the number of matches */
			matches++;

			/* if this is the first match, simply record it */
			if (matches == 1) {
				strcpy(longestmatch,fname);
				longestlen = strlen(longestmatch);
			} else {
				
				/* if there's a difference, stop here */
				if (longestmatch[*cpos] != fname[*cpos])
					return;

				for (index = (*cpos) + 1; index < longestlen; index++)
					if (longestmatch[index] != fname[index]) {
						longestlen = index;
						longestmatch[longestlen] = 0;
					}
			}
		}

		/* on to the next file */
		fname = getnfile();
	}

	/* beep if we never matched */
	if (matches == 0) {
		TTbeep();
		return;
	}

	/* the longestmatch array contains the longest match so copy and print it */
	for ( ; (*cpos < (NSTRING-1)) && (*cpos < longestlen); (*cpos)++) {
		name[*cpos] = longestmatch[*cpos];
		TTputc(name[*cpos]);
	}

	name[*cpos] = 0;

	/* if only one file matched then increment cpos to signal complete() */
	/* that this was a complete match.  If a directory was matched then */
	/* last character will be the DIRSEPCHAR.  In this case we do NOT *
	/* want to signal a complete match. */
	if ((matches == 1) && (name[(*cpos)-1] != DIRSEPCHAR))
		(*cpos)++;

	TTflush();

	return;
}
-- 
Michael J. Arena  (617) 965 8450    | UUCP: ...harvard!linus!axiom!insyte!m2
Innovative Systems Techniques       |       ...harvard!necntc!lpi!insyte!m2
1 Gateway Center, Newton, MA 02158  | ARPA: insyte!m2@harvard.harvard.edu

wsincc@eutrc3.urc.tue.nl (Wim van Dorst) (08/14/89)

In article <234@insyte.UUCP> m2@insyte.UUCP (Michael J. Arena) writes:
>I like MicroEMACS 3.10.  I am impressed with the level and scope of portability
>that has been achieved. 
I too am impressed.
>
>3) The VMS DESCRIP.MMS is referencing SMG.OBJ and VMSVT.C.  Where are these?
>It seems that VMSVT.C was incorporated into VMS.C but the SMG stuff is nowhere
>to be found (VMS4.7, VAXC2.3).
I have Emacs up and running under VMS 4.7. I twiddled with the
VMS.c file as it had some minor bugs. I posted the changes to the
net. VMSVT.c is obsolete by the coming of VMS.c. All VMS.c
functionality is in VMS.c instead of VMSVT.c and others. So don't
search for VMSVT.c as you won't need it. It was in my
distribution though.
SMG.OBJ you should make yourself from the SMG.MAR file. It is an
very short file (two lines) to be compiled with MACRO. It is:
	$$smgtrmptrdef GLOBAL
	.end
This file was included in my distribution too.

>4) The file name completion routines were amazingly inefficient.  
Is there any such thing for VMS yet? Net? Mr. Lawrence?

Again this question of my own:
Does anyone have MicroEmacs 3.10 under VMS _and_ the mouse
working? If so what has been changed to make it so?

Met vriendelijke groeten, Wim van Dorst, wsincc@tuerc3.urc.tue.nl

usenet@cps3xx.UUCP (Usenet file owner) (08/14/89)

in article <234@insyte.UUCP>, m2@insyte.UUCP (Mike Arena) says:
> Xref: cps3xx comp.emacs:6668 comp.sources.d:3985
> 
> 5) For tcap.c, it was a good idea to have function key parsing that
> standardized the names.  However, it is now quite difficult to deal with
> application keypads.  I use a VT100 like terminal with 8 function keys
> and an 18 key keypad.  Most of the keypad is wasted since a standard termcap
> only allows for 10 function keys and a few special keys like delete character,
> page up/down, etc.  I can't think of a solution so maybe I shouldn't complain.
> 
I was able to start using shifted function keys under Xenix with a
simple hack. I added the definition s0 to s9 in my termcap for the
shifted function keys. s[0-9] are names not reserved for anything
special so I've made them private extensions. Then a simple change near
the beginning of tcap.c and a comment out of a few lines in ebind.h and
I then have 10 more function keys.

Please don't email to me asking for these changes, they are simple
enough that the knowledge gained by doing them firsthand warrants them
to be left as an exercise for the user. ;-)

John H. Lawitzke           UUCP: Work: ...uunet!frith!dale1!jhl
Dale Computer Corp., R&D         Home: ...uunet!frith!dale1!ipecac!jhl
2367 Science Parkway       Internet:   jhl@frith.egr.msu.edu
Okemos, MI, 48864                             [35.8.8.108]

nwd@j.cc.purdue.edu (Daniel Lawrence) (08/15/89)

In article <234@insyte.UUCP> m2@insyte.UUCP (Michael J. Arena) writes:
>I like MicroEMACS 3.10.  I am impressed with the level and scope of portability
>that has been achieved.  However, I have a few complaints and fixes:

>1) mlwrite() in display.c tries to do its own variable argument parsing based
>on STACK_GROWS_UP.  This is ridiculous.  Of all the systems I've ported this
					      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>to (HPUX, VMS, SUNOS4, APOLLO, MSDOS), every one had <varargs.h> and some
>handled the stack in strange ways (especially RISC machines and alignment).
>If you have a standard facility, then use it.

	Indeed, if I did, I would.  However, as you pointed out, this
works on the systems YOU ported it to.  However I support uEMACS on a
number of systems and compilers that do not have varargs.h, and I do not
want to simply tell a lot of users there machines must be updated or
changed because of this.

>2) The file char.[co] seems to be left out of several makefiles.  A minor nit
>but I would have assumed that these makefiles were tested.

	Again... supply me with all those machines, and I will happily
test all the make files.  Unfortunatly, no one person can own all the
equipment to do this.  I have to rely on the users whe recieve the first
draft release to help me with this.

>3) The VMS DESCRIP.MMS is referencing SMG.OBJ and VMSVT.C.  Where are these?
>It seems that VMSVT.C was incorporated into VMS.C but the SMG stuff is nowhere
>to be found (VMS4.7, VAXC2.3).

	Again, it is my lack of a VMS machine.  It has already been
noted, and the people at DEC and in Chicago and here at Purdue whom
normally help with the VMS work have gotten together and got both the
ANSI and SMG support packages working.  They will be included in the
next intrim release. (No time promises.  I do this in my spare time for
fun).

>4) The file name completion routines were amazingly inefficient.  It actually
>rescanned the entire directory for each CHARACTER that matched even if there
>was only one matching entry.  Also, it would not complete directory names
>which mostly defeats the purpose of the function.  The fixes below permit
>directory names to be completed and will scan a directory ONCE.  While
>scanning, the longest possible match is remebered.  If the match is a
>directory, then the DIRSEPCHAR is appended.

	I agree here... my original goal was to have one set of
completion routines for all 3 different types of completion.  This
brought the consistancy of completion up, and the size down. 
Unfortunatly the directory scanning is very expensive... I have already
coded a very simple cashing for this that will allow me to use the same
code still.


>5) For tcap.c, it was a good idea to have function key parsing that
>standardized the names.  However, it is now quite difficult to deal with
>application keypads.  I use a VT100 like terminal with 8 function keys
>and an 18 key keypad.  Most of the keypad is wasted since a standard termcap
>only allows for 10 function keys and a few special keys like delete character,
>page up/down, etc.  I can't think of a solution so maybe I shouldn't complain.

	Someone.... send me a VT100! 

>Below are the 2 functions in unix.c which were changed.  Following these
>is the comp_file() function in input.c.

	Thanx for the code.... I will try to extract code to let us scan
directory paths from it.

>Michael J. Arena  (617) 965 8450    | UUCP: ...harvard!linus!axiom!insyte!m2
>Innovative Systems Techniques       |       ...harvard!necntc!lpi!insyte!m2
>1 Gateway Center, Newton, MA 02158  | ARPA: insyte!m2@harvard.harvard.edu

			Daniel Lawrence  voice: (317) 742-5153
					  arpa:	dan@midas.mgmt.purdue.edu
				The Programmer's Room 
				Fido: 1:201/10 - (317) 742-5533

davidsen@sungod.crd.ge.com (ody) (08/15/89)

In article <9847@j.cc.purdue.edu> nwd@j.cc.purdue.edu (Daniel Lawrence) writes:

| >5) For tcap.c, it was a good idea to have function key parsing that
| >standardized the names.  However, it is now quite difficult to deal with
| >application keypads.  I use a VT100 like terminal with 8 function keys
| >and an 18 key keypad.  Most of the keypad is wasted since a standard termcap
| >only allows for 10 function keys and a few special keys like delete character,
| >page up/down, etc.  I can't think of a solution so maybe I shouldn't complain.
| 
| 	Someone.... send me a VT100! 

  My solution was to stick with 3.9p. When 3.10 first came out it was
obvious that the TERMCAP can't handle large numbers of function keys.
Given F1-F12, shift and control (and ALT in DOS), or a Sun with F1-F9,
L1-L10, and R1-R15 (all of which can be modified with shift, control,
alt, left-meta and right-meta). This is a lot of stuff to put in a
TERMCAP, and works a lot better when you can recognize ANY three
character ANSI sequence (that is, ESCAPE, [, {anything}).

  I would humbly suggest that the previous ANSI sequence capability be
restored in addition to the TERMCAP stuff. Let the user compile for one
or the other. Some of us have very complex keyboards and want to use all
the functions.
	bill davidsen		(davidsen@crdos1.crd.GE.COM)
  {uunet | philabs}!crdgw1!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

nwd@j.cc.purdue.edu (Daniel Lawrence) (08/15/89)

In article <1675@crdgw1.crd.ge.com> davidsen@crdos1.UUCP (bill davidsen) writes:
>  I would humbly suggest that the previous ANSI sequence capability be
>restored in addition to the TERMCAP stuff. Let the user compile for one
>or the other. Some of us have very complex keyboards and want to use all
>the functions.
>	bill davidsen		(davidsen@crdos1.crd.GE.COM)
>  {uunet | philabs}!crdgw1!crdos1!davidsen
>"Stupidity, like virtue, is its own reward" -me

	How about a comprimise here....  let the TCAP module scan for the
termcap entries, and if a particular escape sequence is not in the termcap,
use some standard translation rule... perhaps mapping it into the ALT area?
Then the termcap keys will always be bound to the standard, machine
independant bindings, and all the unusual  sequences generated on some
TTYs can still be used.

			Daniel Lawrence  voice: (317) 742-5153
					  arpa:	dan@midas.mgmt.purdue.edu
				The Programmer's Room 
				Fido: 1:201/10 - (317) 742-5533

richk@pogo.WV.TEK.COM (Richard G. Knowles) (08/16/89)

In article <9852@j.cc.purdue.edu> nwd@j.cc.purdue.edu (Daniel Lawrence) writes:
>In article <1675@crdgw1.crd.ge.com> davidsen@crdos1.UUCP (bill davidsen) writes:
>>  I would humbly suggest that the previous ANSI sequence capability be
>>restored in addition to the TERMCAP stuff. Let the user compile for one
>>or the other. Some of us have very complex keyboards and want to use all
>>the functions.
>>	bill davidsen		(davidsen@crdos1.crd.GE.COM)
>
>	How about a comprimise here....  let the TCAP module scan for the
>termcap entries, and if a particular escape sequence is not in the termcap,
>use some standard translation rule... perhaps mapping it into the ALT area?
>Then the termcap keys will always be bound to the standard, machine
>independant bindings, and all the unusual  sequences generated on some
>TTYs can still be used.
>			Daniel Lawrence  voice: (317) 742-5153

This was one of the first things I "fixed" in 3.10 when I got it.  If a
"function key" sequence was detected, but didn't match any key definition in
the termcap, then the sequence was simply passed on as if it had been keyed
directly by the user (I was able to eliminate all but one timing dependancy
by doing this also).  I then wrote a macro (bound to ESC-[) that understood
what all the function keys sent.  When invoked it simply read keyboard
characters till it understood what function key it stood for, determined
what the key was bound to, and invoked the binding (either built-in or
macro).  If no binding was found then it simply inserted the key sequence
into the current buffer.

I did not attempt to handle function keys for which Daniel had not defined
"standard" names (as in the various incarnations of f11, f12, or keypad-5
that are available on the AT enhanced keyboard -- we use AT's via rlogin to
access our UNIX machines and it uses an ANSI-like escape sequence to
represent function keys.).

I sent the above changes to Daniel several weeks ago.  I'd be happy to share
it with others upon request.

-------- Whatever I say is my fault and no one elses! -----------

Richard G. Knowles                        richk@pogo.WV.TEK.COM
Graphics Printing and Imaging                (503) 685-3860
Tektronix, Inc; D/S 63-356
Wilsonville, Or 97070			or just yell "Hey, Rich!"

davidsen@sungod.crd.ge.com (ody) (08/16/89)

In article <9852@j.cc.purdue.edu> nwd@j.cc.purdue.edu (Daniel Lawrence) writes:

| 	How about a comprimise here....  let the TCAP module scan for the
| termcap entries, and if a particular escape sequence is not in the termcap,
| use some standard translation rule... perhaps mapping it into the ALT area?
| Then the termcap keys will always be bound to the standard, machine
| independant bindings, and all the unusual  sequences generated on some
| TTYs can still be used.

  I'm not sure that's compromise, since all parties get everything they
ever wanted, but I like it! That's the perfect solution. I assume that
if I don't add any functions to the termcap everything will come
through, allowing use of my existing macro file, then I can gradually
add function key defs to my termcap after the macro files are updated.

| 
| 			Daniel Lawrence  voice: (317) 742-5153
| 					  arpa:	dan@midas.mgmt.purdue.edu
| 				The Programmer's Room 
| 				Fido: 1:201/10 - (317) 742-5533


	bill davidsen		(davidsen@crdos1.crd.GE.COM)
  {uunet | philabs}!crdgw1!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me