Skip to content

Commit

Permalink
patch 8.2.4093: cached breakindent values not initialized properly
Browse files Browse the repository at this point in the history
Problem:    Cached breakindent values not initialized properly.
Solution:   Initialize and cache formatlistpat. (Christian Brabandt,
            closes #9526, closes #9512)
  • Loading branch information
chrisbra authored and brammool committed Jan 15, 2022
1 parent ece0763 commit c53b467
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 3 deletions.
1 change: 1 addition & 0 deletions runtime/doc/options.txt
Expand Up @@ -1370,6 +1370,7 @@ A jump table for the options with a short description can be found at |Q_op|.
text should normally be narrower. This prevents
text indented almost to the right window border
occupying lot of vertical space when broken.
(default: 20)
shift:{n} After applying 'breakindent', the wrapped line's
beginning will be shifted by the given number of
characters. It permits dynamic French paragraph
Expand Down
17 changes: 14 additions & 3 deletions src/indent.c
Expand Up @@ -924,17 +924,25 @@ get_breakindent_win(
# endif
static int prev_list = 0; // cached list value
static int prev_listopt = 0; // cached w_p_briopt_list value
// cached formatlistpat value
static char_u *prev_flp = NULL;
int bri = 0;
// window width minus window margin space, i.e. what rests for text
const int eff_wwidth = wp->w_width
- ((wp->w_p_nu || wp->w_p_rnu)
&& (vim_strchr(p_cpo, CPO_NUMCOL) == NULL)
? number_width(wp) + 1 : 0);

// used cached indent, unless line, 'tabstop' or briopt_list changed
// used cached indent, unless
// - line pointer changed
// - 'tabstop' changed
// - 'briopt_list changed' changed or
// - 'formatlistpattern' changed
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|| prev_tick != CHANGEDTICK(wp->w_buffer)
|| prev_listopt != wp->w_briopt_list
|| (prev_flp == NULL
|| (STRCMP(prev_flp, get_flp_value(wp->w_buffer)) != 0))
# ifdef FEAT_VARTABS
|| prev_vts != wp->w_buffer->b_p_vts_array
# endif
Expand All @@ -953,13 +961,16 @@ get_breakindent_win(
(int)wp->w_buffer->b_p_ts, wp->w_p_list);
# endif
prev_listopt = wp->w_briopt_list;
prev_list = 0;
vim_free(prev_flp);
prev_flp = vim_strsave(get_flp_value(wp->w_buffer));
// 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);
regmatch.regprog = vim_regcomp(prev_flp,
RE_MAGIC + RE_STRING + RE_AUTO + RE_STRICT);

if (regmatch.regprog != NULL)
{
Expand Down
12 changes: 12 additions & 0 deletions src/option.c
Expand Up @@ -7052,6 +7052,18 @@ get_bkc_value(buf_T *buf)
return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
}

/*
* Get the local or global value of 'formatlistpat'.
*/
char_u *
get_flp_value(buf_T *buf)
{
return buf->b_p_flp ? buf->b_p_flp : p_flp;
if (buf->b_p_flp == NULL || *buf->b_p_flp == NUL)
return p_flp;
return buf->b_p_flp;
}

/*
* Get the local or global value of the 'virtualedit' flags.
*/
Expand Down
1 change: 1 addition & 0 deletions src/proto/option.pro
Expand Up @@ -73,6 +73,7 @@ int can_bs(int what);
long get_scrolloff_value(void);
long get_sidescrolloff_value(void);
unsigned int get_bkc_value(buf_T *buf);
char_u *get_flp_value(buf_T *buf);
unsigned int get_ve_flags(void);
char_u *get_showbreak_value(win_T *win);
dict_T *get_winbuf_options(int bufopt);
Expand Down
57 changes: 57 additions & 0 deletions src/testdir/test_breakindent.vim
Expand Up @@ -849,4 +849,61 @@ func Test_window_resize_with_linebreak()
%bw!
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()
call s:test_windows('setl breakindent breakindentopt=list:-1,min:10')
%d
let &l:formatlistpat='^\s*\d\+\.\s\+'
let text = 'word '
let len = text->strcharlen()
let line1 = text->repeat((winwidth(0) / len) * 2)
let line2 = repeat(' ', 2) .. '1. ' .. line1
call setline(1, [line2])
redraw!
" 1) matches formatlist pattern, so indent
let expect = [
\ " 1. word word word ",
\ " word word word ",
\ " word word ",
\ "~ ",
\ ]
let lines = s:screen_lines2(1, 4, 20)
call s:compare_lines(expect, lines)
" 2) change formatlist pattern
" -> indent adjusted
let &l:formatlistpat='^\s*\d\+\.'
let expect = [
\ " 1. word word word ",
\ " word word word ",
\ " word word ",
\ "~ ",
\ ]
let lines = s:screen_lines2(1, 4, 20)
" 3) add something in front, no additional indent
norm! gg0
exe ":norm! 5iword \<esc>"
redraw!
let expect = [
\ "word word word word ",
\ "word 1. word word ",
\ "word word word word ",
\ "word word ",
\ "~ ",
\ ]
let lines = s:screen_lines2(1, 5, 20)
call s:compare_lines(expect, lines)
bwipeout!
endfunc

" vim: shiftwidth=2 sts=2 expandtab
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -750,6 +750,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
4093,
/**/
4092,
/**/
Expand Down

0 comments on commit c53b467

Please sign in to comment.