To: vim_dev@googlegroups.com Subject: Patch 9.0.0861 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0861 (after 9.0.0858) Problem: Solution for "!!sort" in closed fold is not optimal. Solution: Use a different range instead of the subtle difference in handling a range with an offset. (issue #11487) Files: runtime/doc/cmdline.txt, src/ops.c, src/ex_docmd.c, src/testdir/test_fold.vim *** ../vim-9.0.0860/runtime/doc/cmdline.txt 2022-10-04 16:23:39.002042197 +0100 --- runtime/doc/cmdline.txt 2022-11-11 22:51:01.745976916 +0000 *************** *** 736,742 **** --- 736,744 ---- 'T position of mark T (uppercase); when the mark is in another file it cannot be used in a range /{pattern}[/] the next line where {pattern} matches *:/* + also see |:range-pattern| below ?{pattern}[?] the previous line where {pattern} matches *:?* + also see |:range-pattern| below \/ the next line where the previously used search pattern matches \? the previous line where the previously used search *************** *** 744,754 **** --- 746,794 ---- \& the next line where the previously used substitute pattern matches + *:range-offset* Each may be followed (several times) by '+' or '-' and an optional number. This number is added or subtracted from the preceding line number. If the number is omitted, 1 is used. If there is nothing before the '+' or '-' then the current line is used. + *:range-closed-fold* + When a line number after the comma is in a closed fold it is adjusted to the + last line of the fold, thus the whole fold is included. + + When a number is added this is done after the adjustment to the last line of + the fold. This means these lines are additionally included in the range. For + example: > + :3,4+2print + On this text: + 1 one ~ + 2 two ~ + 3 three ~ + 4 four FOLDED ~ + 5 five FOLDED ~ + 6 six ~ + 7 seven ~ + 8 eight ~ + Where lines four and five are a closed fold, ends up printing lines 3 to 7. + The 7 comes from the "4" in the range, which is adjusted to the end of the + closed fold, which is 5, and then the offset 2 is added. + + An example for subtracting (which isn't very useful): > + :2,4-1print + On this text: + 1 one ~ + 2 two ~ + 3 three FOLDED~ + 4 four FOLDED ~ + 5 five FOLDED ~ + 6 six FOLDED ~ + 7 seven ~ + 8 eight ~ + Where lines three to six are a closed fold, ends up printing lines 2 to 6. + The 6 comes from the "4" in the range, which is adjusted to the end of the + closed fold, which is 6, and then 1 is subtracted, then this is still in the + closed fold and the last line of that fold is used, which is 6. + *:range-pattern* The "/" and "?" after {pattern} are required to separate the pattern from anything that follows. *************** *** 804,812 **** Count and Range *N:* ! When giving a count before entering ":", this is translated into: :.,.+(count - 1) ! In words: The 'count' lines at and after the cursor. Example: To delete three lines: > 3:d is translated into: .,.+2d < --- 844,852 ---- Count and Range *N:* ! When giving a count before entering ":", this is translated into: > :.,.+(count - 1) ! In words: The "count" lines at and after the cursor. Example: To delete three lines: > 3:d is translated into: .,.+2d < *** ../vim-9.0.0860/src/ops.c 2022-10-15 16:41:49.780490432 +0100 --- src/ops.c 2022-11-11 22:02:21.689369371 +0000 *************** *** 3333,3346 **** stuffcharReadbuff('.'); else stuffnumReadbuff((long)oap->start.lnum); ! if (oap->end.lnum != oap->start.lnum) { stuffcharReadbuff(','); if (oap->end.lnum == curwin->w_cursor.lnum) stuffcharReadbuff('.'); else if (oap->end.lnum == curbuf->b_ml.ml_line_count) stuffcharReadbuff('$'); ! else if (oap->start.lnum == curwin->w_cursor.lnum) { stuffReadbuff((char_u *)".+"); stuffnumReadbuff((long)oap->line_count - 1); --- 3333,3364 ---- stuffcharReadbuff('.'); else stuffnumReadbuff((long)oap->start.lnum); ! ! #ifdef FEAT_FOLDING ! // When using !! on a closed fold the range ".!" works best to operate ! // on, it will be made the whole closed fold later. ! linenr_T endOfStartFold = oap->start.lnum; ! (void)hasFolding(oap->start.lnum, NULL, &endOfStartFold); ! #endif ! if (oap->end.lnum != oap->start.lnum ! #ifdef FEAT_FOLDING ! && oap->end.lnum != endOfStartFold ! #endif ! ) { + // Make it a range with the end line. stuffcharReadbuff(','); if (oap->end.lnum == curwin->w_cursor.lnum) stuffcharReadbuff('.'); else if (oap->end.lnum == curbuf->b_ml.ml_line_count) stuffcharReadbuff('$'); ! else if (oap->start.lnum == curwin->w_cursor.lnum ! #ifdef FEAT_FOLDING ! // do not use ".+number" for a closed fold, it would count ! // folded lines twice ! && !hasFolding(oap->end.lnum, NULL, NULL) ! #endif ! ) { stuffReadbuff((char_u *)".+"); stuffnumReadbuff((long)oap->line_count - 1); *** ../vim-9.0.0860/src/ex_docmd.c 2022-11-11 01:40:44.430990388 +0000 --- src/ex_docmd.c 2022-11-11 22:31:58.109716105 +0000 *************** *** 4308,4316 **** lnum = MAXLNUM; do { - #ifdef FEAT_FOLDING - int base_char = *cmd; - #endif switch (*cmd) { case '.': // '.' - Cursor position --- 4308,4313 ---- *************** *** 4631,4646 **** else { #ifdef FEAT_FOLDING ! // Relative line addressing: need to adjust for closed folds ! // after the first address. ! // Subtle difference: "number,+number" and "number,-number" ! // adjusts to end of closed fold before adding/subtracting, ! // while "number,.+number" adjusts to end of closed fold after ! // adding to make "!!" expanded into ".,.+N" work correctly. ! int adjust_for_folding = addr_type == ADDR_LINES ! && (i == '-' || i == '+') ! && address_count >= 2; ! if (adjust_for_folding && (i == '-' || base_char != '.')) (void)hasFolding(lnum, NULL, &lnum); #endif if (i == '-') --- 4628,4637 ---- else { #ifdef FEAT_FOLDING ! // Relative line addressing: need to adjust for lines in a ! // closed fold after the first address. ! if (addr_type == ADDR_LINES && (i == '-' || i == '+') ! && address_count >= 2) (void)hasFolding(lnum, NULL, &lnum); #endif if (i == '-') *************** *** 4653,4664 **** goto error; } lnum += n; - #ifdef FEAT_FOLDING - // ".+number" rounds up to the end of a closed fold after - // adding, so that ":!!sort" sorts one closed fold. - if (adjust_for_folding && base_char == '.') - (void)hasFolding(lnum, NULL, &lnum); - #endif } } } --- 4644,4649 ---- *** ../vim-9.0.0860/src/testdir/test_fold.vim 2022-11-11 01:20:31.682555519 +0000 --- src/testdir/test_fold.vim 2022-11-11 22:43:41.513844255 +0000 *************** *** 72,77 **** --- 72,125 ---- quit! endfunc + func Test_address_offsets() + " check the help for :range-closed-fold + enew + call setline(1, [ + \ '1 one', + \ '2 two', + \ '3 three', + \ '4 four FOLDED', + \ '5 five FOLDED', + \ '6 six', + \ '7 seven', + \ '8 eight', + \]) + set foldmethod=manual + normal 4Gvjzf + 3,4+2yank + call assert_equal([ + \ '3 three', + \ '4 four FOLDED', + \ '5 five FOLDED', + \ '6 six', + \ '7 seven', + \ ], getreg(0,1,1)) + + enew! + call setline(1, [ + \ '1 one', + \ '2 two', + \ '3 three FOLDED', + \ '4 four FOLDED', + \ '5 five FOLDED', + \ '6 six FOLDED', + \ '7 seven', + \ '8 eight', + \]) + normal 3Gv3jzf + 2,4-1yank + call assert_equal([ + \ '2 two', + \ '3 three FOLDED', + \ '4 four FOLDED', + \ '5 five FOLDED', + \ '6 six FOLDED', + \ ], getreg(0,1,1)) + + bwipe! + endfunc + func Test_indent_fold() new call setline(1, ['', 'a', ' b', ' c']) *** ../vim-9.0.0860/src/version.c 2022-11-11 21:24:14.547283117 +0000 --- src/version.c 2022-11-11 22:04:17.269460872 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 861, /**/ -- Well, you come from nothing, you go back to nothing... What have you lost? Nothing! -- Monty Python: The life of Brian /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///