vim-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 vim/vim#9526, closes vim/vim#9512)
c53b467473

Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
zeertzjq
2022-04-01 18:12:55 +08:00
parent 3e60b9f1cc
commit b92ed35a0b
4 changed files with 81 additions and 3 deletions

View File

@@ -1053,6 +1053,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 should normally be narrower. This prevents
text indented almost to the right window border text indented almost to the right window border
occupying lot of vertical space when broken. occupying lot of vertical space when broken.
(default: 20)
shift:{n} After applying 'breakindent', the wrapped line's shift:{n} After applying 'breakindent', the wrapped line's
beginning will be shifted by the given number of beginning will be shifted by the given number of
characters. It permits dynamic French paragraph characters. It permits dynamic French paragraph

View File

@@ -789,16 +789,22 @@ int get_breakindent_win(win_T *wp, char_u *line)
static long *prev_vts = NULL; // Cached vartabs values. static long *prev_vts = NULL; // Cached vartabs values.
static int prev_list = 0; // cached list value static int prev_list = 0; // cached list value
static int prev_listopt = 0; // cached w_p_briopt_list value static int prev_listopt = 0; // cached w_p_briopt_list value
static char *prev_flp = NULL; // cached formatlistpat value
int bri = 0; int bri = 0;
// window width minus window margin space, i.e. what rests for text // window width minus window margin space, i.e. what rests for text
const int eff_wwidth = wp->w_width_inner - const int eff_wwidth = wp->w_width_inner -
((wp->w_p_nu || wp->w_p_rnu) ((wp->w_p_nu || wp->w_p_rnu)
&& (vim_strchr(p_cpo, CPO_NUMCOL) == NULL) ? number_width(wp) + 1 : 0); && (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 if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|| prev_tick != buf_get_changedtick(wp->w_buffer) || prev_tick != buf_get_changedtick(wp->w_buffer)
|| prev_listopt != wp->w_briopt_list || prev_listopt != wp->w_briopt_list
|| (prev_flp == NULL || (strcmp(prev_flp, get_flp_value(wp->w_buffer)) != 0))
|| prev_vts != wp->w_buffer->b_p_vts_array) { || prev_vts != wp->w_buffer->b_p_vts_array) {
prev_line = line; prev_line = line;
prev_ts = wp->w_buffer->b_p_ts; prev_ts = wp->w_buffer->b_p_ts;
@@ -809,11 +815,13 @@ int get_breakindent_win(win_T *wp, char_u *line)
wp->w_buffer->b_p_vts_array, wp->w_buffer->b_p_vts_array,
wp->w_p_list); wp->w_p_list);
prev_listopt = wp->w_briopt_list; prev_listopt = wp->w_briopt_list;
prev_list = 0;
xfree(prev_flp);
prev_flp = xstrdup(get_flp_value(wp->w_buffer));
// add additional indent for numbered lists // add additional indent for numbered lists
if (wp->w_briopt_list != 0) { if (wp->w_briopt_list != 0) {
regmatch_T regmatch = { regmatch_T regmatch = {
.regprog = vim_regcomp(curbuf->b_p_flp, .regprog = vim_regcomp(prev_flp, RE_MAGIC + RE_STRING + RE_AUTO + RE_STRICT),
RE_MAGIC + RE_STRING + RE_AUTO + RE_STRICT),
}; };
if (regmatch.regprog != NULL) { if (regmatch.regprog != NULL) {
regmatch.rm_ic = false; regmatch.rm_ic = false;

View File

@@ -5220,6 +5220,18 @@ unsigned int get_bkc_value(buf_T *buf)
return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags; return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
} }
/// Get the local or global value of 'formatlistpat'.
///
/// @param buf The buffer.
char *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. /// Get the local or global value of the 'virtualedit' flags.
unsigned int get_ve_flags(void) unsigned int get_ve_flags(void)
{ {

View File

@@ -889,4 +889,61 @@ func Test_window_resize_with_linebreak()
%bw! %bw!
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab