# HG changeset patch # User Bram Moolenaar # Date 1642241703 -3600 # Node ID 164d59ddd48a5a59be249de198d6d51e6f8acb4c # Parent 33918a28ec46a7933209c8db1364ef2cfecf4bd4 patch 8.2.4093: cached breakindent values not initialized properly Commit: https://github.com/vim/vim/commit/c53b467473160b5cfce77277fbae414bf43e66ce Author: Christian Brabandt Date: Sat Jan 15 10:01:05 2022 +0000 patch 8.2.4093: cached breakindent values not initialized properly Problem: Cached breakindent values not initialized properly. Solution: Initialize and cache formatlistpat. (Christian Brabandt, closes #9526, closes #9512) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1370,6 +1370,7 @@ A jump table for the options with a shor 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 diff --git a/src/indent.c b/src/indent.c --- a/src/indent.c +++ b/src/indent.c @@ -924,6 +924,8 @@ 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 @@ -931,10 +933,16 @@ get_breakindent_win( && (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 @@ -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) { diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -7053,6 +7053,18 @@ get_bkc_value(buf_T *buf) } /* + * 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. */ unsigned int diff --git a/src/proto/option.pro b/src/proto/option.pro --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -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); diff --git a/src/testdir/test_breakindent.vim b/src/testdir/test_breakindent.vim --- a/src/testdir/test_breakindent.vim +++ b/src/testdir/test_breakindent.vim @@ -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 \" + 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 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4093, +/**/ 4092, /**/ 4091,