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 -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
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/20220630211657.6A9D81C0501%40moolenaar.net.

Raspunde prin e-mail lui