vim-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 vim/vim#8564, closes vim/vim#1661)
4a0b85ad01
This commit is contained in:
Jan Edmund Lazo
2021-08-08 17:44:56 -04:00
parent 68f61b167e
commit f89a275e32
5 changed files with 97 additions and 2 deletions

View File

@@ -1038,7 +1038,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

@@ -1395,6 +1395,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
bool w_briopt_sbr; // sbr in 'briopt' bool w_briopt_sbr; // sbr in 'briopt'
int w_briopt_list; // additional indent for lists
// transform a pointer to a "onebuf" option into a "allbuf" option // transform a pointer to a "onebuf" option into a "allbuf" option
#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T)) #define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))

View File

@@ -432,7 +432,7 @@ int get_number_indent(linenr_T lnum)
// Return appropriate space number for breakindent, taking influencing // Return appropriate space number for breakindent, taking influencing
// parameters into account. Window must be specified, since it is not // parameters into account. Window must be specified, since it is not
// necessarily always the current one. // necessarily always the current one.
int get_breakindent_win(win_T *wp, const char_u *line) int get_breakindent_win(win_T *wp, char_u *line)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
static int prev_indent = 0; // Cached indent value. static int prev_indent = 0; // Cached indent value.
@@ -469,6 +469,22 @@ int get_breakindent_win(win_T *wp, const char_u *line)
// 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 = {
.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;

View File

@@ -7426,6 +7426,7 @@ static bool briopt_check(win_T *wp)
int bri_shift = 0; int bri_shift = 0;
int bri_min = 20; int bri_min = 20;
bool bri_sbr = false; bool bri_sbr = false;
int bri_list = 0;
char_u *p = wp->w_p_briopt; char_u *p = wp->w_p_briopt;
while (*p != NUL) while (*p != NUL)
@@ -7445,6 +7446,9 @@ static bool 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 = (int)getdigits(&p, false, 0);
} }
if (*p != ',' && *p != NUL) { if (*p != ',' && *p != NUL) {
return false; return false;
@@ -7457,6 +7461,7 @@ static bool 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 true; return true;
} }

View File

@@ -16,6 +16,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
@@ -745,4 +749,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