summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Brabandt <cb@256bit.org>2022-01-15 10:01:05 +0000
committerBram Moolenaar <Bram@vim.org>2022-01-15 10:01:05 +0000
commitc53b467473160b5cfce77277fbae414bf43e66ce (patch)
tree0b9c46f21daf65cd1dde027cbae993bcb7d0608f
parentece07639f4989a300276d66b13553c21a7435030 (diff)
patch 8.2.4093: cached breakindent values not initialized properlyv8.2.4093
Problem: Cached breakindent values not initialized properly. Solution: Initialize and cache formatlistpat. (Christian Brabandt, closes #9526, closes #9512)
-rw-r--r--runtime/doc/options.txt1
-rw-r--r--src/indent.c17
-rw-r--r--src/option.c12
-rw-r--r--src/proto/option.pro1
-rw-r--r--src/testdir/test_breakindent.vim57
-rw-r--r--src/version.c2
6 files changed, 87 insertions, 3 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index c7fbde64fd..65ed54f046 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -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
diff --git a/src/indent.c b/src/indent.c
index b74bae6e69..a1012d2689 100644
--- 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
index 169f92998a..0a75c2417c 100644
--- 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
index 2390f58776..a099624d5d 100644
--- 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
index 0c143b1943..2ac127dd54 100644
--- 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 \<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
diff --git a/src/version.c b/src/version.c
index 1dd5c96fd4..5869c2694a 100644
--- 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,