To: [email protected]
Subject: patch 5.4n.23
Fcc: outbox
From: Bram Moolenaar <[email protected]>
------------

Patch 5.4n.23
Problem:    "]m" going to the end of the current method isn't very logical,
           when "[[" and "]]' are compared with "[m" and "]m".
Solution:   Made "]m" go to the start of the next method.  Added "[M" and
           "]M", which go backward/forward to the end of a method.
           Made the use of these commands outside of the class more logical.
           Added tests for these commands.
Files:      src/normal.c, src/testdir/test14.in, src/testdir/test14.ok,
           runtime/doc/motion.txt


*** ../vim-5.4n/src/normal.c    Sun Jul  4 20:36:01 1999
--- src/normal.c        Sat Jul 10 18:22:22 1999
***************
*** 4077,4094 ****
      * "[{", "[(", "]}" or "])": go to Nth unclosed '{', '(', '}' or ')'
      * "[#", "]#": go to start/end of Nth innermost #if..#endif construct.
      * "[/", "[*", "]/", "]*": go to Nth comment start/end.
!      * "[m" or "]m" search for start/end of (Java) method.
      */
     if (  (cap->cmdchar == '['
!               && vim_strchr((char_u *)"{(*/#m", cap->nchar) != NULL)
           || (cap->cmdchar == ']'
!               && vim_strchr((char_u *)"})*/#m", cap->nchar) != NULL))
     {
       if (cap->nchar == '*')
           cap->nchar = '/';
       new_pos.lnum = 0;
       prev_pos.lnum = 0;
!       if (cap->nchar == 'm')
       {
           if (cap->cmdchar == '[')
               findc = '{';
--- 4077,4095 ----
      * "[{", "[(", "]}" or "])": go to Nth unclosed '{', '(', '}' or ')'
      * "[#", "]#": go to start/end of Nth innermost #if..#endif construct.
      * "[/", "[*", "]/", "]*": go to Nth comment start/end.
!      * "[m" or "]m" search for prev/next start of (Java) method.
!      * "[M" or "]M" search for prev/next end of (Java) method.
      */
     if (  (cap->cmdchar == '['
!               && vim_strchr((char_u *)"{(*/#mM", cap->nchar) != NULL)
           || (cap->cmdchar == ']'
!               && vim_strchr((char_u *)"})*/#mM", cap->nchar) != NULL))
     {
       if (cap->nchar == '*')
           cap->nchar = '/';
       new_pos.lnum = 0;
       prev_pos.lnum = 0;
!       if (cap->nchar == 'm' || cap->nchar == 'M')
       {
           if (cap->cmdchar == '[')
               findc = '{';
***************
*** 4107,4113 ****
               (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD, 0)) == NULL)
           {
               if (new_pos.lnum == 0)  /* nothing found */
!                   clearopbeep(cap->oap);
               else
                   pos = &new_pos;     /* use last one found */
               break;
--- 4108,4117 ----
               (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD, 0)) == NULL)
           {
               if (new_pos.lnum == 0)  /* nothing found */
!               {
!                   if (cap->nchar != 'm' && cap->nchar != 'M')
!                       clearopbeep(cap->oap);
!               }
               else
                   pos = &new_pos;     /* use last one found */
               break;
***************
*** 4119,4136 ****
       curwin->w_cursor = old_pos;

       /*
!        * For "[m" and "]m": When no match found, we might be in between
!        * methods.  Try finding other '{' or '}' and then its match.  Also
!        * repeat for the given count.
        */
!       if (cap->nchar == 'm')
       {
           n = cap->count1;
           if (prev_pos.lnum != 0)
           {
               pos = &prev_pos;
               curwin->w_cursor = prev_pos;
!               --n;
           }
           else
               pos = NULL;
--- 4123,4146 ----
       curwin->w_cursor = old_pos;

       /*
!        * Handle "[m", "]m", "[M" and "[M".  The findmatchlimit() only
!        * brought us to the match for "[m" and "]M" when inside a method.
!        * Try finding the '{' or '}' we want to be at.
!        * Also repeat for the given count.
        */
!       if (cap->nchar == 'm' || cap->nchar == 'M')
       {
+           /* norm is TRUE for "]M" and "[m" */
+           int     norm = ((findc == '{') == (cap->nchar == 'm'));
+
           n = cap->count1;
+           /* found a match: we were inside a method */
           if (prev_pos.lnum != 0)
           {
               pos = &prev_pos;
               curwin->w_cursor = prev_pos;
!               if (norm)
!                   --n;
           }
           else
               pos = NULL;
***************
*** 4139,4165 ****
               for (;;)
               {
                   if ((findc == '{' ? dec_cursor() : inc_cursor()) < 0)
-                       break;
-                   c = gchar_cursor();
-                   if (c == findc)
                   {
!                       /* must have found end/start of class: use it */
!                       new_pos = curwin->w_cursor;
!                       pos = &new_pos;
                       n = 0;
                       break;
                   }
                   if (c == '{' || c == '}')
                   {
                       /* found start/end of other method: go to match */
!                       if ((pos = findmatchlimit(cap->oap, findc,
                           (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD,
                                                                 0)) == NULL)
-                       {
                           n = 0;
!                           break;
!                       }
!                       curwin->w_cursor = *pos;
                       break;
                   }
               }
--- 4149,4186 ----
               for (;;)
               {
                   if ((findc == '{' ? dec_cursor() : inc_cursor()) < 0)
                   {
!                       /* if not found anything, that's an error */
!                       if (pos == NULL)
!                           clearopbeep(cap->oap);
                       n = 0;
                       break;
                   }
+                   c = gchar_cursor();
                   if (c == '{' || c == '}')
                   {
+                       /* Must have found end/start of class: use it.
+                        * Or found the place to be at. */
+                       if ((c == findc && norm) || (n == 1 && !norm))
+                       {
+                           new_pos = curwin->w_cursor;
+                           pos = &new_pos;
+                           n = 0;
+                       }
+                       /* if no match found at all, we started outside of the
+                        * class and we're inside now.  Just go on. */
+                       else if (new_pos.lnum == 0)
+                       {
+                           new_pos = curwin->w_cursor;
+                           pos = &new_pos;
+                       }
                       /* found start/end of other method: go to match */
!                       else if ((pos = findmatchlimit(cap->oap, findc,
                           (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD,
                                                                 0)) == NULL)
                           n = 0;
!                       else
!                           curwin->w_cursor = *pos;
                       break;
                   }
               }
*** ../vim-5.4n/src/testdir/test14.in   Sun Jul  4 20:35:24 1999
--- src/testdir/test14.in       Sat Jul 10 18:33:04 1999
***************
*** 1,16 ****
 Tests for "vaBiB", end could be wrong.
 Also test ":s/pat/sub/" with different ~s in sub.
 Also test for ^Vxff and ^Vo123 in Insert mode.

 STARTTEST
 /Start cursor here
! vaBiBD:?Bug?,$w! test.out
 /^- Bug
 :s/u/~u~/
 :s/i/~u~/
 :s/o/~~~/
 :.w >>test.out
 o65x42o103 33axfgo78:.w >>test.out
 :qa!
 ENDTEST

--- 1,30 ----
 Tests for "vaBiB", end could be wrong.
 Also test ":s/pat/sub/" with different ~s in sub.
 Also test for ^Vxff and ^Vo123 in Insert mode.
+ Also test "[m", "]m", "[M" and "]M"

 STARTTEST
 /Start cursor here
! vaBiBD:?Bug?,/Piece/-2w! test.out
 /^- Bug
 :s/u/~u~/
 :s/i/~u~/
 :s/o/~~~/
 :.w >>test.out
 o65x42o103 33axfgo78:.w >>test.out
+ /^Piece
+ 2]maA:.w >>test.out
+ j]maB:.w >>test.out
+ ]maC:.w >>test.out
+ [maD:.w >>test.out
+ k2[maE:.w >>test.out
+ 3[maF:.w >>test.out
+ ]MaG:.w >>test.out
+ j2]MaH:.w >>test.out
+ ]M]MaI:.w >>test.out
+ 2[MaJ:.w >>test.out
+ k[MaK:.w >>test.out
+ 3[MaL:.w >>test.out
 :qa!
 ENDTEST

***************
*** 23,25 ****
--- 37,57 ----
                       }
               }
       }
+
+ Piece of Java
+ {
+       tt m1 {
+               t1;
+       } e1
+
+       tt m2 {
+               t2;
+       } e2
+
+       tt m3 {
+               if (x)
+               {
+                       t3;
+               }
+       } e3
+ }
*** ../vim-5.4n/src/testdir/test14.ok   Sun Jul  4 20:35:25 1999
--- src/testdir/test14.ok       Sat Jul 10 18:33:09 1999
***************
*** 3,5 ****
--- 3,17 ----
       }
 - Bug uuun "vPPPP" uuuuuuuuun this text (Webb):
 ABC !ag8
+       tt m1 {A
+       tt m2 {B
+       tt m3 {C
+       tt m3 {DC
+       tt m1 {EA
+ {F
+       }G e1
+       }H e3
+ }I
+       }JH e3
+       }K e2
+ {LF
*** ../vim-5.4n/runtime/doc/motion.txt  Sun Jul  4 20:36:27 1999
--- runtime/doc/motion.txt      Sat Jul 10 18:21:28 1999
***************
*** 1,4 ****
! *motion.txt*    For Vim version 5.4n.  Last change: 1999 Jun 28


                 VIM REFERENCE MANUAL    by Bram Moolenaar
--- 1,4 ----
! *motion.txt*    For Vim version 5.4o.  Last change: 1999 Jul 10


                 VIM REFERENCE MANUAL    by Bram Moolenaar
***************
*** 791,808 ****
 Very useful for C programs.  Example: When standing on "case x:", "[{" will
 bring you back to the switch statement.

-                                               *[m*
- [m                    go to [count] previous start of method (for Java or
-                       similar structured language).  When not after the
-                       start of a method, jump to the start of the class.
-                       When no '{' is found before the cursor this is an
-                       error. {not in Vi}
                                               *]m*
! ]m                    go to [count] next end of method (for Java or
                       similar structured language).  When not before the end
!                       of a method, jump to the end of the class.  When no
!                       '}' is found after the cursor, this is an error. {not
!                       in Vi}

 The above two commands assume that the file contains a class with methods.
 The class definition is surrounded in '{' and '}'.  Each method in the class
--- 791,820 ----
 Very useful for C programs.  Example: When standing on "case x:", "[{" will
 bring you back to the switch statement.

                                               *]m*
! ]m                    Go to [count] next start of a method (for Java or
!                       similar structured language).  When not before the
!                       start of a method, jump to the start or end of the
!                       class.  When no '{' is found after the cursor, this is
!                       an error.  {not in Vi}
!                                               *]M*
! ]M                    Go to [count] next end of a method (for Java or
                       similar structured language).  When not before the end
!                       of a method, jump to the start or end of the class.
!                       When no '}' is found after the cursor, this is an
!                       error. {not in Vi}
!                                               *[m*
! [m                    Go to [count] previous start of a method (for Java or
!                       similar structured language).  When not after the
!                       start of a method, jump to the start or end of the
!                       class.  When no '{' is found before the cursor this is
!                       an error. {not in Vi}
!                                               *[M*
! [M                    Go to [count] previous end of a method (for Java or
!                       similar structured language).  When not after the
!                       end of a method, jump to the start or end of the
!                       class.  When no '}' is found before the cursor this is
!                       an error. {not in Vi}

 The above two commands assume that the file contains a class with methods.
 The class definition is surrounded in '{' and '}'.  Each method in the class

--
hundred-and-one symptoms of being an internet addict:
31. You code your homework in HTML and give your instructor the URL.

--/-/---- Bram Moolenaar ---- [email protected] ---- [email protected] ---\-\--
 \ \    www.vim.org/iccf      www.moolenaar.net       www.vim.org    / /