Patch 7.4.2259
Problem:    With 'incsearch' can only see the next match.
Solution:   Make CTRL-N/CTRL-P move to the previous/next match. (Christian
            Brabandt)
Files:      runtime/doc/cmdline.txt, src/ex_getln.c, src/testdir/Make_all.mak,
            src/testdir/test_search.vim, src/Makefile


*** ../vim-7.4.2258/runtime/doc/cmdline.txt     2015-09-08 18:46:04.337233673 
+0200
--- runtime/doc/cmdline.txt     2016-08-26 18:56:26.060363506 +0200
***************
*** 404,414 ****
--- 409,427 ----
                                                        *c_CTRL-N*
  CTRL-N                After using 'wildchar' which got multiple matches, go 
to next
                match.  Otherwise recall more recent command-line from history.
+                                                           */_CTRL-N*
+               When 'incsearch' is set, entering a search pattern for "/" or
+               "?" and the current match is displayed then CTRL-N will move
+               to the next match (does not take |search-offset| into account)
  <S-Tab>                                                       *c_CTRL-P* 
*c_<S-Tab>*
  CTRL-P                After using 'wildchar' which got multiple matches, go to
                previous match.  Otherwise recall older command-line from
                history.  <S-Tab> only works with the GUI, on the Amiga and
                with MS-DOS.
+                                                           */_CTRL-P*
+               When 'incsearch' is set, entering a search pattern for "/" or
+               "?" and the current match is displayed then CTRL-P will move
+               to the previous match (does not take |search-offset| into 
account).
                                                        *c_CTRL-A*
  CTRL-A                All names that match the pattern in front of the cursor 
are
                inserted.
*** ../vim-7.4.2258/src/ex_getln.c      2016-07-10 22:11:11.866751401 +0200
--- src/ex_getln.c      2016-08-26 19:03:54.320578262 +0200
***************
*** 137,142 ****
--- 137,145 ----
  #endif
  sort_func_compare(const void *s1, const void *s2);
  #endif
+ #ifdef FEAT_SEARCH_EXTRA
+ static void set_search_match(pos_T *t);
+ #endif
  
  /*
   * getcmdline() - accept a command line starting with firstc.
***************
*** 178,183 ****
--- 181,189 ----
      colnr_T   old_curswant;
      colnr_T   old_leftcol;
      linenr_T  old_topline;
+     pos_T       cursor_start;
+     pos_T       match_start = curwin->w_cursor;
+     pos_T       match_end;
  # ifdef FEAT_DIFF
      int               old_topfill;
  # endif
***************
*** 223,229 ****
--- 229,237 ----
  
      ccline.overstrike = FALSE;                    /* always start in insert 
mode */
  #ifdef FEAT_SEARCH_EXTRA
+     clearpos(&match_end);
      old_cursor = curwin->w_cursor;        /* needs to be restored later */
+     cursor_start = old_cursor;
      old_curswant = curwin->w_curswant;
      old_leftcol = curwin->w_leftcol;
      old_topline = curwin->w_topline;
***************
*** 996,1001 ****
--- 1004,1018 ----
  
                    /* Truncate at the end, required for multi-byte chars. */
                    ccline.cmdbuff[ccline.cmdlen] = NUL;
+ #ifdef FEAT_SEARCH_EXTRA
+                   if (ccline.cmdlen == 0)
+                       old_cursor = cursor_start;
+                   else
+                   {
+                       old_cursor = match_start;
+                       decl(&old_cursor);
+                   }
+ #endif
                    redrawcmd();
                }
                else if (ccline.cmdlen == 0 && c != Ctrl_W
***************
*** 1021,1026 ****
--- 1038,1047 ----
                            msg_col = 0;
                        msg_putchar(' ');               /* delete ':' */
                    }
+ #ifdef FEAT_SEARCH_EXTRA
+                   if (ccline.cmdlen == 0)
+                       old_cursor = cursor_start;
+ #endif
                    redraw_cmdline = TRUE;
                    goto returncmd;             /* back to cmd mode */
                }
***************
*** 1104,1109 ****
--- 1125,1134 ----
                    ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
                /* Truncate at the end, required for multi-byte chars. */
                ccline.cmdbuff[ccline.cmdlen] = NUL;
+ #ifdef FEAT_SEARCH_EXTRA
+               if (ccline.cmdlen == 0)
+                   old_cursor = cursor_start;
+ #endif
                redrawcmd();
                goto cmdline_changed;
  
***************
*** 1440,1465 ****
                if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
                {
                    /* Add a character from under the cursor for 'incsearch' */
!                   if (did_incsearch
!                                  && !equalpos(curwin->w_cursor, old_cursor))
                    {
!                       c = gchar_cursor();
!                       /* If 'ignorecase' and 'smartcase' are set and the
!                       * command line has no uppercase characters, convert
!                       * the character to lowercase */
!                       if (p_ic && p_scs && !pat_has_uppercase(ccline.cmdbuff))
!                           c = MB_TOLOWER(c);
!                       if (c != NUL)
                        {
!                           if (c == firstc || vim_strchr((char_u *)(
!                                           p_magic ? "\\^$.*[" : "\\^$"), c)
!                                                                     != NULL)
                            {
!                               /* put a backslash before special characters */
!                               stuffcharReadbuff(c);
!                               c = '\\';
                            }
-                           break;
                        }
                    }
                    goto cmdline_not_changed;
--- 1465,1495 ----
                if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
                {
                    /* Add a character from under the cursor for 'incsearch' */
!                   if (did_incsearch)
                    {
!                       curwin->w_cursor = match_end;
!                       if (!equalpos(curwin->w_cursor, old_cursor))
                        {
!                           c = gchar_cursor();
!                           /* If 'ignorecase' and 'smartcase' are set and the
!                           * command line has no uppercase characters, convert
!                           * the character to lowercase */
!                           if (p_ic && p_scs
!                                        && !pat_has_uppercase(ccline.cmdbuff))
!                               c = MB_TOLOWER(c);
!                           if (c != NUL)
                            {
!                               if (c == firstc || vim_strchr((char_u *)(
!                                             p_magic ? "\\^$.*[" : "\\^$"), c)
!                                                                      != NULL)
!                               {
!                                   /* put a backslash before special
!                                    * characters */
!                                   stuffcharReadbuff(c);
!                                   c = '\\';
!                               }
!                               break;
                            }
                        }
                    }
                    goto cmdline_not_changed;
***************
*** 1473,1479 ****
  
        case Ctrl_N:        /* next match */
        case Ctrl_P:        /* previous match */
!               if (xpc.xp_numfiles > 0)
                {
                    if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT,
                                                    0, firstc != '@') == FAIL)
--- 1503,1577 ----
  
        case Ctrl_N:        /* next match */
        case Ctrl_P:        /* previous match */
! #ifdef FEAT_SEARCH_EXTRA
!                   if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
!                   {
!                       pos_T  t;
!                       int    search_flags = SEARCH_KEEP + SEARCH_NOOF
!                                                                + SEARCH_PEEK;
! 
!                       if (char_avail())
!                           continue;
!                       cursor_off();
!                       out_flush();
!                       if (c == Ctrl_N)
!                       {
!                           t = match_end;
!                           search_flags += SEARCH_COL;
!                       }
!                       else
!                           t = match_start;
!                       ++emsg_off;
!                       i = searchit(curwin, curbuf, &t,
!                                    c == Ctrl_N ? FORWARD : BACKWARD,
!                                    ccline.cmdbuff, count, search_flags,
!                                    RE_SEARCH, 0, NULL);
!                       --emsg_off;
!                       if (i)
!                       {
!                           old_cursor = match_start;
!                           match_end = t;
!                           match_start = t;
!                           if (c == Ctrl_P && firstc == '/')
!                           {
!                               /* move just before the current match, so that
!                                * when nv_search finishes the cursor will be
!                                * put back on the match */
!                               old_cursor = t;
!                               (void)decl(&old_cursor);
!                           }
!                           if (lt(t, old_cursor) && c == Ctrl_N)
!                           {
!                               /* wrap around */
!                               old_cursor = t;
!                               if (firstc == '?')
!                                   (void)incl(&old_cursor);
!                               else
!                                   (void)decl(&old_cursor);
!                           }
! 
!                           set_search_match(&match_end);
!                           curwin->w_cursor = match_start;
!                           changed_cline_bef_curs();
!                           update_topline();
!                           validate_cursor();
!                           highlight_match = TRUE;
!                           old_curswant = curwin->w_curswant;
!                           old_leftcol = curwin->w_leftcol;
!                           old_topline = curwin->w_topline;
! # ifdef FEAT_DIFF
!                           old_topfill = curwin->w_topfill;
! # endif
!                           old_botline = curwin->w_botline;
!                           update_screen(NOT_VALID);
!                           redrawcmdline();
!                       }
!                       else
!                           vim_beep(BO_ERROR);
!                       goto cmdline_not_changed;
!               }
! #endif
!               else if (xpc.xp_numfiles > 0)
                {
                    if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT,
                                                    0, firstc != '@') == FAIL)
***************
*** 1821,1839 ****
            {
                pos_T       save_pos = curwin->w_cursor;
  
!               /*
!                * First move cursor to end of match, then to the start.  This
!                * moves the whole match onto the screen when 'nowrap' is set.
!                */
!               curwin->w_cursor.lnum += search_match_lines;
!               curwin->w_cursor.col = search_match_endcol;
!               if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
!               {
!                   curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
!                   coladvance((colnr_T)MAXCOL);
!               }
                validate_cursor();
                end_pos = curwin->w_cursor;
                curwin->w_cursor = save_pos;
            }
            else
--- 1919,1929 ----
            {
                pos_T       save_pos = curwin->w_cursor;
  
!               match_start = curwin->w_cursor;
!               set_search_match(&curwin->w_cursor);
                validate_cursor();
                end_pos = curwin->w_cursor;
+               match_end = end_pos;
                curwin->w_cursor = save_pos;
            }
            else
***************
*** 1894,1899 ****
--- 1984,1991 ----
      if (did_incsearch)
      {
        curwin->w_cursor = old_cursor;
+       if (gotesc)
+           curwin->w_cursor = cursor_start;
        curwin->w_curswant = old_curswant;
        curwin->w_leftcol = old_leftcol;
        curwin->w_topline = old_topline;
***************
*** 6983,6985 ****
--- 7075,7095 ----
  
      return (char_u *)ga.ga_data;
  }
+ 
+ #ifdef FEAT_SEARCH_EXTRA
+     static void
+ set_search_match(pos_T *t)
+ {
+     /*
+     * First move cursor to end of match, then to the start.  This
+     * moves the whole match onto the screen when 'nowrap' is set.
+     */
+     t->lnum += search_match_lines;
+     t->col = search_match_endcol;
+     if (t->lnum > curbuf->b_ml.ml_line_count)
+     {
+       t->lnum = curbuf->b_ml.ml_line_count;
+       coladvance((colnr_T)MAXCOL);
+     }
+ }
+ #endif
*** ../vim-7.4.2258/src/testdir/Make_all.mak    2016-08-20 16:56:48.254624304 
+0200
--- src/testdir/Make_all.mak    2016-08-26 18:56:26.064363472 +0200
***************
*** 181,186 ****
--- 181,187 ----
            test_perl.res \
            test_quickfix.res \
            test_ruby.res \
+           test_search.res \
            test_signs.res \
            test_startup.res \
            test_startup_utf8.res \
*** ../vim-7.4.2258/src/testdir/test_search.vim 2016-08-26 19:12:15.700304803 
+0200
--- src/testdir/test_search.vim 2016-08-26 18:56:26.064363472 +0200
***************
*** 0 ****
--- 1,242 ----
+ " Test for the search command
+ 
+ func Test_search_cmdline()
+   if !exists('+incsearch')
+     return
+   endif
+   " need to disable char_avail,
+   " so that expansion of commandline works
+   call test_disable_char_avail(1)
+   new
+   call setline(1, ['  1', '  2 these', '  3 the', '  4 their', '  5 there', ' 
 6 their', '  7 the', '  8 them', '  9 these', ' 10 foobar'])
+   " Test 1
+   " CTRL-N / CTRL-P skips through the previous search history
+   set noincsearch
+   :1
+   call feedkeys("/foobar\<cr>", 'tx')
+   call feedkeys("/the\<cr>",'tx')
+   call assert_equal('the', @/)
+   call feedkeys("/thes\<c-p>\<c-p>\<cr>",'tx')
+   call assert_equal('foobar', @/)
+ 
+   " Test 2
+   " Ctrl-N goes from one match to the next
+   " until the end of the buffer
+   set incsearch nowrapscan
+   :1
+   " first match
+   call feedkeys("/the\<cr>", 'tx')
+   call assert_equal('  2 these', getline('.'))
+   :1
+   " second match
+   call feedkeys("/the\<c-n>\<cr>", 'tx')
+   call assert_equal('  3 the', getline('.'))
+   :1
+   " third match
+   call feedkeys("/the".repeat("\<c-n>", 2)."\<cr>", 'tx')
+   call assert_equal('  4 their', getline('.'))
+   :1
+   " fourth match
+   call feedkeys("/the".repeat("\<c-n>", 3)."\<cr>", 'tx')
+   call assert_equal('  5 there', getline('.'))
+   :1
+   " fifth match
+   call feedkeys("/the".repeat("\<c-n>", 4)."\<cr>", 'tx')
+   call assert_equal('  6 their', getline('.'))
+   :1
+   " sixth match
+   call feedkeys("/the".repeat("\<c-n>", 5)."\<cr>", 'tx')
+   call assert_equal('  7 the', getline('.'))
+   :1
+   " seventh match
+   call feedkeys("/the".repeat("\<c-n>", 6)."\<cr>", 'tx')
+   call assert_equal('  8 them', getline('.'))
+   :1
+   " eigth match
+   call feedkeys("/the".repeat("\<c-n>", 7)."\<cr>", 'tx')
+   call assert_equal('  9 these', getline('.'))
+   :1
+   " no further match
+   call feedkeys("/the".repeat("\<c-n>", 8)."\<cr>", 'tx')
+   call assert_equal('  9 these', getline('.'))
+ 
+   " Test 3
+   " Ctrl-N goes from one match to the next
+   " and continues back at the top
+   set incsearch wrapscan
+   :1
+   " first match
+   call feedkeys("/the\<cr>", 'tx')
+   call assert_equal('  2 these', getline('.'))
+   :1
+   " second match
+   call feedkeys("/the\<c-n>\<cr>", 'tx')
+   call assert_equal('  3 the', getline('.'))
+   :1
+   " third match
+   call feedkeys("/the".repeat("\<c-n>", 2)."\<cr>", 'tx')
+   call assert_equal('  4 their', getline('.'))
+   :1
+   " fourth match
+   call feedkeys("/the".repeat("\<c-n>", 3)."\<cr>", 'tx')
+   call assert_equal('  5 there', getline('.'))
+   :1
+   " fifth match
+   call feedkeys("/the".repeat("\<c-n>", 4)."\<cr>", 'tx')
+   call assert_equal('  6 their', getline('.'))
+   :1
+   " sixth match
+   call feedkeys("/the".repeat("\<c-n>", 5)."\<cr>", 'tx')
+   call assert_equal('  7 the', getline('.'))
+   :1
+   " seventh match
+   call feedkeys("/the".repeat("\<c-n>", 6)."\<cr>", 'tx')
+   call assert_equal('  8 them', getline('.'))
+   :1
+   " eigth match
+   call feedkeys("/the".repeat("\<c-n>", 7)."\<cr>", 'tx')
+   call assert_equal('  9 these', getline('.'))
+   :1
+   " back at first match
+   call feedkeys("/the".repeat("\<c-n>", 8)."\<cr>", 'tx')
+   call assert_equal('  2 these', getline('.'))
+ 
+   " Test 4
+   " CTRL-P goes to the previous match
+   set incsearch nowrapscan
+   $
+   " first match
+   call feedkeys("?the\<cr>", 'tx')
+   call assert_equal('  9 these', getline('.'))
+   $
+   " first match
+   call feedkeys("?the\<c-n>\<cr>", 'tx')
+   call assert_equal('  9 these', getline('.'))
+   $
+   " second match
+   call feedkeys("?the".repeat("\<c-p>", 1)."\<cr>", 'tx')
+   call assert_equal('  8 them', getline('.'))
+   $
+   " last match
+   call feedkeys("?the".repeat("\<c-p>", 7)."\<cr>", 'tx')
+   call assert_equal('  2 these', getline('.'))
+   $
+   " last match
+   call feedkeys("?the".repeat("\<c-p>", 8)."\<cr>", 'tx')
+   call assert_equal('  2 these', getline('.'))
+ 
+   " Test 5
+   " CTRL-P goes to the previous match
+   set incsearch wrapscan
+   $
+   " first match
+   call feedkeys("?the\<cr>", 'tx')
+   call assert_equal('  9 these', getline('.'))
+   $
+   " first match at the top
+   call feedkeys("?the\<c-n>\<cr>", 'tx')
+   call assert_equal('  2 these', getline('.'))
+   $
+   " second match
+   call feedkeys("?the".repeat("\<c-p>", 1)."\<cr>", 'tx')
+   call assert_equal('  8 them', getline('.'))
+   $
+   " last match
+   call feedkeys("?the".repeat("\<c-p>", 7)."\<cr>", 'tx')
+   call assert_equal('  2 these', getline('.'))
+   $
+   " back at the bottom of the buffer
+   call feedkeys("?the".repeat("\<c-p>", 8)."\<cr>", 'tx')
+   call assert_equal('  9 these', getline('.'))
+ 
+   " Test 6
+   " CTRL-L adds to the search pattern
+   set incsearch wrapscan
+   1
+   " first match
+   call feedkeys("/the\<c-l>\<cr>", 'tx')
+   call assert_equal('  2 these', getline('.'))
+   1
+   " go to next match of 'thes'
+   call feedkeys("/the\<c-l>\<c-n>\<cr>", 'tx')
+   call assert_equal('  9 these', getline('.'))
+   1
+   " wrap around
+   call feedkeys("/the\<c-l>\<c-n>\<c-n>\<cr>", 'tx')
+   call assert_equal('  2 these', getline('.'))
+   1
+   " wrap around
+   set nowrapscan
+   call feedkeys("/the\<c-l>\<c-n>\<c-n>\<cr>", 'tx')
+   call assert_equal('  9 these', getline('.'))
+ 
+   " Test 7
+   " <bs> remove from match, but stay at current match
+   set incsearch wrapscan
+   1
+   " first match
+   call feedkeys("/thei\<cr>", 'tx')
+   call assert_equal('  4 their', getline('.'))
+   1
+   " delete one char, add another
+   call feedkeys("/thei\<bs>s\<cr>", 'tx')
+   call assert_equal('  9 these', getline('.'))
+   1
+   " delete one char, add another,  go to previous match, add one char
+   call feedkeys("/thei\<bs>s\<bs>\<c-p>\<c-l>\<cr>", 'tx')
+   call assert_equal('  8 them', getline('.'))
+   1
+   " delete all chars, start from the beginning again
+   call feedkeys("/them". repeat("\<bs>",4).'the\>'."\<cr>", 'tx')
+   call assert_equal('  3 the', getline('.'))
+ 
+   " clean up
+   call test_disable_char_avail(0)
+   bw!
+ endfunc
+ 
+ func Test_search_cmdline2()
+   if !exists('+incsearch')
+     return
+   endif
+   " need to disable char_avail,
+   " so that expansion of commandline works
+   call test_disable_char_avail(1)
+   new
+   call setline(1, ['  1', '  2 these', '  3 the theother'])
+   " Test 1
+   " Ctrl-P goes correctly back and forth
+   set incsearch
+   1
+   " first match
+   call feedkeys("/the\<cr>", 'tx')
+   call assert_equal('  2 these', getline('.'))
+   1
+   " go to next match (on next line)
+   call feedkeys("/the\<c-n>\<cr>", 'tx')
+   call assert_equal('  3 the theother', getline('.'))
+   1
+   " go to next match (still on line 3)
+   call feedkeys("/the\<c-n>\<c-n>\<cr>", 'tx')
+   call assert_equal('  3 the theother', getline('.'))
+   1
+   " go to next match (still on line 3)
+   call feedkeys("/the\<c-n>\<c-n>\<c-n>\<cr>", 'tx')
+   call assert_equal('  3 the theother', getline('.'))
+   1
+   " go to previous match (on line 3)
+   call feedkeys("/the\<c-n>\<c-n>\<c-n>\<c-p>\<cr>", 'tx')
+   call assert_equal('  3 the theother', getline('.'))
+   1
+   " go to previous match (on line 3)
+   call feedkeys("/the\<c-n>\<c-n>\<c-n>\<c-p>\<c-p>\<cr>", 'tx')
+   call assert_equal('  3 the theother', getline('.'))
+   1
+   " go to previous match (on line 2)
+   call feedkeys("/the\<c-n>\<c-n>\<c-n>\<c-p>\<c-p>\<c-p>\<cr>", 'tx')
+   call assert_equal('  2 these', getline('.'))
+ 
+   " clean up
+   call test_disable_char_avail(0)
+   bw!
+ endfunc
*** ../vim-7.4.2258/src/Makefile        2016-08-23 23:50:06.872279942 +0200
--- src/Makefile        2016-08-26 18:59:40.214724763 +0200
***************
*** 2110,2115 ****
--- 2120,2126 ----
        test_regexp_utf8 \
        test_reltime \
        test_ruby \
+       test_search \
        test_searchpos \
        test_set \
        test_signs \
*** ../vim-7.4.2258/src/version.c       2016-08-26 17:58:33.590124381 +0200
--- src/version.c       2016-08-26 18:57:46.763682480 +0200
***************
*** 765,766 ****
--- 765,768 ----
  {   /* Add new patch number below this line */
+ /**/
+     2259,
  /**/

-- 
>From "know your smileys":
 y:-)   Bad toupee

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui