changeset 19631:1d493fce1fbd v8.2.0372

patch 8.2.0372: prop_find() may not find text property at start of the line Commit: https://github.com/vim/vim/commit/66b98854d86f641db036fd1e6cf20f7b8905344e Author: Bram Moolenaar <Bram@vim.org> Date: Wed Mar 11 19:15:52 2020 +0100 patch 8.2.0372: prop_find() may not find text property at start of the line Problem: Prop_find() may not find text property at start of the line. Solution: Adjust the loop to find properties. (Axel Forsman, closes https://github.com/vim/vim/issues/5761, closes #5663)
author Bram Moolenaar <Bram@vim.org>
date Wed, 11 Mar 2020 21:31:02 +0100
parents 522158d28042
children 182d7acd6737
files src/testdir/test_textprop.vim src/textprop.c src/version.c
diffstat 3 files changed, 44 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_textprop.vim
+++ b/src/testdir/test_textprop.vim
@@ -1166,3 +1166,30 @@ func Test_textprop_ins_str()
   call prop_remove({'type': 'test'})
   call prop_type_delete('test')
 endfunc
+
+func Test_find_prop_later_in_line()
+  new
+  call prop_type_add('test', {'highlight': 'ErrorMsg'})
+  call setline(1, 'just some text')
+  call prop_add(1, 1, {'length': 4, 'type': 'test'})
+  call prop_add(1, 10, {'length': 3, 'type': 'test'})
+
+  call assert_equal({'id': 0, 'lnum': 1, 'col': 10, 'end': 1, 'type': 'test', 'length': 3, 'start': 1},
+			  \ prop_find(#{type: 'test', lnum: 1, col: 6}))
+
+  bwipe!
+  call prop_type_delete('test')
+endfunc
+
+func Test_find_zerowidth_prop_sol()
+  new
+  call prop_type_add('test', {'highlight': 'ErrorMsg'})
+  call setline(1, 'just some text')
+  call prop_add(1, 1, {'length': 0, 'type': 'test'})
+
+  call assert_equal({'id': 0, 'lnum': 1, 'col': 1, 'end': 1, 'type': 'test', 'length': 0, 'start': 1},
+			  \ prop_find(#{type: 'test', lnum: 1}))
+
+  bwipe!
+  call prop_type_delete('test')
+endfunc
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -663,24 +663,22 @@ f_prop_find(typval_T *argvars, typval_T 
 	    mch_memmove(&prop, text + textlen + i * sizeof(textprop_T),
 			    sizeof(textprop_T));
 
+	    if (dir < 0)
+	    {
+		if (col < prop.tp_col)
+		    break;
+	    }
+	    else if (prop.tp_col + prop.tp_len - (prop.tp_len != 0) < col)
+		continue;
+
 	    if (prop.tp_id == id || prop.tp_type == type_id)
 	    {
 		// Check if the starting position has text props.
-		if (lnum_start == lnum)
-		{
-		    if (col >= prop.tp_col
-				       && (col <= prop.tp_col + prop.tp_len-1))
-			start_pos_has_prop = 1;
-		}
-		else
-		{
-		    // Not at the first line of the search so adjust col to
-		    // indicate that we're continuing from prev/next line.
-		    if (dir < 0)
-			col = buf->b_ml.ml_line_len;
-		    else
-			col = 1;
-		}
+		if (lnum_start == lnum
+			&& col >= prop.tp_col
+			&& (col <= prop.tp_col + prop.tp_len
+							 - (prop.tp_len != 0)))
+		    start_pos_has_prop = 1;
 
 		prop_start = !(prop.tp_flags & TP_FLAG_CONT_PREV);
 		prop_end = !(prop.tp_flags & TP_FLAG_CONT_NEXT);
@@ -705,17 +703,6 @@ f_prop_find(typval_T *argvars, typval_T 
 		    break;
 		}
 
-		if (dir < 0)
-		{
-		    if (col < prop.tp_col)
-			break;
-		}
-		else
-		{
-		    if (col > prop.tp_col + prop.tp_len-1)
-			break;
-		}
-
 		prop_fill_dict(rettv->vval.v_dict, &prop, buf);
 		dict_add_number(rettv->vval.v_dict, "lnum", lnum);
 
@@ -735,6 +722,8 @@ f_prop_find(typval_T *argvars, typval_T 
 		break;
 	    lnum--;
 	}
+	// Adjust col to indicate that we're continuing from prev/next line.
+	col = dir < 0 ? buf->b_ml.ml_line_len : 1;
     }
 }
 
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    372,
+/**/
     371,
 /**/
     370,