comparison src/search.c @ 6991:814f1f569e4a v7.4.813

patch 7.4.813 Problem: It is not possible to save and restore character search state. Solution: Add getcharsearch() and setcharsearch(). (James McCoy)
author Bram Moolenaar <bram@vim.org>
date Tue, 11 Aug 2015 14:26:19 +0200
parents e859731ea1cd
children db0328a2fa2a
comparison
equal deleted inserted replaced
6990:9c248be4e7d2 6991:814f1f569e4a
86 {NULL, TRUE, FALSE, {'/', 0, 0, 0L}}, /* last used search pat */ 86 {NULL, TRUE, FALSE, {'/', 0, 0, 0L}}, /* last used search pat */
87 {NULL, TRUE, FALSE, {'/', 0, 0, 0L}} /* last used substitute pat */ 87 {NULL, TRUE, FALSE, {'/', 0, 0, 0L}} /* last used substitute pat */
88 }; 88 };
89 89
90 static int last_idx = 0; /* index in spats[] for RE_LAST */ 90 static int last_idx = 0; /* index in spats[] for RE_LAST */
91
92 static char_u lastc[2] = {NUL, NUL}; /* last character searched for */
93 static int lastcdir = FORWARD; /* last direction of character search */
94 static int last_t_cmd = TRUE; /* last search t_cmd */
95 #ifdef FEAT_MBYTE
96 static char_u lastc_bytes[MB_MAXBYTES + 1];
97 static int lastc_bytelen = 1; /* >1 for multi-byte char */
98 #endif
91 99
92 #if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO) 100 #if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
93 /* copy of spats[], for keeping the search patterns while executing autocmds */ 101 /* copy of spats[], for keeping the search patterns while executing autocmds */
94 static struct spat saved_spats[2]; 102 static struct spat saved_spats[2];
95 static int saved_last_idx = 0; 103 static int saved_last_idx = 0;
376 384
377 return ic; 385 return ic;
378 } 386 }
379 387
380 /* 388 /*
381 * Return TRUE if patter "pat" has an uppercase character. 389 * Return TRUE if pattern "pat" has an uppercase character.
382 */ 390 */
383 int 391 int
384 pat_has_uppercase(pat) 392 pat_has_uppercase(pat)
385 char_u *pat; 393 char_u *pat;
386 { 394 {
414 return TRUE; 422 return TRUE;
415 else 423 else
416 ++p; 424 ++p;
417 } 425 }
418 return FALSE; 426 return FALSE;
427 }
428
429 char_u *
430 last_csearch()
431 {
432 #ifdef FEAT_MBYTE
433 return lastc_bytes;
434 #else
435 return lastc;
436 #endif
437 }
438
439 int
440 last_csearch_forward()
441 {
442 return lastcdir == FORWARD;
443 }
444
445 int
446 last_csearch_until()
447 {
448 return last_t_cmd == TRUE;
449 }
450
451 void
452 set_last_csearch(c, s, len)
453 int c;
454 char_u *s;
455 int len;
456 {
457 *lastc = c;
458 #ifdef FEAT_MBYTE
459 lastc_bytelen = len;
460 if (len)
461 memcpy(lastc_bytes, s, len);
462 else
463 vim_memset(lastc_bytes, 0, sizeof(lastc_bytes));
464 #endif
465 }
466
467 void
468 set_csearch_direction(cdir)
469 int cdir;
470 {
471 lastcdir = cdir;
472 }
473
474 void
475 set_csearch_until(t_cmd)
476 int t_cmd;
477 {
478 last_t_cmd = t_cmd;
419 } 479 }
420 480
421 char_u * 481 char_u *
422 last_search_pat() 482 last_search_pat()
423 { 483 {
1557 int t_cmd; 1617 int t_cmd;
1558 { 1618 {
1559 int c = cap->nchar; /* char to search for */ 1619 int c = cap->nchar; /* char to search for */
1560 int dir = cap->arg; /* TRUE for searching forward */ 1620 int dir = cap->arg; /* TRUE for searching forward */
1561 long count = cap->count1; /* repeat count */ 1621 long count = cap->count1; /* repeat count */
1562 static int lastc = NUL; /* last character searched for */
1563 static int lastcdir; /* last direction of character search */
1564 static int last_t_cmd; /* last search t_cmd */
1565 int col; 1622 int col;
1566 char_u *p; 1623 char_u *p;
1567 int len; 1624 int len;
1568 int stop = TRUE; 1625 int stop = TRUE;
1626
1627 if (c != NUL) /* normal search: remember args for repeat */
1628 {
1629 if (!KeyStuffed) /* don't remember when redoing */
1630 {
1631 *lastc = c;
1632 set_csearch_direction(dir);
1633 set_csearch_until(t_cmd);
1569 #ifdef FEAT_MBYTE 1634 #ifdef FEAT_MBYTE
1570 static char_u bytes[MB_MAXBYTES + 1]; 1635 lastc_bytelen = (*mb_char2bytes)(c, lastc_bytes);
1571 static int bytelen = 1; /* >1 for multi-byte char */
1572 #endif
1573
1574 if (c != NUL) /* normal search: remember args for repeat */
1575 {
1576 if (!KeyStuffed) /* don't remember when redoing */
1577 {
1578 lastc = c;
1579 lastcdir = dir;
1580 last_t_cmd = t_cmd;
1581 #ifdef FEAT_MBYTE
1582 bytelen = (*mb_char2bytes)(c, bytes);
1583 if (cap->ncharC1 != 0) 1636 if (cap->ncharC1 != 0)
1584 { 1637 {
1585 bytelen += (*mb_char2bytes)(cap->ncharC1, bytes + bytelen); 1638 lastc_bytelen += (*mb_char2bytes)(cap->ncharC1,
1639 lastc_bytes + lastc_bytelen);
1586 if (cap->ncharC2 != 0) 1640 if (cap->ncharC2 != 0)
1587 bytelen += (*mb_char2bytes)(cap->ncharC2, bytes + bytelen); 1641 lastc_bytelen += (*mb_char2bytes)(cap->ncharC2,
1642 lastc_bytes + lastc_bytelen);
1588 } 1643 }
1589 #endif 1644 #endif
1590 } 1645 }
1591 } 1646 }
1592 else /* repeat previous search */ 1647 else /* repeat previous search */
1593 { 1648 {
1594 if (lastc == NUL) 1649 if (*lastc == NUL)
1595 return FAIL; 1650 return FAIL;
1596 if (dir) /* repeat in opposite direction */ 1651 if (dir) /* repeat in opposite direction */
1597 dir = -lastcdir; 1652 dir = -lastcdir;
1598 else 1653 else
1599 dir = lastcdir; 1654 dir = lastcdir;
1600 t_cmd = last_t_cmd; 1655 t_cmd = last_t_cmd;
1601 c = lastc; 1656 c = *lastc;
1602 /* For multi-byte re-use last bytes[] and bytelen. */ 1657 /* For multi-byte re-use last lastc_bytes[] and lastc_bytelen. */
1603 1658
1604 /* Force a move of at least one char, so ";" and "," will move the 1659 /* Force a move of at least one char, so ";" and "," will move the
1605 * cursor, even if the cursor is right in front of char we are looking 1660 * cursor, even if the cursor is right in front of char we are looking
1606 * at. */ 1661 * at. */
1607 if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1 && t_cmd) 1662 if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1 && t_cmd)
1634 { 1689 {
1635 if (col == 0) 1690 if (col == 0)
1636 return FAIL; 1691 return FAIL;
1637 col -= (*mb_head_off)(p, p + col - 1) + 1; 1692 col -= (*mb_head_off)(p, p + col - 1) + 1;
1638 } 1693 }
1639 if (bytelen == 1) 1694 if (lastc_bytelen == 1)
1640 { 1695 {
1641 if (p[col] == c && stop) 1696 if (p[col] == c && stop)
1642 break; 1697 break;
1643 } 1698 }
1644 else 1699 else
1645 { 1700 {
1646 if (vim_memcmp(p + col, bytes, bytelen) == 0 && stop) 1701 if (vim_memcmp(p + col, lastc_bytes, lastc_bytelen) == 0 && stop)
1647 break; 1702 break;
1648 } 1703 }
1649 stop = TRUE; 1704 stop = TRUE;
1650 } 1705 }
1651 } 1706 }
1669 col -= dir; 1724 col -= dir;
1670 #ifdef FEAT_MBYTE 1725 #ifdef FEAT_MBYTE
1671 if (has_mbyte) 1726 if (has_mbyte)
1672 { 1727 {
1673 if (dir < 0) 1728 if (dir < 0)
1674 /* Landed on the search char which is bytelen long */ 1729 /* Landed on the search char which is lastc_bytelen long */
1675 col += bytelen - 1; 1730 col += lastc_bytelen - 1;
1676 else 1731 else
1677 /* To previous char, which may be multi-byte. */ 1732 /* To previous char, which may be multi-byte. */
1678 col -= (*mb_head_off)(p, p + col); 1733 col -= (*mb_head_off)(p, p + col);
1679 } 1734 }
1680 #endif 1735 #endif