Mercurial > vim
comparison src/search.c @ 16533:5e25171e0e75 v8.1.1270
patch 8.1.1270: cannot see current match position
commit https://github.com/vim/vim/commit/9dfa3139198b38b28673e251a3756430065914e9
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat May 4 21:08:40 2019 +0200
patch 8.1.1270: cannot see current match position
Problem: Cannot see current match position.
Solution: Show "3/44" when using the "n" command and "S" is not in
'shortmess'. (Christian Brabandt, closes #4317)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 04 May 2019 21:15:05 +0200 |
parents | 5df26b29e809 |
children | be24441bf806 |
comparison
equal
deleted
inserted
replaced
16532:582612b67818 | 16533:5e25171e0e75 |
---|---|
24 int, int, FILE *, linenr_T *, long); | 24 int, int, FILE *, linenr_T *, long); |
25 #endif | 25 #endif |
26 #ifdef FEAT_VIMINFO | 26 #ifdef FEAT_VIMINFO |
27 static void wvsp_one(FILE *fp, int idx, char *s, int sc); | 27 static void wvsp_one(FILE *fp, int idx, char *s, int sc); |
28 #endif | 28 #endif |
29 static void search_stat(int dirc, pos_T *pos, char_u *msgbuf); | |
29 | 30 |
30 /* | 31 /* |
31 * This file contains various searching-related routines. These fall into | 32 * This file contains various searching-related routines. These fall into |
32 * three groups: | 33 * three groups: |
33 * 1. string searches (for /, ?, n, and N) | 34 * 1. string searches (for /, ?, n, and N) |
1214 char_u *p; | 1215 char_u *p; |
1215 long c; | 1216 long c; |
1216 char_u *dircp; | 1217 char_u *dircp; |
1217 char_u *strcopy = NULL; | 1218 char_u *strcopy = NULL; |
1218 char_u *ps; | 1219 char_u *ps; |
1220 char_u *msgbuf = NULL; | |
1221 size_t len; | |
1219 | 1222 |
1220 /* | 1223 /* |
1221 * A line offset is not remembered, this is vi compatible. | 1224 * A line offset is not remembered, this is vi compatible. |
1222 */ | 1225 */ |
1223 if (spats[0].off.line && vim_strchr(p_cpo, CPO_LINEOFF) != NULL) | 1226 if (spats[0].off.line && vim_strchr(p_cpo, CPO_LINEOFF) != NULL) |
1372 } | 1375 } |
1373 | 1376 |
1374 if ((options & SEARCH_ECHO) && messaging() | 1377 if ((options & SEARCH_ECHO) && messaging() |
1375 && !cmd_silent && msg_silent == 0) | 1378 && !cmd_silent && msg_silent == 0) |
1376 { | 1379 { |
1377 char_u *msgbuf; | |
1378 char_u *trunc; | 1380 char_u *trunc; |
1381 | |
1382 // Compute msg_row early. | |
1383 msg_start(); | |
1379 | 1384 |
1380 if (*searchstr == NUL) | 1385 if (*searchstr == NUL) |
1381 p = spats[0].pat; | 1386 p = spats[0].pat; |
1382 else | 1387 else |
1383 p = searchstr; | 1388 p = searchstr; |
1384 msgbuf = alloc((unsigned)(STRLEN(p) + 40)); | 1389 |
1390 if (!shortmess(SHM_SEARCHCOUNT)) | |
1391 { | |
1392 // Reserve enough space for the search pattern + offset + | |
1393 // search stat. | |
1394 if (msg_scrolled != 0) | |
1395 // Use all the columns. | |
1396 len = (int)(Rows - msg_row) * Columns - 1; | |
1397 else | |
1398 // Use up to 'showcmd' column. | |
1399 len = (int)(Rows - msg_row - 1) * Columns + sc_col - 1; | |
1400 if (len < STRLEN(p) + 40 + 11) | |
1401 len = STRLEN(p) + 40 + 11; | |
1402 } | |
1403 else | |
1404 // Reserve enough space for the search pattern + offset. | |
1405 len = STRLEN(p) + 40; | |
1406 | |
1407 msgbuf = alloc((int)len); | |
1385 if (msgbuf != NULL) | 1408 if (msgbuf != NULL) |
1386 { | 1409 { |
1410 vim_memset(msgbuf, ' ', len); | |
1387 msgbuf[0] = dirc; | 1411 msgbuf[0] = dirc; |
1412 msgbuf[len - 1] = NUL; | |
1413 | |
1388 if (enc_utf8 && utf_iscomposing(utf_ptr2char(p))) | 1414 if (enc_utf8 && utf_iscomposing(utf_ptr2char(p))) |
1389 { | 1415 { |
1390 /* Use a space to draw the composing char on. */ | 1416 // Use a space to draw the composing char on. |
1391 msgbuf[1] = ' '; | 1417 msgbuf[1] = ' '; |
1392 STRCPY(msgbuf + 2, p); | 1418 STRNCPY(msgbuf + 2, p, STRLEN(p)); |
1393 } | 1419 } |
1394 else | 1420 else |
1395 STRCPY(msgbuf + 1, p); | 1421 STRNCPY(msgbuf + 1, p, STRLEN(p)); |
1396 if (spats[0].off.line || spats[0].off.end || spats[0].off.off) | 1422 if (spats[0].off.line || spats[0].off.end || spats[0].off.off) |
1397 { | 1423 { |
1398 p = msgbuf + STRLEN(msgbuf); | 1424 p = msgbuf + STRLEN(p) + 1; |
1399 *p++ = dirc; | 1425 *p++ = dirc; |
1400 if (spats[0].off.end) | 1426 if (spats[0].off.end) |
1401 *p++ = 'e'; | 1427 *p++ = 'e'; |
1402 else if (!spats[0].off.line) | 1428 else if (!spats[0].off.line) |
1403 *p++ = 's'; | 1429 *p++ = 's'; |
1404 if (spats[0].off.off > 0 || spats[0].off.line) | 1430 if (spats[0].off.off > 0 || spats[0].off.line) |
1405 *p++ = '+'; | 1431 *p++ = '+'; |
1406 if (spats[0].off.off != 0 || spats[0].off.line) | 1432 if (spats[0].off.off != 0 || spats[0].off.line) |
1407 sprintf((char *)p, "%ld", spats[0].off.off); | 1433 { |
1408 else | 1434 int l = 0; |
1409 *p = NUL; | 1435 l = sprintf((char *)p, "%ld", spats[0].off.off); |
1436 p[l] = ' '; // remove NUL from sprintf | |
1437 } | |
1410 } | 1438 } |
1411 | 1439 |
1412 msg_start(); | |
1413 trunc = msg_strtrunc(msgbuf, FALSE); | 1440 trunc = msg_strtrunc(msgbuf, FALSE); |
1441 if (trunc != NULL) | |
1442 { | |
1443 vim_free(msgbuf); | |
1444 msgbuf = trunc; | |
1445 } | |
1414 | 1446 |
1415 #ifdef FEAT_RIGHTLEFT | 1447 #ifdef FEAT_RIGHTLEFT |
1416 /* The search pattern could be shown on the right in rightleft | 1448 // The search pattern could be shown on the right in rightleft |
1417 * mode, but the 'ruler' and 'showcmd' area use it too, thus | 1449 // mode, but the 'ruler' and 'showcmd' area use it too, thus |
1418 * it would be blanked out again very soon. Show it on the | 1450 // it would be blanked out again very soon. Show it on the |
1419 * left, but do reverse the text. */ | 1451 // left, but do reverse the text. |
1420 if (curwin->w_p_rl && *curwin->w_p_rlc == 's') | 1452 if (curwin->w_p_rl && *curwin->w_p_rlc == 's') |
1421 { | 1453 { |
1422 char_u *r; | 1454 char_u *r; |
1423 | 1455 |
1424 r = reverse_text(trunc != NULL ? trunc : msgbuf); | 1456 r = reverse_text(msgbuf); |
1425 if (r != NULL) | 1457 if (r != NULL) |
1426 { | 1458 { |
1427 vim_free(trunc); | 1459 vim_free(msgbuf); |
1428 trunc = r; | 1460 msgbuf = r; |
1461 // move reversed text to beginning of buffer | |
1462 while (*r != NUL && *r == ' ') | |
1463 r++; | |
1464 mch_memmove(msgbuf, r, msgbuf + STRLEN(msgbuf) - r); | |
1465 // overwrite old text | |
1466 vim_memset(r, ' ', msgbuf + STRLEN(msgbuf) - r); | |
1429 } | 1467 } |
1430 } | 1468 } |
1431 #endif | 1469 #endif |
1432 if (trunc != NULL) | 1470 msg_outtrans(msgbuf); |
1433 { | |
1434 msg_outtrans(trunc); | |
1435 vim_free(trunc); | |
1436 } | |
1437 else | |
1438 msg_outtrans(msgbuf); | |
1439 msg_clr_eos(); | 1471 msg_clr_eos(); |
1440 msg_check(); | 1472 msg_check(); |
1441 vim_free(msgbuf); | |
1442 | 1473 |
1443 gotocmdline(FALSE); | 1474 gotocmdline(FALSE); |
1444 out_flush(); | 1475 out_flush(); |
1445 msg_nowait = TRUE; /* don't wait for this message */ | 1476 msg_nowait = TRUE; // don't wait for this message |
1446 } | 1477 } |
1447 } | 1478 } |
1448 | 1479 |
1449 /* | 1480 /* |
1450 * If there is a character offset, subtract it from the current | 1481 * If there is a character offset, subtract it from the current |
1486 + SEARCH_MSG + SEARCH_START | 1517 + SEARCH_MSG + SEARCH_START |
1487 + ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))), | 1518 + ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))), |
1488 RE_LAST, (linenr_T)0, tm, timed_out); | 1519 RE_LAST, (linenr_T)0, tm, timed_out); |
1489 | 1520 |
1490 if (dircp != NULL) | 1521 if (dircp != NULL) |
1491 *dircp = dirc; /* restore second '/' or '?' for normal_cmd() */ | 1522 *dircp = dirc; // restore second '/' or '?' for normal_cmd() |
1523 | |
1524 if (!shortmess(SHM_SEARCH) | |
1525 && ((dirc == '/' && LT_POS(pos, curwin->w_cursor)) | |
1526 || (dirc == '?' && LT_POS(curwin->w_cursor, pos)))) | |
1527 ui_delay(500L, FALSE); // leave some time for top_bot_msg | |
1528 | |
1492 if (c == FAIL) | 1529 if (c == FAIL) |
1493 { | 1530 { |
1494 retval = 0; | 1531 retval = 0; |
1495 goto end_do_search; | 1532 goto end_do_search; |
1496 } | 1533 } |
1535 break; | 1572 break; |
1536 } | 1573 } |
1537 } | 1574 } |
1538 } | 1575 } |
1539 | 1576 |
1577 // Show [1/15] if 'S' is not in 'shortmess'. | |
1578 if ((options & SEARCH_ECHO) | |
1579 && messaging() | |
1580 && !(cmd_silent + msg_silent) | |
1581 && c != FAIL | |
1582 && !shortmess(SHM_SEARCHCOUNT) | |
1583 && msgbuf != NULL) | |
1584 search_stat(dirc, &pos, msgbuf); | |
1585 | |
1540 /* | 1586 /* |
1541 * The search command can be followed by a ';' to do another search. | 1587 * The search command can be followed by a ';' to do another search. |
1542 * For example: "/pat/;/foo/+3;?bar" | 1588 * For example: "/pat/;/foo/+3;?bar" |
1543 * This is like doing another search command, except: | 1589 * This is like doing another search command, except: |
1544 * - The remembered direction '/' or '?' is from the first search. | 1590 * - The remembered direction '/' or '?' is from the first search. |
1565 | 1611 |
1566 end_do_search: | 1612 end_do_search: |
1567 if ((options & SEARCH_KEEP) || cmdmod.keeppatterns) | 1613 if ((options & SEARCH_KEEP) || cmdmod.keeppatterns) |
1568 spats[0].off = old_off; | 1614 spats[0].off = old_off; |
1569 vim_free(strcopy); | 1615 vim_free(strcopy); |
1616 vim_free(msgbuf); | |
1570 | 1617 |
1571 return retval; | 1618 return retval; |
1572 } | 1619 } |
1573 | 1620 |
1574 #if defined(FEAT_INS_EXPAND) || defined(PROTO) | 1621 #if defined(FEAT_INS_EXPAND) || defined(PROTO) |
4854 | 4901 |
4855 p = skipwhite(ml_get(lnum)); | 4902 p = skipwhite(ml_get(lnum)); |
4856 return (*p == NUL); | 4903 return (*p == NUL); |
4857 } | 4904 } |
4858 #endif | 4905 #endif |
4906 | |
4907 /* | |
4908 * Add the search count "[3/19]" to "msgbuf". | |
4909 */ | |
4910 static void | |
4911 search_stat( | |
4912 int dirc, | |
4913 pos_T *pos, | |
4914 char_u *msgbuf) | |
4915 { | |
4916 int save_ws = p_ws; | |
4917 int wraparound = FALSE; | |
4918 pos_T p = (*pos); | |
4919 static pos_T lastpos = {0, 0, 0}; | |
4920 static int cur = 0; | |
4921 static int cnt = 0; | |
4922 static int chgtick = 0; | |
4923 static char_u *lastpat = NULL; | |
4924 static buf_T *lbuf = NULL; | |
4925 #ifdef FEAT_RELTIME | |
4926 proftime_T start; | |
4927 #endif | |
4928 #define OUT_OF_TIME 999 | |
4929 | |
4930 wraparound = ((dirc == '?' && LT_POS(lastpos, p)) | |
4931 || (dirc == '/' && LT_POS(p, lastpos))); | |
4932 | |
4933 // If anything relevant changed the count has to be recomputed. | |
4934 // MB_STRNICMP ignores case, but we should not ignore case. | |
4935 // Unfortunately, there is no MB_STRNICMP function. | |
4936 if (!(chgtick == CHANGEDTICK(curbuf) | |
4937 && MB_STRNICMP(lastpat, spats[last_idx].pat, STRLEN(lastpat)) == 0 | |
4938 && STRLEN(lastpat) == STRLEN(spats[last_idx].pat) | |
4939 && EQUAL_POS(lastpos, curwin->w_cursor) | |
4940 && lbuf == curbuf) || wraparound || cur < 0 || cur > 99) | |
4941 { | |
4942 cur = 0; | |
4943 cnt = 0; | |
4944 CLEAR_POS(&lastpos); | |
4945 lbuf = curbuf; | |
4946 } | |
4947 | |
4948 if (EQUAL_POS(lastpos, curwin->w_cursor) && !wraparound | |
4949 && (dirc == '/' ? cur < cnt : cur > 0)) | |
4950 cur += dirc == '/' ? 1 : -1; | |
4951 else | |
4952 { | |
4953 p_ws = FALSE; | |
4954 #ifdef FEAT_RELTIME | |
4955 profile_setlimit(20L, &start); | |
4956 #endif | |
4957 while (!got_int && searchit(curwin, curbuf, &lastpos, NULL, | |
4958 FORWARD, NULL, 1, SEARCH_PEEK + SEARCH_KEEP, | |
4959 RE_LAST, (linenr_T)0, NULL, NULL) != FAIL) | |
4960 { | |
4961 #ifdef FEAT_RELTIME | |
4962 // Stop after passing the time limit. | |
4963 if (profile_passed_limit(&start)) | |
4964 { | |
4965 cnt = OUT_OF_TIME; | |
4966 cur = OUT_OF_TIME; | |
4967 break; | |
4968 } | |
4969 #endif | |
4970 cnt++; | |
4971 if (LTOREQ_POS(lastpos, p)) | |
4972 cur++; | |
4973 fast_breakcheck(); | |
4974 if (cnt > 99) | |
4975 break; | |
4976 } | |
4977 if (got_int) | |
4978 cur = -1; // abort | |
4979 } | |
4980 if (cur > 0) | |
4981 { | |
4982 #define STAT_BUF_LEN 10 | |
4983 char t[STAT_BUF_LEN] = ""; | |
4984 | |
4985 #ifdef FEAT_RIGHTLEFT | |
4986 if (curwin->w_p_rl && *curwin->w_p_rlc == 's') | |
4987 { | |
4988 if (cur == OUT_OF_TIME) | |
4989 vim_snprintf(t, STAT_BUF_LEN, "[?/??]"); | |
4990 else if (cnt > 99 && cur > 99) | |
4991 vim_snprintf(t, STAT_BUF_LEN, "[>99/>99]"); | |
4992 else if (cnt > 99) | |
4993 vim_snprintf(t, STAT_BUF_LEN, "[>99/%d]", cur); | |
4994 else | |
4995 vim_snprintf(t, STAT_BUF_LEN, "[%d/%d]", cnt, cur); | |
4996 } | |
4997 else | |
4998 #endif | |
4999 { | |
5000 if (cur == OUT_OF_TIME) | |
5001 vim_snprintf(t, STAT_BUF_LEN, "[?/??]"); | |
5002 else if (cnt > 99 && cur > 99) | |
5003 vim_snprintf(t, STAT_BUF_LEN, "[>99/>99]"); | |
5004 else if (cnt > 99) | |
5005 vim_snprintf(t, STAT_BUF_LEN, "[%d/>99]", cur); | |
5006 else | |
5007 vim_snprintf(t, STAT_BUF_LEN, "[%d/%d]", cur, cnt); | |
5008 } | |
5009 STRNCPY(msgbuf + STRLEN(msgbuf) - STRLEN(t), t, STRLEN(t)); | |
5010 if (dirc == '?' && cur == 100) | |
5011 cur = -1; | |
5012 | |
5013 vim_free(lastpat); | |
5014 lastpat = vim_strsave(spats[last_idx].pat); | |
5015 chgtick = CHANGEDTICK(curbuf); | |
5016 lbuf = curbuf; | |
5017 lastpos = p; | |
5018 | |
5019 // keep the message even after redraw | |
5020 give_warning(msgbuf, FALSE); | |
5021 } | |
5022 p_ws = save_ws; | |
5023 } | |
4859 | 5024 |
4860 #if defined(FEAT_FIND_ID) || defined(PROTO) | 5025 #if defined(FEAT_FIND_ID) || defined(PROTO) |
4861 /* | 5026 /* |
4862 * Find identifiers or defines in included files. | 5027 * Find identifiers or defines in included files. |
4863 * If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase. | 5028 * If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase. |