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)
This commit is contained in:
Christian Brabandt
2021-07-14 20:00:27 +02:00
committed by Bram Moolenaar
parent 5bea41dea3
commit 4a0b85ad01
5 changed files with 100 additions and 1 deletions

View File

@ -1326,7 +1326,10 @@ A jump table for the options with a short description can be found at |Q_op|.
continuation (positive). continuation (positive).
sbr Display the 'showbreak' value before applying the sbr Display the 'showbreak' value before applying the
additional indent. additional indent.
The default value for min is 20 and shift is 0. list:{n} Adds an additional indent for lines that match a
numbered or bulleted list (using the
'formatlistpat' setting).
The default value for min is 20, shift and list is 0.
*'browsedir'* *'bsdir'* *'browsedir'* *'bsdir'*
'browsedir' 'bsdir' string (default: "last") 'browsedir' 'bsdir' string (default: "last")

View File

@ -854,6 +854,7 @@ briopt_check(win_T *wp)
int bri_shift = 0; int bri_shift = 0;
long bri_min = 20; long bri_min = 20;
int bri_sbr = FALSE; int bri_sbr = FALSE;
int bri_list = 0;
p = wp->w_p_briopt; p = wp->w_p_briopt;
while (*p != NUL) while (*p != NUL)
@ -874,6 +875,11 @@ briopt_check(win_T *wp)
p += 3; p += 3;
bri_sbr = TRUE; bri_sbr = TRUE;
} }
else if (STRNCMP(p, "list:", 5) == 0)
{
p += 5;
bri_list = getdigits(&p);
}
if (*p != ',' && *p != NUL) if (*p != ',' && *p != NUL)
return FAIL; return FAIL;
if (*p == ',') if (*p == ',')
@ -883,6 +889,7 @@ briopt_check(win_T *wp)
wp->w_briopt_shift = bri_shift; wp->w_briopt_shift = bri_shift;
wp->w_briopt_min = bri_min; wp->w_briopt_min = bri_min;
wp->w_briopt_sbr = bri_sbr; wp->w_briopt_sbr = bri_sbr;
wp->w_briopt_list = bri_list;
return OK; return OK;
} }
@ -941,9 +948,25 @@ get_breakindent_win(
// Add offset for number column, if 'n' is in 'cpoptions' // Add offset for number column, if 'n' is in 'cpoptions'
bri += win_col_off2(wp); 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 // never indent past left window margin
if (bri < 0) if (bri < 0)
bri = 0; bri = 0;
// always leave at least bri_min characters on the left, // always leave at least bri_min characters on the left,
// if text width is sufficient // if text width is sufficient
else if (bri > eff_wwidth - wp->w_briopt_min) else if (bri > eff_wwidth - wp->w_briopt_min)

View File

@ -3671,6 +3671,7 @@ struct window_S
int w_briopt_min; // minimum width for breakindent int w_briopt_min; // minimum width for breakindent
int w_briopt_shift; // additional shift for breakindent int w_briopt_shift; // additional shift for breakindent
int w_briopt_sbr; // sbr in 'briopt' int w_briopt_sbr; // sbr in 'briopt'
int w_briopt_list; // additional indent for lists
#endif #endif
// transform a pointer to a "onebuf" option into a "allbuf" option // transform a pointer to a "onebuf" option into a "allbuf" option

View File

@ -15,6 +15,10 @@ func s:screen_lines(lnum, width) abort
return ScreenLines([a:lnum, a:lnum + 2], a:width) return ScreenLines([a:lnum, a:lnum + 2], a:width)
endfunc endfunc
func s:screen_lines2(lnums, lnume, width) abort
return ScreenLines([a:lnums, a:lnume], a:width)
endfunc
func s:compare_lines(expect, actual) func s:compare_lines(expect, actual)
call assert_equal(join(a:expect, "\n"), join(a:actual, "\n")) call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
endfunc endfunc
@ -708,4 +712,70 @@ func Test_breakindent20_cpo_n_nextpage()
call s:close_windows('set breakindent& briopt& cpo& number&') call s:close_windows('set breakindent& briopt& cpo& number&')
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@ -755,6 +755,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
3160,
/**/ /**/
3159, 3159,
/**/ /**/