changeset 56167:ce63b548f490

(Ftry_completion, Fall_completions): Do lazy binding and unbinding of `case-fold-search' according to `completion-ignore-case' around calls of string-match and predicates, respectively. Should give satisfactory performance in all relevant cases.
author David Kastrup <dak@gnu.org>
date Sun, 20 Jun 2004 22:29:47 +0000
parents f3b5bc2908b3
children 432785020c95
files src/ChangeLog src/minibuf.c
diffstat 2 files changed, 58 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sun Jun 20 21:50:53 2004 +0000
+++ b/src/ChangeLog	Sun Jun 20 22:29:47 2004 +0000
@@ -1,3 +1,11 @@
+2004-06-21  David Kastrup  <dak@gnu.org>
+
+	* minibuf.c (Ftry_completion, Fall_completions): Do lazy binding
+	and unbinding of `case-fold-search' according to
+	`completion-ignore-case' around calls of string-match and
+	predicates, respectively.  Should give satisfactory performance
+	in all relevant cases.
+
 2004-06-17  Jan Dj,Ad(Brv  <jan.h.d@swipnet.se>
 
 	* xterm.c (x_draw_image_foreground_1): Subtract slice.x/y from
--- a/src/minibuf.c	Sun Jun 20 21:50:53 2004 +0000
+++ b/src/minibuf.c	Sun Jun 20 22:29:47 2004 +0000
@@ -1207,6 +1207,7 @@
 			   || NILP (XCAR (alist))));
   int index = 0, obsize = 0;
   int matchcount = 0;
+  int bindcount = -1;
   Lisp_Object bucket, zero, end, tem;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
 
@@ -1285,21 +1286,22 @@
 	  XSETFASTINT (zero, 0);
 
 	  /* Ignore this element if it fails to match all the regexps.  */
-	  if (CONSP (Vcompletion_regexp_list))
-	    {
-	      int count = SPECPDL_INDEX ();
-	      specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil);
-	      for (regexps = Vcompletion_regexp_list; CONSP (regexps);
-		   regexps = XCDR (regexps))
-		{
-		  tem = Fstring_match (XCAR (regexps), eltstring, zero);
-		  if (NILP (tem))
-		    break;
+	  {
+	    for (regexps = Vcompletion_regexp_list; CONSP (regexps);
+		 regexps = XCDR (regexps))
+	      {
+		if (bindcount < 0) {
+		  bindcount = SPECPDL_INDEX ();
+		  specbind (Qcase_fold_search,
+			    completion_ignore_case ? Qt : Qnil);
 		}
-	      unbind_to (count, Qnil);
-	      if (CONSP (regexps))
-		continue;
-	    }
+		tem = Fstring_match (XCAR (regexps), eltstring, zero);
+		if (NILP (tem))
+		  break;
+	      }
+	    if (CONSP (regexps))
+	      continue;
+	  }
 
 	  /* Ignore this element if there is a predicate
 	     and the predicate doesn't like it. */
@@ -1310,6 +1312,10 @@
 		tem = Fcommandp (elt, Qnil);
 	      else
 		{
+		  if (bindcount >= 0) {
+		    unbind_to (bindcount, Qnil);
+		    bindcount = -1;
+		  }
 		  GCPRO4 (tail, string, eltstring, bestmatch);
 		  tem = type == 3
 		    ? call2 (predicate, elt,
@@ -1391,6 +1397,11 @@
 	}
     }
 
+  if (bindcount >= 0) {
+    unbind_to (bindcount, Qnil);
+    bindcount = -1;
+  }
+
   if (NILP (bestmatch))
     return Qnil;		/* No completions found */
   /* If we are ignoring case, and there is no exact match,
@@ -1453,6 +1464,7 @@
 		       && (!SYMBOLP (XCAR (alist))
 			   || NILP (XCAR (alist))));
   int index = 0, obsize = 0;
+  int bindcount = -1;
   Lisp_Object bucket, tem;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
 
@@ -1537,21 +1549,22 @@
 	  XSETFASTINT (zero, 0);
 
 	  /* Ignore this element if it fails to match all the regexps.  */
-	  if (CONSP (Vcompletion_regexp_list))
-	    {
-	      int count = SPECPDL_INDEX ();
-	      specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil);
-	      for (regexps = Vcompletion_regexp_list; CONSP (regexps);
-		   regexps = XCDR (regexps))
-		{
-		  tem = Fstring_match (XCAR (regexps), eltstring, zero);
-		  if (NILP (tem))
-		    break;
+	  {
+	    for (regexps = Vcompletion_regexp_list; CONSP (regexps);
+		 regexps = XCDR (regexps))
+	      {
+		if (bindcount < 0) {
+		  bindcount = SPECPDL_INDEX ();
+		  specbind (Qcase_fold_search,
+			    completion_ignore_case ? Qt : Qnil);
 		}
-	      unbind_to (count, Qnil);
-	      if (CONSP (regexps))
-		continue;
-	    }
+		tem = Fstring_match (XCAR (regexps), eltstring, zero);
+		if (NILP (tem))
+		  break;
+	      }
+	    if (CONSP (regexps))
+	      continue;
+	  }
 
 	  /* Ignore this element if there is a predicate
 	     and the predicate doesn't like it. */
@@ -1562,6 +1575,10 @@
 		tem = Fcommandp (elt, Qnil);
 	      else
 		{
+		  if (bindcount >= 0) {
+		    unbind_to (bindcount, Qnil);
+		    bindcount = -1;
+		  }
 		  GCPRO4 (tail, eltstring, allmatches, string);
 		  tem = type == 3
 		    ? call2 (predicate, elt,
@@ -1576,6 +1593,11 @@
 	}
     }
 
+  if (bindcount >= 0) {
+    unbind_to (bindcount, Qnil);
+    bindcount = -1;
+  }
+
   return Fnreverse (allmatches);
 }