patch 9.1.0007: can select empty inner text blocks

Commit: 
https://github.com/vim/vim/commit/ad4d7f446dc6754bde212234d46f4849b520b6e0
Author: Christian Brabandt <[email protected]>
Date:   Thu Jan 4 21:43:36 2024 +0100

    patch 9.1.0007: can select empty inner text blocks
    
    Problem:  can select empty inner text blocks
              (laurentalacoque)
    Solution: make selecting empty inner text blocks an error
    
    textobjects: Make selecting inner empty blocks an error
    
    fixes: #13514
    closes: #13523
    
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/doc/motion.txt b/runtime/doc/motion.txt
index 448b68bce..8c07fbf53 100644
--- a/runtime/doc/motion.txt
+++ b/runtime/doc/motion.txt
@@ -600,7 +600,8 @@ i]                                          *v_i]* *v_i[* 
*i]* *i[*
 i[                     "inner [] block", select [count] '[' ']' blocks.  This
                        goes backwards to the [count] unclosed '[', and finds
                        the matching ']'.  The enclosed text is selected,
-                       excluding the '[' and ']'.  The |cpo-M| option flag
+                       excluding the '[' and ']'.  It's an error to select an
+                       empty inner block like "[]".  The |cpo-M| option flag
                        is used to handle escaped brackets.
                        When used in Visual mode it is made characterwise.
 
@@ -618,7 +619,8 @@ i(                                                  *vib* 
*v_ib* *v_i(* *ib*
 ib                     "inner block", select [count] blocks, from "[count] [("
                        to the matching ')', excluding the '(' and ')' (see
                        |[(|).  If the cursor is not inside a () block, then
-                       find the next "(".  The |cpo-M| option flag
+                       find the next "(".  It's an error to select an empty
+                       inner block like "()".  The |cpo-M| option flag
                        is used to handle escaped parenthesis.
                        When used in Visual mode it is made characterwise.
 
@@ -632,8 +634,9 @@ a<                  "a <> block", select [count] <> blocks, 
from the
 i>                                             *v_i>* *v_i<* *i>* *i<*
 i<                     "inner <> block", select [count] <> blocks, from
                        the [count]'th unmatched '<' backwards to the matching
-                       '>', excluding the '<' and '>'.  The |cpo-M| option flag
-                       is used to handle escaped '<' and '>'.
+                       '>', excluding the '<' and '>'.  It's an error to
+                       select an empty inner block like "<>".  The |cpo-M|
+                       option flag is used to handle escaped '<' and '>'.
                        When used in Visual mode it is made characterwise.
 
                                                *v_at* *at*
@@ -663,7 +666,8 @@ i}                                                  *v_i}* 
*i}* *i{*
 i{                                                     *v_iB* *v_i{* *iB*
 iB                     "inner Block", select [count] Blocks, from "[count] [{"
                        to the matching '}', excluding the '{' and '}' (see
-                       |[{|).  The |cpo-M| option flag is used to handle
+                       |[{|).  It's an error to select an empty inner block
+                       like "{}".  The |cpo-M| option flag is used to handle
                        escaped braces.
                        When used in Visual mode it is made characterwise.
 
diff --git a/src/testdir/test_textobjects.vim b/src/testdir/test_textobjects.vim
index 746b3268b..89e741c71 100644
--- a/src/testdir/test_textobjects.vim
+++ b/src/testdir/test_textobjects.vim
@@ -400,7 +400,7 @@ func Test_paragraph()
   call assert_beeps("normal Vipip")
   exe "normal \<C-C>"
 
-  close!
+  bw!
 endfunc
 
 " Tests for text object aw
@@ -606,7 +606,7 @@ func Test_textobj_quote()
   normal $hhyi"
   call assert_equal('bar', @")
 
-  close!
+  bw!
 endfunc
 
 " Test for i(, i<, etc. when cursor is in front of a block
@@ -638,7 +638,115 @@ func Test_textobj_find_paren_forward()
   normal 0di)
   call assert_equal('foo ()', getline(1))
 
-  close!
+  bw!
+endfunc
+
+func Test_inner_block_empty_paren()
+  new
+  call setline(1, ["(text)()", "", "(text)(", ")", "", "()()"])
+
+  " Example 1
+  call cursor(1, 1)
+  let @" = ''
+  call assert_beeps(':call feedkeys("0f(viby","xt")')
+  call assert_equal(7, getpos('.')[2])
+  call assert_equal('(', @")
+
+  " Example 2
+  call cursor(3, 1)
+  let @" = ''
+  call assert_beeps('call feedkeys("0f(viby", "xt")')
+  call assert_equal(7, getpos('.')[2])
+  call assert_equal('(', @")
+
+  " Example 3
+  call cursor(6, 1)
+  let @" = ''
+  call assert_beeps('call feedkeys("0f(viby", "xt")')
+  call assert_equal(3, getpos('.')[2])
+  call assert_equal('(', @")
+  bwipe!
+endfunc
+
+func Test_inner_block_empty_bracket()
+  new
+  call setline(1, ["[text][]", "", "[text][", "]", "", "[][]"])
+
+  " Example 1
+  call cursor(1, 1)
+  let @" = ''
+  call assert_beeps(':call feedkeys("0f[viby","xt")')
+  call assert_equal(7, getpos('.')[2])
+  call assert_equal('[', @")
+
+  " Example 2
+  call cursor(3, 1)
+  let @" = ''
+  call assert_beeps('call feedkeys("0f[viby", "xt")')
+  call assert_equal(7, getpos('.')[2])
+  call assert_equal('[', @")
+
+  " Example 3
+  call cursor(6, 1)
+  let @" = ''
+  call assert_beeps('call feedkeys("0f[viby", "xt")')
+  call assert_equal(3, getpos('.')[2])
+  call assert_equal('[', @")
+  bwipe!
+endfunc
+
+func Test_inner_block_empty_brace()
+  new
+  call setline(1, ["{text}{}", "", "{text}{", "}", "", "{}{}"])
+
+  " Example 1
+  call cursor(1, 1)
+  let @" = ''
+  call assert_beeps(':call feedkeys("0f{viby","xt")')
+  call assert_equal(7, getpos('.')[2])
+  call assert_equal('{', @")
+
+  " Example 2
+  call cursor(3, 1)
+  let @" = ''
+  call assert_beeps('call feedkeys("0f{viby", "xt")')
+  call assert_equal(7, getpos('.')[2])
+  call assert_equal('{', @")
+
+  " Example 3
+  call cursor(6, 1)
+  let @" = ''
+  call assert_beeps('call feedkeys("0f{viby", "xt")')
+  call assert_equal(3, getpos('.')[2])
+  call assert_equal('{', @")
+  bwipe!
+endfunc
+
+func Test_inner_block_empty_lessthan()
+  new
+  call setline(1, ["<text><>", "", "<text><", ">", "", "<><>"])
+
+  " Example 1
+  call cursor(1, 1)
+  let @" = ''
+  call assert_beeps(':call feedkeys("0f<viby","xt")')
+  call assert_equal(7, getpos('.')[2])
+  call assert_equal('<', @")
+
+  " Example 2
+  call cursor(3, 1)
+  let @" = ''
+  call assert_beeps('call feedkeys("0f<viby", "xt")')
+  call assert_equal(7, getpos('.')[2])
+  call assert_equal('<', @")
+
+  " Example 3
+  call cursor(6, 1)
+  let @" = ''
+  call assert_beeps('call feedkeys("0f<viby", "xt")')
+  call assert_equal(3, getpos('.')[2])
+  call assert_equal('<', @")
+  bwipe!
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/textobject.c b/src/textobject.c
index d03b6244e..af94d06bc 100644
--- a/src/textobject.c
+++ b/src/textobject.c
@@ -1131,6 +1131,11 @@ current_block(
                break;
        }
 
+       if (EQUAL_POS(start_pos, *end_pos))
+           // empty block like this: ()
+           // there is no inner block to select, abort
+           return FAIL;
+
        /*
         * In Visual mode, when the resulting area is not bigger than what we
         * started with, extend it to the next block, and then exclude again.
diff --git a/src/version.c b/src/version.c
index 3dc537d18..d00e80276 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    7,
 /**/
     6,
 /**/

-- 
-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1rLV3O-00D3VL-Vu%40256bit.org.

Raspunde prin e-mail lui