Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Improvement (?) to spell-word and correct/correctall

The following simple patch to spname() causes spell-word and correction
prompts to fix up as much of a path as possible.  spname() was already
computing the best-guess corrections for every element of the path prefix,
but then would give up on the entire path as soon as it encountered any
single element that was "too far off" to be corrected.  All this patch
does is record the intermediate results and, if any reasonable match has
been found so far, return the corrected prefix with the still-incorrect

This may actually be wrong in some cases, e.g. two very similar prefixes
exist, one of which "contains" the suffix and the other does not; without
this patch, correction simply fails in that case.  Ideally, any time two
or more close matches are found on the prefix, each of those would be
compared against the suffix, and the overall best chosen; but that needs
a much more significant rewrite of spname() and mindist().

If you're willing to ignore that particular glitch, this patch enables zsh
to perform tcsh-style autocorrections via something like:

	bindkey ^X^I expand-or-complete
	bindkey -s \\t \\es^X^I

(that is, rebind tab to first attempt spelling and then perform completion).
Unfortunately, this still doesn't work with expand-or-complete-prefix or
completeinword, because spell-word always moves the cursor to the end of
the word.  I think I have a fix for that, too, but right now it's bedtime.

*** Src/utils.c.1	Wed Nov 13 08:36:13 1996
--- Src/utils.c	Tue Nov 19 03:20:50 1996
*** 2583,2588 ****
--- 2583,2589 ----
      char *p, spnameguess[PATH_MAX + 1], spnamebest[PATH_MAX + 1];
      static char newname[PATH_MAX + 1];
      char *new = newname, *old;
+     int bestdist = 200, thisdist;
      old = oldname;
      for (;;) {
*** 2596,2603 ****
  	    if (p < spnameguess + PATH_MAX)
  		*p++ = *old;
  	*p = '\0';
! 	if (mindist(newname, spnameguess, spnamebest) >= 3)
! 	    return NULL;
  	for (p = spnamebest; (*new = *p++);)
--- 2597,2611 ----
  	    if (p < spnameguess + PATH_MAX)
  		*p++ = *old;
  	*p = '\0';
! 	if ((thisdist = mindist(newname, spnameguess, spnamebest)) >= 3) {
! 	    if (bestdist < 3) {
! 		strcpy(new, spnameguess);
! 		strcat(new, old);
! 		return newname;
! 	    } else
! 	    	return NULL;
! 	} else
! 	    bestdist = thisdist;
  	for (p = spnamebest; (*new = *p++);)

Bart Schaefer                             Brass Lantern Enterprises
http://www.well.com/user/barts            http://www.nbn.com/people/lantern

Messages sorted by: Reverse Date, Date, Thread, Author