]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.0858: "!!sort" in a closed fold sorts too many lines v9.0.0858
authorBram Moolenaar <Bram@vim.org>
Fri, 11 Nov 2022 01:20:35 +0000 (01:20 +0000)
committerBram Moolenaar <Bram@vim.org>
Fri, 11 Nov 2022 01:20:35 +0000 (01:20 +0000)
Problem:    "!!sort" in a closed fold sorts too many lines.
Solution:   Round to end of fold after adding the line count. (closes #11487)

src/ex_docmd.c
src/testdir/test_fold.vim
src/version.c

index f5b39804653e4b8c3a1f57a43bb887329b2e6157..a445c3135cb9f647c71090baf079a4ebcc1ac65e 100644 (file)
@@ -4308,6 +4308,8 @@ get_address(
     lnum = MAXLNUM;
     do
     {
+       int base_char = *cmd;
+
        switch (*cmd)
        {
            case '.':                       // '.' - Cursor position
@@ -4602,10 +4604,11 @@ get_address(
                i = '+';                // "number" is same as "+number"
            else
                i = *cmd++;
-           if (!VIM_ISDIGIT(*cmd))     // '+' is '+1', but '+0' is not '+1'
+           if (!VIM_ISDIGIT(*cmd))     // '+' is '+1'
                n = 1;
            else
            {
+               // "number", "+number" or "-number"
                n = getdigits(&cmd);
                if (n == MAXLNUM)
                {
@@ -4627,10 +4630,16 @@ get_address(
            else
            {
 #ifdef FEAT_FOLDING
-               // Relative line addressing, need to adjust for folded lines
-               // now, but only do it after the first address.
-               if (addr_type == ADDR_LINES && (i == '-' || i == '+')
-                                                        && address_count >= 2)
+               // 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 == '-')
@@ -4643,6 +4652,12 @@ get_address(
                        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
                }
            }
        }
index e22ede9a1bc7a3ad5186d864dbb6fe5c209747b0..a14772134ca938dfce9bc84a003d948567b8792c 100644 (file)
@@ -1570,4 +1570,40 @@ func Test_indent_append_blank_small_fold_close()
   bw!
 endfunc
 
+func Test_sort_closed_fold()
+  CheckExecutable sort
+
+  call setline(1, [
+        \ 'Section 1',
+        \ '   how',
+        \ '   now',
+        \ '   brown',
+        \ '   cow',
+        \ 'Section 2',
+        \ '   how',
+        \ '   now',
+        \ '   brown',
+        \ '   cow',
+        \])
+  setlocal foldmethod=indent sw=3
+  normal 2G
+
+  " The "!!" expands to ".,.+3" and must only sort four lines
+  call feedkeys("!!sort\<CR>", 'xt')
+  call assert_equal([
+        \ 'Section 1',
+        \ '   brown',
+        \ '   cow',
+        \ '   how',
+        \ '   now',
+        \ 'Section 2',
+        \ '   how',
+        \ '   now',
+        \ '   brown',
+        \ '   cow',
+        \ ], getline(1, 10))
+
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index 19f0692dba1b4e5497ce04c6c03586653d6fd7ba..981bd548a88b0dc74dec89e48e1544c70fd83605 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    858,
 /**/
     857,
 /**/