Patch 8.2.4787
Problem: prop_find() does not find the right property.
Solution: Fix the scan order. (closes #10220)
Files: src/textprop.c, src/testdir/test_textprop.vim
*** ../vim-8.2.4786/src/textprop.c 2022-04-04 15:16:50.742014128 +0100
--- src/textprop.c 2022-04-18 21:53:08.566183423 +0100
***************
*** 713,726 ****
dictitem_T *di;
int lnum_start;
int start_pos_has_prop = 0;
! int seen_end = 0;
int id = 0;
int id_found = FALSE;
int type_id = -1;
! int skipstart = 0;
int lnum = -1;
int col = -1;
! int dir = 1; // 1 = forward, -1 = backward
int both;
if (in_vim9script()
--- 713,726 ----
dictitem_T *di;
int lnum_start;
int start_pos_has_prop = 0;
! int seen_end = FALSE;
int id = 0;
int id_found = FALSE;
int type_id = -1;
! int skipstart = FALSE;
int lnum = -1;
int col = -1;
! int dir = FORWARD; // FORWARD == 1, BACKWARD == -1
int both;
if (in_vim9script()
***************
*** 745,751 ****
char_u *dir_s = tv_get_string(&argvars[1]);
if (*dir_s == 'b')
! dir = -1;
else if (*dir_s != 'f')
{
emsg(_(e_invalid_argument));
--- 745,751 ----
char_u *dir_s = tv_get_string(&argvars[1]);
if (*dir_s == 'b')
! dir = BACKWARD;
else if (*dir_s != 'f')
{
emsg(_(e_invalid_argument));
***************
*** 819,835 ****
int prop_start;
int prop_end;
! for (i = 0; i < count; ++i)
{
mch_memmove(&prop, text + textlen + i * sizeof(textprop_T),
! sizeof(textprop_T));
if (lnum == lnum_start)
{
! if (dir < 0)
{
! if (col < prop.tp_col)
! break;
}
else if (prop.tp_col + prop.tp_len - (prop.tp_len != 0) < col)
continue;
--- 819,837 ----
int prop_start;
int prop_end;
! for (i = dir == BACKWARD ? count - 1 : 0; i >= 0 && i < count; i += dir)
{
mch_memmove(&prop, text + textlen + i * sizeof(textprop_T),
! sizeof(textprop_T));
+ // For the very first line try to find the first property before or
+ // after `col`, depending on the search direction.
if (lnum == lnum_start)
{
! if (dir == BACKWARD)
{
! if (prop.tp_col > col)
! continue;
}
else if (prop.tp_col + prop.tp_len - (prop.tp_len != 0) < col)
continue;
***************
*** 845,853 ****
- (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);
! if (!prop_start && prop_end && dir > 0)
seen_end = 1;
// Skip lines without the start flag.
--- 847,859 ----
- (prop.tp_len != 0)))
start_pos_has_prop = 1;
+ // The property was not continued from last line, it starts on
+ // this line.
prop_start = !(prop.tp_flags & TP_FLAG_CONT_PREV);
+ // The property does not continue on the next line, it ends on
+ // this line.
prop_end = !(prop.tp_flags & TP_FLAG_CONT_NEXT);
! if (!prop_start && prop_end && dir == FORWARD)
seen_end = 1;
// Skip lines without the start flag.
***************
*** 856,862 ****
// Always search backwards for start when search started
// on a prop and we're not skipping.
if (start_pos_has_prop && !skipstart)
! dir = -1;
continue;
}
--- 862,868 ----
// Always search backwards for start when search started
// on a prop and we're not skipping.
if (start_pos_has_prop && !skipstart)
! dir = BACKWARD;
continue;
}
***************
*** 887,894 ****
break;
lnum--;
}
- // Adjust col to indicate that we're continuing from prev/next line.
- col = dir < 0 ? buf->b_ml.ml_line_len : 1;
}
}
--- 893,898 ----
*** ../vim-8.2.4786/src/testdir/test_textprop.vim 2022-02-10 19:51:42.549569899 +0000
--- src/testdir/test_textprop.vim 2022-04-18 21:46:26.166369702 +0100
***************
*** 1847,1850 ****
--- 1847,1874 ----
call v9.CheckLegacyAndVim9Success(lines)
endfunc
+ func Test_prop_find_prev_on_same_line()
+ new
+
+ call setline(1, 'the quikc bronw fox jumsp over the layz dog')
+ call prop_type_add('misspell', #{highlight: 'ErrorMsg'})
+ for col in [8, 14, 24, 38]
+ call prop_add(1, col, #{type: 'misspell', length: 2})
+ endfor
+
+ call cursor(1,18)
+ let expected = [
+ \ #{lnum: 1, id: 0, col: 14, end: 1, type: 'misspell', type_bufnr: 0, length: 2, start: 1},
+ \ #{lnum: 1, id: 0, col: 24, end: 1, type: 'misspell', type_bufnr: 0, length: 2, start: 1}
+ \ ]
+
+ let result = prop_find(#{type: 'misspell'}, 'b')
+ call assert_equal(expected[0], result)
+ let result = prop_find(#{type: 'misspell'}, 'f')
+ call assert_equal(expected[1], result)
+
+ call prop_type_delete('misspell')
+ bwipe!
+ endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.4786/src/version.c 2022-04-18 19:16:50.929953487 +0100
--- src/version.c 2022-04-18 21:48:05.762325186 +0100
***************
*** 748,749 ****
--- 748,751 ----
{ /* Add new patch number below this line */
+ /**/
+ 4787,
/**/
--
"Making it up? Why should I want to make anything up? Life's bad enough
as it is without wanting to invent any more of it."
-- Marvin, the Paranoid Android in Douglas Adams'
"The Hitchhiker's Guide to the Galaxy"
/// Bram Moolenaar -- Br...@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 ///