patch 8.2.3160: 'breakindent' does not work well for bulleted lists

Problem:    'breakindent' does not work well for bulleted and numbered lists.
Solution:   Add the "list" entry to 'breakindentopt'. (Christian Brabandt,
            closes #8564, closes #1661)
diff --git a/src/indent.c b/src/indent.c
index a26344b..cf07f4a 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -854,6 +854,7 @@
     int		bri_shift = 0;
     long	bri_min = 20;
     int		bri_sbr = FALSE;
+    int		bri_list = 0;
 
     p = wp->w_p_briopt;
     while (*p != NUL)
@@ -874,6 +875,11 @@
 	    p += 3;
 	    bri_sbr = TRUE;
 	}
+	else if (STRNCMP(p, "list:", 5) == 0)
+	{
+	    p += 5;
+	    bri_list = getdigits(&p);
+	}
 	if (*p != ',' && *p != NUL)
 	    return FAIL;
 	if (*p == ',')
@@ -883,6 +889,7 @@
     wp->w_briopt_shift = bri_shift;
     wp->w_briopt_min   = bri_min;
     wp->w_briopt_sbr   = bri_sbr;
+    wp->w_briopt_list  = bri_list;
 
     return OK;
 }
@@ -941,9 +948,25 @@
     // Add offset for number column, if 'n' is in 'cpoptions'
     bri += win_col_off2(wp);
 
+    // add additional indent for numbered lists
+    if (wp->w_briopt_list > 0)
+    {
+	regmatch_T	    regmatch;
+
+	regmatch.regprog = vim_regcomp(curbuf->b_p_flp,
+				   RE_MAGIC + RE_STRING + RE_AUTO + RE_STRICT);
+	if (regmatch.regprog != NULL)
+	{
+	    if (vim_regexec(&regmatch, line, 0))
+		bri += wp->w_briopt_list;
+	    vim_regfree(regmatch.regprog);
+	}
+    }
+
     // never indent past left window margin
     if (bri < 0)
 	bri = 0;
+
     // always leave at least bri_min characters on the left,
     // if text width is sufficient
     else if (bri > eff_wwidth - wp->w_briopt_min)
diff --git a/src/structs.h b/src/structs.h
index f1f8f32..5331183 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3671,6 +3671,7 @@
     int		w_briopt_min;	    // minimum width for breakindent
     int		w_briopt_shift;	    // additional shift for breakindent
     int		w_briopt_sbr;	    // sbr in 'briopt'
+    int		w_briopt_list;      // additional indent for lists
 #endif
 
     // transform a pointer to a "onebuf" option into a "allbuf" option
diff --git a/src/testdir/test_breakindent.vim b/src/testdir/test_breakindent.vim
index bb0f6dd..bfca06a 100644
--- a/src/testdir/test_breakindent.vim
+++ b/src/testdir/test_breakindent.vim
@@ -15,6 +15,10 @@
   return ScreenLines([a:lnum, a:lnum + 2], a:width)
 endfunc
 
+func s:screen_lines2(lnums, lnume, width) abort
+  return ScreenLines([a:lnums, a:lnume], a:width)
+endfunc
+
 func s:compare_lines(expect, actual)
   call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
 endfunc
@@ -708,4 +712,70 @@
   call s:close_windows('set breakindent& briopt& cpo& number&')
 endfunc
 
+func Test_breakindent20_list()
+  call s:test_windows('setl breakindent breakindentopt= linebreak')
+  " default:
+  call setline(1, ['  1.  Congress shall make no law',
+        \ '  2.) Congress shall make no law',
+        \ '  3.] Congress shall make no law'])
+  norm! 1gg
+  redraw!
+  let lines = s:screen_lines2(1, 6, 20)
+  let expect = [
+	\ "  1.  Congress      ",
+	\ "shall make no law   ",
+	\ "  2.) Congress      ",
+	\ "shall make no law   ",
+	\ "  3.] Congress      ",
+	\ "shall make no law   ",
+	\ ]
+  call s:compare_lines(expect, lines)
+  " set mininum indent
+  setl briopt=min:5
+  redraw!
+  let lines = s:screen_lines2(1, 6, 20)
+  let expect = [
+	\ "  1.  Congress      ",
+	\ "  shall make no law ",
+	\ "  2.) Congress      ",
+	\ "  shall make no law ",
+	\ "  3.] Congress      ",
+	\ "  shall make no law ",
+	\ ]
+  call s:compare_lines(expect, lines)
+  " set additional handing indent
+  setl briopt+=list:4
+  redraw!
+  let expect = [
+	\ "  1.  Congress      ",
+	\ "      shall make no ",
+	\ "      law           ",
+	\ "  2.) Congress      ",
+	\ "      shall make no ",
+	\ "      law           ",
+	\ "  3.] Congress      ",
+	\ "      shall make no ",
+	\ "      law           ",
+	\ ]
+  let lines = s:screen_lines2(1, 9, 20)
+  call s:compare_lines(expect, lines)
+  " reset linebreak option
+  " Note: it indents by one additional
+  " space, because of the leading space.
+  setl linebreak&vim list listchars=eol:$,space:_
+  redraw!
+  let expect = [
+	\ "__1.__Congress_shall",
+	\ "      _make_no_law$ ",
+	\ "__2.)_Congress_shall",
+	\ "      _make_no_law$ ",
+	\ "__3.]_Congress_shall",
+	\ "      _make_no_law$ ",
+	\ ]
+  let lines = s:screen_lines2(1, 6, 20)
+  call s:compare_lines(expect, lines)
+
+  call s:close_windows('set breakindent& briopt& linebreak& list& listchars&')
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 86a6380..e20a32c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3160,
+/**/
     3159,
 /**/
     3158,