# HG changeset patch # User David Kastrup # Date 1087770587 0 # Node ID ce63b548f4909178a78eaa8c80de0d329b9b0c4d # Parent f3b5bc2908b30ff253c1ef1ff592315b2279263b (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. diff -r f3b5bc2908b3 -r ce63b548f490 src/ChangeLog --- 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 + + * 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 * xterm.c (x_draw_image_foreground_1): Subtract slice.x/y from diff -r f3b5bc2908b3 -r ce63b548f490 src/minibuf.c --- 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); }