diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-02-11 17:16:19 +0100 |
---|---|---|
committer | Christian Brabandt <cb@256bit.org> | 2024-02-11 17:16:19 +0100 |
commit | efabd7c8d4f733350364356b8950a11f013aec49 (patch) | |
tree | 4f98be4825f10911b6eb520904c0fafd2bcf745e /src/indent.c | |
parent | b614b284ee06523511308f8381b47db34d921d39 (diff) |
patch 9.1.0097: 'breakindent' behaves inconsistently with 'list' and splitsv9.1.0097
Problem: 'breakindent' behaves inconsistently with 'list' and splits.
Solution: Use 'listchars' from the correct window and handle caching
properly. Move cheaper comparisons to the top.
(zeertzjq)
closes: #14008
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Diffstat (limited to 'src/indent.c')
-rw-r--r-- | src/indent.c | 64 |
1 files changed, 35 insertions, 29 deletions
diff --git a/src/indent.c b/src/indent.c index 1858ecf8f3..34d31579bd 100644 --- a/src/indent.c +++ b/src/indent.c @@ -434,20 +434,17 @@ get_indent_buf(buf_T *buf, linenr_T lnum) get_indent_str( char_u *ptr, int ts, - int list) // if TRUE, count only screen size for tabs + int no_ts) // if TRUE, count a tab as ^I { int count = 0; for ( ; *ptr; ++ptr) { - if (*ptr == TAB) + if (*ptr == TAB) // count a tab for what it is worth { - if (!list || curwin->w_lcs_chars.tab1) - // count a tab for what it is worth + if (!no_ts) count += ts - (count % ts); else - // In list mode, when tab is not set, count screen char width - // for Tab, displays: ^I count += ptr2cells(ptr); } else if (*ptr == ' ') @@ -462,10 +459,10 @@ get_indent_str( /* * Count the size (in window cells) of the indent in line "ptr", using * variable tabstops. - * if "list" is TRUE, count only screen size for tabs. + * If "no_ts" is TRUE, count a tab as ^I. */ int -get_indent_str_vtab(char_u *ptr, int ts, int *vts, int list) +get_indent_str_vtab(char_u *ptr, int ts, int *vts, int no_ts) { int count = 0; @@ -473,11 +470,9 @@ get_indent_str_vtab(char_u *ptr, int ts, int *vts, int list) { if (*ptr == TAB) // count a tab for what it is worth { - if (!list || curwin->w_lcs_chars.tab1) + if (!no_ts) count += tabstop_padding(count, ts, vts); else - // In list mode, when tab is not set, count screen char width - // for Tab, displays: ^I count += ptr2cells(ptr); } else if (*ptr == ' ') @@ -925,14 +920,16 @@ get_breakindent_win( { static int prev_indent = 0; // cached indent value static long prev_ts = 0L; // cached tabstop value - static int prev_fnum = 0; // cached buffer number - static char_u *prev_line = NULL; // cached copy of "line" - static varnumber_T prev_tick = 0; // changedtick of cached value # ifdef FEAT_VARTABS static int *prev_vts = NULL; // cached vartabs values # endif - static int prev_list = 0; // cached list value + static int prev_fnum = 0; // cached buffer number + static char_u *prev_line = NULL; // cached copy of "line" + static varnumber_T prev_tick = 0; // changedtick of cached value + static int prev_list = 0; // cached list indent static int prev_listopt = 0; // cached w_p_briopt_list value + static int prev_no_ts = FALSE; // cached no_ts value + static unsigned prev_dy_uhex = 0; // cached 'display' "uhex" value // cached formatlistpat value static char_u *prev_flp = NULL; int bri = 0; @@ -942,44 +939,53 @@ get_breakindent_win( && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL) ? number_width(wp) + 1 : 0); - // used cached indent, unless - // - buffer changed - // - 'tabstop' changed - // - buffer was changed - // - 'briopt_list changed' changed or - // - 'formatlistpattern' changed - // - line changed - // - 'vartabs' changed + // In list mode, if 'listchars' "tab" isn't set, a TAB is displayed as ^I. + int no_ts = wp->w_p_list && wp->w_lcs_chars.tab1 == NUL; + + // Used cached indent, unless + // - buffer changed, or + // - 'tabstop' changed, or + // - 'vartabstop' changed, or + // - buffer was changed, or + // - 'breakindentopt' "list" changed, or + // - 'list' or 'listchars' "tab" changed, or + // - 'display' "uhex" flag changed, or + // - 'formatlistpat' changed, or + // - line changed. if (prev_fnum != wp->w_buffer->b_fnum || prev_ts != wp->w_buffer->b_p_ts +# ifdef FEAT_VARTABS + || prev_vts != wp->w_buffer->b_p_vts_array +# endif || prev_tick != CHANGEDTICK(wp->w_buffer) || prev_listopt != wp->w_briopt_list + || prev_no_ts != no_ts + || prev_dy_uhex != (dy_flags & DY_UHEX) || prev_flp == NULL || STRCMP(prev_flp, get_flp_value(wp->w_buffer)) != 0 || prev_line == NULL || STRCMP(prev_line, line) != 0 -# ifdef FEAT_VARTABS - || prev_vts != wp->w_buffer->b_p_vts_array -# endif ) { prev_fnum = wp->w_buffer->b_fnum; vim_free(prev_line); prev_line = vim_strsave(line); prev_ts = wp->w_buffer->b_p_ts; - prev_tick = CHANGEDTICK(wp->w_buffer); # ifdef FEAT_VARTABS prev_vts = wp->w_buffer->b_p_vts_array; if (wp->w_briopt_vcol == 0) prev_indent = get_indent_str_vtab(line, (int)wp->w_buffer->b_p_ts, - wp->w_buffer->b_p_vts_array, wp->w_p_list); + wp->w_buffer->b_p_vts_array, no_ts); # else if (wp->w_briopt_vcol == 0) prev_indent = get_indent_str(line, - (int)wp->w_buffer->b_p_ts, wp->w_p_list); + (int)wp->w_buffer->b_p_ts, no_ts); # endif + prev_tick = CHANGEDTICK(wp->w_buffer); prev_listopt = wp->w_briopt_list; prev_list = 0; + prev_no_ts = no_ts; + prev_dy_uhex = (dy_flags & DY_UHEX); vim_free(prev_flp); prev_flp = vim_strsave(get_flp_value(wp->w_buffer)); // add additional indent for numbered lists |