Patch 9.0.0013

11 views
Skip to first unread message

Bram Moolenaar

unread,
Jun 30, 2022, 5:17:05 PM6/30/22
to vim...@googlegroups.com

Patch 9.0.0013
Problem: Reproducing memory access errors can be difficult.
Solution: When testing, copy each line to allocated memory, so that valgrind
can detect accessing memory before and/or after it. Fix uncovered
problems.
Files: runtime/doc/testing.txt, src/structs.h, src/globals.h,
src/testdir/runtest.vim, src/memline.c, src/edit.c, src/ops.c,
src/textprop.c, src/cindent.c, src/normal.c, src/netbeans.c,
src/change.c, src/testdir/test_edit.vim,
src/testdir/test_breakindent.vim


*** ../vim-9.0.0012/runtime/doc/testing.txt 2022-06-28 11:21:06.000000000 +0100
--- runtime/doc/testing.txt 2022-06-30 16:41:57.192764888 +0100
***************
*** 268,273 ****
--- 268,276 ----
Current supported values for {name} are:

{name} effect when {val} is non-zero ~
+ alloc_lines make a copy of every buffer line into allocated
+ memory, so that memory access errors can be found
+ by valgrind
autoload `import autoload` will load the script right
away, not postponed until an item is used
char_avail disable the char_avail() function
***************
*** 287,293 ****
uptime overrules sysinfo.uptime
vterm_title setting the window title by a job running in a
terminal window
! ALL clear all overrides ({val} is not used)

"starting" is to be used when a test should behave like
startup was done. Since the tests are run by sourcing a
--- 290,297 ----
uptime overrules sysinfo.uptime
vterm_title setting the window title by a job running in a
terminal window
! ALL clear all overrides, except alloc_lines ({val} is
! not used)

"starting" is to be used when a test should behave like
startup was done. Since the tests are run by sourcing a
*** ../vim-9.0.0012/src/structs.h 2022-06-14 13:26:55.000000000 +0100
--- src/structs.h 2022-06-30 16:33:11.213880764 +0100
***************
*** 756,765 ****
int ml_stack_top; // current top of ml_stack
int ml_stack_size; // total number of entries in ml_stack

! #define ML_EMPTY 1 // empty buffer
! #define ML_LINE_DIRTY 2 // cached line was changed and allocated
! #define ML_LOCKED_DIRTY 4 // ml_locked was changed
! #define ML_LOCKED_POS 8 // ml_locked needs positive block number
int ml_flags;

colnr_T ml_line_len; // length of the cached line, including NUL
--- 756,766 ----
int ml_stack_top; // current top of ml_stack
int ml_stack_size; // total number of entries in ml_stack

! #define ML_EMPTY 0x01 // empty buffer
! #define ML_LINE_DIRTY 0x02 // cached line was changed and allocated
! #define ML_LOCKED_DIRTY 0x04 // ml_locked was changed
! #define ML_LOCKED_POS 0x08 // ml_locked needs positive block number
! #define ML_ALLOCATED 0x10 // ml_line_ptr is an allocated copy
int ml_flags;

colnr_T ml_line_len; // length of the cached line, including NUL
*** ../vim-9.0.0012/src/globals.h 2022-06-19 12:17:14.000000000 +0100
--- src/globals.h 2022-06-30 16:44:09.300491955 +0100
***************
*** 1654,1659 ****
--- 1654,1660 ----
EXTERN int disable_vterm_title_for_testing INIT(= FALSE);
EXTERN long override_sysinfo_uptime INIT(= -1);
EXTERN int override_autoload INIT(= FALSE);
+ EXTERN int ml_get_alloc_lines INIT(= FALSE);

EXTERN int in_free_unref_items INIT(= FALSE);
#endif
*** ../vim-9.0.0012/src/testdir/runtest.vim 2022-06-15 18:59:52.000000000 +0100
--- src/testdir/runtest.vim 2022-06-30 22:07:31.526102234 +0100
***************
*** 154,159 ****
--- 154,163 ----
" Prepare for calling test_garbagecollect_now().
let v:testing = 1

+ " By default, copy each buffer line into allocated memory, so that valgrind can
+ " detect accessing memory before and after it.
+ call test_override('alloc_lines', 1)
+
" Support function: get the alloc ID by name.
function GetAllocId(name)
exe 'split ' . s:srcdir . '/alloc.h'
***************
*** 182,188 ****
" mode message.
set noshowmode

! " Clear any overrides.
call test_override('ALL', 0)

" Some tests wipe out buffers. To be consistent, always wipe out all
--- 186,192 ----
" mode message.
set noshowmode

! " Clear any overrides, except "alloc_lines".
call test_override('ALL', 0)

" Some tests wipe out buffers. To be consistent, always wipe out all
*** ../vim-9.0.0012/src/memline.c 2022-05-24 21:22:09.000000000 +0100
--- src/memline.c 2022-06-30 21:06:18.808784571 +0100
***************
*** 858,864 ****
if (buf->b_ml.ml_mfp == NULL) // not open
return;
mf_close(buf->b_ml.ml_mfp, del_file); // close the .swp file
! if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
vim_free(buf->b_ml.ml_line_ptr);
vim_free(buf->b_ml.ml_stack);
#ifdef FEAT_BYTEOFF
--- 858,865 ----
if (buf->b_ml.ml_mfp == NULL) // not open
return;
mf_close(buf->b_ml.ml_mfp, del_file); // close the .swp file
! if (buf->b_ml.ml_line_lnum != 0
! && (buf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED)))
vim_free(buf->b_ml.ml_line_ptr);
vim_free(buf->b_ml.ml_stack);
#ifdef FEAT_BYTEOFF
***************
*** 2620,2626 ****
--recursive;
}
ml_flush_line(buf);
- buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
errorret:
STRCPY(questions, "???");
buf->b_ml.ml_line_len = 4;
--- 2621,2626 ----
***************
*** 2686,2702 ****
buf->b_ml.ml_line_ptr = (char_u *)dp + start;
buf->b_ml.ml_line_len = len;
buf->b_ml.ml_line_lnum = lnum;
! buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
}
if (will_change)
buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);

return buf->b_ml.ml_line_ptr;
}

/*
* Check if a line that was just obtained by a call to ml_get
* is in allocated memory.
*/
int
ml_line_alloced(void)
--- 2686,2729 ----
buf->b_ml.ml_line_ptr = (char_u *)dp + start;
buf->b_ml.ml_line_len = len;
buf->b_ml.ml_line_lnum = lnum;
! buf->b_ml.ml_flags &= ~(ML_LINE_DIRTY | ML_ALLOCATED);
}
if (will_change)
+ {
buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
+ #ifdef FEAT_EVAL
+ if (ml_get_alloc_lines && (buf->b_ml.ml_flags & ML_ALLOCATED))
+ // can't make the change in the data block
+ buf->b_ml.ml_flags |= ML_LINE_DIRTY;
+ #endif
+ }
+
+ #ifdef FEAT_EVAL
+ if (ml_get_alloc_lines
+ && (buf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED)) == 0)
+ {
+ char_u *p = alloc(buf->b_ml.ml_line_len);

+ // make sure the text is in allocated memory
+ if (p != NULL)
+ {
+ memmove(p, buf->b_ml.ml_line_ptr, buf->b_ml.ml_line_len);
+ buf->b_ml.ml_line_ptr = p;
+ buf->b_ml.ml_flags |= ML_ALLOCATED;
+ if (will_change)
+ // can't make the change in the data block
+ buf->b_ml.ml_flags |= ML_LINE_DIRTY;
+ }
+ }
+ #endif
return buf->b_ml.ml_line_ptr;
}

/*
* Check if a line that was just obtained by a call to ml_get
* is in allocated memory.
+ * This ignores ML_ALLOCATED to get the same behavior as without the test
+ * override.
*/
int
ml_line_alloced(void)
***************
*** 3409,3414 ****
--- 3436,3443 ----
* "len_arg" is the length of the text, excluding NUL.
* If "has_props" is TRUE then "line_arg" includes the text properties and
* "len_arg" includes the NUL of the text.
+ * When "copy" is TRUE copy the text into allocated memory, otherwise
+ * "line_arg" must be allocated and will be consumed here.
*/
int
ml_replace_len(
***************
*** 3454,3460 ****
{
// another line is buffered, flush it
ml_flush_line(curbuf);
- curbuf->b_ml.ml_flags &= ~ML_LINE_DIRTY;

#ifdef FEAT_PROP_POPUP
if (curbuf->b_has_textprop && !has_props)
--- 3483,3488 ----
***************
*** 3488,3495 ****
}
#endif

! if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) // same line allocated
! vim_free(curbuf->b_ml.ml_line_ptr); // free it

curbuf->b_ml.ml_line_ptr = line;
curbuf->b_ml.ml_line_len = len;
--- 3516,3523 ----
}
#endif

! if (curbuf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED))
! vim_free(curbuf->b_ml.ml_line_ptr); // free allocated line

curbuf->b_ml.ml_line_ptr = line;
curbuf->b_ml.ml_line_len = len;
***************
*** 4064,4070 ****
--- 4092,4101 ----

entered = FALSE;
}
+ else if (buf->b_ml.ml_flags & ML_ALLOCATED)
+ vim_free(buf->b_ml.ml_line_ptr);

+ buf->b_ml.ml_flags &= ~(ML_LINE_DIRTY | ML_ALLOCATED);
buf->b_ml.ml_line_lnum = 0;
}

*** ../vim-9.0.0012/src/edit.c 2022-06-26 12:58:24.000000000 +0100
--- src/edit.c 2022-06-30 21:29:37.178822506 +0100
***************
*** 5013,5019 ****
mch_memmove(newp + col, ptr + i,
curbuf->b_ml.ml_line_len - col - i);

! if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY)
vim_free(curbuf->b_ml.ml_line_ptr);
curbuf->b_ml.ml_line_ptr = newp;
curbuf->b_ml.ml_line_len -= i;
--- 5013,5019 ----
mch_memmove(newp + col, ptr + i,
curbuf->b_ml.ml_line_len - col - i);

! if (curbuf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED))
vim_free(curbuf->b_ml.ml_line_ptr);
curbuf->b_ml.ml_line_ptr = newp;
curbuf->b_ml.ml_line_len -= i;
***************
*** 5232,5241 ****
}

// try to advance to the cursor column
temp = 0;
line = ptr = ml_get(lnum);
prev_ptr = ptr;
- validate_virtcol();
while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL)
{
prev_ptr = ptr;
--- 5232,5241 ----
}

// try to advance to the cursor column
+ validate_virtcol();
temp = 0;
line = ptr = ml_get(lnum);
prev_ptr = ptr;
while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL)
{
prev_ptr = ptr;
*** ../vim-9.0.0012/src/ops.c 2022-05-21 19:32:33.000000000 +0100
--- src/ops.c 2022-06-30 21:27:04.875745604 +0100
***************
*** 1273,1278 ****
--- 1273,1280 ----

netbeans_removed(curbuf, pos.lnum, bd.textcol,
(long)bd.textlen);
+ // get the line again, it may have been flushed
+ ptr = ml_get_buf(curbuf, pos.lnum, FALSE);
netbeans_inserted(curbuf, pos.lnum, bd.textcol,
&ptr[bd.textcol], bd.textlen);
}
***************
*** 1322,1327 ****
--- 1324,1331 ----
ptr = ml_get_buf(curbuf, pos.lnum, FALSE);
count = (int)STRLEN(ptr) - pos.col;
netbeans_removed(curbuf, pos.lnum, pos.col, (long)count);
+ // get the line again, it may have been flushed
+ ptr = ml_get_buf(curbuf, pos.lnum, FALSE);
netbeans_inserted(curbuf, pos.lnum, pos.col,
&ptr[pos.col], count);
pos.col = 0;
***************
*** 1330,1335 ****
--- 1334,1341 ----
ptr = ml_get_buf(curbuf, pos.lnum, FALSE);
count = oap->end.col - pos.col + 1;
netbeans_removed(curbuf, pos.lnum, pos.col, (long)count);
+ // get the line again, it may have been flushed
+ ptr = ml_get_buf(curbuf, pos.lnum, FALSE);
netbeans_inserted(curbuf, pos.lnum, pos.col,
&ptr[pos.col], count);
}
*** ../vim-9.0.0012/src/textprop.c 2022-06-16 11:34:23.000000000 +0100
--- src/textprop.c 2022-06-30 17:52:08.685848503 +0100
***************
*** 287,293 ****
props + i * sizeof(textprop_T),
sizeof(textprop_T) * (proplen - i));

! if (buf->b_ml.ml_flags & ML_LINE_DIRTY)
vim_free(buf->b_ml.ml_line_ptr);
buf->b_ml.ml_line_ptr = newtext;
buf->b_ml.ml_line_len += sizeof(textprop_T);
--- 287,293 ----
props + i * sizeof(textprop_T),
sizeof(textprop_T) * (proplen - i));

! if (buf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED))
vim_free(buf->b_ml.ml_line_ptr);
buf->b_ml.ml_line_ptr = newtext;
buf->b_ml.ml_line_len += sizeof(textprop_T);
***************
*** 564,570 ****
mch_memmove(newtext, text, textlen);
if (len > 0)
mch_memmove(newtext + textlen, props, len);
! if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY)
vim_free(curbuf->b_ml.ml_line_ptr);
curbuf->b_ml.ml_line_ptr = newtext;
curbuf->b_ml.ml_line_len = textlen + len;
--- 564,570 ----
mch_memmove(newtext, text, textlen);
if (len > 0)
mch_memmove(newtext + textlen, props, len);
! if (curbuf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED))
vim_free(curbuf->b_ml.ml_line_ptr);
curbuf->b_ml.ml_line_ptr = newtext;
curbuf->b_ml.ml_line_len = textlen + len;
***************
*** 698,703 ****
--- 698,705 ----
// need to allocate the line now
if (newtext == NULL)
return;
+ if (buf->b_ml.ml_flags & ML_ALLOCATED)
+ vim_free(buf->b_ml.ml_line_ptr);
buf->b_ml.ml_line_ptr = newtext;
buf->b_ml.ml_flags |= ML_LINE_DIRTY;
}
***************
*** 1273,1278 ****
--- 1275,1282 ----
return;
mch_memmove(newptr, buf->b_ml.ml_line_ptr,
buf->b_ml.ml_line_len);
+ if (buf->b_ml.ml_flags & ML_ALLOCATED)
+ vim_free(buf->b_ml.ml_line_ptr);
buf->b_ml.ml_line_ptr = newptr;
buf->b_ml.ml_flags |= ML_LINE_DIRTY;

***************
*** 1766,1773 ****
colnr_T newlen = (int)textlen + wi * (colnr_T)sizeof(textprop_T);

if ((curbuf->b_ml.ml_flags & ML_LINE_DIRTY) == 0)
! curbuf->b_ml.ml_line_ptr =
! vim_memsave(curbuf->b_ml.ml_line_ptr, newlen);
curbuf->b_ml.ml_flags |= ML_LINE_DIRTY;
curbuf->b_ml.ml_line_len = newlen;
}
--- 1770,1782 ----
colnr_T newlen = (int)textlen + wi * (colnr_T)sizeof(textprop_T);

if ((curbuf->b_ml.ml_flags & ML_LINE_DIRTY) == 0)
! {
! char_u *p = vim_memsave(curbuf->b_ml.ml_line_ptr, newlen);
!
! if (curbuf->b_ml.ml_flags & ML_ALLOCATED)
! vim_free(curbuf->b_ml.ml_line_ptr);
! curbuf->b_ml.ml_line_ptr = p;
! }
curbuf->b_ml.ml_flags |= ML_LINE_DIRTY;
curbuf->b_ml.ml_line_len = newlen;
}
*** ../vim-9.0.0012/src/cindent.c 2022-05-21 19:11:25.000000000 +0100
--- src/cindent.c 2022-06-30 20:29:34.168129338 +0100
***************
*** 2794,2801 ****
break;
}

- l = ml_get_curline();
-
// If we're in a comment or raw string now, skip to
// the start of it.
trypos = ind_find_start_CORS(NULL);
--- 2794,2799 ----
***************
*** 2806,2811 ****
--- 2804,2811 ----
continue;
}

+ l = ml_get_curline();
+
// Skip preprocessor directives and blank lines.
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum,
&amount))
***************
*** 2905,2912 ****
< ourscope - FIND_NAMESPACE_LIM)
break;

- l = ml_get_curline();
-
// If we're in a comment or raw string now, skip
// to the start of it.
trypos = ind_find_start_CORS(NULL);
--- 2905,2910 ----
***************
*** 2917,2922 ****
--- 2915,2922 ----
continue;
}

+ l = ml_get_curline();
+
// Skip preprocessor directives and blank lines.
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum,
&amount))
***************
*** 3196,3206 ****
&& trypos->col < tryposBrace->col)))
trypos = NULL;

// If we are looking for ',', we also look for matching
// braces.
! if (trypos == NULL && terminated == ','
! && find_last_paren(l, '{', '}'))
! trypos = find_start_brace();

if (trypos != NULL)
{
--- 3196,3211 ----
&& trypos->col < tryposBrace->col)))
trypos = NULL;

+ l = ml_get_curline();
+
// If we are looking for ',', we also look for matching
// braces.
! if (trypos == NULL && terminated == ',')
! {
! if (find_last_paren(l, '{', '}'))
! trypos = find_start_brace();
! l = ml_get_curline();
! }

if (trypos != NULL)
{
***************
*** 3233,3238 ****
--- 3238,3244 ----
--curwin->w_cursor.lnum;
curwin->w_cursor.col = 0;
}
+ l = ml_get_curline();
}

// Get indent and pointer to text for current line,
*** ../vim-9.0.0012/src/normal.c 2022-06-16 13:02:16.000000000 +0100
--- src/normal.c 2022-06-30 21:12:40.915606329 +0100
***************
*** 5120,5125 ****
--- 5120,5127 ----
count = (int)STRLEN(ptr) - pos.col;
netbeans_removed(curbuf, pos.lnum, pos.col,
(long)count);
+ // line may have been flushed, get it again
+ ptr = ml_get(pos.lnum);
netbeans_inserted(curbuf, pos.lnum, pos.col,
&ptr[pos.col], count);
}
*** ../vim-9.0.0012/src/netbeans.c 2022-06-16 11:08:29.000000000 +0100
--- src/netbeans.c 2022-06-30 21:15:41.199085164 +0100
***************
*** 2741,2753 ****
if (nbbuf->insertDone)
nbbuf->modified = 1;

pos.lnum = linenr;
pos.col = col;
off = pos2off(bufp, &pos);

- // send the "insert" EVT
- newtxt = alloc(newlen + 1);
- vim_strncpy(newtxt, txt, newlen);
p = nb_quote(newtxt);
if (p != NULL)
{
--- 2741,2755 ----
if (nbbuf->insertDone)
nbbuf->modified = 1;

+ // send the "insert" EVT
+ newtxt = alloc(newlen + 1);
+ vim_strncpy(newtxt, txt, newlen);
+
+ // Note: this may make "txt" invalid
pos.lnum = linenr;
pos.col = col;
off = pos2off(bufp, &pos);

p = nb_quote(newtxt);
if (p != NULL)
{
*** ../vim-9.0.0012/src/change.c 2022-05-31 13:31:50.000000000 +0100
--- src/change.c 2022-06-30 21:38:24.380228427 +0100
***************
*** 1535,1547 ****
{
// End of C comment, indent should line up
// with the line containing the start of
! // the comment
curwin->w_cursor.col = (colnr_T)(p - ptr);
if ((pos = findmatch(NULL, NUL)) != NULL)
{
curwin->w_cursor.lnum = pos->lnum;
newindent = get_indent();
}
}
}
}
--- 1535,1551 ----
{
// End of C comment, indent should line up
// with the line containing the start of
! // the comment.
curwin->w_cursor.col = (colnr_T)(p - ptr);
if ((pos = findmatch(NULL, NUL)) != NULL)
{
curwin->w_cursor.lnum = pos->lnum;
newindent = get_indent();
+ break;
}
+ // this may make "ptr" invalid, get it again
+ ptr = ml_get(curwin->w_cursor.lnum);
+ p = ptr + curwin->w_cursor.col;
}
}
}
*** ../vim-9.0.0012/src/testdir/test_edit.vim 2022-06-19 15:20:24.000000000 +0100
--- src/testdir/test_edit.vim 2022-06-30 17:32:53.183525611 +0100
***************
*** 1860,1865 ****
--- 1860,1868 ----
call writefile(lines, 'Xtest_edit_insertmode_ex_edit')

let buf = RunVimInTerminal('-S Xtest_edit_insertmode_ex_edit', #{rows: 6})
+ " Somehow this can be very slow with valgrind. A separate TermWait() works
+ " better than a longer time with WaitForAssert() (why?)
+ call TermWait(buf, 1000)
call WaitForAssert({-> assert_match('^-- INSERT --\s*$', term_getline(buf, 6))})
call term_sendkeys(buf, "\<C-B>\<C-L>")
call WaitForAssert({-> assert_notmatch('^-- INSERT --\s*$', term_getline(buf, 6))})
*** ../vim-9.0.0012/src/testdir/test_breakindent.vim 2022-05-06 12:05:02.000000000 +0100
--- src/testdir/test_breakindent.vim 2022-06-30 22:11:10.065395673 +0100
***************
*** 10,16 ****
source view_util.vim
source screendump.vim

! let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP"

func s:screen_lines(lnum, width) abort
return ScreenLines([a:lnum, a:lnum + 2], a:width)
--- 10,18 ----
source view_util.vim
source screendump.vim

! func SetUp()
! let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP"
! endfunc

func s:screen_lines(lnum, width) abort
return ScreenLines([a:lnum, a:lnum + 2], a:width)
***************
*** 714,719 ****
--- 716,724 ----
endfunc

func Test_breakindent20_list()
+ " FIXME - this should not matter
+ call test_override('alloc_lines', 0)
+
call s:test_windows('setl breakindent breakindentopt= linebreak')
" default:
call setline(1, [' 1. Congress shall make no law',
***************
*** 830,835 ****
--- 835,843 ----
let lines = s:screen_lines2(1, 6, 20)
call s:compare_lines(expect, lines)
call s:close_windows('set breakindent& briopt& linebreak& list& listchars& showbreak&')
+
+ " FIXME - this should not matter
+ call test_override('alloc_lines', 1)
endfunc

" The following used to crash Vim. This is fixed by 8.2.3391.
***************
*** 873,887 ****
endfunc

func Test_no_spurious_match()
let s:input = printf('- y %s y %s', repeat('x', 50), repeat('x', 50))
call s:test_windows('setl breakindent breakindentopt=list:-1 formatlistpat=^- hls')
let @/ = '\%>3v[y]'
redraw!
call searchcount().total->assert_equal(1)
" cleanup
set hls&vim
- let s:input = "\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP"
bwipeout!
endfunc

func Test_no_extra_indent()
--- 881,900 ----
endfunc

func Test_no_spurious_match()
+ " FIXME - fails under valgrind - this should not matter - timing issue?
+ call test_override('alloc_lines', 0)
+
let s:input = printf('- y %s y %s', repeat('x', 50), repeat('x', 50))
call s:test_windows('setl breakindent breakindentopt=list:-1 formatlistpat=^- hls')
let @/ = '\%>3v[y]'
redraw!
call searchcount().total->assert_equal(1)
+
" cleanup
set hls&vim
bwipeout!
+ " FIXME - this should not matter
+ call test_override('alloc_lines', 1)
endfunc

func Test_no_extra_indent()
***************
*** 945,952 ****
endfunc

func Test_breakindent_column()
- " restore original
- let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP"
call s:test_windows('setl breakindent breakindentopt=column:10')
redraw!
" 1) default: does not indent, too wide :(
--- 958,963 ----
*** ../vim-9.0.0012/src/version.c 2022-06-30 16:25:14.782979300 +0100
--- src/version.c 2022-06-30 17:33:10.191399066 +0100
***************
*** 737,738 ****
--- 737,740 ----
{ /* Add new patch number below this line */
+ /**/
+ 13,
/**/

--
`The Guide says there is an art to flying,' said Ford, `or at least a
knack. The knack lies in learning how to throw yourself at the ground
and miss.' He smiled weakly.
-- 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 ///
Reply all
Reply to author
Forward
0 new messages