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<CR>         is translated into: .,.+2d<CR>
  <
--- 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<CR>         is translated into: .,.+2d<CR>
  <
*** ../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 -- b...@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    ///

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20221111225903.07B4D1C0473%40moolenaar.net.

Raspunde prin e-mail lui