To: vim-dev@vim.org Subject: patch 5.4n.23 Fcc: outbox From: Bram Moolenaar ------------ 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 ---- Bram@moolenaar.net ---- Bram@vim.org ---\-\-- \ \ www.vim.org/iccf www.moolenaar.net www.vim.org / / .