diff options
| author | David Kastrup | 2004-06-20 22:29:47 +0000 |
|---|---|---|
| committer | David Kastrup | 2004-06-20 22:29:47 +0000 |
| commit | acd81db980f183af036638b0aac9d3ecfaf3ca15 (patch) | |
| tree | d15454e9d8f287b432e2e0ed7ec28472b4fd286c | |
| parent | e47ac72737173f4738137f3dbff885426cf74582 (diff) | |
| download | emacs-acd81db980f183af036638b0aac9d3ecfaf3ca15.tar.gz emacs-acd81db980f183af036638b0aac9d3ecfaf3ca15.zip | |
(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.
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/minibuf.c | 78 |
2 files changed, 58 insertions, 28 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2c1db9730f0..f30631f83ef 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2004-06-21 David Kastrup <dak@gnu.org> | ||
| 2 | |||
| 3 | * minibuf.c (Ftry_completion, Fall_completions): Do lazy binding | ||
| 4 | and unbinding of `case-fold-search' according to | ||
| 5 | `completion-ignore-case' around calls of string-match and | ||
| 6 | predicates, respectively. Should give satisfactory performance | ||
| 7 | in all relevant cases. | ||
| 8 | |||
| 1 | 2004-06-17 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | 9 | 2004-06-17 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> |
| 2 | 10 | ||
| 3 | * xterm.c (x_draw_image_foreground_1): Subtract slice.x/y from | 11 | * xterm.c (x_draw_image_foreground_1): Subtract slice.x/y from |
diff --git a/src/minibuf.c b/src/minibuf.c index ee37142a4a6..dd7bb42263b 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -1207,6 +1207,7 @@ is used to further constrain the set of candidates. */) | |||
| 1207 | || NILP (XCAR (alist)))); | 1207 | || NILP (XCAR (alist)))); |
| 1208 | int index = 0, obsize = 0; | 1208 | int index = 0, obsize = 0; |
| 1209 | int matchcount = 0; | 1209 | int matchcount = 0; |
| 1210 | int bindcount = -1; | ||
| 1210 | Lisp_Object bucket, zero, end, tem; | 1211 | Lisp_Object bucket, zero, end, tem; |
| 1211 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 1212 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 1212 | 1213 | ||
| @@ -1285,21 +1286,22 @@ is used to further constrain the set of candidates. */) | |||
| 1285 | XSETFASTINT (zero, 0); | 1286 | XSETFASTINT (zero, 0); |
| 1286 | 1287 | ||
| 1287 | /* Ignore this element if it fails to match all the regexps. */ | 1288 | /* Ignore this element if it fails to match all the regexps. */ |
| 1288 | if (CONSP (Vcompletion_regexp_list)) | 1289 | { |
| 1289 | { | 1290 | for (regexps = Vcompletion_regexp_list; CONSP (regexps); |
| 1290 | int count = SPECPDL_INDEX (); | 1291 | regexps = XCDR (regexps)) |
| 1291 | specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil); | 1292 | { |
| 1292 | for (regexps = Vcompletion_regexp_list; CONSP (regexps); | 1293 | if (bindcount < 0) { |
| 1293 | regexps = XCDR (regexps)) | 1294 | bindcount = SPECPDL_INDEX (); |
| 1294 | { | 1295 | specbind (Qcase_fold_search, |
| 1295 | tem = Fstring_match (XCAR (regexps), eltstring, zero); | 1296 | completion_ignore_case ? Qt : Qnil); |
| 1296 | if (NILP (tem)) | ||
| 1297 | break; | ||
| 1298 | } | 1297 | } |
| 1299 | unbind_to (count, Qnil); | 1298 | tem = Fstring_match (XCAR (regexps), eltstring, zero); |
| 1300 | if (CONSP (regexps)) | 1299 | if (NILP (tem)) |
| 1301 | continue; | 1300 | break; |
| 1302 | } | 1301 | } |
| 1302 | if (CONSP (regexps)) | ||
| 1303 | continue; | ||
| 1304 | } | ||
| 1303 | 1305 | ||
| 1304 | /* Ignore this element if there is a predicate | 1306 | /* Ignore this element if there is a predicate |
| 1305 | and the predicate doesn't like it. */ | 1307 | and the predicate doesn't like it. */ |
| @@ -1310,6 +1312,10 @@ is used to further constrain the set of candidates. */) | |||
| 1310 | tem = Fcommandp (elt, Qnil); | 1312 | tem = Fcommandp (elt, Qnil); |
| 1311 | else | 1313 | else |
| 1312 | { | 1314 | { |
| 1315 | if (bindcount >= 0) { | ||
| 1316 | unbind_to (bindcount, Qnil); | ||
| 1317 | bindcount = -1; | ||
| 1318 | } | ||
| 1313 | GCPRO4 (tail, string, eltstring, bestmatch); | 1319 | GCPRO4 (tail, string, eltstring, bestmatch); |
| 1314 | tem = type == 3 | 1320 | tem = type == 3 |
| 1315 | ? call2 (predicate, elt, | 1321 | ? call2 (predicate, elt, |
| @@ -1391,6 +1397,11 @@ is used to further constrain the set of candidates. */) | |||
| 1391 | } | 1397 | } |
| 1392 | } | 1398 | } |
| 1393 | 1399 | ||
| 1400 | if (bindcount >= 0) { | ||
| 1401 | unbind_to (bindcount, Qnil); | ||
| 1402 | bindcount = -1; | ||
| 1403 | } | ||
| 1404 | |||
| 1394 | if (NILP (bestmatch)) | 1405 | if (NILP (bestmatch)) |
| 1395 | return Qnil; /* No completions found */ | 1406 | return Qnil; /* No completions found */ |
| 1396 | /* If we are ignoring case, and there is no exact match, | 1407 | /* If we are ignoring case, and there is no exact match, |
| @@ -1453,6 +1464,7 @@ are ignored unless STRING itself starts with a space. */) | |||
| 1453 | && (!SYMBOLP (XCAR (alist)) | 1464 | && (!SYMBOLP (XCAR (alist)) |
| 1454 | || NILP (XCAR (alist)))); | 1465 | || NILP (XCAR (alist)))); |
| 1455 | int index = 0, obsize = 0; | 1466 | int index = 0, obsize = 0; |
| 1467 | int bindcount = -1; | ||
| 1456 | Lisp_Object bucket, tem; | 1468 | Lisp_Object bucket, tem; |
| 1457 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 1469 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 1458 | 1470 | ||
| @@ -1537,21 +1549,22 @@ are ignored unless STRING itself starts with a space. */) | |||
| 1537 | XSETFASTINT (zero, 0); | 1549 | XSETFASTINT (zero, 0); |
| 1538 | 1550 | ||
| 1539 | /* Ignore this element if it fails to match all the regexps. */ | 1551 | /* Ignore this element if it fails to match all the regexps. */ |
| 1540 | if (CONSP (Vcompletion_regexp_list)) | 1552 | { |
| 1541 | { | 1553 | for (regexps = Vcompletion_regexp_list; CONSP (regexps); |
| 1542 | int count = SPECPDL_INDEX (); | 1554 | regexps = XCDR (regexps)) |
| 1543 | specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil); | 1555 | { |
| 1544 | for (regexps = Vcompletion_regexp_list; CONSP (regexps); | 1556 | if (bindcount < 0) { |
| 1545 | regexps = XCDR (regexps)) | 1557 | bindcount = SPECPDL_INDEX (); |
| 1546 | { | 1558 | specbind (Qcase_fold_search, |
| 1547 | tem = Fstring_match (XCAR (regexps), eltstring, zero); | 1559 | completion_ignore_case ? Qt : Qnil); |
| 1548 | if (NILP (tem)) | ||
| 1549 | break; | ||
| 1550 | } | 1560 | } |
| 1551 | unbind_to (count, Qnil); | 1561 | tem = Fstring_match (XCAR (regexps), eltstring, zero); |
| 1552 | if (CONSP (regexps)) | 1562 | if (NILP (tem)) |
| 1553 | continue; | 1563 | break; |
| 1554 | } | 1564 | } |
| 1565 | if (CONSP (regexps)) | ||
| 1566 | continue; | ||
| 1567 | } | ||
| 1555 | 1568 | ||
| 1556 | /* Ignore this element if there is a predicate | 1569 | /* Ignore this element if there is a predicate |
| 1557 | and the predicate doesn't like it. */ | 1570 | and the predicate doesn't like it. */ |
| @@ -1562,6 +1575,10 @@ are ignored unless STRING itself starts with a space. */) | |||
| 1562 | tem = Fcommandp (elt, Qnil); | 1575 | tem = Fcommandp (elt, Qnil); |
| 1563 | else | 1576 | else |
| 1564 | { | 1577 | { |
| 1578 | if (bindcount >= 0) { | ||
| 1579 | unbind_to (bindcount, Qnil); | ||
| 1580 | bindcount = -1; | ||
| 1581 | } | ||
| 1565 | GCPRO4 (tail, eltstring, allmatches, string); | 1582 | GCPRO4 (tail, eltstring, allmatches, string); |
| 1566 | tem = type == 3 | 1583 | tem = type == 3 |
| 1567 | ? call2 (predicate, elt, | 1584 | ? call2 (predicate, elt, |
| @@ -1576,6 +1593,11 @@ are ignored unless STRING itself starts with a space. */) | |||
| 1576 | } | 1593 | } |
| 1577 | } | 1594 | } |
| 1578 | 1595 | ||
| 1596 | if (bindcount >= 0) { | ||
| 1597 | unbind_to (bindcount, Qnil); | ||
| 1598 | bindcount = -1; | ||
| 1599 | } | ||
| 1600 | |||
| 1579 | return Fnreverse (allmatches); | 1601 | return Fnreverse (allmatches); |
| 1580 | } | 1602 | } |
| 1581 | 1603 | ||