Patch 8.1.1270

24 views
Skip to first unread message

Bram Moolenaar

unread,
May 4, 2019, 3:09:28 PM5/4/19
to vim...@googlegroups.com

Patch 8.1.1270
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)
Files: runtime/doc/options.txt, runtime/doc/pattern.txt, src/option.c,
src/option.h, src/search.c, src/testdir/Make_all.mak,
src/testdir/test_search_stat.vim


*** ../vim-8.1.1269/runtime/doc/options.txt 2019-04-28 18:04:56.054492198 +0200
--- runtime/doc/options.txt 2019-05-04 20:39:29.300113211 +0200
***************
*** 1789,1795 ****
'scrolloff' + 0 no scroll offset
'shelltemp' - {unchanged} {set vim default only on resetting 'cp'}
'shiftround' + off indent not rounded to shiftwidth
! 'shortmess' & "" no shortening of messages
'showcmd' & off command characters not shown
'showmode' & off current mode not shown
'sidescrolloff' + 0 cursor moves to edge of screen in scroll
--- 1789,1795 ----
'scrolloff' + 0 no scroll offset
'shelltemp' - {unchanged} {set vim default only on resetting 'cp'}
'shiftround' + off indent not rounded to shiftwidth
! 'shortmess' & "S" no shortening of messages
'showcmd' & off command characters not shown
'showmode' & off current mode not shown
'sidescrolloff' + 0 cursor moves to edge of screen in scroll
***************
*** 6563,6570 ****
function to get the effective shiftwidth value.

*'shortmess'* *'shm'*
! 'shortmess' 'shm' string (Vim default "filnxtToO", Vi default: "",
! POSIX default: "A")
global
This option helps to avoid all the |hit-enter| prompts caused by file
messages, for example with CTRL-G, and to avoid some other messages.
--- 6563,6570 ----
function to get the effective shiftwidth value.

*'shortmess'* *'shm'*
! 'shortmess' 'shm' string (Vim default "filnxtToOS", Vi default: "S",
! POSIX default: "AS")
global
This option helps to avoid all the |hit-enter| prompts caused by file
messages, for example with CTRL-G, and to avoid some other messages.
***************
*** 6604,6609 ****
--- 6604,6611 ----
q use "recording" instead of "recording @a"
F don't give the file info when editing a file, like `:silent`
was used for the command
+ S do not show search count message when searching, e.g.
+ "[1/5]"

This gives you the opportunity to avoid that a change between buffers
requires you to hit <Enter>, but still gives as useful a message as
*** ../vim-8.1.1269/runtime/doc/pattern.txt 2019-01-31 15:34:35.864056935 +0100
--- runtime/doc/pattern.txt 2019-05-04 20:40:26.891793904 +0200
***************
*** 152,157 ****
--- 152,168 ----
All matches for the last used search pattern will be highlighted if you set
the 'hlsearch' option. This can be suspended with the |:nohlsearch| command.

+ When 'shortmess' does not include the "S" flag, Vim will automatically show an
+ index, on which the cursor is. This can look like this: >
+
+ [1/5] Cursor is on first of 5 matches.
+ [1/>99] Cursor is on first of more than 99 matches.
+ [>99/>99] Cursor is after 99 match of more than 99 matches.
+ [?/??] Unknown how many matches exists, generating the
+ statistics was aborted because of search timeout.
+
+ Note: the count does not take offset into account.
+
When no match is found you get the error: *E486* Pattern not found
Note that for the |:global| command this behaves like a normal message, for Vi
compatibility. For the |:s| command the "e" flag can be used to avoid the
***************
*** 293,298 ****
--- 304,317 ----
the "*" is under your right hand middle finger (search to the right and down).
(this depends on your keyboard layout though).

+ *E956*
+ In very rare cases a regular expression is used recursively. This can happen
+ when executing a pattern takes a long time and when checking for messages on
+ channels a callback is invoked that also uses a pattern or an autocommand is
+ triggered. In most cases this should be fine, but if a pattern is in use when
+ it's used again it fails. Usually this means there is something wrong with
+ the pattern.
+
==============================================================================
2. The definition of a pattern *search-pattern* *pattern* *[pattern]*
*regular-expression* *regexp* *Pattern*
*** ../vim-8.1.1269/src/option.c 2019-04-28 19:46:17.034060084 +0200
--- src/option.c 2019-05-04 20:12:23.560448086 +0200
***************
*** 2449,2455 ****
{(char_u *)8L, (char_u *)0L} SCTX_INIT},
{"shortmess", "shm", P_STRING|P_VIM|P_FLAGLIST,
(char_u *)&p_shm, PV_NONE,
! {(char_u *)"", (char_u *)"filnxtToO"}
SCTX_INIT},
{"shortname", "sn", P_BOOL|P_VI_DEF,
(char_u *)&p_sn, PV_SN,
--- 2449,2455 ----
{(char_u *)8L, (char_u *)0L} SCTX_INIT},
{"shortmess", "shm", P_STRING|P_VIM|P_FLAGLIST,
(char_u *)&p_shm, PV_NONE,
! {(char_u *)"S", (char_u *)"filnxtToOS"}
SCTX_INIT},
{"shortname", "sn", P_BOOL|P_VI_DEF,
(char_u *)&p_sn, PV_SN,
***************
*** 3311,3317 ****
if (mch_getenv((char_u *)"VIM_POSIX") != NULL)
{
set_string_default("cpo", (char_u *)CPO_ALL);
! set_string_default("shm", (char_u *)"A");
}

/*
--- 3311,3317 ----
if (mch_getenv((char_u *)"VIM_POSIX") != NULL)
{
set_string_default("cpo", (char_u *)CPO_ALL);
! set_string_default("shm", (char_u *)SHM_POSIX);
}

/*
*** ../vim-8.1.1269/src/option.h 2019-04-28 18:04:56.058492178 +0200
--- src/option.h 2019-05-04 20:41:45.615356951 +0200
***************
*** 183,209 ****
#define COCU_ALL "nvic" /* flags for 'concealcursor' */

/* characters for p_shm option: */
! #define SHM_RO 'r' /* readonly */
! #define SHM_MOD 'm' /* modified */
! #define SHM_FILE 'f' /* (file 1 of 2) */
! #define SHM_LAST 'i' /* last line incomplete */
! #define SHM_TEXT 'x' /* tx instead of textmode */
! #define SHM_LINES 'l' /* "L" instead of "lines" */
! #define SHM_NEW 'n' /* "[New]" instead of "[New file]" */
! #define SHM_WRI 'w' /* "[w]" instead of "written" */
! #define SHM_A "rmfixlnw" /* represented by 'a' flag */
! #define SHM_WRITE 'W' /* don't use "written" at all */
! #define SHM_TRUNC 't' /* truncate file messages */
! #define SHM_TRUNCALL 'T' /* truncate all messages */
! #define SHM_OVER 'o' /* overwrite file messages */
! #define SHM_OVERALL 'O' /* overwrite more messages */
! #define SHM_SEARCH 's' /* no search hit bottom messages */
! #define SHM_ATTENTION 'A' /* no ATTENTION messages */
! #define SHM_INTRO 'I' /* intro messages */
! #define SHM_COMPLETIONMENU 'c' /* completion menu messages */
! #define SHM_RECORDING 'q' /* short recording message */
! #define SHM_FILEINFO 'F' /* no file info messages */
! #define SHM_ALL "rmfixlnwaWtToOsAIcqF" /* all possible flags for 'shm' */

/* characters for p_go: */
#define GO_TERMINAL '!' /* use terminal for system commands */
--- 183,211 ----
#define COCU_ALL "nvic" /* flags for 'concealcursor' */

/* characters for p_shm option: */
! #define SHM_RO 'r' // readonly
! #define SHM_MOD 'm' // modified
! #define SHM_FILE 'f' // (file 1 of 2)
! #define SHM_LAST 'i' // last line incomplete
! #define SHM_TEXT 'x' // tx instead of textmode
! #define SHM_LINES 'l' // "L" instead of "lines"
! #define SHM_NEW 'n' // "[New]" instead of "[New file]"
! #define SHM_WRI 'w' // "[w]" instead of "written"
! #define SHM_A "rmfixlnw" // represented by 'a' flag
! #define SHM_WRITE 'W' // don't use "written" at all
! #define SHM_TRUNC 't' // truncate file messages
! #define SHM_TRUNCALL 'T' // truncate all messages
! #define SHM_OVER 'o' // overwrite file messages
! #define SHM_OVERALL 'O' // overwrite more messages
! #define SHM_SEARCH 's' // no search hit bottom messages
! #define SHM_ATTENTION 'A' // no ATTENTION messages
! #define SHM_INTRO 'I' // intro messages
! #define SHM_COMPLETIONMENU 'c' // completion menu messages
! #define SHM_RECORDING 'q' // short recording message
! #define SHM_FILEINFO 'F' // no file info messages
! #define SHM_SEARCHCOUNT 'S' // search stats: '[1/10]'
! #define SHM_POSIX "AS" // POSIX value
! #define SHM_ALL "rmfixlnwaWtToOsAIcqFS" // all possible flags for 'shm'

/* characters for p_go: */
#define GO_TERMINAL '!' /* use terminal for system commands */
*** ../vim-8.1.1269/src/search.c 2019-04-06 14:22:17.754642647 +0200
--- src/search.c 2019-05-04 20:54:06.096065458 +0200
***************
*** 26,31 ****
--- 26,32 ----
#ifdef FEAT_VIMINFO
static void wvsp_one(FILE *fp, int idx, char *s, int sc);
#endif
+ static void search_stat(int dirc, pos_T *pos, char_u *msgbuf);

/*
* This file contains various searching-related routines. These fall into
***************
*** 1216,1221 ****
--- 1217,1224 ----
char_u *dircp;
char_u *strcopy = NULL;
char_u *ps;
+ char_u *msgbuf = NULL;
+ size_t len;

/*
* A line offset is not remembered, this is vi compatible.
***************
*** 1374,1401 ****
if ((options & SEARCH_ECHO) && messaging()
&& !cmd_silent && msg_silent == 0)
{
- char_u *msgbuf;
char_u *trunc;

if (*searchstr == NUL)
p = spats[0].pat;
else
p = searchstr;
! msgbuf = alloc((unsigned)(STRLEN(p) + 40));
if (msgbuf != NULL)
{
msgbuf[0] = dirc;
if (enc_utf8 && utf_iscomposing(utf_ptr2char(p)))
{
! /* Use a space to draw the composing char on. */
msgbuf[1] = ' ';
! STRCPY(msgbuf + 2, p);
}
else
! STRCPY(msgbuf + 1, p);
if (spats[0].off.line || spats[0].off.end || spats[0].off.off)
{
! p = msgbuf + STRLEN(msgbuf);
*p++ = dirc;
if (spats[0].off.end)
*p++ = 'e';
--- 1377,1427 ----
if ((options & SEARCH_ECHO) && messaging()
&& !cmd_silent && msg_silent == 0)
{
char_u *trunc;

+ // Compute msg_row early.
+ msg_start();
+
if (*searchstr == NUL)
p = spats[0].pat;
else
p = searchstr;
!
! if (!shortmess(SHM_SEARCHCOUNT))
! {
! // Reserve enough space for the search pattern + offset +
! // search stat.
! if (msg_scrolled != 0)
! // Use all the columns.
! len = (int)(Rows - msg_row) * Columns - 1;
! else
! // Use up to 'showcmd' column.
! len = (int)(Rows - msg_row - 1) * Columns + sc_col - 1;
! if (len < STRLEN(p) + 40 + 11)
! len = STRLEN(p) + 40 + 11;
! }
! else
! // Reserve enough space for the search pattern + offset.
! len = STRLEN(p) + 40;
!
! msgbuf = alloc((int)len);
if (msgbuf != NULL)
{
+ vim_memset(msgbuf, ' ', len);
msgbuf[0] = dirc;
+ msgbuf[len - 1] = NUL;
+
if (enc_utf8 && utf_iscomposing(utf_ptr2char(p)))
{
! // Use a space to draw the composing char on.
msgbuf[1] = ' ';
! STRNCPY(msgbuf + 2, p, STRLEN(p));
}
else
! STRNCPY(msgbuf + 1, p, STRLEN(p));
if (spats[0].off.line || spats[0].off.end || spats[0].off.off)
{
! p = msgbuf + STRLEN(p) + 1;
*p++ = dirc;
if (spats[0].off.end)
*p++ = 'e';
***************
*** 1404,1448 ****
if (spats[0].off.off > 0 || spats[0].off.line)
*p++ = '+';
if (spats[0].off.off != 0 || spats[0].off.line)
! sprintf((char *)p, "%ld", spats[0].off.off);
! else
! *p = NUL;
}

- msg_start();
trunc = msg_strtrunc(msgbuf, FALSE);

#ifdef FEAT_RIGHTLEFT
! /* The search pattern could be shown on the right in rightleft
! * mode, but the 'ruler' and 'showcmd' area use it too, thus
! * it would be blanked out again very soon. Show it on the
! * left, but do reverse the text. */
if (curwin->w_p_rl && *curwin->w_p_rlc == 's')
{
char_u *r;

! r = reverse_text(trunc != NULL ? trunc : msgbuf);
if (r != NULL)
{
! vim_free(trunc);
! trunc = r;
}
}
#endif
! if (trunc != NULL)
! {
! msg_outtrans(trunc);
! vim_free(trunc);
! }
! else
! msg_outtrans(msgbuf);
msg_clr_eos();
msg_check();
- vim_free(msgbuf);

gotocmdline(FALSE);
out_flush();
! msg_nowait = TRUE; /* don't wait for this message */
}
}

--- 1430,1479 ----
if (spats[0].off.off > 0 || spats[0].off.line)
*p++ = '+';
if (spats[0].off.off != 0 || spats[0].off.line)
! {
! int l = 0;
! l = sprintf((char *)p, "%ld", spats[0].off.off);
! p[l] = ' '; // remove NUL from sprintf
! }
}

trunc = msg_strtrunc(msgbuf, FALSE);
+ if (trunc != NULL)
+ {
+ vim_free(msgbuf);
+ msgbuf = trunc;
+ }

#ifdef FEAT_RIGHTLEFT
! // The search pattern could be shown on the right in rightleft
! // mode, but the 'ruler' and 'showcmd' area use it too, thus
! // it would be blanked out again very soon. Show it on the
! // left, but do reverse the text.
if (curwin->w_p_rl && *curwin->w_p_rlc == 's')
{
char_u *r;

! r = reverse_text(msgbuf);
if (r != NULL)
{
! vim_free(msgbuf);
! msgbuf = r;
! // move reversed text to beginning of buffer
! while (*r != NUL && *r == ' ')
! r++;
! mch_memmove(msgbuf, r, msgbuf + STRLEN(msgbuf) - r);
! // overwrite old text
! vim_memset(r, ' ', msgbuf + STRLEN(msgbuf) - r);
}
}
#endif
! msg_outtrans(msgbuf);
msg_clr_eos();
msg_check();

gotocmdline(FALSE);
out_flush();
! msg_nowait = TRUE; // don't wait for this message
}
}

***************
*** 1488,1494 ****
RE_LAST, (linenr_T)0, tm, timed_out);

if (dircp != NULL)
! *dircp = dirc; /* restore second '/' or '?' for normal_cmd() */
if (c == FAIL)
{
retval = 0;
--- 1519,1531 ----
RE_LAST, (linenr_T)0, tm, timed_out);

if (dircp != NULL)
! *dircp = dirc; // restore second '/' or '?' for normal_cmd()
!
! if (!shortmess(SHM_SEARCH)
! && ((dirc == '/' && LT_POS(pos, curwin->w_cursor))
! || (dirc == '?' && LT_POS(curwin->w_cursor, pos))))
! ui_delay(500L, FALSE); // leave some time for top_bot_msg
!
if (c == FAIL)
{
retval = 0;
***************
*** 1537,1542 ****
--- 1574,1588 ----
}
}

+ // Show [1/15] if 'S' is not in 'shortmess'.
+ if ((options & SEARCH_ECHO)
+ && messaging()
+ && !(cmd_silent + msg_silent)
+ && c != FAIL
+ && !shortmess(SHM_SEARCHCOUNT)
+ && msgbuf != NULL)
+ search_stat(dirc, &pos, msgbuf);
+
/*
* The search command can be followed by a ';' to do another search.
* For example: "/pat/;/foo/+3;?bar"
***************
*** 1567,1572 ****
--- 1613,1619 ----
if ((options & SEARCH_KEEP) || cmdmod.keeppatterns)
spats[0].off = old_off;
vim_free(strcopy);
+ vim_free(msgbuf);

return retval;
}
***************
*** 4857,4862 ****
--- 4904,5027 ----
}
#endif

+ /*
+ * Add the search count "[3/19]" to "msgbuf".
+ */
+ static void
+ search_stat(
+ int dirc,
+ pos_T *pos,
+ char_u *msgbuf)
+ {
+ int save_ws = p_ws;
+ int wraparound = FALSE;
+ pos_T p = (*pos);
+ static pos_T lastpos = {0, 0, 0};
+ static int cur = 0;
+ static int cnt = 0;
+ static int chgtick = 0;
+ static char_u *lastpat = NULL;
+ static buf_T *lbuf = NULL;
+ #ifdef FEAT_RELTIME
+ proftime_T start;
+ #endif
+ #define OUT_OF_TIME 999
+
+ wraparound = ((dirc == '?' && LT_POS(lastpos, p))
+ || (dirc == '/' && LT_POS(p, lastpos)));
+
+ // If anything relevant changed the count has to be recomputed.
+ // MB_STRNICMP ignores case, but we should not ignore case.
+ // Unfortunately, there is no MB_STRNICMP function.
+ if (!(chgtick == CHANGEDTICK(curbuf)
+ && MB_STRNICMP(lastpat, spats[last_idx].pat, STRLEN(lastpat)) == 0
+ && STRLEN(lastpat) == STRLEN(spats[last_idx].pat)
+ && EQUAL_POS(lastpos, curwin->w_cursor)
+ && lbuf == curbuf) || wraparound || cur < 0 || cur > 99)
+ {
+ cur = 0;
+ cnt = 0;
+ CLEAR_POS(&lastpos);
+ lbuf = curbuf;
+ }
+
+ if (EQUAL_POS(lastpos, curwin->w_cursor) && !wraparound
+ && (dirc == '/' ? cur < cnt : cur > 0))
+ cur += dirc == '/' ? 1 : -1;
+ else
+ {
+ p_ws = FALSE;
+ #ifdef FEAT_RELTIME
+ profile_setlimit(20L, &start);
+ #endif
+ while (!got_int && searchit(curwin, curbuf, &lastpos, NULL,
+ FORWARD, NULL, 1, SEARCH_PEEK + SEARCH_KEEP,
+ RE_LAST, (linenr_T)0, NULL, NULL) != FAIL)
+ {
+ #ifdef FEAT_RELTIME
+ // Stop after passing the time limit.
+ if (profile_passed_limit(&start))
+ {
+ cnt = OUT_OF_TIME;
+ cur = OUT_OF_TIME;
+ break;
+ }
+ #endif
+ cnt++;
+ if (LTOREQ_POS(lastpos, p))
+ cur++;
+ fast_breakcheck();
+ if (cnt > 99)
+ break;
+ }
+ if (got_int)
+ cur = -1; // abort
+ }
+ if (cur > 0)
+ {
+ #define STAT_BUF_LEN 10
+ char t[STAT_BUF_LEN] = "";
+
+ #ifdef FEAT_RIGHTLEFT
+ if (curwin->w_p_rl && *curwin->w_p_rlc == 's')
+ {
+ if (cur == OUT_OF_TIME)
+ vim_snprintf(t, STAT_BUF_LEN, "[?/??]");
+ else if (cnt > 99 && cur > 99)
+ vim_snprintf(t, STAT_BUF_LEN, "[>99/>99]");
+ else if (cnt > 99)
+ vim_snprintf(t, STAT_BUF_LEN, "[>99/%d]", cur);
+ else
+ vim_snprintf(t, STAT_BUF_LEN, "[%d/%d]", cnt, cur);
+ }
+ else
+ #endif
+ {
+ if (cur == OUT_OF_TIME)
+ vim_snprintf(t, STAT_BUF_LEN, "[?/??]");
+ else if (cnt > 99 && cur > 99)
+ vim_snprintf(t, STAT_BUF_LEN, "[>99/>99]");
+ else if (cnt > 99)
+ vim_snprintf(t, STAT_BUF_LEN, "[%d/>99]", cur);
+ else
+ vim_snprintf(t, STAT_BUF_LEN, "[%d/%d]", cur, cnt);
+ }
+ STRNCPY(msgbuf + STRLEN(msgbuf) - STRLEN(t), t, STRLEN(t));
+ if (dirc == '?' && cur == 100)
+ cur = -1;
+
+ vim_free(lastpat);
+ lastpat = vim_strsave(spats[last_idx].pat);
+ chgtick = CHANGEDTICK(curbuf);
+ lbuf = curbuf;
+ lastpos = p;
+
+ // keep the message even after redraw
+ give_warning(msgbuf, FALSE);
+ }
+ p_ws = save_ws;
+ }
+
#if defined(FEAT_FIND_ID) || defined(PROTO)
/*
* Find identifiers or defines in included files.
*** ../vim-8.1.1269/src/testdir/Make_all.mak 2019-04-28 18:04:56.062492159 +0200
--- src/testdir/Make_all.mak 2019-05-04 20:20:01.218364660 +0200
***************
*** 219,224 ****
--- 219,225 ----
test_scroll_opt \
test_scrollbind \
test_search \
+ test_search_stat \
test_searchpos \
test_set \
test_sha256 \
***************
*** 388,393 ****
--- 389,395 ----
test_scriptnames.res \
test_scrollbind.res \
test_search.res \
+ test_search_stat.res \
test_shortpathname.res \
test_signals.res \
test_signs.res \
*** ../vim-8.1.1269/src/testdir/test_search_stat.vim 2019-05-04 21:07:16.848124792 +0200
--- src/testdir/test_search_stat.vim 2019-05-04 21:00:59.010048385 +0200
***************
*** 0 ****
--- 1,108 ----
+ " Tests for search_stats, when "S" is not in 'shortmess'
+ "
+ " This test is fragile, it might not work interactively, but it works when run
+ " as test!
+
+ func! Test_search_stat()
+ new
+ set shortmess-=S
+ call append(0, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 10))
+
+ " 1) match at second line
+ call cursor(1, 1)
+ let @/ = 'fo*\(bar\?\)\?'
+ let g:a = execute(':unsilent :norm! n')
+ let stat = '\[2/50\]'
+ let pat = escape(@/, '()*?'). '\s\+'
+ call assert_match(pat .. stat, g:a)
+
+ " 2) Match at last line
+ call cursor(line('$')-2, 1)
+ let g:a = execute(':unsilent :norm! n')
+ let stat = '\[50/50\]'
+ call assert_match(pat .. stat, g:a)
+
+ " 3) No search stat
+ set shortmess+=S
+ call cursor(1, 1)
+ let stat = '\[2/50\]'
+ let g:a = execute(':unsilent :norm! n')
+ call assert_notmatch(pat .. stat, g:a)
+ set shortmess-=S
+
+ " 4) Many matches
+ call cursor(line('$')-2, 1)
+ let @/ = '.'
+ let pat = escape(@/, '()*?'). '\s\+'
+ let g:a = execute(':unsilent :norm! n')
+ let stat = '\[>99/>99\]'
+ call assert_match(pat .. stat, g:a)
+
+ " 5) Many matches
+ call cursor(1, 1)
+ let g:a = execute(':unsilent :norm! n')
+ let stat = '\[2/>99\]'
+ call assert_match(pat .. stat, g:a)
+
+ " 6) right-left
+ if exists("+rightleft")
+ set rl
+ call cursor(1,1)
+ let @/ = 'foobar'
+ let pat = 'raboof/\s\+'
+ let g:a = execute(':unsilent :norm! n')
+ let stat = '\[20/2\]'
+ call assert_match(pat .. stat, g:a)
+ set norl
+ endif
+
+ " 7) right-left bottom
+ if exists("+rightleft")
+ set rl
+ call cursor('$',1)
+ let pat = 'raboof?\s\+'
+ let g:a = execute(':unsilent :norm! N')
+ let stat = '\[20/20\]'
+ call assert_match(pat .. stat, g:a)
+ set norl
+ endif
+
+ " 8) right-left back at top
+ if exists("+rightleft")
+ set rl
+ call cursor('$',1)
+ let pat = 'raboof/\s\+'
+ let g:a = execute(':unsilent :norm! n')
+ let stat = '\[20/1\]'
+ call assert_match(pat .. stat, g:a)
+ call assert_match('search hit BOTTOM, continuing at TOP', g:a)
+ set norl
+ endif
+
+ " 9) normal, back at top
+ call cursor(1,1)
+ let @/ = 'foobar'
+ let pat = '?foobar\s\+'
+ let g:a = execute(':unsilent :norm! N')
+ let stat = '\[20/20\]'
+ call assert_match(pat .. stat, g:a)
+ call assert_match('search hit TOP, continuing at BOTTOM', g:a)
+
+ " 10) normal, no match
+ call cursor(1,1)
+ let @/ = 'zzzzzz'
+ let g:a = ''
+ try
+ let g:a = execute(':unsilent :norm! n')
+ catch /^Vim\%((\a\+)\)\=:E486/
+ let stat = ''
+ " error message is not redir'ed to g:a, it is empty
+ call assert_true(empty(g:a))
+ catch
+ call assert_false(1)
+ endtry
+
+ " close the window
+ set shortmess+=S
+ bwipe!
+ endfunc
*** ../vim-8.1.1269/src/version.c 2019-05-04 19:59:56.544589575 +0200
--- src/version.c 2019-05-04 21:07:03.180195105 +0200
***************
*** 769,770 ****
--- 769,772 ----
{ /* Add new patch number below this line */
+ /**/
+ 1270,
/**/

--
Dreams are free, but there's a small charge for alterations.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

John Marriott

unread,
May 4, 2019, 7:27:49 PM5/4/19
to vim...@googlegroups.com

On 05-May-2019 05:09, Bram Moolenaar wrote:
> Patch 8.1.1270
> 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)
> Files: runtime/doc/options.txt, runtime/doc/pattern.txt, src/option.c,
> src/option.h, src/search.c, src/testdir/Make_all.mak,
> src/testdir/test_search_stat.vim
>
>
After this patch, mingw64 (gcc 8.3.1) throws up these warnings:
gcc -c -I. -Iproto -DWIN32 -DWINVER=0x0603 -D_WIN32_WINNT=0x0603
-DHAVE_PATHDEF -DFEAT_NORMAL -DHAVE_STDINT_H -pipe -march=native -Wall
-O3 -fomit-frame-pointer -freg-struct-return search.c -o objnative/search.o
In file included from search.c:13:
search.c: In function 'do_search':
vim.h:1568:29: warning: 'strncpy' output truncated before terminating
nul copying as many bytes from a string as its length
[-Wstringop-truncation]
 #define STRNCPY(d, s, n)    strncpy((char *)(d), (char *)(s),
(size_t)(n))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vim.h:1568:29: note: in definition of macro 'STRNCPY'
 #define STRNCPY(d, s, n)    strncpy((char *)(d), (char *)(s),
(size_t)(n))
^~~~~~~
vim.h:1566:23: note: length computed here
 #define STRLEN(s)     strlen((char *)(s))
^
vim.h:1568:72: note: in definition of macro 'STRNCPY'
 #define STRNCPY(d, s, n)    strncpy((char *)(d), (char *)(s),
(size_t)(n))
^
search.c:1418:30: note: in expansion of macro 'STRLEN'
       STRNCPY(msgbuf + 2, p, STRLEN(p));
^~~~~~
vim.h:1568:29: warning: 'strncpy' output truncated before terminating
nul copying as many bytes from a string as its length
[-Wstringop-truncation]
 #define STRNCPY(d, s, n)    strncpy((char *)(d), (char *)(s),
(size_t)(n))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vim.h:1568:29: note: in definition of macro 'STRNCPY'
 #define STRNCPY(d, s, n)    strncpy((char *)(d), (char *)(s),
(size_t)(n))
^~~~~~~
vim.h:1566:23: note: length computed here
 #define STRLEN(s)     strlen((char *)(s))
^
vim.h:1568:72: note: in definition of macro 'STRNCPY'
 #define STRNCPY(d, s, n)    strncpy((char *)(d), (char *)(s),
(size_t)(n))
^
search.c:1421:30: note: in expansion of macro 'STRLEN'
       STRNCPY(msgbuf + 1, p, STRLEN(p));
^~~~~~
In function 'search_stat',
    inlined from 'do_search' at search.c:1584:6:
vim.h:1568:29: warning: 'strncpy' output truncated before terminating
nul copying as many bytes from a string as its length
[-Wstringop-truncation]
 #define STRNCPY(d, s, n)    strncpy((char *)(d), (char *)(s),
(size_t)(n))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vim.h:1568:29: note: in definition of macro 'STRNCPY'
 #define STRNCPY(d, s, n)    strncpy((char *)(d), (char *)(s),
(size_t)(n))
^~~~~~~
search.c: In function 'do_search':
vim.h:1566:23: note: length computed here
 #define STRLEN(s)     strlen((char *)(s))
^
vim.h:1568:72: note: in definition of macro 'STRNCPY'
 #define STRNCPY(d, s, n)    strncpy((char *)(d), (char *)(s),
(size_t)(n))
^
search.c:5009:50: note: in expansion of macro 'STRLEN'
  STRNCPY(msgbuf + STRLEN(msgbuf) - STRLEN(t), t, STRLEN(t));
^~~~~~

Please check the attached patch which tries to correct it.

Cheers


search.c.1270.patch

Bram Moolenaar

unread,
May 5, 2019, 7:02:51 AM5/5/19
to John Marriott, vim...@googlegroups.com
Hmm, that doesn't look like the right fix. I think replacing STRNCPY()
with mch_memmove() will do the trick.

--
I bought a book on hair loss, but the pages kept falling out.

Christian Brabandt

unread,
May 7, 2019, 4:31:27 AM5/7/19
to vim...@googlegroups.com

On Sa, 04 Mai 2019, Bram Moolenaar wrote:

> Patch 8.1.1270
> 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)
> Files: runtime/doc/options.txt, runtime/doc/pattern.txt, src/option.c,
> src/option.h, src/search.c, src/testdir/Make_all.mak,
> src/testdir/test_search_stat.vim

I noticed one problem. I usually have n mapped to nzv and noticed that
after a search wrap, the count and matches are no longer displayed. I
think this happens, because the search_stat function uses the
`SEARCH_PEEK` flag and aborts once it notices that there are more
characters comming from a mapping. Don't ask me, why this does not
happen the first time :(

So here is a patch with a test, note the test won't probably not fail
currently, but I figured it should be added nonetheless.

diff --git a/src/search.c b/src/search.c
index dd5519e79..74a35e9f5 100644
--- a/src/search.c
+++ b/src/search.c
@@ -4958,7 +4958,7 @@ search_stat(
profile_setlimit(20L, &start);
#endif
while (!got_int && searchit(curwin, curbuf, &lastpos, NULL,
- FORWARD, NULL, 1, SEARCH_PEEK + SEARCH_KEEP,
+ FORWARD, NULL, 1, SEARCH_KEEP,
RE_LAST, (linenr_T)0, NULL, NULL) != FAIL)
{
#ifdef FEAT_RELTIME
diff --git a/src/testdir/test_search_stat.vim b/src/testdir/test_search_stat.vim
index 57dad81b8..797d58244 100644
--- a/src/testdir/test_search_stat.vim
+++ b/src/testdir/test_search_stat.vim
@@ -105,6 +105,26 @@ func! Test_search_stat()
call assert_false(1)
endtry

+ " 11) normal, n comes from a mapping
+ nnoremap n nzv
+ call cursor(1,1)
+ let @/ = 'foobar'
+ let pat = '/foobar\s\+'
+ let g:a = execute(':unsilent :norm n')
+ " g:a will contain several lines
+ let g:b = split(g:a, "\n")[-1]
+ let stat = '\[2/20\]'
+ call assert_match(pat .. stat, g:b)
+ unmap n
+
+ " 11) normal, but silent
+ call cursor(1,1)
+ let @/ = 'foobar'
+ let pat = '/foobar\s\+'
+ let g:a = execute(':norm! n')
+ let stat = '\[2/20\]'
+ call assert_notmatch(pat .. stat, g:a)
+
" close the window
set shortmess+=S
bwipe!


Mit freundlichen Grüßen
Christian
--
Lebenskünstler leben von den Zinsen eines nicht vorhandenen Kapitals.
-- Stanislaw Jerzy Lec

Bram Moolenaar

unread,
May 7, 2019, 3:29:35 PM5/7/19
to vim...@googlegroups.com, Christian Brabandt

Christian wrote:

> On Sa, 04 Mai 2019, Bram Moolenaar wrote:
>
> > Patch 8.1.1270
> > 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)
> > Files: runtime/doc/options.txt, runtime/doc/pattern.txt, src/option.c,
> > src/option.h, src/search.c, src/testdir/Make_all.mak,
> > src/testdir/test_search_stat.vim
>
> I noticed one problem. I usually have n mapped to nzv and noticed that
> after a search wrap, the count and matches are no longer displayed. I
> think this happens, because the search_stat function uses the
> `SEARCH_PEEK` flag and aborts once it notices that there are more
> characters comming from a mapping. Don't ask me, why this does not
> happen the first time :(
>
> So here is a patch with a test, note the test won't probably not fail
> currently, but I figured it should be added nonetheless.

It doesn't fail because char_avail() is only called every 64 lines.
The test needs to have the matches furthere apart.

It will make mapped commands slower, but having the info show up
inconsistently is worse. E.g. when "n" is mapped then "?" does show the
info and "n" does not.


--
So when I saw the post to comp.editors, I rushed over to the FTP site to
grab it. So I yank apart the tarball, light x candles, where x= the
vim version multiplied by the md5sum of the source divided by the MAC of
my NIC (8A3FA78155A8A1D346C3C4A), put on black robes, dim the lights,
wave a dead chicken over the hard drive, and summon the power of GNU GCC
with the magic words "make config ; make!".
[Jason Spence, compiling Vim 5.0]
Reply all
Reply to author
Forward
0 new messages